diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2014-01-27 13:09:20 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-01-27 13:12:33 +0100 |
commit | 1f078fcaddd45bb074e4d0a4933db01f6e8b623e (patch) | |
tree | b3c91e350f82022ff0a4d2d20f89ea050b6ea69b /compilerplugins/clang/pluginhandler.cxx | |
parent | a94f0f92e8b09f6cd3989b646500ff5814274621 (diff) |
Prepare dual-mode compiler plugin feature
...which can act as either a rewriter or a non-rewriter that emits warnings.
Also added COMPILER_PLUGIN_WARNINGS_ONLY=X to demote warnings from plugin X from
errors to warnings, even under --enable-werror.
Change-Id: I05361936240a890515c6bba2459565417c1746b7
Diffstat (limited to 'compilerplugins/clang/pluginhandler.cxx')
-rw-r--r-- | compilerplugins/clang/pluginhandler.cxx | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/compilerplugins/clang/pluginhandler.cxx b/compilerplugins/clang/pluginhandler.cxx index a49398a53a82..440df1cf07fb 100644 --- a/compilerplugins/clang/pluginhandler.cxx +++ b/compilerplugins/clang/pluginhandler.cxx @@ -38,11 +38,11 @@ namespace loplugin struct PluginData { - Plugin* (*create)( CompilerInstance&, Rewriter& ); + Plugin* (*create)( const Plugin::InstantiationData& ); Plugin* object; const char* optionName; - bool isRewriter; bool isPPCallback; + bool byDefault; }; const int MAX_PLUGINS = 100; @@ -100,6 +100,10 @@ void PluginHandler::handleOption( const string& option ) report( DiagnosticsEngine::Fatal, "unknown scope %0 (no such module directory)" ) << scope; } } + else if( option.substr( 0, 14 ) == "warnings-only=" ) + { + warningsOnly = option.substr(14); + } else report( DiagnosticsEngine::Fatal, "unknown option %0" ) << option; } @@ -110,14 +114,17 @@ void PluginHandler::createPlugin( const string& name ) i < pluginCount; ++i ) { - if( name.empty()) // no plugin given -> create non-writer plugins + // if no plugin is given, create all by-default plugins as non- + // rewriters; otherwise, create the given plugin as a potential + // rewriter: + if( name.empty()) { - if( !plugins[ i ].isRewriter ) - plugins[ i ].object = plugins[ i ].create( compiler, rewriter ); + if( plugins[ i ].byDefault ) + plugins[ i ].object = plugins[ i ].create( Plugin::InstantiationData { plugins[ i ].optionName, *this, compiler, NULL } ); } else if( plugins[ i ].optionName == name ) { - plugins[ i ].object = plugins[ i ].create( compiler, rewriter ); + plugins[ i ].object = plugins[ i ].create( Plugin::InstantiationData { plugins[ i ].optionName, *this, compiler, &rewriter } ); return; } } @@ -125,21 +132,43 @@ void PluginHandler::createPlugin( const string& name ) report( DiagnosticsEngine::Fatal, "unknown plugin tool %0" ) << name; } -void PluginHandler::registerPlugin( Plugin* (*create)( CompilerInstance&, Rewriter& ), const char* optionName, bool isRewriter, bool isPPCallback ) +void PluginHandler::registerPlugin( Plugin* (*create)( const Plugin::InstantiationData& ), const char* optionName, bool isPPCallback, bool byDefault ) { assert( !pluginObjectsCreated ); assert( pluginCount < MAX_PLUGINS ); plugins[ pluginCount ].create = create; plugins[ pluginCount ].object = NULL; plugins[ pluginCount ].optionName = optionName; - plugins[ pluginCount ].isRewriter = isRewriter; plugins[ pluginCount ].isPPCallback = isPPCallback; + plugins[ pluginCount ].byDefault = byDefault; ++pluginCount; } +DiagnosticBuilder PluginHandler::report( DiagnosticsEngine::Level level, const char* plugin, StringRef message, CompilerInstance& compiler, + SourceLocation loc ) + { + DiagnosticsEngine& diag = compiler.getDiagnostics(); + // Do some mappings (e.g. for -Werror) that clang does not do for custom messages for some reason. + if( level == DiagnosticsEngine::Warning && diag.getWarningsAsErrors() && (plugin == nullptr || plugin != warningsOnly)) + level = DiagnosticsEngine::Error; + if( level == DiagnosticsEngine::Error && diag.getErrorsAsFatal()) + level = DiagnosticsEngine::Fatal; + string fullMessage = ( message + " [loplugin" ).str(); + if( plugin ) + { + fullMessage += ":"; + fullMessage += plugin; + } + fullMessage += "]"; + if( loc.isValid()) + return diag.Report( loc, diag.getCustomDiagID( level, fullMessage )); + else + return diag.Report( diag.getCustomDiagID( level, fullMessage )); + } + DiagnosticBuilder PluginHandler::report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc ) { - return Plugin::report( level, message, compiler, loc ); + return report( level, nullptr, message, compiler, loc ); } void PluginHandler::HandleTranslationUnit( ASTContext& context ) |