summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-04-14 08:05:55 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-04-14 08:05:55 +0000
commit389325715b3b63f0a6080489a48111960b172d2b (patch)
treef9777790f86e0d65e4e0ff0f727ebf18ff383b86 /clang/lib/CodeGen/CodeGenModule.cpp
parent81a3f1bdf31c1db98d8db1bec2de91c17aac77b6 (diff)
downloadbcm5719-llvm-389325715b3b63f0a6080489a48111960b172d2b.tar.gz
bcm5719-llvm-389325715b3b63f0a6080489a48111960b172d2b.zip
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. llvm-svn: 69036
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp164
1 files changed, 77 insertions, 87 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index dad1214b37a..2b331a9e718 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/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<AlwaysInlineAttr>())
+ 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<DLLExportAttr>()) {
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(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<WeakAttr>() || D->hasAttr<WeakImportAttr>()) {
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<UsedAttr>())
- AddUsedGlobal(GV);
-
- if (const SectionAttr *SA = D->getAttr<SectionAttr>())
- 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<DLLImportAttr>() && !D->hasAttr<DLLExportAttr>()) {
- // dllimport attribute can be applied only to function decls, not to
- // definitions.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- if (!FD->getBody())
- GV->setLinkage(llvm::Function::DLLImportLinkage);
- } else
- GV->setLinkage(llvm::Function::DLLImportLinkage);
- } else if (D->hasAttr<WeakAttr>() || D->hasAttr<WeakImportAttr>()) {
- // "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<SectionAttr>())
- 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<ObjCMethodDecl>(D))
- return CodeGenModule::GVA_Internal;
-
- const FunctionDecl *FD = cast<FunctionDecl>(D);
- // "static" and attr(always_inline) functions get internal linkage.
- if (FD->getStorageClass() == FunctionDecl::Static ||
- FD->hasAttr<AlwaysInlineAttr>())
- 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<UsedAttr>())
+ AddUsedGlobal(GV);
+
+ if (const SectionAttr *SA = D->getAttr<SectionAttr>())
+ 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<DLLImportAttr>()) {
+ F->setLinkage(llvm::Function::DLLImportLinkage);
+ } else if (FD->hasAttr<WeakAttr>() || FD->hasAttr<WeakImportAttr>()) {
+ // "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<SectionAttr>())
+ F->setSection(SA->getName());
}
void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) {
@@ -485,7 +466,7 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())
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<UsedAttr>())
- AddUsedGlobal(GV);
-
- if (const SectionAttr *SA = D->getAttr<SectionAttr>())
- 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<ConstructorAttr>())
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<DLLExportAttr>()) {
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(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<WeakAttr>() || D->hasAttr<WeakImportAttr>()) {
+ GA->setLinkage(llvm::Function::WeakAnyLinkage);
+ }
+
+ SetCommonAttributes(D, GA);
}
/// getBuiltinLibFunction - Given a builtin id for a function like
OpenPOWER on IntegriCloud