summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/pluginhandler.cxx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2014-01-27 13:09:20 +0100
committerStephan Bergmann <sbergman@redhat.com>2014-01-27 13:12:33 +0100
commit1f078fcaddd45bb074e4d0a4933db01f6e8b623e (patch)
treeb3c91e350f82022ff0a4d2d20f89ea050b6ea69b /compilerplugins/clang/pluginhandler.cxx
parenta94f0f92e8b09f6cd3989b646500ff5814274621 (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.cxx47
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 )