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());
DI->setLocation(D.getLocation());
DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(GV), &D);
}
-
}
/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
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) {
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,
}
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)) {
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) {
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.
--- /dev/null
+// 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;
+}