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:
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 ==
......
......@@ -29,8 +29,8 @@ For example:
Here either both statements should be inside {} or the second statement in indented wrong.
*/
BodyNotInBlock::BodyNotInBlock( CompilerInstance& compiler )
: Plugin( compiler )
BodyNotInBlock::BodyNotInBlock( const InstantiationData& data )
: Plugin( data )
{
}
......
......@@ -22,7 +22,7 @@ class BodyNotInBlock
, public Plugin
{
public:
explicit BodyNotInBlock( CompilerInstance& compiler );
explicit BodyNotInBlock( const InstantiationData& data );
virtual void run() override;
bool VisitIfStmt( const IfStmt* stmt );
bool VisitWhileStmt( const WhileStmt* stmt );
......
......@@ -31,7 +31,7 @@ class CheckConfigMacros
, public Plugin
{
public:
explicit CheckConfigMacros( CompilerInstance& compiler );
explicit CheckConfigMacros( const InstantiationData& data );
virtual void run() override;
#if __clang_major__ < 3 || __clang_major__ == 3 && __clang_minor__ < 3
virtual void MacroDefined( const Token& macroToken, const MacroInfo* info ) override;
......@@ -56,8 +56,8 @@ class CheckConfigMacros
std::set< string > configMacros;
};
CheckConfigMacros::CheckConfigMacros( CompilerInstance& compiler )
: Plugin( compiler )
CheckConfigMacros::CheckConfigMacros( const InstantiationData& data )
: Plugin( data )
{
compiler.getPreprocessor().addPPCallbacks( this );
}
......
......@@ -99,8 +99,8 @@ class ImplicitBoolConversion:
public RecursiveASTVisitor<ImplicitBoolConversion>, public loplugin::Plugin
{
public:
explicit ImplicitBoolConversion(CompilerInstance & compiler):
Plugin(compiler) {}
explicit ImplicitBoolConversion(InstantiationData const & data):
Plugin(data) {}
virtual void run() override
{ TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
......
......@@ -21,7 +21,7 @@ class LiteralAlternative:
public RecursiveASTVisitor<LiteralAlternative>, public loplugin::Plugin
{
public:
explicit LiteralAlternative(CompilerInstance & compiler): Plugin(compiler) {}
explicit LiteralAlternative(InstantiationData const & data): Plugin(data) {}
virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
......
......@@ -11,6 +11,8 @@
#include "plugin.hxx"
#include <cassert>
#include <clang/Basic/FileManager.h>
#include <clang/Lex/Lexer.h>
......@@ -22,30 +24,14 @@ Base classes for plugin actions.
namespace loplugin
{
Plugin::Plugin( CompilerInstance& compiler )
: compiler( compiler )
Plugin::Plugin( const InstantiationData& data )
: compiler( data.compiler ), name( data.name ), handler( data.handler )
{
}
DiagnosticBuilder Plugin::report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc )
{
return report( level, 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 ));
return handler.report( level, name, message, compiler, loc );
}
bool Plugin::ignoreLocation( SourceLocation loc )
......@@ -63,9 +49,9 @@ bool Plugin::ignoreLocation( SourceLocation loc )
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;
......@@ -152,36 +138,40 @@ SourceLocation Plugin::locationAfterToken( SourceLocation location )
/////
RewritePlugin::RewritePlugin( CompilerInstance& compiler, Rewriter& rewriter )
: Plugin( compiler )
, rewriter( rewriter )
RewritePlugin::RewritePlugin( const InstantiationData& data )
: Plugin( data )
, rewriter( data.rewriter )
{
}
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 true;
}
bool RewritePlugin::insertTextAfter( SourceLocation Loc, StringRef Str )
{
if( rewriter.InsertTextAfter( Loc, Str ))
assert( rewriter );
if( rewriter->InsertTextAfter( Loc, Str ))
return reportEditFailure( Loc );
return true;
}
bool RewritePlugin::insertTextAfterToken( SourceLocation Loc, StringRef Str )
{
if( rewriter.InsertTextAfterToken( Loc, Str ))
assert( rewriter );
if( rewriter->InsertTextAfterToken( Loc, Str ))
return reportEditFailure( Loc );
return true;
}
bool RewritePlugin::insertTextBefore( SourceLocation Loc, StringRef Str )
{
if( rewriter.InsertTextBefore( Loc, Str ))
assert( rewriter );
if( rewriter->InsertTextBefore( Loc, Str ))
return reportEditFailure( Loc );
return true;
}
......@@ -199,7 +189,8 @@ bool RewritePlugin::removeText( SourceRange 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());
if( removals.find( range.getBegin()) != removals.end())
report( DiagnosticsEngine::Warning, "double code removal, possible plugin error", range.getBegin());
......@@ -209,14 +200,15 @@ bool RewritePlugin::removeText( CharSourceRange range, RewriteOptions opts )
if( !adjustRangeForOptions( &range, opts ))
return reportEditFailure( range.getBegin());
}
if( rewriter.RemoveText( range, opts ))
if( rewriter->RemoveText( range, opts ))
return reportEditFailure( range.getBegin());
return true;
}
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()));
if( fileStartLoc.isInvalid())
return false;
......@@ -256,34 +248,37 @@ bool RewritePlugin::adjustRangeForOptions( CharSourceRange* range, RewriteOption
bool RewritePlugin::replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr )
{
assert( rewriter );
if( OrigLength != 0 && removals.find( Start ) != removals.end())
report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", Start );
removals.insert( Start );
if( rewriter.ReplaceText( Start, OrigLength, NewStr ))
if( rewriter->ReplaceText( Start, OrigLength, NewStr ))
return reportEditFailure( Start );
return true;
}
bool RewritePlugin::replaceText( SourceRange range, StringRef NewStr )
{
if( rewriter.getRangeSize( range ) == -1 )
assert( rewriter );
if( rewriter->getRangeSize( range ) == -1 )
return reportEditFailure( range.getBegin());
if( removals.find( range.getBegin()) != removals.end())
report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", range.getBegin());
removals.insert( range.getBegin());
if( rewriter.ReplaceText( range, NewStr ))
if( rewriter->ReplaceText( range, NewStr ))
return reportEditFailure( range.getBegin());
return true;
}
bool RewritePlugin::replaceText( SourceRange range, SourceRange replacementRange )
{
if( rewriter.getRangeSize( range ) == -1 )
assert( rewriter );
if( rewriter->getRangeSize( range ) == -1 )
return reportEditFailure( range.getBegin());
if( removals.find( range.getBegin()) != removals.end())
report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", range.getBegin());
removals.insert( range.getBegin());
if( rewriter.ReplaceText( range, replacementRange ))
if( rewriter->ReplaceText( range, replacementRange ))
return reportEditFailure( range.getBegin());
return true;
}
......
......@@ -19,6 +19,7 @@
#include <clang/Basic/FileManager.h>
#include <clang/Basic/SourceManager.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Lex/Preprocessor.h>
#include <set>
#include <unordered_map>
......@@ -35,6 +36,8 @@ using namespace std;
namespace loplugin
{
class PluginHandler;
/**
Base class for plugins.
......@@ -44,17 +47,22 @@ namespace loplugin
class Plugin
{
public:
explicit Plugin( CompilerInstance& compiler );
struct InstantiationData
{
const char* name;
PluginHandler& handler;
CompilerInstance& compiler;
Rewriter* rewriter;
};
explicit Plugin( const InstantiationData& data );
virtual ~Plugin();
virtual void run() = 0;
template< typename T > class Registration;
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.
SourceLocation locationAfterToken( SourceLocation location );
protected:
DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc = SourceLocation());
bool ignoreLocation( SourceLocation loc );
bool ignoreLocation( const Decl* decl );
bool ignoreLocation( const Stmt* stmt );
......@@ -66,9 +74,11 @@ class Plugin
const Stmt* parentStmt( const Stmt* stmt );
Stmt* parentStmt( Stmt* stmt );
private:
static void registerPlugin( Plugin* (*create)( CompilerInstance&, Rewriter& ), const char* optionName, bool isRewriter, bool isPPCallback );
template< typename T > static Plugin* createHelper( CompilerInstance& compiler, Rewriter& rewriter );
static void registerPlugin( Plugin* (*create)( const InstantiationData& ), const char* optionName, bool isPPCallback, bool byDefault );
template< typename T > static Plugin* createHelper( const InstantiationData& data );
enum { isRewriter = false };
const char* name;
PluginHandler& handler;
static unordered_map< const Stmt*, const Stmt* > parents;
static void buildParents( CompilerInstance& compiler );
};
......@@ -82,7 +92,7 @@ class RewritePlugin
: public Plugin
{
public:
explicit RewritePlugin( CompilerInstance& compiler, Rewriter& rewriter );
explicit RewritePlugin( const InstantiationData& data );
protected:
enum RewriteOption
{
......@@ -123,10 +133,9 @@ class RewritePlugin
bool replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr );
bool replaceText( SourceRange range, StringRef NewStr );
bool replaceText( SourceRange range, SourceRange replacementRange );
Rewriter& rewriter;
Rewriter* rewriter;
private:
template< typename T > friend class Plugin::Registration;
template< typename T > static Plugin* createHelper( CompilerInstance& compiler, Rewriter& rewriter );
enum { isRewriter = true };
bool reportEditFailure( SourceLocation loc );
bool adjustRangeForOptions( CharSourceRange* range, RewriteOptions options );
......@@ -148,13 +157,13 @@ template< typename T >
class Plugin::Registration
{
public:
Registration( const char* optionName );
Registration( const char* optionName, bool byDefault = !T::isRewriter );
};
class RegistrationCreate
{
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 )
}
template< typename T >
Plugin* Plugin::createHelper( CompilerInstance& compiler, Rewriter& )
{
return new T( compiler );
}
template< typename T >
Plugin* RewritePlugin::createHelper( CompilerInstance& compiler, Rewriter& rewriter )
Plugin* Plugin::createHelper( const InstantiationData& data )
{
return new T( compiler, rewriter );
return new T( data );
}
template< typename T >
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
......
......@@ -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 )
......
......@@ -30,7 +30,9 @@ class PluginHandler
PluginHandler( CompilerInstance& compiler, const vector< string >& args );
virtual ~PluginHandler();
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:
void handleOption( const string& option );
void createPlugin( const string& name );
......@@ -38,6 +40,7 @@ class PluginHandler
CompilerInstance& compiler;
Rewriter rewriter;
string scope;
string warningsOnly;
};
/**
......
......@@ -41,15 +41,15 @@ class PointerToBool
, public Plugin
{
public:
explicit PointerToBool( CompilerInstance& compiler );
explicit PointerToBool( const InstantiationData& data );
void run();
bool VisitImplicitCastExpr( const ImplicitCastExpr* expr );
private:
bool ignoreConversion( const Stmt* stmt );
};
PointerToBool::PointerToBool( CompilerInstance& compiler )
: Plugin( compiler )
PointerToBool::PointerToBool( const InstantiationData& data )
: Plugin( data )
{
}
......
......@@ -20,8 +20,8 @@ Change all postfix ++ operators of non-trivial types to prefix if possible.
namespace loplugin
{
PostfixIncrementFix::PostfixIncrementFix( CompilerInstance& compiler, Rewriter& rewriter )
: RewritePlugin( compiler, rewriter )
PostfixIncrementFix::PostfixIncrementFix( const InstantiationData& data )
: RewritePlugin( data )
{
}
......
......@@ -22,7 +22,7 @@ class PostfixIncrementFix
, public RewritePlugin
{
public:
explicit PostfixIncrementFix( CompilerInstance& compiler, Rewriter& rewriter );
explicit PostfixIncrementFix( const InstantiationData& data );
virtual void run() override;
bool VisitCXXOperatorCallExpr( const CXXOperatorCallExpr* op );
private:
......
......@@ -29,7 +29,7 @@ class RtlConstAsciiMacro
, public RewritePlugin
{
public:
explicit RtlConstAsciiMacro( CompilerInstance& compiler, Rewriter& rewriter );
explicit RtlConstAsciiMacro( const InstantiationData& data );
virtual void run() override;
bool VisitCXXConstructExpr( CXXConstructExpr* expr );
bool VisitCXXTemporaryObjectExpr( CXXTemporaryObjectExpr* expr );
......@@ -47,8 +47,8 @@ class RtlConstAsciiMacro
bool suitableString;
};
RtlConstAsciiMacro::RtlConstAsciiMacro( CompilerInstance& compiler, Rewriter& rewriter )
: RewritePlugin( compiler, rewriter )
RtlConstAsciiMacro::RtlConstAsciiMacro( const InstantiationData& data )
: RewritePlugin( data )
, searchingForString( false )
{
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
if appropriate.
*/
SalLogAreas::SalLogAreas( CompilerInstance& compiler )
: Plugin( compiler )
SalLogAreas::SalLogAreas( const InstantiationData& data )
: Plugin( data )
{
}
......
......@@ -24,7 +24,7 @@ class SalLogAreas
, public Plugin
{
public:
explicit SalLogAreas( CompilerInstance& compiler );
explicit SalLogAreas( const InstantiationData& data );
virtual void run() override;
bool VisitFunctionDecl( const FunctionDecl* function );
bool VisitCallExpr( const CallExpr* call );
......
......@@ -37,15 +37,15 @@ class SvStreamOutputOperators
, public RewritePlugin
{
public:
explicit SvStreamOutputOperators( CompilerInstance& compiler, Rewriter& rewriter );
explicit SvStreamOutputOperators( InstantiationData const & data );
virtual void run() override;
bool VisitCallExpr( const CallExpr* call );
private:
SourceLocation after(const SourceLocation& loc);
};
SvStreamOutputOperators::SvStreamOutputOperators( CompilerInstance& compiler, Rewriter& rewriter )
: RewritePlugin( compiler, rewriter )
SvStreamOutputOperators::SvStreamOutputOperators( InstantiationData const & data )
: RewritePlugin( data )
{
}
......
......@@ -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.
*/
UnusedVariableCheck::UnusedVariableCheck( CompilerInstance& compiler )
: Plugin( compiler )
UnusedVariableCheck::UnusedVariableCheck( const InstantiationData& data )
: Plugin( data )
{
}
......
......@@ -22,7 +22,7 @@ class UnusedVariableCheck
, public Plugin
{
public:
explicit UnusedVariableCheck( CompilerInstance& compiler );
explicit UnusedVariableCheck( const InstantiationData& data );
virtual void run() override;
bool VisitVarDecl( const VarDecl* var );
};
......
......@@ -154,6 +154,10 @@ gb_LinkTarget_INCLUDE :=\
ifeq ($(COM_GCC_IS_CLANG),TRUE)
ifeq ($(COMPILER_PLUGIN_TOOL),)
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
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),)
......
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