Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -357,7 +357,8 @@ llvm::StringMap Manglings; /// Global annotations. - std::vector Annotations; + typedef std::map AnnotationMap; + AnnotationMap NeededAnnotations; /// Map used to get unique annotation strings. llvm::StringMap AnnotationStrings; Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -877,6 +877,9 @@ if (FD->isReplaceableGlobalAllocationFunction()) F->addAttribute(llvm::AttributeSet::FunctionIndex, llvm::Attribute::NoBuiltin); + + if (FD->hasAttr()) + AddGlobalAnnotations(FD, F); } void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) { @@ -1087,9 +1090,25 @@ } void CodeGenModule::EmitGlobalAnnotations() { - if (Annotations.empty()) + if (NeededAnnotations.empty()) return; + std::vector Annotations; + + for (AnnotationMap::const_iterator it = NeededAnnotations.begin(), + end = NeededAnnotations.end(); it != end; ++it) { + llvm::Value* V = it->second; + if (!V) + continue; + llvm::GlobalValue* GV = cast(V); + const ValueDecl* D = it->first; + // Get the struct elements for these annotations. + for (specific_attr_iterator + ai = D->specific_attr_begin(), + ae = D->specific_attr_end(); ai != ae; ++ai) + Annotations.push_back(EmitAnnotateAttr(GV, *ai, D->getLocation())); + } + // Create a new global variable for the ConstantStruct in the Module. llvm::Constant *Array = llvm::ConstantArray::get(llvm::ArrayType::get( Annotations[0]->getType(), Annotations.size()), Annotations); @@ -1152,9 +1171,7 @@ void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV) { assert(D->hasAttr() && "no annotate attribute"); - // Get the struct elements for these annotations. - for (const auto *I : D->specific_attrs()) - Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation())); + NeededAnnotations[D] = GV; } bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { Index: test/CodeGen/annotations-forward-declaration-crash.c =================================================================== --- /dev/null +++ test/CodeGen/annotations-forward-declaration-crash.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -o - -emit-llvm | FileCheck %s + +// CHECK: private unnamed_addr constant [4 x i8] c"foo\00", section "llvm.metadata" +// CHECK: @llvm.global.annotations = appending global [1 x { i8*, i8*, i8*, i32 }] [{ i8*, i8*, i8*, i32 } { i8* bitcast (void ()* @foo to i8*), i8* getelementptr inbounds ([4 x i8]* {{.+}}, i32 0, i32 0), i8* getelementptr inbounds ([{{.+}} x i8]* {{.+}}, i32 0, i32 0), i32 8 }], section "llvm.metadata" + +__attribute__((annotate("foo"))) void foo(); +void bar(){foo();} +void foo() {} Index: test/CodeGen/annotations-forward-declaration.c =================================================================== --- /dev/null +++ test/CodeGen/annotations-forward-declaration.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -o - -emit-llvm | FileCheck %s + +// CHECK: private unnamed_addr constant [4 x i8] c"foo\00", section "llvm.metadata" +// CHECK: @llvm.global.annotations = appending global [1 x { i8*, i8*, i8*, i32 }] [{ i8*, i8*, i8*, i32 } { i8* bitcast (void ()* @foo to i8*), i8* getelementptr inbounds ([4 x i8]* {{.+}}, i32 0, i32 0), i8* getelementptr inbounds ([{{.+}} x i8]* {{.+}}, i32 0, i32 0), i32 6 }], section "llvm.metadata" + +__attribute__((annotate("foo"))) void foo(void); +void bar(){foo();}