Kaydet (Commit) 1f078fca authored tarafından Stephan Bergmann's avatar Stephan Bergmann

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
üst a94f0f92
...@@ -46,6 +46,22 @@ Additional optional make arguments: ...@@ -46,6 +46,22 @@ Additional optional make arguments:
Modifications will be written directly to the source files. Modifications will be written directly to the source files.
Some rewriter plugins are dual-mode and can also be used in a non-rewriting mode
in which they emit warnings for problematic code that they would otherwise
automatically rewrite. When any rewriter is enabled explicitly via "make
COMPILER_PLUGIN_TOOL=<rewriter_name>" it works in rewriting mode (and all other
plugins are disabled), but when no rewriter is explicitly enabled (i.e., just
"make"), all dual-mode rewriters are enabled in non-rewriting mode (along with
all non-rewriter plugins; and all non--dual-mode plugins are disabled). The
typical process to use such a dual-mode rewriter X in rewriting mode is
make COMPILER_PLUGIN_WARNINGS_ONLY=X \
&& make COMPILER_PLUGIN_TOOL=X FORCE_COMPILE_ALL=1 UPDATE_FILES=all
which first generates a full build without failing due to warnings from plugin
X in non-rewriting mode (in case of --enable-werror) and then repeats the build
in rewriting mode (during which no object files are generate).
== Code documentation / howtos == == Code documentation / howtos ==
......
...@@ -29,8 +29,8 @@ For example: ...@@ -29,8 +29,8 @@ For example:
Here either both statements should be inside {} or the second statement in indented wrong. Here either both statements should be inside {} or the second statement in indented wrong.
*/ */
BodyNotInBlock::BodyNotInBlock( CompilerInstance& compiler ) BodyNotInBlock::BodyNotInBlock( const InstantiationData& data )
: Plugin( compiler ) : Plugin( data )
{ {
} }
......
...@@ -22,7 +22,7 @@ class BodyNotInBlock ...@@ -22,7 +22,7 @@ class BodyNotInBlock
, public Plugin , public Plugin
{ {
public: public:
explicit BodyNotInBlock( CompilerInstance& compiler ); explicit BodyNotInBlock( const InstantiationData& data );
virtual void run() override; virtual void run() override;
bool VisitIfStmt( const IfStmt* stmt ); bool VisitIfStmt( const IfStmt* stmt );
bool VisitWhileStmt( const WhileStmt* stmt ); bool VisitWhileStmt( const WhileStmt* stmt );
......
...@@ -31,7 +31,7 @@ class CheckConfigMacros ...@@ -31,7 +31,7 @@ class CheckConfigMacros
, public Plugin , public Plugin
{ {
public: public:
explicit CheckConfigMacros( CompilerInstance& compiler ); explicit CheckConfigMacros( const InstantiationData& data );
virtual void run() override; virtual void run() override;
#if __clang_major__ < 3 || __clang_major__ == 3 && __clang_minor__ < 3 #if __clang_major__ < 3 || __clang_major__ == 3 && __clang_minor__ < 3
virtual void MacroDefined( const Token& macroToken, const MacroInfo* info ) override; virtual void MacroDefined( const Token& macroToken, const MacroInfo* info ) override;
...@@ -56,8 +56,8 @@ class CheckConfigMacros ...@@ -56,8 +56,8 @@ class CheckConfigMacros
std::set< string > configMacros; std::set< string > configMacros;
}; };
CheckConfigMacros::CheckConfigMacros( CompilerInstance& compiler ) CheckConfigMacros::CheckConfigMacros( const InstantiationData& data )
: Plugin( compiler ) : Plugin( data )
{ {
compiler.getPreprocessor().addPPCallbacks( this ); compiler.getPreprocessor().addPPCallbacks( this );
} }
......
...@@ -99,8 +99,8 @@ class ImplicitBoolConversion: ...@@ -99,8 +99,8 @@ class ImplicitBoolConversion:
public RecursiveASTVisitor<ImplicitBoolConversion>, public loplugin::Plugin public RecursiveASTVisitor<ImplicitBoolConversion>, public loplugin::Plugin
{ {
public: public:
explicit ImplicitBoolConversion(CompilerInstance & compiler): explicit ImplicitBoolConversion(InstantiationData const & data):
Plugin(compiler) {} Plugin(data) {}
virtual void run() override virtual void run() override
{ TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
......
...@@ -21,7 +21,7 @@ class LiteralAlternative: ...@@ -21,7 +21,7 @@ class LiteralAlternative:
public RecursiveASTVisitor<LiteralAlternative>, public loplugin::Plugin public RecursiveASTVisitor<LiteralAlternative>, public loplugin::Plugin
{ {
public: public:
explicit LiteralAlternative(CompilerInstance & compiler): Plugin(compiler) {} explicit LiteralAlternative(InstantiationData const & data): Plugin(data) {}
virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "plugin.hxx" #include "plugin.hxx"
#include <cassert>
#include <clang/Basic/FileManager.h> #include <clang/Basic/FileManager.h>
#include <clang/Lex/Lexer.h> #include <clang/Lex/Lexer.h>
...@@ -22,30 +24,14 @@ Base classes for plugin actions. ...@@ -22,30 +24,14 @@ Base classes for plugin actions.
namespace loplugin namespace loplugin
{ {
Plugin::Plugin( CompilerInstance& compiler ) Plugin::Plugin( const InstantiationData& data )
: compiler( compiler ) : compiler( data.compiler ), name( data.name ), handler( data.handler )
{ {
} }
DiagnosticBuilder Plugin::report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc ) DiagnosticBuilder Plugin::report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc )
{ {
return report( level, message, compiler, loc ); return handler.report( level, name, message, compiler, loc );
}
DiagnosticBuilder Plugin::report( DiagnosticsEngine::Level level, 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())
level = DiagnosticsEngine::Error;
if( level == DiagnosticsEngine::Error && diag.getErrorsAsFatal())
level = DiagnosticsEngine::Fatal;
string fullMessage = ( message + " [loplugin]" ).str();
if( loc.isValid())
return diag.Report( loc, diag.getCustomDiagID( level, fullMessage ));
else
return diag.Report( diag.getCustomDiagID( level, fullMessage ));
} }
bool Plugin::ignoreLocation( SourceLocation loc ) bool Plugin::ignoreLocation( SourceLocation loc )
...@@ -63,9 +49,9 @@ bool Plugin::ignoreLocation( SourceLocation loc ) ...@@ -63,9 +49,9 @@ bool Plugin::ignoreLocation( SourceLocation loc )
return true; return true;
} }
void Plugin::registerPlugin( Plugin* (*create)( CompilerInstance&, Rewriter& ), const char* optionName, bool isRewriter, bool isPPCallback ) void Plugin::registerPlugin( Plugin* (*create)( const InstantiationData& ), const char* optionName, bool isPPCallback, bool byDefault )
{ {
PluginHandler::registerPlugin( create, optionName, isRewriter, isPPCallback ); PluginHandler::registerPlugin( create, optionName, isPPCallback, byDefault );
} }
unordered_map< const Stmt*, const Stmt* > Plugin::parents; unordered_map< const Stmt*, const Stmt* > Plugin::parents;
...@@ -152,36 +138,40 @@ SourceLocation Plugin::locationAfterToken( SourceLocation location ) ...@@ -152,36 +138,40 @@ SourceLocation Plugin::locationAfterToken( SourceLocation location )
///// /////
RewritePlugin::RewritePlugin( CompilerInstance& compiler, Rewriter& rewriter ) RewritePlugin::RewritePlugin( const InstantiationData& data )
: Plugin( compiler ) : Plugin( data )
, rewriter( rewriter ) , rewriter( data.rewriter )
{ {
} }
bool RewritePlugin::insertText( SourceLocation Loc, StringRef Str, bool InsertAfter, bool indentNewLines ) bool RewritePlugin::insertText( SourceLocation Loc, StringRef Str, bool InsertAfter, bool indentNewLines )
{ {
if( rewriter.InsertText( Loc, Str, InsertAfter, indentNewLines )) assert( rewriter );
if( rewriter->InsertText( Loc, Str, InsertAfter, indentNewLines ))
return reportEditFailure( Loc ); return reportEditFailure( Loc );
return true; return true;
} }
bool RewritePlugin::insertTextAfter( SourceLocation Loc, StringRef Str ) bool RewritePlugin::insertTextAfter( SourceLocation Loc, StringRef Str )
{ {
if( rewriter.InsertTextAfter( Loc, Str )) assert( rewriter );
if( rewriter->InsertTextAfter( Loc, Str ))
return reportEditFailure( Loc ); return reportEditFailure( Loc );
return true; return true;
} }
bool RewritePlugin::insertTextAfterToken( SourceLocation Loc, StringRef Str ) bool RewritePlugin::insertTextAfterToken( SourceLocation Loc, StringRef Str )
{ {
if( rewriter.InsertTextAfterToken( Loc, Str )) assert( rewriter );
if( rewriter->InsertTextAfterToken( Loc, Str ))
return reportEditFailure( Loc ); return reportEditFailure( Loc );
return true; return true;
} }
bool RewritePlugin::insertTextBefore( SourceLocation Loc, StringRef Str ) bool RewritePlugin::insertTextBefore( SourceLocation Loc, StringRef Str )
{ {
if( rewriter.InsertTextBefore( Loc, Str )) assert( rewriter );
if( rewriter->InsertTextBefore( Loc, Str ))
return reportEditFailure( Loc ); return reportEditFailure( Loc );
return true; return true;
} }
...@@ -199,7 +189,8 @@ bool RewritePlugin::removeText( SourceRange range, RewriteOptions opts ) ...@@ -199,7 +189,8 @@ bool RewritePlugin::removeText( SourceRange range, RewriteOptions opts )
bool RewritePlugin::removeText( CharSourceRange range, RewriteOptions opts ) bool RewritePlugin::removeText( CharSourceRange range, RewriteOptions opts )
{ {
if( rewriter.getRangeSize( range, opts ) == -1 ) assert( rewriter );
if( rewriter->getRangeSize( range, opts ) == -1 )
return reportEditFailure( range.getBegin()); return reportEditFailure( range.getBegin());
if( removals.find( range.getBegin()) != removals.end()) if( removals.find( range.getBegin()) != removals.end())
report( DiagnosticsEngine::Warning, "double code removal, possible plugin error", range.getBegin()); report( DiagnosticsEngine::Warning, "double code removal, possible plugin error", range.getBegin());
...@@ -209,14 +200,15 @@ bool RewritePlugin::removeText( CharSourceRange range, RewriteOptions opts ) ...@@ -209,14 +200,15 @@ bool RewritePlugin::removeText( CharSourceRange range, RewriteOptions opts )
if( !adjustRangeForOptions( &range, opts )) if( !adjustRangeForOptions( &range, opts ))
return reportEditFailure( range.getBegin()); return reportEditFailure( range.getBegin());
} }
if( rewriter.RemoveText( range, opts )) if( rewriter->RemoveText( range, opts ))
return reportEditFailure( range.getBegin()); return reportEditFailure( range.getBegin());
return true; return true;
} }
bool RewritePlugin::adjustRangeForOptions( CharSourceRange* range, RewriteOptions opts ) bool RewritePlugin::adjustRangeForOptions( CharSourceRange* range, RewriteOptions opts )
{ {
SourceManager& SM = rewriter.getSourceMgr(); assert( rewriter );
SourceManager& SM = rewriter->getSourceMgr();
SourceLocation fileStartLoc = SM.getLocForStartOfFile( SM.getFileID( range->getBegin())); SourceLocation fileStartLoc = SM.getLocForStartOfFile( SM.getFileID( range->getBegin()));
if( fileStartLoc.isInvalid()) if( fileStartLoc.isInvalid())
return false; return false;
...@@ -256,34 +248,37 @@ bool RewritePlugin::adjustRangeForOptions( CharSourceRange* range, RewriteOption ...@@ -256,34 +248,37 @@ bool RewritePlugin::adjustRangeForOptions( CharSourceRange* range, RewriteOption
bool RewritePlugin::replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr ) bool RewritePlugin::replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr )
{ {
assert( rewriter );
if( OrigLength != 0 && removals.find( Start ) != removals.end()) if( OrigLength != 0 && removals.find( Start ) != removals.end())
report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", Start ); report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", Start );
removals.insert( Start ); removals.insert( Start );
if( rewriter.ReplaceText( Start, OrigLength, NewStr )) if( rewriter->ReplaceText( Start, OrigLength, NewStr ))
return reportEditFailure( Start ); return reportEditFailure( Start );
return true; return true;
} }
bool RewritePlugin::replaceText( SourceRange range, StringRef NewStr ) bool RewritePlugin::replaceText( SourceRange range, StringRef NewStr )
{ {
if( rewriter.getRangeSize( range ) == -1 ) assert( rewriter );
if( rewriter->getRangeSize( range ) == -1 )
return reportEditFailure( range.getBegin()); return reportEditFailure( range.getBegin());
if( removals.find( range.getBegin()) != removals.end()) if( removals.find( range.getBegin()) != removals.end())
report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", range.getBegin()); report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", range.getBegin());
removals.insert( range.getBegin()); removals.insert( range.getBegin());
if( rewriter.ReplaceText( range, NewStr )) if( rewriter->ReplaceText( range, NewStr ))
return reportEditFailure( range.getBegin()); return reportEditFailure( range.getBegin());
return true; return true;
} }
bool RewritePlugin::replaceText( SourceRange range, SourceRange replacementRange ) bool RewritePlugin::replaceText( SourceRange range, SourceRange replacementRange )
{ {
if( rewriter.getRangeSize( range ) == -1 ) assert( rewriter );
if( rewriter->getRangeSize( range ) == -1 )
return reportEditFailure( range.getBegin()); return reportEditFailure( range.getBegin());
if( removals.find( range.getBegin()) != removals.end()) if( removals.find( range.getBegin()) != removals.end())
report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", range.getBegin()); report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", range.getBegin());
removals.insert( range.getBegin()); removals.insert( range.getBegin());
if( rewriter.ReplaceText( range, replacementRange )) if( rewriter->ReplaceText( range, replacementRange ))
return reportEditFailure( range.getBegin()); return reportEditFailure( range.getBegin());
return true; return true;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <clang/Basic/FileManager.h> #include <clang/Basic/FileManager.h>
#include <clang/Basic/SourceManager.h> #include <clang/Basic/SourceManager.h>
#include <clang/Frontend/CompilerInstance.h> #include <clang/Frontend/CompilerInstance.h>
#include <clang/Lex/Preprocessor.h>
#include <set> #include <set>
#include <unordered_map> #include <unordered_map>
...@@ -35,6 +36,8 @@ using namespace std; ...@@ -35,6 +36,8 @@ using namespace std;
namespace loplugin namespace loplugin
{ {
class PluginHandler;
/** /**
Base class for plugins. Base class for plugins.
...@@ -44,17 +47,22 @@ namespace loplugin ...@@ -44,17 +47,22 @@ namespace loplugin
class Plugin class Plugin
{ {
public: public:
explicit Plugin( CompilerInstance& compiler ); struct InstantiationData
{
const char* name;
PluginHandler& handler;
CompilerInstance& compiler;
Rewriter* rewriter;
};
explicit Plugin( const InstantiationData& data );
virtual ~Plugin(); virtual ~Plugin();
virtual void run() = 0; virtual void run() = 0;
template< typename T > class Registration; template< typename T > class Registration;
enum { isPPCallback = false }; enum { isPPCallback = false };
DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc = SourceLocation());
static DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message,
CompilerInstance& compiler, SourceLocation loc = SourceLocation());
// Returns location right after the end of the token that starts at the given location. // Returns location right after the end of the token that starts at the given location.
SourceLocation locationAfterToken( SourceLocation location ); SourceLocation locationAfterToken( SourceLocation location );
protected: protected:
DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc = SourceLocation());
bool ignoreLocation( SourceLocation loc ); bool ignoreLocation( SourceLocation loc );
bool ignoreLocation( const Decl* decl ); bool ignoreLocation( const Decl* decl );
bool ignoreLocation( const Stmt* stmt ); bool ignoreLocation( const Stmt* stmt );
...@@ -66,9 +74,11 @@ class Plugin ...@@ -66,9 +74,11 @@ class Plugin
const Stmt* parentStmt( const Stmt* stmt ); const Stmt* parentStmt( const Stmt* stmt );
Stmt* parentStmt( Stmt* stmt ); Stmt* parentStmt( Stmt* stmt );
private: private:
static void registerPlugin( Plugin* (*create)( CompilerInstance&, Rewriter& ), const char* optionName, bool isRewriter, bool isPPCallback ); static void registerPlugin( Plugin* (*create)( const InstantiationData& ), const char* optionName, bool isPPCallback, bool byDefault );
template< typename T > static Plugin* createHelper( CompilerInstance& compiler, Rewriter& rewriter ); template< typename T > static Plugin* createHelper( const InstantiationData& data );
enum { isRewriter = false }; enum { isRewriter = false };
const char* name;
PluginHandler& handler;
static unordered_map< const Stmt*, const Stmt* > parents; static unordered_map< const Stmt*, const Stmt* > parents;
static void buildParents( CompilerInstance& compiler ); static void buildParents( CompilerInstance& compiler );
}; };
...@@ -82,7 +92,7 @@ class RewritePlugin ...@@ -82,7 +92,7 @@ class RewritePlugin
: public Plugin : public Plugin
{ {
public: public:
explicit RewritePlugin( CompilerInstance& compiler, Rewriter& rewriter ); explicit RewritePlugin( const InstantiationData& data );
protected: protected:
enum RewriteOption enum RewriteOption
{ {
...@@ -123,10 +133,9 @@ class RewritePlugin ...@@ -123,10 +133,9 @@ class RewritePlugin
bool replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr ); bool replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr );
bool replaceText( SourceRange range, StringRef NewStr ); bool replaceText( SourceRange range, StringRef NewStr );
bool replaceText( SourceRange range, SourceRange replacementRange ); bool replaceText( SourceRange range, SourceRange replacementRange );
Rewriter& rewriter; Rewriter* rewriter;
private: private:
template< typename T > friend class Plugin::Registration; template< typename T > friend class Plugin::Registration;
template< typename T > static Plugin* createHelper( CompilerInstance& compiler, Rewriter& rewriter );
enum { isRewriter = true }; enum { isRewriter = true };
bool reportEditFailure( SourceLocation loc ); bool reportEditFailure( SourceLocation loc );
bool adjustRangeForOptions( CharSourceRange* range, RewriteOptions options ); bool adjustRangeForOptions( CharSourceRange* range, RewriteOptions options );
...@@ -148,13 +157,13 @@ template< typename T > ...@@ -148,13 +157,13 @@ template< typename T >
class Plugin::Registration class Plugin::Registration
{ {
public: public:
Registration( const char* optionName ); Registration( const char* optionName, bool byDefault = !T::isRewriter );
}; };
class RegistrationCreate class RegistrationCreate
{ {
public: public:
template< typename T, bool > static T* create( CompilerInstance& compiler, Rewriter& rewriter ); template< typename T, bool > static T* create( const Plugin::InstantiationData& data );
}; };
///// /////
...@@ -177,22 +186,16 @@ bool Plugin::ignoreLocation( const Stmt* stmt ) ...@@ -177,22 +186,16 @@ bool Plugin::ignoreLocation( const Stmt* stmt )
} }
template< typename T > template< typename T >
Plugin* Plugin::createHelper( CompilerInstance& compiler, Rewriter& ) Plugin* Plugin::createHelper( const InstantiationData& data )
{
return new T( compiler );
}
template< typename T >
Plugin* RewritePlugin::createHelper( CompilerInstance& compiler, Rewriter& rewriter )
{ {
return new T( compiler, rewriter ); return new T( data );
} }
template< typename T > template< typename T >
inline inline
Plugin::Registration< T >::Registration( const char* optionName ) Plugin::Registration< T >::Registration( const char* optionName, bool byDefault )
{ {
registerPlugin( &T::template createHelper< T >, optionName, T::isRewriter, T::isPPCallback ); registerPlugin( &T::template createHelper< T >, optionName, T::isPPCallback, byDefault );
} }
inline inline
......
...@@ -38,11 +38,11 @@ namespace loplugin ...@@ -38,11 +38,11 @@ namespace loplugin
struct PluginData struct PluginData
{ {
Plugin* (*create)( CompilerInstance&, Rewriter& ); Plugin* (*create)( const Plugin::InstantiationData& );
Plugin* object; Plugin* object;
const char* optionName; const char* optionName;
bool isRewriter;
bool isPPCallback; bool isPPCallback;
bool byDefault;
}; };
const int MAX_PLUGINS = 100; const int MAX_PLUGINS = 100;
...@@ -100,6 +100,10 @@ void PluginHandler::handleOption( const string& option ) ...@@ -100,6 +100,10 @@ void PluginHandler::handleOption( const string& option )
report( DiagnosticsEngine::Fatal, "unknown scope %0 (no such module directory)" ) << scope; report( DiagnosticsEngine::Fatal, "unknown scope %0 (no such module directory)" ) << scope;
} }
} }
else if( option.substr( 0, 14 ) == "warnings-only=" )
{
warningsOnly = option.substr(14);
}
else else
report( DiagnosticsEngine::Fatal, "unknown option %0" ) << option; report( DiagnosticsEngine::Fatal, "unknown option %0" ) << option;
} }
...@@ -110,14 +114,17 @@ void PluginHandler::createPlugin( const string& name ) ...@@ -110,14 +114,17 @@ void PluginHandler::createPlugin( const string& name )
i < pluginCount; i < pluginCount;
++i ) ++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 ) if( plugins[ i ].byDefault )
plugins[ i ].object = plugins[ i ].create( compiler, rewriter ); plugins[ i ].object = plugins[ i ].create( Plugin::InstantiationData { plugins[ i ].optionName, *this, compiler, NULL } );
} }
else if( plugins[ i ].optionName == name ) 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; return;
} }
} }
...@@ -125,21 +132,43 @@ void PluginHandler::createPlugin( const string& name ) ...@@ -125,21 +132,43 @@ void PluginHandler::createPlugin( const string& name )
report( DiagnosticsEngine::Fatal, "unknown plugin tool %0" ) << 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( !pluginObjectsCreated );
assert( pluginCount < MAX_PLUGINS ); assert( pluginCount < MAX_PLUGINS );
plugins[ pluginCount ].create = create; plugins[ pluginCount ].create = create;
plugins[ pluginCount ].object = NULL; plugins[ pluginCount ].object = NULL;
plugins[ pluginCount ].optionName = optionName; plugins[ pluginCount ].optionName = optionName;
plugins[ pluginCount ].isRewriter = isRewriter;
plugins[ pluginCount ].isPPCallback = isPPCallback; plugins[ pluginCount ].isPPCallback = isPPCallback;
plugins[ pluginCount ].byDefault = byDefault;
++pluginCount; ++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 ) 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 ) void PluginHandler::HandleTranslationUnit( ASTContext& context )
......
...@@ -30,7 +30,9 @@ class PluginHandler ...@@ -30,7 +30,9 @@ class PluginHandler
PluginHandler( CompilerInstance& compiler, const vector< string >& args ); PluginHandler( CompilerInstance& compiler, const vector< string >& args );
virtual ~PluginHandler(); virtual ~PluginHandler();
virtual void HandleTranslationUnit( ASTContext& context ) override; virtual void HandleTranslationUnit( ASTContext& context ) override;
static void registerPlugin( Plugin* (*create)( CompilerInstance&, Rewriter& ), const char* optionName, bool isRewriter, bool isPPCallback ); static void registerPlugin( Plugin* (*create)( const Plugin::InstantiationData& ), const char* optionName, bool isPPCallback, bool byDefault );
DiagnosticBuilder report( DiagnosticsEngine::Level level, const char * plugin, StringRef message,
CompilerInstance& compiler, SourceLocation loc = SourceLocation());
private: private:
void handleOption( const string& option ); void handleOption( const string& option );
void createPlugin( const string& name ); void createPlugin( const string& name );
...@@ -38,6 +40,7 @@ class PluginHandler ...@@ -38,6 +40,7 @@ class PluginHandler
CompilerInstance& compiler; CompilerInstance& compiler;
Rewriter rewriter; Rewriter rewriter;
string scope; string scope;
string warningsOnly;
}; };
/** /**
......
...@@ -41,15 +41,15 @@ class PointerToBool ...@@ -41,15 +41,15 @@ class PointerToBool
, public Plugin , public Plugin
{ {
public: public:
explicit PointerToBool( CompilerInstance& compiler ); explicit PointerToBool( const InstantiationData& data );
void run(); void run();
bool VisitImplicitCastExpr( const ImplicitCastExpr* expr ); bool VisitImplicitCastExpr( const ImplicitCastExpr* expr );
private: private:
bool ignoreConversion( const Stmt* stmt ); bool ignoreConversion( const Stmt* stmt );
}; };
PointerToBool::PointerToBool( CompilerInstance& compiler ) PointerToBool::PointerToBool( const InstantiationData& data )
: Plugin( compiler ) : Plugin( data )
{ {
} }
......
...@@ -20,8 +20,8 @@ Change all postfix ++ operators of non-trivial types to prefix if possible. ...@@ -20,8 +20,8 @@ Change all postfix ++ operators of non-trivial types to prefix if possible.
namespace loplugin namespace loplugin
{ {
PostfixIncrementFix::PostfixIncrementFix( CompilerInstance& compiler, Rewriter& rewriter ) PostfixIncrementFix::PostfixIncrementFix( const InstantiationData& data )
: RewritePlugin( compiler, rewriter ) : RewritePlugin( data )
{ {
} }
......
...@@ -22,7 +22,7 @@ class PostfixIncrementFix ...@@ -22,7 +22,7 @@ class PostfixIncrementFix
, public RewritePlugin , public RewritePlugin
{ {
public: public:
explicit PostfixIncrementFix( CompilerInstance& compiler, Rewriter& rewriter ); explicit PostfixIncrementFix( const InstantiationData& data );
virtual void run() override; virtual void run() override;
bool VisitCXXOperatorCallExpr( const CXXOperatorCallExpr* op ); bool VisitCXXOperatorCallExpr( const CXXOperatorCallExpr* op );
private: private:
......
...@@ -29,7 +29,7 @@ class RtlConstAsciiMacro ...@@ -29,7 +29,7 @@ class RtlConstAsciiMacro
, public RewritePlugin , public RewritePlugin
{ {
public: public:
explicit RtlConstAsciiMacro( CompilerInstance& compiler, Rewriter& rewriter ); explicit RtlConstAsciiMacro( const InstantiationData& data );
virtual void run() override; virtual void run() override;
bool VisitCXXConstructExpr( CXXConstructExpr* expr ); bool VisitCXXConstructExpr( CXXConstructExpr* expr );
bool VisitCXXTemporaryObjectExpr( CXXTemporaryObjectExpr* expr ); bool VisitCXXTemporaryObjectExpr( CXXTemporaryObjectExpr* expr );
...@@ -47,8 +47,8 @@ class RtlConstAsciiMacro ...@@ -47,8 +47,8 @@ class RtlConstAsciiMacro
bool suitableString; bool suitableString;
}; };
RtlConstAsciiMacro::RtlConstAsciiMacro( CompilerInstance& compiler, Rewriter& rewriter ) RtlConstAsciiMacro::RtlConstAsciiMacro( const InstantiationData& data )
: RewritePlugin( compiler, rewriter ) : RewritePlugin( data )
, searchingForString( false ) , searchingForString( false )
{ {
compiler.getPreprocessor().addPPCallbacks( this ); compiler.getPreprocessor().addPPCallbacks( this );
......
...@@ -26,8 +26,8 @@ report if the area is not listed there. The fix is either use a proper area or a ...@@ -26,8 +26,8 @@ report if the area is not listed there. The fix is either use a proper area or a
if appropriate. if appropriate.
*/ */
SalLogAreas::SalLogAreas( CompilerInstance& compiler ) SalLogAreas::SalLogAreas( const InstantiationData& data )
: Plugin( compiler ) : Plugin( data )
{ {
} }
......
...@@ -24,7 +24,7 @@ class SalLogAreas ...@@ -24,7 +24,7 @@ class SalLogAreas
, public Plugin , public Plugin
{ {
public: public:
explicit SalLogAreas( CompilerInstance& compiler ); explicit SalLogAreas( const InstantiationData& data );
virtual void run() override; virtual void run() override;
bool VisitFunctionDecl( const FunctionDecl* function ); bool VisitFunctionDecl( const FunctionDecl* function );
bool VisitCallExpr( const CallExpr* call ); bool VisitCallExpr( const CallExpr* call );
......
...@@ -37,15 +37,15 @@ class SvStreamOutputOperators ...@@ -37,15 +37,15 @@ class SvStreamOutputOperators
, public RewritePlugin , public RewritePlugin
{ {
public: public:
explicit SvStreamOutputOperators( CompilerInstance& compiler, Rewriter& rewriter ); explicit SvStreamOutputOperators( InstantiationData const & data );
virtual void run() override; virtual void run() override;
bool VisitCallExpr( const CallExpr* call ); bool VisitCallExpr( const CallExpr* call );
private: private:
SourceLocation after(const SourceLocation& loc); SourceLocation after(const SourceLocation& loc);
}; };
SvStreamOutputOperators::SvStreamOutputOperators( CompilerInstance& compiler, Rewriter& rewriter ) SvStreamOutputOperators::SvStreamOutputOperators( InstantiationData const & data )
: RewritePlugin( compiler, rewriter ) : RewritePlugin( data )
{ {
} }
......
...@@ -38,8 +38,8 @@ SAL_WARN_UNUSED (see e.g. OUString). For external classes such as std::vector ...@@ -38,8 +38,8 @@ SAL_WARN_UNUSED (see e.g. OUString). For external classes such as std::vector
that cannot be edited there is a manual list below. that cannot be edited there is a manual list below.
*/ */
UnusedVariableCheck::UnusedVariableCheck( CompilerInstance& compiler ) UnusedVariableCheck::UnusedVariableCheck( const InstantiationData& data )
: Plugin( compiler ) : Plugin( data )
{ {
} }
......
...@@ -22,7 +22,7 @@ class UnusedVariableCheck ...@@ -22,7 +22,7 @@ class UnusedVariableCheck
, public Plugin , public Plugin
{ {
public: public:
explicit UnusedVariableCheck( CompilerInstance& compiler ); explicit UnusedVariableCheck( const InstantiationData& data );
virtual void run() override; virtual void run() override;
bool VisitVarDecl( const VarDecl* var ); bool VisitVarDecl( const VarDecl* var );
}; };
......
...@@ -154,6 +154,10 @@ gb_LinkTarget_INCLUDE :=\ ...@@ -154,6 +154,10 @@ gb_LinkTarget_INCLUDE :=\
ifeq ($(COM_GCC_IS_CLANG),TRUE) ifeq ($(COM_GCC_IS_CLANG),TRUE)
ifeq ($(COMPILER_PLUGIN_TOOL),) ifeq ($(COMPILER_PLUGIN_TOOL),)
gb_COMPILER_PLUGINS := -Xclang -load -Xclang $(BUILDDIR)/compilerplugins/obj/plugin.so -Xclang -add-plugin -Xclang loplugin gb_COMPILER_PLUGINS := -Xclang -load -Xclang $(BUILDDIR)/compilerplugins/obj/plugin.so -Xclang -add-plugin -Xclang loplugin
ifneq ($(COMPILER_PLUGIN_WARNINGS_ONLY),)
gb_COMPILER_PLUGINS += -Xclang -plugin-arg-loplugin -Xclang \
--warnings-only='$(COMPILER_PLUGIN_WARNINGS_ONLY)'
endif
else else
gb_COMPILER_PLUGINS := -Xclang -load -Xclang $(BUILDDIR)/compilerplugins/obj/plugin.so -Xclang -plugin -Xclang loplugin -Xclang -plugin-arg-loplugin -Xclang $(COMPILER_PLUGIN_TOOL) gb_COMPILER_PLUGINS := -Xclang -load -Xclang $(BUILDDIR)/compilerplugins/obj/plugin.so -Xclang -plugin -Xclang loplugin -Xclang -plugin-arg-loplugin -Xclang $(COMPILER_PLUGIN_TOOL)
ifneq ($(UPDATE_FILES),) ifneq ($(UPDATE_FILES),)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment