diff options
author | Luboš Luňák <l.lunak@suse.cz> | 2012-10-15 15:36:25 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@suse.cz> | 2012-10-15 15:40:33 +0200 |
commit | 0349c738da5970d9f0fc10d7cf4d7b766ce10e13 (patch) | |
tree | 572fa7304614ae5cac51938d45823114655e145e /compilerplugins/clang | |
parent | 41d6a0ea2d2d3c8daa758771bf956036d84cbe1a (diff) |
support for compiler rewriters
Change-Id: I12e98ac9fc49ef2007914324006a396d183b778c
Diffstat (limited to 'compilerplugins/clang')
-rw-r--r-- | compilerplugins/clang/bodynotinblock.cxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/bodynotinblock.hxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/lclstaticfix.cxx | 58 | ||||
-rw-r--r-- | compilerplugins/clang/lclstaticfix.hxx | 34 | ||||
-rw-r--r-- | compilerplugins/clang/plugin.cxx (renamed from compilerplugins/clang/compileplugin.cxx) | 61 | ||||
-rw-r--r-- | compilerplugins/clang/plugin.hxx (renamed from compilerplugins/clang/compileplugin.hxx) | 14 | ||||
-rw-r--r-- | compilerplugins/clang/sallogareas.cxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/sallogareas.hxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/unusedvariablecheck.cxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/unusedvariablecheck.hxx | 2 |
10 files changed, 163 insertions, 16 deletions
diff --git a/compilerplugins/clang/bodynotinblock.cxx b/compilerplugins/clang/bodynotinblock.cxx index f13eb9392357..b6572bfc8a7a 100644 --- a/compilerplugins/clang/bodynotinblock.cxx +++ b/compilerplugins/clang/bodynotinblock.cxx @@ -16,6 +16,8 @@ namespace loplugin { /* +This is a compile check. + Check for two statements that are both indented to look like a body of if/while/for but are not inside a compound statement and thus the second one is unrelated. */ diff --git a/compilerplugins/clang/bodynotinblock.hxx b/compilerplugins/clang/bodynotinblock.hxx index 0d3425213a30..304bbf0a0480 100644 --- a/compilerplugins/clang/bodynotinblock.hxx +++ b/compilerplugins/clang/bodynotinblock.hxx @@ -11,7 +11,7 @@ #ifndef BODYNOTINBLOCK_H #define BODYNOTINBLOCK_H -#include "compileplugin.hxx" +#include "plugin.hxx" namespace loplugin { diff --git a/compilerplugins/clang/lclstaticfix.cxx b/compilerplugins/clang/lclstaticfix.cxx new file mode 100644 index 000000000000..c6b61363e134 --- /dev/null +++ b/compilerplugins/clang/lclstaticfix.cxx @@ -0,0 +1,58 @@ +/* + * This file is part of the LibreOffice project. + * + * Based on LLVM/Clang. + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + */ + +#include "lclstaticfix.hxx" + +#include <clang/Basic/SourceManager.h> + +/* +This is a rewriter. + +Check all lcl_ functions and prepend static if needed. +*/ + +namespace loplugin +{ + +LclStaticFix::LclStaticFix( ASTContext& context, Rewriter& rewriter ) + : Plugin( context ), rewriter( rewriter ) + { + } + +void LclStaticFix::run() + { + TraverseDecl( context.getTranslationUnitDecl()); + } + +bool LclStaticFix::VisitFunctionDecl( FunctionDecl* declaration ) + { + // TODO also LO header files? or a subdir? + // Only the .cxx file can be normally edited ... ? + if( !context.getSourceManager().isFromMainFile( declaration->getLocStart())) + return true; + if( declaration->isCXXClassMember()) + return true; + if( declaration->getStorageClass() == SC_Static ) + return true; + string name = declaration->getQualifiedNameAsString(); + if( name.find( "::" ) != string::npos ) + return true; + if( name.compare( 0, 4, "lcl_" ) != 0 ) + return true; + if( rewriter.InsertText( declaration->getLocStart(), "static " )) + { // the logic is backwards, true here meant it failed, so report + report( DiagnosticsEngine::Warning, + "cannot fix lcl_ function (result of macro expansion?) [loplugin]", + declaration->getLocStart()); + } + return true; + } + +} // namespace diff --git a/compilerplugins/clang/lclstaticfix.hxx b/compilerplugins/clang/lclstaticfix.hxx new file mode 100644 index 000000000000..be89b4622620 --- /dev/null +++ b/compilerplugins/clang/lclstaticfix.hxx @@ -0,0 +1,34 @@ +/* + * This file is part of the LibreOffice project. + * + * Based on LLVM/Clang. + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + */ + +#ifndef LCLSTATICFIX_H +#define LCLSTATICFIX_H + +#include "plugin.hxx" + +namespace loplugin +{ + +class LclStaticFix + : public RecursiveASTVisitor< LclStaticFix > + , public Plugin + { + public: + explicit LclStaticFix( ASTContext& context, Rewriter& rewriter ); + void run(); + bool VisitFunctionDecl( FunctionDecl* declaration ); + private: + Rewriter& rewriter; + }; + +} // namespace + +#endif // POSTFIXINCREMENTFIX_H + diff --git a/compilerplugins/clang/compileplugin.cxx b/compilerplugins/clang/plugin.cxx index 0bb378a73d95..115193c14137 100644 --- a/compilerplugins/clang/compileplugin.cxx +++ b/compilerplugins/clang/plugin.cxx @@ -8,16 +8,18 @@ * */ -#include "compileplugin.hxx" +#include "plugin.hxx" #include <clang/AST/ASTConsumer.h> #include <clang/AST/ASTContext.h> +#include <clang/Basic/FileManager.h> #include <clang/Frontend/CompilerInstance.h> #include <clang/Frontend/FrontendAction.h> #include <clang/Frontend/FrontendPluginRegistry.h> #include <clang/Rewrite/Rewriter.h> #include "bodynotinblock.hxx" +#include "lclstaticfix.hxx" #include "sallogareas.hxx" #include "unusedvariablecheck.hxx" @@ -57,9 +59,11 @@ class PluginHandler : public ASTConsumer { public: - explicit PluginHandler( ASTContext& context ) + explicit PluginHandler( ASTContext& context, const vector< string >& args ) : rewriter( context.getSourceManager(), context.getLangOpts()) + , args( args ) , bodyNotInBlock( context ) + , lclStaticFix( context, rewriter ) , salLogAreas( context ) , unusedVariableCheck( context ) { @@ -68,17 +72,49 @@ class PluginHandler { if( context.getDiagnostics().hasErrorOccurred()) return; - bodyNotInBlock.run(); - salLogAreas.run(); - unusedVariableCheck.run(); - // TODO also LO header files? or a subdir? - if( const RewriteBuffer* buf = rewriter.getRewriteBufferFor( context.getSourceManager().getMainFileID())) - buf->write( llvm::outs()); - // TODO else write out the original file? + if( isArg( "lclstaticfix" )) + lclStaticFix.run(); + else if( args.empty()) + { + bodyNotInBlock.run(); + salLogAreas.run(); + unusedVariableCheck.run(); + } + else + { + DiagnosticsEngine& diag = context.getDiagnostics(); + diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Fatal, + "unknown plugin tool %0 [loplugin]" )) << args.front(); + } + for( Rewriter::buffer_iterator it = rewriter.buffer_begin(); + it != rewriter.buffer_end(); + ++it ) + { + const FileEntry* e = context.getSourceManager().getFileEntryForID( it->first ); + string filename = std::string( e->getName()) + ".new"; + string error; + // TODO If there will be actually plugins also modifying headers, + // race conditions should be avoided here. + raw_fd_ostream ostream( filename.c_str(), error ); + DiagnosticsEngine& diag = context.getDiagnostics(); + if( !error.empty()) + diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Error, + "cannot write modified source to %0 (%1) [loplugin]" )) << filename << error; + else + diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Note, + "modified source %0 [loplugin]" )) << filename; + it->second.write( ostream ); + } } private: + bool isArg( const char* arg ) const + { + return find( args.begin(), args.end(), arg ) != args.end(); + } Rewriter rewriter; + vector< string > args; BodyNotInBlock bodyNotInBlock; + LclStaticFix lclStaticFix; SalLogAreas salLogAreas; UnusedVariableCheck unusedVariableCheck; }; @@ -92,12 +128,15 @@ class LibreOfficeAction public: virtual ASTConsumer* CreateASTConsumer( CompilerInstance& Compiler, StringRef InFile ) { - return new PluginHandler( Compiler.getASTContext()); + return new PluginHandler( Compiler.getASTContext(), _args ); } - virtual bool ParseArgs( const CompilerInstance& CI, const std::vector< std::string >& args ) + virtual bool ParseArgs( const CompilerInstance& CI, const vector< string >& args ) { + _args = args; return true; } + private: + vector< string > _args; }; } // namespace diff --git a/compilerplugins/clang/compileplugin.hxx b/compilerplugins/clang/plugin.hxx index a413501fea95..6d273eda3c3e 100644 --- a/compilerplugins/clang/compileplugin.hxx +++ b/compilerplugins/clang/plugin.hxx @@ -8,10 +8,11 @@ * */ -#ifndef COMPILEPLUGIN_H -#define COMPILEPLUGIN_H +#ifndef PLUGIN_H +#define PLUGIN_H #include <clang/AST/RecursiveASTVisitor.h> +#include <clang/Rewrite/Rewriter.h> using namespace clang; using namespace llvm; @@ -32,6 +33,15 @@ class Plugin ASTContext& context; }; +class RewritePlugin + : public Plugin + { + public: + explicit RewritePlugin( ASTContext& context, Rewriter& rewriter ); + protected: + Rewriter& rewriter; + }; + inline bool Plugin::ignoreLocation( const Decl* decl ) { diff --git a/compilerplugins/clang/sallogareas.cxx b/compilerplugins/clang/sallogareas.cxx index f1a524ca5164..1dd99b9b727a 100644 --- a/compilerplugins/clang/sallogareas.cxx +++ b/compilerplugins/clang/sallogareas.cxx @@ -18,6 +18,8 @@ namespace loplugin { /* +This is a compile check. + Check that areas used in SAL_LOG/SAL_WARN are listed in sal/inc/sal/log-areas.dox . */ diff --git a/compilerplugins/clang/sallogareas.hxx b/compilerplugins/clang/sallogareas.hxx index f17b8aa1ace4..72f0e756d633 100644 --- a/compilerplugins/clang/sallogareas.hxx +++ b/compilerplugins/clang/sallogareas.hxx @@ -13,7 +13,7 @@ #include <set> -#include "compileplugin.hxx" +#include "plugin.hxx" namespace loplugin { diff --git a/compilerplugins/clang/unusedvariablecheck.cxx b/compilerplugins/clang/unusedvariablecheck.cxx index 340cd9ef863b..7e3bb53c5ba4 100644 --- a/compilerplugins/clang/unusedvariablecheck.cxx +++ b/compilerplugins/clang/unusedvariablecheck.cxx @@ -16,6 +16,8 @@ namespace loplugin { /* +This is a compile check. + Check for unused classes where the compiler cannot decide (e.g. because of non-trivial or extern ctors) if a variable is unused if only its ctor/dtor are called and nothing else. For example std::vector is a class where diff --git a/compilerplugins/clang/unusedvariablecheck.hxx b/compilerplugins/clang/unusedvariablecheck.hxx index 3099eec39522..7bf1cdd15ddd 100644 --- a/compilerplugins/clang/unusedvariablecheck.hxx +++ b/compilerplugins/clang/unusedvariablecheck.hxx @@ -11,7 +11,7 @@ #ifndef UNUSEDVARIABLECHECK_H #define UNUSEDVARIABLECHECK_H -#include "compileplugin.hxx" +#include "plugin.hxx" namespace loplugin { |