diff options
author | Luboš Luňák <l.lunak@suse.cz> | 2013-02-02 16:35:47 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@suse.cz> | 2013-02-02 22:59:44 +0100 |
commit | b8f932b6a5c6ace05df975f82e682f10804dad5d (patch) | |
tree | f5a5e0f53f060484ff14486a10ddc36383868f67 /compilerplugins/clang | |
parent | a31f4654169f9b00c9e1b7158280c11c4c54aa17 (diff) |
move plugin handling to separate source files
Change-Id: Ifa1af34121bda9ca3250d09a3b8a46ea226795ed
Diffstat (limited to 'compilerplugins/clang')
-rw-r--r-- | compilerplugins/clang/plugin.cxx | 157 | ||||
-rw-r--r-- | compilerplugins/clang/pluginhandler.cxx | 137 | ||||
-rw-r--r-- | compilerplugins/clang/pluginhandler.hxx | 73 |
3 files changed, 211 insertions, 156 deletions
diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx index db9521f8dac3..05172b7a9a91 100644 --- a/compilerplugins/clang/plugin.cxx +++ b/compilerplugins/clang/plugin.cxx @@ -10,21 +10,10 @@ #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 <stdio.h> -#include <unistd.h> -#include "bodynotinblock.hxx" -#include "lclstaticfix.hxx" -#include "postfixincrementfix.hxx" -#include "removeforwardstringdecl.hxx" -#include "sallogareas.hxx" -#include "unusedvariablecheck.hxx" +#include "pluginhandler.hxx" namespace loplugin { @@ -176,148 +165,4 @@ bool RewritePlugin::reportEditFailure( SourceLocation loc ) return false; } - -/** - Class that manages all LO modules. -*/ -class PluginHandler - : public ASTConsumer - { - public: - explicit PluginHandler( ASTContext& context, const vector< string >& args ) - : rewriter( context.getSourceManager(), context.getLangOpts()) - , args( args ) - , bodyNotInBlock( context ) - , lclStaticFix( context, rewriter ) - , postfixIncrementFix( context, rewriter ) - , removeForwardStringDecl( context, rewriter ) - , salLogAreas( context ) - , unusedVariableCheck( context ) - { - } - virtual void HandleTranslationUnit( ASTContext& context ) - { - if( context.getDiagnostics().hasErrorOccurred()) - return; - if( isArg( "lclstaticfix" )) - lclStaticFix.run(); - else if( isArg( "postfixincrementfix" )) - postfixIncrementFix.run(); - else if( isArg( "removeforwardstringdecl" )) - removeForwardStringDecl.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 ); - DiagnosticsEngine& diag = context.getDiagnostics(); - /* Check where the file actually is, and warn about cases where modification - most probably doesn't matter (generated files in workdir). - The order here is important, as OUTDIR and WORKDIR are often in SRCDIR/BUILDDIR, - and BUILDDIR is sometimes in SRCDIR. */ - string modifyFile; - if( strncmp( e->getName(), OUTDIR, strlen( OUTDIR )) == 0 ) - { - /* Try to find a matching file for a file in solver/ (include files - are usually included from there rather than from the source dir) if possible. */ - if( strncmp( e->getName(), OUTDIR "/inc/", strlen( OUTDIR ) + strlen( "/inc/" )) == 0 ) - { - string filename( e->getName()); - int modulePos = strlen( OUTDIR ) + strlen( "/inc/" ); - size_t moduleEnd = filename.find( '/', modulePos ); - if( moduleEnd != string::npos ) - { - modifyFile = SRCDIR "/" + filename.substr( modulePos, moduleEnd - modulePos ) - + "/inc/" + filename.substr( modulePos ); - } - } - if( modifyFile.empty()) - diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Warning, - "modified source in solver/ : %0 [loplugin]" )) << e->getName(); - } - else if( strncmp( e->getName(), WORKDIR, strlen( WORKDIR )) == 0 ) - diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Warning, - "modified source in workdir/ : %0 [loplugin]" )) << e->getName(); - else if( strcmp( SRCDIR, BUILDDIR ) != 0 && strncmp( e->getName(), BUILDDIR, strlen( BUILDDIR )) == 0 ) - diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Warning, - "modified source in build dir : %0 [loplugin]" )) << e->getName(); - else if( strncmp( e->getName(), SRCDIR, strlen( SRCDIR )) == 0 ) - ; // ok - else - { - diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Warning, - "modified source in unknown location, not modifying : %0 [loplugin]" )) << e->getName(); - continue; // ---> - } - if( modifyFile.empty()) - modifyFile = e->getName(); - char* filename = new char[ modifyFile.length() + 100 ]; - sprintf( filename, "%s.new.%d", modifyFile.c_str(), getpid()); - string error; - bool ok = false; - raw_fd_ostream ostream( filename, error ); - if( error.empty()) - { - it->second.write( ostream ); - ostream.close(); - if( !ostream.has_error() && rename( filename, modifyFile.c_str()) == 0 ) - ok = true; - } - ostream.clear_error(); - unlink( filename ); - if( !ok ) - diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Error, - "cannot write modified source to %0 (%1) [loplugin]" )) << modifyFile << error; - delete[] filename; - } - } - 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; - PostfixIncrementFix postfixIncrementFix; - RemoveForwardStringDecl removeForwardStringDecl; - SalLogAreas salLogAreas; - UnusedVariableCheck unusedVariableCheck; - }; - -/** - The Clang plugin class, just forwards to PluginHandler. -*/ -class LibreOfficeAction - : public PluginASTAction - { - public: - virtual ASTConsumer* CreateASTConsumer( CompilerInstance& Compiler, StringRef InFile ) - { - return new PluginHandler( Compiler.getASTContext(), _args ); - } - virtual bool ParseArgs( const CompilerInstance& CI, const vector< string >& args ) - { - _args = args; - return true; - } - private: - vector< string > _args; - }; - } // namespace - -static FrontendPluginRegistry::Add< loplugin::LibreOfficeAction > X( "loplugin", "LibreOffice compile check plugin" ); diff --git a/compilerplugins/clang/pluginhandler.cxx b/compilerplugins/clang/pluginhandler.cxx new file mode 100644 index 000000000000..fd2c62e58caf --- /dev/null +++ b/compilerplugins/clang/pluginhandler.cxx @@ -0,0 +1,137 @@ +/* + * 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 "pluginhandler.hxx" + +#include <clang/AST/ASTContext.h> +#include <clang/Frontend/CompilerInstance.h> +#include <clang/Frontend/FrontendPluginRegistry.h> +#include <stdio.h> +#include <unistd.h> + +namespace loplugin +{ + +PluginHandler::PluginHandler( ASTContext& context, const vector< string >& args ) + : rewriter( context.getSourceManager(), context.getLangOpts()) + , args( args ) + , bodyNotInBlock( context ) + , lclStaticFix( context, rewriter ) + , postfixIncrementFix( context, rewriter ) + , removeForwardStringDecl( context, rewriter ) + , salLogAreas( context ) + , unusedVariableCheck( context ) + { + } + +void PluginHandler::HandleTranslationUnit( ASTContext& context ) + { + if( context.getDiagnostics().hasErrorOccurred()) + return; + if( isArg( "lclstaticfix" )) + lclStaticFix.run(); + else if( isArg( "postfixincrementfix" )) + postfixIncrementFix.run(); + else if( isArg( "removeforwardstringdecl" )) + removeForwardStringDecl.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 ); + DiagnosticsEngine& diag = context.getDiagnostics(); + /* Check where the file actually is, and warn about cases where modification + most probably doesn't matter (generated files in workdir). + The order here is important, as OUTDIR and WORKDIR are often in SRCDIR/BUILDDIR, + and BUILDDIR is sometimes in SRCDIR. */ + string modifyFile; + if( strncmp( e->getName(), OUTDIR, strlen( OUTDIR )) == 0 ) + { + /* Try to find a matching file for a file in solver/ (include files + are usually included from there rather than from the source dir) if possible. */ + if( strncmp( e->getName(), OUTDIR "/inc/", strlen( OUTDIR ) + strlen( "/inc/" )) == 0 ) + { + string filename( e->getName()); + int modulePos = strlen( OUTDIR ) + strlen( "/inc/" ); + size_t moduleEnd = filename.find( '/', modulePos ); + if( moduleEnd != string::npos ) + { + modifyFile = SRCDIR "/" + filename.substr( modulePos, moduleEnd - modulePos ) + + "/inc/" + filename.substr( modulePos ); + } + } + if( modifyFile.empty()) + diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Warning, + "modified source in solver/ : %0 [loplugin]" )) << e->getName(); + } + else if( strncmp( e->getName(), WORKDIR, strlen( WORKDIR )) == 0 ) + diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Warning, + "modified source in workdir/ : %0 [loplugin]" )) << e->getName(); + else if( strcmp( SRCDIR, BUILDDIR ) != 0 && strncmp( e->getName(), BUILDDIR, strlen( BUILDDIR )) == 0 ) + diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Warning, + "modified source in build dir : %0 [loplugin]" )) << e->getName(); + else if( strncmp( e->getName(), SRCDIR, strlen( SRCDIR )) == 0 ) + ; // ok + else + { + diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Warning, + "modified source in unknown location, not modifying : %0 [loplugin]" )) << e->getName(); + continue; // ---> + } + if( modifyFile.empty()) + modifyFile = e->getName(); + char* filename = new char[ modifyFile.length() + 100 ]; + sprintf( filename, "%s.new.%d", modifyFile.c_str(), getpid()); + string error; + bool ok = false; + raw_fd_ostream ostream( filename, error ); + if( error.empty()) + { + it->second.write( ostream ); + ostream.close(); + if( !ostream.has_error() && rename( filename, modifyFile.c_str()) == 0 ) + ok = true; + } + ostream.clear_error(); + unlink( filename ); + if( !ok ) + diag.Report( diag.getCustomDiagID( DiagnosticsEngine::Error, + "cannot write modified source to %0 (%1) [loplugin]" )) << modifyFile << error; + delete[] filename; + } + } + +ASTConsumer* LibreOfficeAction::CreateASTConsumer( CompilerInstance& Compiler, StringRef InFile ) + { + return new PluginHandler( Compiler.getASTContext(), _args ); + } + +bool LibreOfficeAction::ParseArgs( const CompilerInstance& CI, const vector< string >& args ) + { + _args = args; + return true; + } + + +static FrontendPluginRegistry::Add< loplugin::LibreOfficeAction > X( "loplugin", "LibreOffice compile check plugin" ); + +} // namespace diff --git a/compilerplugins/clang/pluginhandler.hxx b/compilerplugins/clang/pluginhandler.hxx new file mode 100644 index 000000000000..d9ac63341122 --- /dev/null +++ b/compilerplugins/clang/pluginhandler.hxx @@ -0,0 +1,73 @@ +/* + * 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 PLUGINHANDLER_H +#define PLUGINHANDLER_H + +#include "plugin.hxx" + +#include <clang/AST/ASTConsumer.h> +#include <clang/Frontend/FrontendAction.h> + +#include "bodynotinblock.hxx" +#include "lclstaticfix.hxx" +#include "postfixincrementfix.hxx" +#include "removeforwardstringdecl.hxx" +#include "sallogareas.hxx" +#include "unusedvariablecheck.hxx" + +namespace loplugin +{ + +/** + Class that manages all LO modules. +*/ +class PluginHandler + : public ASTConsumer + { + public: + PluginHandler( ASTContext& context, const vector< string >& args ); + virtual void HandleTranslationUnit( ASTContext& context ); + private: + bool isArg( const char* arg ) const; + Rewriter rewriter; + vector< string > args; + BodyNotInBlock bodyNotInBlock; + LclStaticFix lclStaticFix; + PostfixIncrementFix postfixIncrementFix; + RemoveForwardStringDecl removeForwardStringDecl; + SalLogAreas salLogAreas; + UnusedVariableCheck unusedVariableCheck; + }; + +/** + The Clang plugin class, just forwards to PluginHandler. +*/ +class LibreOfficeAction + : public PluginASTAction + { + public: + virtual ASTConsumer* CreateASTConsumer( CompilerInstance& Compiler, StringRef InFile ); + virtual bool ParseArgs( const CompilerInstance& CI, const vector< string >& args ); + private: + vector< string > _args; + }; + +///// + +inline +bool PluginHandler::isArg( const char* arg ) const + { + return find( args.begin(), args.end(), arg ) != args.end(); + } + +} // namespace + +#endif // COMPILEPLUGIN_H |