diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2338,7 +2338,7 @@ /// ShouldInstrumentFunction - Return true if the current function should be /// instrumented with __cyg_profile_func_* calls - bool ShouldInstrumentFunction(llvm::Function *F); + bool ShouldInstrumentFunction(); /// ShouldSkipSanitizerInstrumentation - Return true if the current function /// should not be instrumented with sanitizers. diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -30,10 +30,12 @@ #include "clang/AST/StmtObjC.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Demangle/Demangle.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" @@ -375,7 +377,7 @@ // Emit function epilog (to return). llvm::DebugLoc Loc = EmitReturnBlock(); - if (ShouldInstrumentFunction(CurFn)) { + if (ShouldInstrumentFunction()) { if (CGM.getCodeGenOpts().InstrumentFunctions) CurFn->addFnAttr("instrument-function-exit", "__cyg_profile_func_exit"); if (CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining) @@ -521,7 +523,7 @@ /// ShouldInstrumentFunction - Return true if the current function should be /// instrumented with __cyg_profile_func_* calls -bool CodeGenFunction::ShouldInstrumentFunction(llvm::Function *F) { +bool CodeGenFunction::ShouldInstrumentFunction() { if (!CGM.getCodeGenOpts().InstrumentFunctions && !CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining && !CGM.getCodeGenOpts().InstrumentFunctionEntryBare) @@ -534,25 +536,56 @@ // generate tracing for it: at link-time, the function will be gone and the // first argument to the __cyg_profile_* function will be unresolvable. const FunctionDecl *FDecl = dyn_cast(CurFuncDecl); - if (FDecl && FDecl->isInlined() && + if (FDecl && + FDecl->isInlined() && !FDecl->isInlineDefinitionExternallyVisible()) return false; + // The list of excluded file name substrings specified on the command line + // is searched to see if any of them is a substring the current function's + // declaration location. + static std::map CachedFilePaths; + SourceLocation DeclarationLocation = CurFuncDecl->getLocation(); + + // If the declaration location doesn't correspond directly to a file, it + // can't be excluded based file name. + if (DeclarationLocation.isFileID()) { + if (CachedFilePaths.find(DeclarationLocation) == CachedFilePaths.end()) { + ASTContext &Context = CurFuncDecl->getASTContext(); + const SourceManager &SM = Context.getSourceManager(); + + PresumedLoc PresumedLocation = SM.getPresumedLoc(DeclarationLocation); + CachedFilePaths[DeclarationLocation] = PresumedLocation.getFilename(); + } + + std::string Path = CachedFilePaths[DeclarationLocation]; + + typedef std::vector::const_iterator ExcludedPathIterator; + + const std::vector &ExcludedPaths = + CGM.getCodeGenOpts().InstrumentFunctionsExcludedPaths; + + for (ExcludedPathIterator ExcludedPath = ExcludedPaths.begin(), + Sentinel = ExcludedPaths.end(); ExcludedPath != Sentinel; ++ExcludedPath) + if (Path.find(*ExcludedPath) != std::string::npos) + return false; + } + typedef std::vector::const_iterator ExcludedFunctionIterator; // The list of excluded function name substrings specified on the command-line // is searched to see if any of them is a substring of our (current) function // name. const std::vector &ExcludedFunctions = - CGM.getCodeGenOpts().InstrumentFunctionsExcludedFunctions; + CGM.getCodeGenOpts().InstrumentFunctionsExcludedFunctions; - std::string FName(F->getName()); + std::string MangledName(CurFn->getName()); + std::string DemangledName(llvm::demangle(MangledName)); for (ExcludedFunctionIterator ExcludedFunction = ExcludedFunctions.begin(), - Sentinel = ExcludedFunctions.end(); - ExcludedFunction != Sentinel; ++ExcludedFunction) { - if (FName.find(*ExcludedFunction) != std::string::npos) + Sentinel = ExcludedFunctions.end(); + ExcludedFunction != Sentinel; ++ExcludedFunction) + if (DemangledName.find(*ExcludedFunction) != std::string::npos) return false; - } return true; } @@ -1044,7 +1077,7 @@ CurFuncIsThunk); } - if (ShouldInstrumentFunction(CurFn)) { + if (ShouldInstrumentFunction()) { if (CGM.getCodeGenOpts().InstrumentFunctions) CurFn->addFnAttr("instrument-function-entry", "__cyg_profile_func_enter"); if (CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)