From: Daniel Dunbar Date: Tue, 14 Apr 2009 08:05:55 +0000 (+0000) Subject: Refactor how attributes are set on values. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c65e990e9f0dafaf9adbc59b766dcc23eaee845;p=clang Refactor how attributes are set on values. - Pull out SetCommonAttributes, which handles the things common to aliases, methods, functions, and variables. - Pull out SetLLVMFunctionAttributesForDefinition, which handles the LLVM attributes which we only want to apply to a definition (like noinline and alwaysinline). - Kill SetGVDeclarationAttributes (inlined into SetFunctionAttributes and specialized). - Kill SetFunctionAttributesForDefinition (inlined into sole caller). - Inline SetGVDefinitionAttributes into SetMethodAttributes and specialize. - Rename SetGVDefinitionAttributes to SetFunctionDefinitionAttributes. This is supposed to be a no functionality change commit, but I may have made a mistake. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69036 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index dad1214b37..2b331a9e71 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -221,24 +221,34 @@ void CodeGenModule::EmitAnnotations() { gv->setSection("llvm.metadata"); } -/// SetGlobalValueAttributes - Set attributes for a global. +static CodeGenModule::GVALinkage GetLinkageForFunction(const FunctionDecl *FD) { + // "static" and attr(always_inline) functions get internal linkage. + if (FD->getStorageClass() == FunctionDecl::Static || + FD->hasAttr()) + return CodeGenModule::GVA_Internal; + + if (FD->isInline()) { + if (FD->getStorageClass() == FunctionDecl::Extern) + return CodeGenModule::GVA_ExternInline; + return CodeGenModule::GVA_Inline; + } + + return CodeGenModule::GVA_Normal; +} + +/// SetFunctionDefinitionAttributes - Set attributes for a global. /// /// FIXME: This is currently only done for aliases and functions, but /// not for variables (these details are set in /// EmitGlobalVarDefinition for variables). -void CodeGenModule::SetGVDefinitionAttributes(const Decl *D, - GVALinkage Linkage, - llvm::GlobalValue *GV) { +void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D, + llvm::GlobalValue *GV) { + GVALinkage Linkage = GetLinkageForFunction(D); + if (Linkage == GVA_Internal) { GV->setLinkage(llvm::Function::InternalLinkage); } else if (D->hasAttr()) { - if (const FunctionDecl *FD = dyn_cast(D)) { - // The dllexport attribute is ignored for undefined symbols. - if (FD->getBody()) - GV->setLinkage(llvm::Function::DLLExportLinkage); - } else { - GV->setLinkage(llvm::Function::DLLExportLinkage); - } + GV->setLinkage(llvm::Function::DLLExportLinkage); } else if (D->hasAttr() || D->hasAttr()) { GV->setLinkage(llvm::Function::WeakAnyLinkage); } else if (Linkage == GVA_ExternInline) { @@ -267,43 +277,11 @@ void CodeGenModule::SetGVDefinitionAttributes(const Decl *D, // external linkage. GV->setLinkage(llvm::Function::ExternalLinkage); } + } else { + GV->setLinkage(llvm::Function::ExternalLinkage); } - setGlobalVisibility(GV, D); - - // Only add to llvm.used when we see a definition, otherwise we - // might add it multiple times or risk the value being replaced by - // a subsequent RAUW. - if (D->hasAttr()) - AddUsedGlobal(GV); - - if (const SectionAttr *SA = D->getAttr()) - GV->setSection(SA->getName()); -} - -void CodeGenModule::SetGVDeclarationAttributes(const Decl *D, - llvm::GlobalValue *GV) { - // Only a few attributes are set on declarations; these may later be - // overridden by a definition. - - // The dllimport attribute is overridden by a subsequent declaration as - // dllexport. - if (D->hasAttr() && !D->hasAttr()) { - // dllimport attribute can be applied only to function decls, not to - // definitions. - if (const FunctionDecl *FD = dyn_cast(D)) { - if (!FD->getBody()) - GV->setLinkage(llvm::Function::DLLImportLinkage); - } else - GV->setLinkage(llvm::Function::DLLImportLinkage); - } else if (D->hasAttr() || D->hasAttr()) { - // "extern_weak" is overloaded in LLVM; we probably should have - // separate linkage types for this. - GV->setLinkage(llvm::Function::ExternalWeakLinkage); - } - - if (const SectionAttr *SA = D->getAttr()) - GV->setSection(SA->getName()); + SetCommonAttributes(D, GV); } void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D, @@ -323,33 +301,8 @@ void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D, F->setCallingConv(llvm::CallingConv::X86_StdCall); } - -static CodeGenModule::GVALinkage -GetLinkageForFunctionOrMethodDecl(const Decl *D) { - if (isa(D)) - return CodeGenModule::GVA_Internal; - - const FunctionDecl *FD = cast(D); - // "static" and attr(always_inline) functions get internal linkage. - if (FD->getStorageClass() == FunctionDecl::Static || - FD->hasAttr()) - return CodeGenModule::GVA_Internal; - - if (FD->isInline()) { - if (FD->getStorageClass() == FunctionDecl::Extern) - return CodeGenModule::GVA_ExternInline; - return CodeGenModule::GVA_Inline; - } - - return CodeGenModule::GVA_Normal; -} - -/// SetFunctionAttributesForDefinition - Set function attributes -/// specific to a function definition. -void CodeGenModule::SetFunctionAttributesForDefinition(const Decl *D, - llvm::Function *F) { - SetGVDefinitionAttributes(D, GetLinkageForFunctionOrMethodDecl(D), F); - +void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, + llvm::Function *F) { if (!Features.Exceptions && !Features.ObjCNonFragileABI) F->addFnAttr(llvm::Attribute::NoUnwind); @@ -360,18 +313,46 @@ void CodeGenModule::SetFunctionAttributesForDefinition(const Decl *D, F->addFnAttr(llvm::Attribute::NoInline); } +void CodeGenModule::SetCommonAttributes(const Decl *D, + llvm::GlobalValue *GV) { + setGlobalVisibility(GV, D); + + if (D->hasAttr()) + AddUsedGlobal(GV); + + if (const SectionAttr *SA = D->getAttr()) + GV->setSection(SA->getName()); +} + void CodeGenModule::SetMethodAttributes(const ObjCMethodDecl *MD, llvm::Function *F) { SetLLVMFunctionAttributes(MD, getTypes().getFunctionInfo(MD), F); - - SetFunctionAttributesForDefinition(MD, F); + SetLLVMFunctionAttributesForDefinition(MD, F); + + F->setLinkage(llvm::Function::InternalLinkage); + + SetCommonAttributes(MD, F); } void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, llvm::Function *F) { SetLLVMFunctionAttributes(FD, getTypes().getFunctionInfo(FD), F); - SetGVDeclarationAttributes(FD, F); + // Only a few attributes are set on declarations; these may later be + // overridden by a definition. + + if (FD->hasAttr()) { + F->setLinkage(llvm::Function::DLLImportLinkage); + } else if (FD->hasAttr() || FD->hasAttr()) { + // "extern_weak" is overloaded in LLVM; we probably should have + // separate linkage types for this. + F->setLinkage(llvm::Function::ExternalWeakLinkage); + } else { + F->setLinkage(llvm::Function::ExternalLinkage); + } + + if (const SectionAttr *SA = FD->getAttr()) + F->setSection(SA->getName()); } void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) { @@ -485,7 +466,7 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { if (FD->hasAttr() || FD->hasAttr()) return false; - GVALinkage Linkage = GetLinkageForFunctionOrMethodDecl(FD); + GVALinkage Linkage = GetLinkageForFunction(FD); // static, static inline, always_inline, and extern inline functions can // always be deferred. @@ -825,13 +806,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { else GV->setLinkage(llvm::GlobalVariable::ExternalLinkage); - setGlobalVisibility(GV, D); - - if (D->hasAttr()) - AddUsedGlobal(GV); - - if (const SectionAttr *SA = D->getAttr()) - GV->setSection(SA->getName()); + SetCommonAttributes(D, GV); // Emit global variable debug information. if (CGDebugInfo *DI = getDebugInfo()) { @@ -906,7 +881,8 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { CodeGenFunction(*this).GenerateCode(D, Fn); - SetFunctionAttributesForDefinition(D, Fn); + SetFunctionDefinitionAttributes(D, Fn); + SetLLVMFunctionAttributesForDefinition(D, Fn); if (const ConstructorAttr *CA = D->getAttr()) AddGlobalCtor(Fn, CA->getPriority()); @@ -968,8 +944,22 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { Entry = GA; GA->setName(MangledName); - // Alias should never be internal or inline. - SetGVDefinitionAttributes(D, GVA_Normal, GA); + // Set attributes which are particular to an alias; this is a + // specialization of the attributes which may be set on a global + // variable/function. + if (D->hasAttr()) { + if (const FunctionDecl *FD = dyn_cast(D)) { + // The dllexport attribute is ignored for undefined symbols. + if (FD->getBody()) + GA->setLinkage(llvm::Function::DLLExportLinkage); + } else { + GA->setLinkage(llvm::Function::DLLExportLinkage); + } + } else if (D->hasAttr() || D->hasAttr()) { + GA->setLinkage(llvm::Function::WeakAnyLinkage); + } + + SetCommonAttributes(D, GA); } /// getBuiltinLibFunction - Given a builtin id for a function like diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 3dada6d1b7..f540a73e76 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -298,6 +298,10 @@ public: const CGFunctionInfo &Info, llvm::Function *F); + /// SetLLVMFunctionAttributesForDefinition - Set the LLVM function attributes + /// which only apply to a function definintion. + void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F); + /// ReturnTypeUsesSret - Return true iff the given type uses 'sret' when used /// as a return type. bool ReturnTypeUsesSret(const CGFunctionInfo &FI); @@ -323,22 +327,17 @@ private: const llvm::PointerType *PTy, const VarDecl *D); - /// SetGVDefinitionAttributes - Set attributes for a global definition. - void SetGVDefinitionAttributes(const Decl *D, - GVALinkage Linkage, - llvm::GlobalValue *GV); - - /// SetGVDeclarationAttributes - Set attributes for a global declaration. - void SetGVDeclarationAttributes(const Decl *D, - llvm::GlobalValue *GV); - - /// SetFunctionAttributesForDefinition - Set function attributes specific to a - /// function definition. + /// SetCommonAttributes - Set attributes which are common to any + /// form of a global definition (alias, Objective-C method, + /// function, global variable). /// - /// \param D - The ObjCMethodDecl or FunctionDecl defining \arg F. - void SetFunctionAttributesForDefinition(const Decl *D, - llvm::Function *F); + /// NOTE: This should only be called for definitions. + void SetCommonAttributes(const Decl *D, llvm::GlobalValue *GV); + /// SetFunctionDefinitionAttributes - Set attributes for a global definition. + void SetFunctionDefinitionAttributes(const FunctionDecl *D, + llvm::GlobalValue *GV); + /// SetFunctionAttributes - Set function attributes for a function /// declaration. void SetFunctionAttributes(const FunctionDecl *FD,