diff options
author | Luboš Luňák <l.lunak@suse.cz> | 2013-01-03 20:15:21 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@suse.cz> | 2013-01-04 15:27:24 +0100 |
commit | 217e3f2ea1e8983328364607f244daceeafca167 (patch) | |
tree | 136686e0e8faadfcc91c8a24a74318cf550700b4 /compilerplugins | |
parent | 1cec392ef50699cc0f310823e4e5fdbb9b272f0f (diff) |
better handling of which files are processed by clang plugins
Check that only LO's files are processed, as there's no point otherwise.
Also warn about files in workdir/solver/builddir, as those are either
generated or copies. Try to automatically match include files from
solver to srcdir though, as that's where include files are usually
included from :(.
Change-Id: Ie8389e903f623a9d0e75015091acc0da78e76c3a
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/lclstaticfix.cxx | 4 | ||||
-rw-r--r-- | compilerplugins/clang/plugin.cxx | 66 | ||||
-rw-r--r-- | compilerplugins/clang/postfixincrementfix.cxx | 3 |
3 files changed, 62 insertions, 11 deletions
diff --git a/compilerplugins/clang/lclstaticfix.cxx b/compilerplugins/clang/lclstaticfix.cxx index 9227af81282f..a5c765b229b7 100644 --- a/compilerplugins/clang/lclstaticfix.cxx +++ b/compilerplugins/clang/lclstaticfix.cxx @@ -34,9 +34,7 @@ void LclStaticFix::run() 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())) + if( ignoreLocation( declaration )) return true; if( declaration->isCXXClassMember()) return true; diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx index 62412e626ac0..6535e1a96471 100644 --- a/compilerplugins/clang/plugin.cxx +++ b/compilerplugins/clang/plugin.cxx @@ -25,6 +25,8 @@ #include "sallogareas.hxx" #include "unusedvariablecheck.hxx" +#include <config_clang.h> + namespace loplugin { @@ -51,7 +53,19 @@ DiagnosticBuilder Plugin::report( DiagnosticsEngine::Level level, StringRef mess bool Plugin::ignoreLocation( SourceLocation loc ) { - return context.getSourceManager().isInSystemHeader( context.getSourceManager().getExpansionLoc( loc )); + SourceLocation expansionLoc = context.getSourceManager().getExpansionLoc( loc ); + if( context.getSourceManager().isInSystemHeader( expansionLoc )) + return true; + bool invalid; + const char* bufferName = context.getSourceManager().getBufferName( expansionLoc, &invalid ); + if( invalid ) + return true; + if( strncmp( bufferName, OUTDIR, strlen( OUTDIR )) == 0 + || strncmp( bufferName, WORKDIR, strlen( WORKDIR )) == 0 + || strncmp( bufferName, BUILDDIR, strlen( BUILDDIR )) == 0 + || strncmp( bufferName, SRCDIR, strlen( SRCDIR )) == 0 ) + return false; // ok + return true; } @@ -182,24 +196,64 @@ class PluginHandler ++it ) { const FileEntry* e = context.getSourceManager().getFileEntryForID( it->first ); - char* filename = new char[ strlen( e->getName()) + 100 ]; - sprintf( filename, "%s.new.%d", e->getName(), getpid()); + 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/" ); + int 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( 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 ); - DiagnosticsEngine& diag = context.getDiagnostics(); if( error.empty()) { it->second.write( ostream ); ostream.close(); - if( !ostream.has_error() && rename( filename, e->getName()) == 0 ) + 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]" )) << e->getName() << error; + "cannot write modified source to %0 (%1) [loplugin]" )) << modifyFile << error; delete[] filename; } } diff --git a/compilerplugins/clang/postfixincrementfix.cxx b/compilerplugins/clang/postfixincrementfix.cxx index c5c17fb14b5d..bfaf77cefa6c 100644 --- a/compilerplugins/clang/postfixincrementfix.cxx +++ b/compilerplugins/clang/postfixincrementfix.cxx @@ -28,8 +28,7 @@ void PostfixIncrementFix::run() bool PostfixIncrementFix::VisitFunctionDecl( FunctionDecl* declaration ) { - // TODO also LO header files? or a subdir? - if( !context.getSourceManager().isFromMainFile( declaration->getLocStart())) + if( ignoreLocation( declaration )) return true; if( !declaration->doesThisDeclarationHaveABody()) return true; |