diff options
Diffstat (limited to 'compilerplugins/clang/pluginhandler.cxx')
-rw-r--r-- | compilerplugins/clang/pluginhandler.cxx | 62 |
1 files changed, 29 insertions, 33 deletions
diff --git a/compilerplugins/clang/pluginhandler.cxx b/compilerplugins/clang/pluginhandler.cxx index 35b5e03298b4..0fb62eb56c48 100644 --- a/compilerplugins/clang/pluginhandler.cxx +++ b/compilerplugins/clang/pluginhandler.cxx @@ -13,6 +13,8 @@ #include <system_error> #include <utility> +#include "config_clang.h" + #include "compat.hxx" #include "plugin.hxx" #include "pluginhandler.hxx" @@ -20,11 +22,8 @@ #include <clang/Frontend/CompilerInstance.h> #include <clang/Frontend/FrontendPluginRegistry.h> #include <clang/Lex/PPCallbacks.h> -#include <stdio.h> - -#if CLANG_VERSION >= 90000 +#include <llvm/ADT/StringExtras.h> #include <llvm/Support/TimeProfiler.h> -#endif #if defined _WIN32 #include <process.h> @@ -65,7 +64,7 @@ static bool unitTestMode = false; StringRef initMainFileName(CompilerInstance& compiler) { - StringRef const& fn(compiler.getASTContext().getSourceManager().getFileEntryForID( + StringRef const& fn(compiler.getASTContext().getSourceManager().getFileEntryRefForID( compiler.getASTContext().getSourceManager().getMainFileID())->getName()); if (fn == "<stdin>") // stdin means icecream, so we can rely on -main-file-name containing the full path name @@ -232,19 +231,22 @@ bool PluginHandler::ignoreLocation(SourceLocation loc) { bool PluginHandler::checkIgnoreLocation(SourceLocation loc) { -#if CLANG_VERSION >= 80000 - // If a location comes from a PCH, it is not necessary to check it - // in every compilation using the PCH, since with Clang we use - // -building-pch-with-obj to build a separate precompiled_foo.cxx file - // for the PCH, and so it is known that everything in the PCH will - // be checked while compiling this file. Skip the checks for all - // other files using the PCH. - if( !compiler.getSourceManager().isLocalSourceLocation( loc )) + // The tree-wide analysis plugins (like unusedmethods) don't want + // this logic, they only want to ignore external code + if (!treeWideAnalysisMode) { - if( !compiler.getLangOpts().BuildingPCHWithObjectFile ) - return true; + // If a location comes from a PCH, it is not necessary to check it + // in every compilation using the PCH, since with Clang we use + // -building-pch-with-obj to build a separate precompiled_foo.cxx file + // for the PCH, and so it is known that everything in the PCH will + // be checked while compiling this file. Skip the checks for all + // other files using the PCH. + if( !compiler.getSourceManager().isLocalSourceLocation( loc )) + { + if( !compiler.getLangOpts().BuildingPCHWithObjectFile ) + return true; + } } -#endif SourceLocation expansionLoc = compiler.getSourceManager().getExpansionLoc( loc ); if( compiler.getSourceManager().isInSystemHeader( expansionLoc )) return true; @@ -314,12 +316,10 @@ void PluginHandler::addSourceModification(SourceRange range) void PluginHandler::HandleTranslationUnit( ASTContext& context ) { -#if CLANG_VERSION >= 90000 llvm::TimeTraceScope mainTimeScope("LOPluginMain", StringRef("")); -#endif if( context.getDiagnostics().hasErrorOccurred()) return; - if (mainFileName.endswith(".ii")) + if (compat::ends_with(mainFileName, ".ii")) { report(DiagnosticsEngine::Fatal, "input file has suffix .ii: \"%0\"\nhighly suspicious, probably ccache generated, this will break warning suppressions; export CCACHE_CPP2=1 to prevent this") << mainFileName; @@ -330,9 +330,7 @@ void PluginHandler::HandleTranslationUnit( ASTContext& context ) { if( plugins[ i ].object != NULL && !plugins[ i ].disabledRun ) { -#if CLANG_VERSION >= 90000 llvm::TimeTraceScope timeScope("LOPlugin", [&]() { return plugins[i].optionName; }); -#endif plugins[ i ].object->run(); } } @@ -345,8 +343,8 @@ void PluginHandler::HandleTranslationUnit( ASTContext& context ) it != rewriter.buffer_end(); ++it ) { - const FileEntry* e = context.getSourceManager().getFileEntryForID( it->first ); - if( e == NULL ) + auto e = context.getSourceManager().getFileEntryRefForID( it->first ); + if( !e ) continue; // Failed modification because of a macro expansion? /* Check where the file actually is, and warn about cases where modification most probably doesn't matter (generated files in workdir). @@ -356,11 +354,11 @@ void PluginHandler::HandleTranslationUnit( ASTContext& context ) const char* pathWarning = NULL; bool bSkip = false; StringRef const name = e->getName(); - if( name.startswith(WORKDIR "/") ) + if( compat::starts_with(name, WORKDIR "/") ) pathWarning = "modified source in workdir/ : %0"; - else if( strcmp( SRCDIR, BUILDDIR ) != 0 && name.startswith(BUILDDIR "/") ) + else if( strcmp( SRCDIR, BUILDDIR ) != 0 && compat::starts_with(name, BUILDDIR "/") ) pathWarning = "modified source in build dir : %0"; - else if( name.startswith(SRCDIR "/") ) + else if( compat::starts_with(name, SRCDIR "/") ) ; // ok else { @@ -387,27 +385,25 @@ void PluginHandler::HandleTranslationUnit( ASTContext& context ) report( DiagnosticsEngine::Warning, pathWarning ) << name; if( bSkip ) continue; - char* filename = new char[ modifyFile.length() + 100 ]; - sprintf( filename, "%s.new.%d", modifyFile.c_str(), getpid()); + auto const filename = modifyFile + ".new." + itostr(getpid()); std::string error; bool bOk = false; std::error_code ec; std::unique_ptr<raw_fd_ostream> ostream( - new raw_fd_ostream(filename, ec, compat::OF_None)); + new raw_fd_ostream(filename, ec, sys::fs::OF_None)); if( !ec) { it->second.write( *ostream ); ostream->close(); - if( !ostream->has_error() && rename( filename, modifyFile.c_str()) == 0 ) + if( !ostream->has_error() && rename( filename.c_str(), modifyFile.c_str()) == 0 ) bOk = true; } else error = "error: " + ec.message(); ostream->clear_error(); - unlink( filename ); + unlink( filename.c_str() ); if( !bOk ) report( DiagnosticsEngine::Error, "cannot write modified source to %0 (%1)" ) << modifyFile << error; - delete[] filename; } #endif } @@ -434,7 +430,7 @@ static bool MethodsAndNestedClassesComplete(const CXXRecordDecl *RD, I != E && Complete; ++I) { if (const CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(*I)) Complete = M->isDefined() || M->isDefaulted() || - (M->isPure() && !isa<CXXDestructorDecl>(M)); + (compat::isPureVirtual(M) && !isa<CXXDestructorDecl>(M)); else if (const FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(*I)) // If the template function is marked as late template parsed at this // point, it has not been instantiated and therefore we have not |