diff options
| author | Alp Toker <alp@nuanti.com> | 2014-06-05 22:10:59 +0000 |
|---|---|---|
| committer | Alp Toker <alp@nuanti.com> | 2014-06-05 22:10:59 +0000 |
| commit | fb8d02b179732b17897f1d4024583949a56b0bb5 (patch) | |
| tree | 9773c072cdc1e0f4a6ccfba97f3ed6cda7f2d958 /clang/lib/CodeGen | |
| parent | 66f676e9e53aaaba12fd9848a94915346ab76b87 (diff) | |
| download | bcm5719-llvm-fb8d02b179732b17897f1d4024583949a56b0bb5.tar.gz bcm5719-llvm-fb8d02b179732b17897f1d4024583949a56b0bb5.zip | |
Implement -Wframe-larger-than backend diagnostic
Add driver and frontend support for the GCC -Wframe-larger-than=bytes warning.
This is the first GCC-compatible backend diagnostic built around LLVM's
reporting feature.
This commit adds infrastructure to perform reverse lookup from mangled names
emitted after LLVM IR generation. We use that to resolve precise locations and
originating AST functions, lambdas or block declarations to produce seamless
codegen-guided diagnostics.
An associated change, StringMap now maintains unique mangled name strings
instead of allocating copies. This is a net memory saving in C++ and a small
hit for C where we no longer reuse IdentifierInfo storage, pending further
optimisation.
llvm-svn: 210293
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGBlocks.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 18 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 14 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 70 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 11 | ||||
| -rw-r--r-- | clang/lib/CodeGen/ModuleBuilder.cpp | 15 |
6 files changed, 76 insertions, 54 deletions
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 71a2447cb5d..7ffebe28910 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -1127,7 +1127,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo); - std::string name = CGM.getBlockMangledName(GD, blockDecl); + StringRef name = CGM.getBlockMangledName(GD, blockDecl); llvm::Function *fn = llvm::Function::Create( fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule()); CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 7cf9cb2417b..8d6b4188733 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -149,12 +149,11 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) { static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D, const char *Separator) { CodeGenModule &CGM = CGF.CGM; - if (CGF.getLangOpts().CPlusPlus) { - StringRef Name = CGM.getMangledName(&D); - return Name.str(); - } - std::string ContextName; + if (CGF.getLangOpts().CPlusPlus) + return CGM.getMangledName(&D).str(); + + StringRef ContextName; if (!CGF.CurFuncDecl) { // Better be in a block declared in global scope. const NamedDecl *ND = cast<NamedDecl>(&D); @@ -163,15 +162,14 @@ static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D, ContextName = CGM.getBlockMangledName(GlobalDecl(), BD); else llvm_unreachable("Unknown context for block static var decl"); - } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) { - StringRef Name = CGM.getMangledName(FD); - ContextName = Name.str(); - } else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) + } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) + ContextName = CGM.getMangledName(FD); + else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) ContextName = CGF.CurFn->getName(); else llvm_unreachable("Unknown context for static var decl"); - return ContextName + Separator + D.getNameAsString(); + return ContextName.str() + Separator + D.getNameAsString(); } llvm::Constant * diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index f593ccf431d..455299f2df7 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -404,12 +404,14 @@ BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) { // We do not know how to format other severities. return false; - // FIXME: We should demangle the function name. - // FIXME: Is there a way to get a location for that function? - FullSourceLoc Loc; - Diags.Report(Loc, diag::warn_fe_backend_frame_larger_than) - << D.getStackSize() << D.getFunction().getName(); - return true; + if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) { + Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()), + diag::warn_fe_frame_larger_than) + << D.getStackSize() << Decl::castToDeclContext(ND); + return true; + } + + return false; } void BackendConsumer::EmitOptimizationRemark( diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index ac89ce699a6..9cb84f890af 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -498,47 +498,40 @@ void CodeGenModule::setTLSMode(llvm::GlobalVariable *GV, } StringRef CodeGenModule::getMangledName(GlobalDecl GD) { - const auto *ND = cast<NamedDecl>(GD.getDecl()); - - StringRef &Str = MangledDeclNames[GD.getCanonicalDecl()]; - if (!Str.empty()) - return Str; + StringRef &FoundStr = MangledDeclNames[GD.getCanonicalDecl()]; + if (!FoundStr.empty()) + return FoundStr; - if (!getCXXABI().getMangleContext().shouldMangleDeclName(ND)) { + const auto *ND = cast<NamedDecl>(GD.getDecl()); + SmallString<256> Buffer; + StringRef Str; + if (getCXXABI().getMangleContext().shouldMangleDeclName(ND)) { + llvm::raw_svector_ostream Out(Buffer); + if (const auto *D = dyn_cast<CXXConstructorDecl>(ND)) + getCXXABI().getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Out); + else if (const auto *D = dyn_cast<CXXDestructorDecl>(ND)) + getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out); + else + getCXXABI().getMangleContext().mangleName(ND, Out); + Str = Out.str(); + } else { IdentifierInfo *II = ND->getIdentifier(); assert(II && "Attempt to mangle unnamed decl."); - Str = II->getName(); - return Str; } - - SmallString<256> Buffer; - llvm::raw_svector_ostream Out(Buffer); - if (const auto *D = dyn_cast<CXXConstructorDecl>(ND)) - getCXXABI().getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Out); - else if (const auto *D = dyn_cast<CXXDestructorDecl>(ND)) - getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out); - else - getCXXABI().getMangleContext().mangleName(ND, Out); - // Allocate space for the mangled name. - Out.flush(); - size_t Length = Buffer.size(); - char *Name = MangledNamesAllocator.Allocate<char>(Length); - std::copy(Buffer.begin(), Buffer.end(), Name); - - Str = StringRef(Name, Length); - - return Str; + auto &Mangled = Manglings.GetOrCreateValue(Str); + Mangled.second = GD; + return FoundStr = Mangled.first(); } -std::string CodeGenModule::getBlockMangledName(GlobalDecl GD, - const BlockDecl *BD) { +StringRef CodeGenModule::getBlockMangledName(GlobalDecl GD, + const BlockDecl *BD) { MangleContext &MangleCtx = getCXXABI().getMangleContext(); const Decl *D = GD.getDecl(); - std::string Buffer; - llvm::raw_string_ostream Out(Buffer); + SmallString<256> Buffer; + llvm::raw_svector_ostream Out(Buffer); if (!D) MangleCtx.mangleGlobalBlock(BD, dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()), Out); @@ -549,7 +542,9 @@ std::string CodeGenModule::getBlockMangledName(GlobalDecl GD, else MangleCtx.mangleBlock(cast<DeclContext>(D), BD, Out); - return Out.str(); + auto &Mangled = Manglings.GetOrCreateValue(Out.str()); + Mangled.second = BD; + return Mangled.first(); } llvm::GlobalValue *CodeGenModule::GetGlobalValue(StringRef Name) { @@ -1462,7 +1457,7 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, // This is the first use or definition of a mangled name. If there is a // deferred decl with this name, remember that we need to emit it at the end // of the file. - llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName); + auto DDI = DeferredDecls.find(MangledName); if (DDI != DeferredDecls.end()) { // Move the potentially referenced deferred decl to the // DeferredDeclsToEmit list, and remove it from DeferredDecls (since we @@ -1622,7 +1617,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, // This is the first use or definition of a mangled name. If there is a // deferred decl with this name, remember that we need to emit it at the end // of the file. - llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName); + auto DDI = DeferredDecls.find(MangledName); if (DDI != DeferredDecls.end()) { // Move the potentially referenced deferred decl to the DeferredDeclsToEmit // list, and remove it from DeferredDecls (since we don't need it anymore). @@ -3205,6 +3200,15 @@ void CodeGenModule::EmitStaticExternCAliases() { } } +bool CodeGenModule::lookupRepresentativeDecl(StringRef MangledName, + GlobalDecl &Result) const { + auto Res = Manglings.find(MangledName); + if (Res == Manglings.end()) + return false; + Result = Res->getValue(); + return true; +} + /// Emits metadata nodes associating all the global values in the /// current module with the Decls they came from. This is useful for /// projects using IR gen as a subroutine. diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index f157d20e6cf..6cb4fc17c5e 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -287,7 +287,7 @@ class CodeGenModule : public CodeGenTypeCache { /// for emission and therefore should only be output if they are actually /// used. If a decl is in this, then it is known to have not been referenced /// yet. - llvm::StringMap<GlobalDecl> DeferredDecls; + std::map<StringRef, GlobalDecl> DeferredDecls; /// This is a list of deferred decls which we have seen that *are* actually /// referenced. These get code generated when the module is done. @@ -327,8 +327,8 @@ class CodeGenModule : public CodeGenTypeCache { /// A map of canonical GlobalDecls to their mangled names. llvm::DenseMap<GlobalDecl, StringRef> MangledDeclNames; - llvm::BumpPtrAllocator MangledNamesAllocator; - + llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings; + /// Global annotations. std::vector<llvm::Constant*> Annotations; @@ -522,6 +522,9 @@ public: StaticLocalDeclGuardMap[D] = C; } + bool lookupRepresentativeDecl(StringRef MangledName, + GlobalDecl &Result) const; + llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) { return AtomicSetterHelperFnMap[Ty]; } @@ -922,7 +925,7 @@ public: bool AttrOnCallSite); StringRef getMangledName(GlobalDecl GD); - std::string getBlockMangledName(GlobalDecl GD, const BlockDecl *BD); + StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD); void EmitTentativeDefinition(const VarDecl *D); diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 78cb82dc558..e5bdae93fe7 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -49,6 +49,21 @@ namespace { return M.get(); } + const Decl *GetDeclForMangledName(StringRef MangledName) override { + GlobalDecl Result; + if (!Builder->lookupRepresentativeDecl(MangledName, Result)) + return nullptr; + const Decl *D = Result.getCanonicalDecl().getDecl(); + if (auto FD = dyn_cast<FunctionDecl>(D)) { + if (FD->hasBody(FD)) + return FD; + } else if (auto TD = dyn_cast<TagDecl>(D)) { + if (auto Def = TD->getDefinition()) + return Def; + } + return D; + } + llvm::Module *ReleaseModule() override { return M.release(); } void Initialize(ASTContext &Context) override { |

