IRgen support for attribute used.
- PR3566
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64492 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index abcd547..ddc68d6 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -138,6 +138,9 @@
if (const SectionAttr *SA = D.getAttr<SectionAttr>())
GV->setSection(SA->getName());
+ if (D.getAttr<UsedAttr>())
+ CGM.AddUsedGlobal(GV);
+
const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
const llvm::Type *LPtrTy =
llvm::PointerType::get(LTy, D.getType().getAddressSpace());
@@ -149,7 +152,6 @@
DI->setLocation(D.getLocation());
DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(GV), &D);
}
-
}
/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index ecfd8c9..e60edce 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -238,11 +238,11 @@
gv->setSection("llvm.metadata");
}
-static void SetGlobalValueAttributes(const Decl *D,
- bool IsInternal,
- bool IsInline,
- llvm::GlobalValue *GV,
- bool ForDefinition) {
+void CodeGenModule::SetGlobalValueAttributes(const Decl *D,
+ bool IsInternal,
+ bool IsInline,
+ llvm::GlobalValue *GV,
+ bool ForDefinition) {
// FIXME: Set up linkage and many other things. Note, this is a simple
// approximation of what we really want.
if (!ForDefinition) {
@@ -290,6 +290,14 @@
if (const SectionAttr *SA = D->getAttr<SectionAttr>())
GV->setSection(SA->getName());
+
+ // Only add to llvm.used when we see a definition, otherwise we
+ // might add multiple times or risk the value being replaced by a
+ // subsequent RAUW.
+ if (ForDefinition) {
+ if (D->getAttr<UsedAttr>())
+ AddUsedGlobal(GV);
+ }
}
void CodeGenModule::SetFunctionAttributes(const Decl *D,
@@ -492,8 +500,9 @@
}
bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
- // Never defer when EmitAllDecls is specified.
- if (Features.EmitAllDecls)
+ // Never defer when EmitAllDecls is specified or the decl has
+ // attribute used.
+ if (Features.EmitAllDecls || Global->getAttr<UsedAttr>())
return false;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
@@ -728,6 +737,9 @@
if (const SectionAttr *SA = D->getAttr<SectionAttr>())
GV->setSection(SA->getName());
+ if (D->getAttr<UsedAttr>())
+ AddUsedGlobal(GV);
+
// Emit global variable debug information.
CGDebugInfo *DI = getDebugInfo();
if(DI) {
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 967889a..4c2aeb7 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -284,6 +284,13 @@
private:
+ /// SetGlobalValueAttributes - Set attributes for a global decl.
+ void SetGlobalValueAttributes(const Decl *D,
+ bool IsInternal,
+ bool IsInline,
+ llvm::GlobalValue *GV,
+ bool ForDefinition);
+
/// SetFunctionAttributesForDefinition - Set function attributes specific to a
/// function definition.
/// \param D - The ObjCMethodDecl or FunctionDecl defining \arg F.