]> granicus.if.org Git - clang/commitdiff
IRgen support for attribute used.
authorDaniel Dunbar <daniel@zuster.org>
Fri, 13 Feb 2009 22:08:43 +0000 (22:08 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Fri, 13 Feb 2009 22:08:43 +0000 (22:08 +0000)
 - PR3566

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64492 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDecl.cpp
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
test/CodeGen/attr-used.c [new file with mode: 0644]

index abcd547be996320b8da07044a6533ef886d4005b..ddc68d68c5e44304aa022096acab3472cff72f89 100644 (file)
@@ -138,6 +138,9 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) {
   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 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) {
     DI->setLocation(D.getLocation());
     DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(GV), &D);
   }
-
 }
   
 /// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
index ecfd8c98c32c544340814648c3b812cc2f851f88..e60edce213b4d56183bff02236aa00e2c5e56ab0 100644 (file)
@@ -238,11 +238,11 @@ void CodeGenModule::EmitAnnotations() {
   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 @@ static void SetGlobalValueAttributes(const Decl *D,
 
   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 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
 }
 
 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 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
   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) {
index 967889a92dfd742f79c662caf21b2c85f954e93d..4c2aeb75ac236d182cbcd63c899ed15de1e66e7b 100644 (file)
@@ -284,6 +284,13 @@ public:
 
 
 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.
diff --git a/test/CodeGen/attr-used.c b/test/CodeGen/attr-used.c
new file mode 100644 (file)
index 0000000..c7f6760
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: clang -emit-llvm -o %t %s &&
+// RUN: grep '@llvm.used = .*@g0' %t &&
+// RUN: grep '@llvm.used = .*@f0' %t &&
+// RUN: grep '@llvm.used = .*@f1.l0' %t
+
+
+int g0 __attribute__((used));
+
+static void __attribute__((used)) f0(void) {
+}
+
+void f1() { 
+  static int l0 __attribute__((used)) = 5225; 
+}