diff options
-rw-r--r-- | compilerplugins/clang/lclstaticfix.cxx | 4 | ||||
-rw-r--r-- | compilerplugins/clang/plugin.cxx | 66 | ||||
-rw-r--r-- | compilerplugins/clang/postfixincrementfix.cxx | 3 | ||||
-rw-r--r-- | config/config_clang.h.in | 3 | ||||
-rw-r--r-- | configure.ac | 3 |
5 files changed, 68 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; diff --git a/config/config_clang.h.in b/config/config_clang.h.in index 60ff5bf5914d..9d87e7a80b26 100644 --- a/config/config_clang.h.in +++ b/config/config_clang.h.in @@ -7,6 +7,9 @@ Settings related to Clang compiler plugins. #ifndef CONFIG_CLANG_H #define CONFIG_CLANG_H +#undef BUILDDIR +#undef OUTDIR #undef SRCDIR +#undef WORKDIR #endif diff --git a/configure.ac b/configure.ac index 9f9527d67f99..bd5b0749240e 100644 --- a/configure.ac +++ b/configure.ac @@ -107,6 +107,7 @@ AC_SUBST(BUILDDIR) AC_SUBST(EXEEXT_FOR_BUILD) AC_SUBST(x_Cygwin) AC_DEFINE_UNQUOTED(SRCDIR,"$SRC_ROOT") +AC_DEFINE_UNQUOTED(BUILDDIR,"$BUILDDIR") if test "z$EUID" = "z0" -a "`uname -o 2>/dev/null`" = "Cygwin"; then AC_MSG_ERROR([You must build LibreOffice as a normal user - not using an administrative account]) @@ -4092,6 +4093,8 @@ AC_SUBST(P_SEP) AC_SUBST(SOLARVER) AC_SUBST(WORKDIR) AC_SUBST(PLATFORMID) +AC_DEFINE_UNQUOTED(OUTDIR,"$OUTDIR") +AC_DEFINE_UNQUOTED(WORKDIR,"$WORKDIR") dnl =================================================================== dnl Test which package format to use |