summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2013-01-03 20:15:21 +0100
committerLuboš Luňák <l.lunak@suse.cz>2013-01-04 15:27:24 +0100
commit217e3f2ea1e8983328364607f244daceeafca167 (patch)
tree136686e0e8faadfcc91c8a24a74318cf550700b4
parentn#793262 testcase (diff)
downloadcore-217e3f2ea1e8983328364607f244daceeafca167.tar.gz
core-217e3f2ea1e8983328364607f244daceeafca167.zip
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
-rw-r--r--compilerplugins/clang/lclstaticfix.cxx4
-rw-r--r--compilerplugins/clang/plugin.cxx66
-rw-r--r--compilerplugins/clang/postfixincrementfix.cxx3
-rw-r--r--config/config_clang.h.in3
-rw-r--r--configure.ac3
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