[cfe-commits] [PATCH] llvm.annotation support
Julien Lerouge
jlerouge at apple.com
Tue Jun 14 00:14:40 PDT 2011
Hello,
Attached is a patch that brings back annotation support to the state it
was (or close) with llvm-gcc. The patch adds the __builtin_annotation
and support for annotating struct fields and local variables (support
for globals was already in there).
I moved all the code related to those annotations in CGAnnotations.h/cpp
The other changes are minor tweaks for the annotate attribute and a
bunch of tests.
Thanks,
Julien
---
include/clang/Basic/Attr.td | 2 +-
include/clang/Basic/Builtins.def | 3 +
lib/CodeGen/CGAnnotations.cpp | 165 ++++++++++++++++++++++++++++++++++++
lib/CodeGen/CGAnnotations.h | 99 +++++++++++++++++++++
lib/CodeGen/CGBuiltin.cpp | 5 +-
lib/CodeGen/CGDecl.cpp | 17 ++--
lib/CodeGen/CGExpr.cpp | 4 +
lib/CodeGen/CodeGenModule.cpp | 88 ++++---------------
lib/CodeGen/CodeGenModule.h | 12 +--
lib/Sema/SemaDecl.cpp | 6 ++
lib/Sema/SemaDeclAttr.cpp | 8 ++
test/CodeGen/annotate.c | 10 --
test/CodeGen/annotations-builtin.c | 52 +++++++++++
test/CodeGen/annotations-field.c | 27 ++++++
test/CodeGen/annotations-global.c | 41 +++++++++
test/CodeGen/annotations-loc.c | 10 ++
test/CodeGen/annotations-var.c | 43 +++++++++
17 files changed, 492 insertions(+), 100 deletions(-)
--
Julien Lerouge
PGP Key Id: 0xB1964A62
PGP Fingerprint: 392D 4BAD DB8B CE7F 4E5F FA3C 62DB 4AA7 B196 4A62
PGP Public Key from: keyserver.pgp.com
-------------- next part --------------
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index e4c6722..d231372 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -128,7 +128,7 @@ def AnalyzerNoReturn : InheritableAttr {
let Spellings = ["analyzer_noreturn"];
}
-def Annotate : InheritableAttr {
+def Annotate : InheritableParamAttr {
let Spellings = ["annotate"];
let Args = [StringArgument<"Annotation">];
}
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 9a4c768..5a25275 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -732,5 +732,8 @@ LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.
+// Annotation function
+BUILTIN(__builtin_annotation, "UiUicC*", "nc")
+
#undef BUILTIN
#undef LIBBUILTIN
diff --git a/lib/CodeGen/CGAnnotations.cpp b/lib/CodeGen/CGAnnotations.cpp
new file mode 100644
index 0000000..cafef84
--- /dev/null
+++ b/lib/CodeGen/CGAnnotations.cpp
@@ -0,0 +1,165 @@
+//===-- CGAnnotations.cpp - Annotations codegen -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGAnnotations.h"
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/SourceManager.h"
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Module.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+static const char *AnnotationSection = "llvm.metadata";
+
+void CGAnnotations::EmitGlobalAnnotations() const {
+ if (Annotations.empty())
+ return;
+
+ // 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);
+ llvm::Module &M = CGM.getModule();
+ llvm::GlobalValue *gv = new llvm::GlobalVariable(M, Array->getType(), false,
+ llvm::GlobalValue::AppendingLinkage, Array, "llvm.global.annotations");
+ gv->setSection(AnnotationSection);
+}
+
+llvm::Constant *CGAnnotations::EmitAnnotationString(llvm::StringRef Str) const {
+ llvm::Module &M = CGM.getModule();
+ llvm::LLVMContext &VMContext = CGM.getLLVMContext();
+
+ llvm::Constant *s = llvm::ConstantArray::get(VMContext, Str, true);
+ for (llvm::Value::use_iterator i = s->use_begin(), e = s->use_end(); i != e;
+ ++i) {
+ llvm::GlobalVariable *gv = dyn_cast<llvm::GlobalVariable>(*i);
+ if (!gv || gv->getSection() != AnnotationSection)
+ continue;
+ return gv;
+ }
+
+ // Not found yet, create a new global.
+ llvm::GlobalValue *gv = new llvm::GlobalVariable(M, s->getType(), true,
+ llvm::GlobalValue::PrivateLinkage, s, ".str");
+ gv->setSection(AnnotationSection);
+ gv->setUnnamedAddr(true);
+ return gv;
+}
+
+llvm::Constant *CGAnnotations::EmitAnnotationUnit(SourceLocation Loc) const {
+ SourceManager &SM = CGM.getContext().getSourceManager();
+ PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+ if (PLoc.isValid())
+ return EmitAnnotationString(PLoc.getFilename());
+ return EmitAnnotationString(SM.getBufferName(Loc));
+}
+
+llvm::Constant *CGAnnotations::EmitAnnotationLineNo(SourceLocation L) const {
+ SourceManager &SM = CGM.getContext().getSourceManager();
+ PresumedLoc PLoc = SM.getPresumedLoc(L);
+ unsigned LineNo = PLoc.isValid() ? PLoc.getLine() :
+ SM.getInstantiationLineNumber(L);
+ return llvm::ConstantInt::get(CGM.Int32Ty, LineNo);
+}
+
+llvm::Constant *CGAnnotations::EmitAnnotateAttr(llvm::GlobalValue *GV,
+ const AnnotateAttr *AA,
+ SourceLocation L) const {
+ const llvm::Type *SBP = CGM.Int8PtrTy;
+
+ // Get the globals for file name, annotation, and the line number.
+ llvm::Constant *AnnoGV = EmitAnnotationString(AA->getAnnotation()),
+ *UnitGV = EmitAnnotationUnit(L),
+ *LineNoCst = EmitAnnotationLineNo(L);
+
+ // Create the ConstantStruct for the global annotation.
+ llvm::Constant *Fields[4] = {
+ llvm::ConstantExpr::getBitCast(GV, SBP),
+ llvm::ConstantExpr::getBitCast(AnnoGV, SBP),
+ llvm::ConstantExpr::getBitCast(UnitGV, SBP),
+ LineNoCst
+ };
+ return llvm::ConstantStruct::get(CGM.getLLVMContext(), Fields, 4, false);
+}
+
+void CGAnnotations::AddGlobalAnnotations(const ValueDecl *D,
+ llvm::GlobalValue *GV) {
+ assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
+ // Get the struct elements for these annotations.
+ for (ann_iterator ai = ann_begin(D), ae = ann_end(D); ai != ae; ++ai)
+ Annotations.push_back(EmitAnnotateAttr(GV, *ai, D->getLocation()));
+}
+
+llvm::Value *CGAnnotations::EmitAnnotationCall(llvm::Value *AnnotationFn,
+ llvm::Value *AnnotatedVal,
+ llvm::StringRef AnnotationStr,
+ SourceLocation Location,
+ CGBuilderTy &Builder) const {
+ llvm::Value *Args[4];
+ Args[0] = AnnotatedVal;
+ Args[1] = Builder.CreateBitCast(EmitAnnotationString(AnnotationStr),
+ CGM.Int8PtrTy);
+ Args[2] = Builder.CreateBitCast(EmitAnnotationUnit(Location), CGM.Int8PtrTy);
+ Args[3] = EmitAnnotationLineNo(Location);
+ return Builder.CreateCall(AnnotationFn, Args, Args + 4);
+}
+
+llvm::Value *CGAnnotations::EmitBuiltinAnnotation(CodeGenFunction &CGF,
+ const CallExpr *E) const {
+ CGBuilderTy &Builder = CGF.Builder;
+ llvm::Value *AnnVal = CGF.EmitScalarExpr(E->getArg(0));
+
+ // Get the intrinsic.
+ const llvm::Type *ArgTy = AnnVal->getType();
+ llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, &ArgTy, 1);
+
+ // Get the anntotation string.
+ const Expr *AnnotationStrExpr = E->getArg(1);
+ while (const CastExpr *CE = dyn_cast<CastExpr>(AnnotationStrExpr))
+ AnnotationStrExpr = CE->getSubExpr();
+ llvm::StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString();
+
+ return EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc(), Builder);
+}
+
+void CGAnnotations::EmitVarAnnotations(const VarDecl *D, llvm::Value *V,
+ CGBuilderTy &Builder) const {
+ assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
+ for (ann_iterator ai = ann_begin(D), ae = ann_end(D); ai != ae; ++ai)
+ EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation),
+ Builder.CreateBitCast(V, CGM.Int8PtrTy, V->getName()),
+ (*ai)->getAnnotation(), D->getLocation(), Builder);
+}
+
+llvm::Value *CGAnnotations::EmitFieldAnnotations(const FieldDecl *D,
+ llvm::Value *V,
+ CGBuilderTy &Builder) const {
+ assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
+ const llvm::Type *ArgTy = CGM.Int8PtrTy, *VTy = V->getType();
+ llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation, &ArgTy, 1);
+
+ for (ann_iterator ai = ann_begin(D), ae = ann_end(D); ai != ae; ++ai) {
+ // Always emit the cast inst so we can differentiate between annotation on
+ // the first field of a struct and annotation on the strut itself.
+ if (V->getType() != ArgTy)
+ V = Builder.Insert(new llvm::BitCastInst(V, ArgTy));
+ V = EmitAnnotationCall(F, V, (*ai)->getAnnotation(), D->getLocation(),
+ Builder);
+ V = Builder.CreateBitCast(V, VTy);
+ }
+
+ return V;
+}
diff --git a/lib/CodeGen/CGAnnotations.h b/lib/CodeGen/CGAnnotations.h
new file mode 100644
index 0000000..f51dcd9
--- /dev/null
+++ b/lib/CodeGen/CGAnnotations.h
@@ -0,0 +1,99 @@
+//===-- CGAnnotations.h - Annotations codegen -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_ANNOTATIONS_H
+#define CLANG_CODEGEN_ANNOTATIONS_H
+
+#include "CGBuilder.h"
+#include "CodeGenModule.h"
+
+namespace llvm {
+ class Value;
+ class Constant;
+ class GlobalValue;
+}
+
+namespace clang {
+ class VarDecl;
+
+namespace CodeGen {
+
+class CGAnnotations {
+ typedef specific_attr_iterator<AnnotateAttr> ann_iterator;
+
+ CodeGenModule &CGM;
+
+ /// Global annotations.
+ std::vector<llvm::Constant*> Annotations;
+
+ /// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the
+ /// annotation information for a given GlobalValue. The annotation struct is
+ /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the
+ /// GlobalValue being annotated. The second field is the constant string
+ /// created from the AnnotateAttr's annotation. The third field is a constant
+ /// string containing the name of the translation unit. The fourth field is
+ /// the line number in the file of the annotated value declaration.
+ llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
+ const AnnotateAttr *AA,
+ SourceLocation L) const;
+
+ /// Emit the annotation's translation unit.
+ llvm::Constant *EmitAnnotationUnit(SourceLocation L) const;
+
+ /// Emit the annotation string.
+ llvm::Constant *EmitAnnotationString(llvm::StringRef Str) const;
+
+ /// Emit the annotation line number.
+ llvm::Constant *EmitAnnotationLineNo(SourceLocation L) const;
+
+ /// Emit an annotation call (intrinsic or builtin).
+ llvm::Value *EmitAnnotationCall(llvm::Value *AnnotationFn,
+ llvm::Value *AnnotatedVal,
+ llvm::StringRef AnnotationStr,
+ SourceLocation Location,
+ CGBuilderTy &Builder) const;
+
+ /// Get the beginning / end of annotations for a decl.
+ static ann_iterator ann_begin(const Decl *D) {
+ return D->specific_attr_begin<AnnotateAttr>();
+ }
+ static ann_iterator ann_end(const Decl *D) {
+ return D->specific_attr_end<AnnotateAttr>();
+ }
+
+public:
+
+ /// Emit all the global annotations.
+ void EmitGlobalAnnotations() const;
+
+ /// Add global annotations that are set on D, for the global GV.
+ void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
+
+ /// Emit a builtin annotation, return the anntotation call.
+ llvm::Value *EmitBuiltinAnnotation(CodeGenFunction &CGF,
+ const CallExpr *E) const;
+
+ /// Emit local annotations for the local variable V, declared by D.
+ /// Instructions are added using the Builder passed.
+ void EmitVarAnnotations(const VarDecl *D, llvm::Value *V,
+ CGBuilderTy &Builder) const;
+
+ /// Emit field annotations for the given field & value. Returns the
+ /// annotation result.
+ llvm::Value *EmitFieldAnnotations(const FieldDecl *D, llvm::Value *V,
+ CGBuilderTy &Builder) const;
+
+ CGAnnotations(CodeGenModule &CGM) : CGM(CGM) {}
+};
+
+}
+
+}
+
+#endif // CLANG_CODEGEN_ANNOTATIONS_H
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 14bebaf..f781191 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -14,6 +14,7 @@
#include "TargetInfo.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
+#include "CGAnnotations.h"
#include "CGObjCRuntime.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/APValue.h"
@@ -453,7 +454,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
}
case Builtin::BI__builtin_isfinite: {
- // isfinite(x) --> x == x && fabs(x) != infinity; }
+ // isfinite(x) --> x == x && fabs(x) != infinity;
Value *V = EmitScalarExpr(E->getArg(0));
Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq");
@@ -998,6 +999,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp);
return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType())));
}
+ case Builtin::BI__builtin_annotation:
+ return RValue::get(CGM.getAnnotations()->EmitBuiltinAnnotation(*this, E));
}
// If this is an alias for a libm function (e.g. __builtin_sin) turn it into
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 8a1a853..c6fd1dd 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "CGAnnotations.h"
#include "CGDebugInfo.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
@@ -270,14 +271,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
- // FIXME: Merge attribute handling.
- if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) {
- SourceManager &SM = CGM.getContext().getSourceManager();
- llvm::Constant *Ann =
- CGM.EmitAnnotateAttr(GV, AA,
- SM.getInstantiationLineNumber(D.getLocation()));
- CGM.AddAnnotation(Ann);
- }
+ if (D.hasAttr<AnnotateAttr>())
+ CGM.getAnnotations()->AddGlobalAnnotations(&D, GV);
if (const SectionAttr *SA = D.getAttr<SectionAttr>())
GV->setSection(SA->getName());
@@ -638,6 +633,9 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder);
}
+ if (D.hasAttr<AnnotateAttr>())
+ CGM.getAnnotations()->EmitVarAnnotations(&D, emission.Address, Builder);
+
return emission;
}
@@ -898,4 +896,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg,
DI->setLocation(D.getLocation());
DI->EmitDeclareOfArgVariable(&D, DeclPtr, ArgNo, Builder);
}
+
+ if (D.hasAttr<AnnotateAttr>())
+ CGM.getAnnotations()->EmitVarAnnotations(&D, DeclPtr, Builder);
}
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 2f6b55b..638ded9 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -13,6 +13,7 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
+#include "CGAnnotations.h"
#include "CGCall.h"
#include "CGCXXABI.h"
#include "CGDebugInfo.h"
@@ -1692,6 +1693,9 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr,
}
}
+ if (field->hasAttr<AnnotateAttr>())
+ addr = CGM.getAnnotations()->EmitFieldAnnotations(field, addr, Builder);
+
unsigned alignment = getContext().getDeclAlign(field).getQuantity();
LValue LV = MakeAddrLValue(addr, type, alignment);
LV.getQuals().addCVRQualifiers(cvr);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 7a1a968..4336f17 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "CodeGenModule.h"
+#include "CGAnnotations.h"
#include "CGDebugInfo.h"
#include "CodeGenFunction.h"
#include "CodeGenTBAA.h"
@@ -64,7 +65,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
ABI(createCXXABI(*this)),
Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI),
TBAA(0),
- VTables(*this), Runtime(0), DebugInfo(0),
+ VTables(*this), Runtime(0), DebugInfo(0), Annotations(0),
CFConstantStringClassRef(0), ConstantStringClassRef(0),
VMContext(M.getContext()),
NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0),
@@ -108,6 +109,8 @@ CodeGenModule::~CodeGenModule() {
delete &ABI;
delete TBAA;
delete DebugInfo;
+ if (Annotations)
+ delete Annotations;
}
void CodeGenModule::createObjCRuntime() {
@@ -126,7 +129,8 @@ void CodeGenModule::Release() {
AddGlobalCtor(ObjCInitFunction);
EmitCtorList(GlobalCtors, "llvm.global_ctors");
EmitCtorList(GlobalDtors, "llvm.global_dtors");
- EmitAnnotations();
+ if (Annotations)
+ Annotations->EmitGlobalAnnotations();
EmitLLVMUsed();
SimplifyPersonality();
@@ -370,22 +374,6 @@ void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {
}
}
-void CodeGenModule::EmitAnnotations() {
- if (Annotations.empty())
- return;
-
- // 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);
- llvm::GlobalValue *gv =
- new llvm::GlobalVariable(TheModule, Array->getType(), false,
- llvm::GlobalValue::AppendingLinkage, Array,
- "llvm.global.annotations");
- gv->setSection("llvm.metadata");
-}
-
llvm::GlobalValue::LinkageTypes
CodeGenModule::getFunctionLinkage(const FunctionDecl *D) {
GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);
@@ -500,6 +488,13 @@ void CodeGenModule::SetCommonAttributes(const Decl *D,
getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this);
}
+CGAnnotations *CodeGenModule::getAnnotations() {
+ if (Annotations)
+ return Annotations;
+ Annotations = new CGAnnotations(*this);
+ return Annotations;
+}
+
void CodeGenModule::SetInternalFunctionAttributes(const Decl *D,
llvm::Function *F,
const CGFunctionInfo &FI) {
@@ -625,54 +620,6 @@ void CodeGenModule::EmitDeferred() {
}
}
-/// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the
-/// annotation information for a given GlobalValue. The annotation struct is
-/// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the
-/// GlobalValue being annotated. The second field is the constant string
-/// created from the AnnotateAttr's annotation. The third field is a constant
-/// string containing the name of the translation unit. The fourth field is
-/// the line number in the file of the annotated value declaration.
-///
-/// FIXME: this does not unique the annotation string constants, as llvm-gcc
-/// appears to.
-///
-llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
- const AnnotateAttr *AA,
- unsigned LineNo) {
- llvm::Module *M = &getModule();
-
- // get [N x i8] constants for the annotation string, and the filename string
- // which are the 2nd and 3rd elements of the global annotation structure.
- const llvm::Type *SBP = llvm::Type::getInt8PtrTy(VMContext);
- llvm::Constant *anno = llvm::ConstantArray::get(VMContext,
- AA->getAnnotation(), true);
- llvm::Constant *unit = llvm::ConstantArray::get(VMContext,
- M->getModuleIdentifier(),
- true);
-
- // Get the two global values corresponding to the ConstantArrays we just
- // created to hold the bytes of the strings.
- llvm::GlobalValue *annoGV =
- new llvm::GlobalVariable(*M, anno->getType(), false,
- llvm::GlobalValue::PrivateLinkage, anno,
- GV->getName());
- // translation unit name string, emitted into the llvm.metadata section.
- llvm::GlobalValue *unitGV =
- new llvm::GlobalVariable(*M, unit->getType(), false,
- llvm::GlobalValue::PrivateLinkage, unit,
- ".str");
- unitGV->setUnnamedAddr(true);
-
- // Create the ConstantStruct for the global annotation.
- llvm::Constant *Fields[4] = {
- llvm::ConstantExpr::getBitCast(GV, SBP),
- llvm::ConstantExpr::getBitCast(annoGV, SBP),
- llvm::ConstantExpr::getBitCast(unitGV, SBP),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LineNo)
- };
- return llvm::ConstantStruct::get(VMContext, Fields, 4, false);
-}
-
bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
// Never defer when EmitAllDecls is specified.
if (Features.EmitAllDecls)
@@ -1282,11 +1229,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
cast<llvm::GlobalValue>(Entry)->eraseFromParent();
}
- if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) {
- SourceManager &SM = Context.getSourceManager();
- AddAnnotation(EmitAnnotateAttr(GV, AA,
- SM.getInstantiationLineNumber(D->getLocation())));
- }
+ if (D->hasAttr<AnnotateAttr>())
+ getAnnotations()->AddGlobalAnnotations(D, GV);
GV->setInitializer(Init);
@@ -1496,6 +1440,8 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
AddGlobalCtor(Fn, CA->getPriority());
if (const DestructorAttr *DA = D->getAttr<DestructorAttr>())
AddGlobalDtor(Fn, DA->getPriority());
+ if (D->hasAttr<AnnotateAttr>())
+ getAnnotations()->AddGlobalAnnotations(D, Fn);
}
void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 779a352..db61900 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -73,6 +73,7 @@ namespace CodeGen {
class CodeGenTBAA;
class CGCXXABI;
class CGDebugInfo;
+ class CGAnnotations;
class CGObjCRuntime;
class BlockFieldFlags;
class FunctionArgList;
@@ -157,6 +158,7 @@ class CodeGenModule : public CodeGenTypeCache {
CGObjCRuntime* Runtime;
CGDebugInfo* DebugInfo;
+ CGAnnotations *Annotations;
// WeakRefReferences - A set of references that have only been seen via
// a weakref so far. This is used to remove the weak of the reference if we ever
@@ -192,8 +194,6 @@ class CodeGenModule : public CodeGenTypeCache {
llvm::DenseMap<GlobalDecl, llvm::StringRef> MangledDeclNames;
llvm::BumpPtrAllocator MangledNamesAllocator;
- std::vector<llvm::Constant*> Annotations;
-
llvm::StringMap<llvm::Constant*> CFConstantStringMap;
llvm::StringMap<llvm::Constant*> ConstantStringMap;
llvm::DenseMap<const Decl*, llvm::Value*> StaticLocalDeclMap;
@@ -297,6 +297,7 @@ public:
llvm::LLVMContext &getLLVMContext() { return VMContext; }
const TargetCodeGenInfo &getTargetCodeGenInfo();
bool isTargetDarwin() const;
+ CGAnnotations *getAnnotations();
bool shouldUseTBAA() const { return TBAA != 0; }
@@ -503,8 +504,6 @@ public:
/// metadata global.
void AddUsedGlobal(llvm::GlobalValue *GV);
- void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
-
/// AddCXXDtorEntry - Add a destructor and object to add to the C++ global
/// destructor function.
void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) {
@@ -546,9 +545,6 @@ public:
/// but not always, an LLVM null constant.
llvm::Constant *EmitNullConstant(QualType T);
- llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
- const AnnotateAttr *AA, unsigned LineNo);
-
/// Error - Emit a general error that something can't be done.
void Error(SourceLocation loc, llvm::StringRef error);
@@ -719,8 +715,6 @@ private:
/// suitable for use as a LLVM constructor or destructor array.
void EmitCtorList(const CtorList &Fns, const char *GlobalName);
- void EmitAnnotations(void);
-
/// EmitFundamentalRTTIDescriptor - Emit the RTTI descriptors for the
/// given type.
void EmitFundamentalRTTIDescriptor(QualType Type);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index a308892..f231f11 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1425,8 +1425,14 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) {
static bool
DeclHasAttr(const Decl *D, const Attr *A) {
const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A);
+ const AnnotateAttr *Ann = dyn_cast<AnnotateAttr>(A);
for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i)
if ((*i)->getKind() == A->getKind()) {
+ if (Ann) {
+ if (Ann->getAnnotation() == cast<AnnotateAttr>(*i)->getAnnotation())
+ return true;
+ continue;
+ }
// FIXME: Don't hardcode this check
if (OA && isa<OwnershipAttr>(*i))
return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind();
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 7f93ab7..b48344c 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1992,6 +1992,14 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
return;
}
+
+ // Don't duplicate annotation that are already set.
+ for (specific_attr_iterator<AnnotateAttr>
+ i = d->specific_attr_begin<AnnotateAttr>(),
+ e = d->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
+ if ((*i)->getAnnotation() == SE->getString())
+ return;
+ }
d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
SE->getString()));
}
diff --git a/test/CodeGen/annotate.c b/test/CodeGen/annotate.c
deleted file mode 100644
index ffaeebb..0000000
--- a/test/CodeGen/annotate.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
-
-__attribute((annotate("foo"))) char foo;
-void a(char *a) {
- __attribute__((annotate("bar"))) static char bar;
-}
-
-// CHECK: private unnamed_addr global
-// CHECK: private unnamed_addr global
-// CHECK: @llvm.global.annotations = appending global [2 x %0]
diff --git a/test/CodeGen/annotations-builtin.c b/test/CodeGen/annotations-builtin.c
new file mode 100644
index 0000000..43b2c68
--- /dev/null
+++ b/test/CodeGen/annotations-builtin.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// END.
+
+static long long llfoo;
+static int intfoo;
+static short shortfoo;
+static char charfoo;
+
+// CHECK: private unnamed_addr constant [13 x i8] {{.*}}annotation_a{{.*}} section "llvm.metadata"
+// CHECK-NOT: {{.*}}annotation_a{{.*}}
+
+static int foo(int a) {
+ return a + 1;
+}
+
+int main(int argc, char **argv) {
+ char barray[16];
+ char *b = (char *) __builtin_annotation((int)barray, "annotation_a");
+// CHECK: ptrtoint i8* {{.*}} to i32
+// CHECK-NEXT: call i32 @llvm.annotation.i32
+// CHECK: inttoptr {{.*}} to i8*
+
+ int call = __builtin_annotation(foo(argc), "annotation_a");
+// CHECK: call {{.*}} @foo
+// CHECK: call i32 @llvm.annotation.i32
+
+ long long lla = __builtin_annotation(llfoo, "annotation_a");
+// CHECK: trunc i64 {{.*}} to i32
+// CHECK-NEXT: call i32 @llvm.annotation.i32
+// CHECK-NEXT: zext i32 {{.*}} to i64
+
+ int inta = __builtin_annotation(intfoo, "annotation_a");
+// CHECK: load i32* @intfoo
+// CHECK-NEXT: call i32 @llvm.annotation.i32
+// CHECK-NEXT: store
+
+ short shorta = __builtin_annotation(shortfoo, "annotation_a");
+// CHECK: sext i16 {{.*}} to i32
+// CHECK-NEXT: call i32 @llvm.annotation.i32
+// CHECK-NEXT: trunc i32 {{.*}} to i16
+
+ char chara = __builtin_annotation(charfoo, "annotation_a");
+// CHECK: sext i8 {{.*}} to i32
+// CHECK-NEXT: call i32 @llvm.annotation.i32
+// CHECK-NEXT: trunc i32 {{.*}} to i8
+//
+ char **arg = (char**) __builtin_annotation((int) argv, "annotation_a");
+// CHECK: ptrtoint i8** {{.*}} to
+// CHECK: call i32 @llvm.annotation.i32
+// CHECK: inttoptr {{.*}} to i8**
+ return 0;
+}
diff --git a/test/CodeGen/annotations-field.c b/test/CodeGen/annotations-field.c
new file mode 100644
index 0000000..6b44367
--- /dev/null
+++ b/test/CodeGen/annotations-field.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// END.
+
+// CHECK: private unnamed_addr constant [8 x i8] c"v_ann_{{.}}\00", section "llvm.metadata"
+// CHECK: private unnamed_addr constant [8 x i8] c"v_ann_{{.}}\00", section "llvm.metadata"
+
+struct foo {
+ int v __attribute__((annotate("v_ann_0"))) __attribute__((annotate("v_ann_1")));
+};
+
+static struct foo gf;
+
+int main(int argc, char **argv) {
+ struct foo f;
+ f.v = argc;
+// CHECK: getelementptr inbounds %struct.foo* %f, i32 0, i32 0
+// CHECK-NEXT: bitcast i32* {{.*}} to i8*
+// CHECK-NEXT: call i8* @llvm.ptr.annotation.p0i8({{.*}}str{{.*}}str{{.*}}i32 8)
+// CHECK-NEXT: bitcast i8* {{.*}} to i32*
+// CHECK-NEXT: bitcast i32* {{.*}} to i8*
+// CHECK-NEXT: call i8* @llvm.ptr.annotation.p0i8({{.*}}str{{.*}}str{{.*}}i32 8)
+// CHECK-NEXT: bitcast i8* {{.*}} to i32*
+ gf.v = argc;
+// CHECK: bitcast i32* getelementptr inbounds (%struct.foo* @gf, i32 0, i32 0) to i8*
+// CHECK-NEXT: call i8* @llvm.ptr.annotation.p0i8({{.*}}str{{.*}}str{{.*}}i32 8)
+ return 0;
+}
diff --git a/test/CodeGen/annotations-global.c b/test/CodeGen/annotations-global.c
new file mode 100644
index 0000000..ec9b76d
--- /dev/null
+++ b/test/CodeGen/annotations-global.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t1
+// RUN: FileCheck --check-prefix=FOO %s < %t1
+// RUN: FileCheck --check-prefix=A %s < %t1
+// RUN: FileCheck --check-prefix=BAR %s < %t1
+// RUN: FileCheck --check-prefix=FOOS %s < %t1
+// END.
+
+static __attribute((annotate("sfoo_0"))) __attribute((annotate("sfoo_1"))) char sfoo;
+__attribute((annotate("foo_0"))) __attribute((annotate("foo_1"))) char foo;
+
+void __attribute((annotate("ann_a_0"))) __attribute((annotate("ann_a_1"))) __attribute((annotate("ann_a_2"))) __attribute((annotate("ann_a_3"))) a(char *a);
+void __attribute((annotate("ann_a_0"))) __attribute((annotate("ann_a_1"))) a(char *a) {
+ __attribute__((annotate("bar_0"))) __attribute__((annotate("bar_1"))) static char bar;
+ sfoo = 0;
+}
+
+// FOOS: target triple
+// FOOS: private unnamed_addr constant [7 x i8] c"sfoo_{{.}}\00", section "llvm.metadata"
+// FOOS: private unnamed_addr constant [7 x i8] c"sfoo_{{.}}\00", section "llvm.metadata"
+// FOOS-NOT: sfoo_
+// FOOS: @llvm.global.annotations{{.*}}i8* @sfoo{{.*}}i8* @sfoo{{.*}}, section "llvm.metadata"
+
+// FOO: target triple
+// FOO: private unnamed_addr constant [6 x i8] c"foo_{{.}}\00", section "llvm.metadata"
+// FOO: private unnamed_addr constant [6 x i8] c"foo_{{.}}\00", section "llvm.metadata"
+// FOO-NOT: foo_
+// FOO: @llvm.global.annotations{{.*}}i8* @foo{{.*}}i8* @foo{{.*}}, section "llvm.metadata"
+
+// A: target triple
+// A: private unnamed_addr constant [8 x i8] c"ann_a_{{.}}\00", section "llvm.metadata"
+// A: private unnamed_addr constant [8 x i8] c"ann_a_{{.}}\00", section "llvm.metadata"
+// A: private unnamed_addr constant [8 x i8] c"ann_a_{{.}}\00", section "llvm.metadata"
+// A: private unnamed_addr constant [8 x i8] c"ann_a_{{.}}\00", section "llvm.metadata"
+// A-NOT: ann_a_
+// A: @llvm.global.annotations{{.*}}i8* bitcast (void (i8*)* @a to i8*){{.*}}i8* bitcast (void (i8*)* @a to i8*){{.*}}i8* bitcast (void (i8*)* @a to i8*){{.*}}i8* bitcast (void (i8*)* @a to i8*){{.*}}, section "llvm.metadata"
+
+// BAR: target triple
+// BAR: private unnamed_addr constant [6 x i8] c"bar_{{.}}\00", section "llvm.metadata"
+// BAR: private unnamed_addr constant [6 x i8] c"bar_{{.}}\00", section "llvm.metadata"
+// BAR-NOT: bar_
+// BAR: @llvm.global.annotations{{.*}}i8* @a.bar{{.*}}i8* @a.bar{{.*}}, section "llvm.metadata"
diff --git a/test/CodeGen/annotations-loc.c b/test/CodeGen/annotations-loc.c
new file mode 100644
index 0000000..4644f0e
--- /dev/null
+++ b/test/CodeGen/annotations-loc.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// END.
+# 1 "t.c"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "t.c"
+int __attribute((annotate("foo"))) foo(void) { return 0; }
+
+// CHECK: private unnamed_addr constant [4 x i8] c"t.c\00"
+// CHECK: @llvm.global.annotations = {{.*}}, i32 1 }
diff --git a/test/CodeGen/annotations-var.c b/test/CodeGen/annotations-var.c
new file mode 100644
index 0000000..97a10ac
--- /dev/null
+++ b/test/CodeGen/annotations-var.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -emit-llvm -o %t1 %s
+// RUN: FileCheck --check-prefix=LOCAL %s < %t1
+// RUN: FileCheck --check-prefix=UNDEF %s < %t1
+// RUN: FileCheck --check-prefix=PARAM %s < %t1
+// END.
+
+// LOCAL: private unnamed_addr constant [15 x i8] c"localvar_ann_{{.}}\00", section "llvm.metadata"
+// LOCAL: private unnamed_addr constant [15 x i8] c"localvar_ann_{{.}}\00", section "llvm.metadata"
+
+// UNDEF: private unnamed_addr constant [15 x i8] c"undefvar_ann_0\00", section "llvm.metadata"
+
+// PARAM: private unnamed_addr constant [12 x i8] c"param_ann_{{.}}\00", section "llvm.metadata"
+// PARAM: private unnamed_addr constant [12 x i8] c"param_ann_{{.}}\00", section "llvm.metadata"
+// PARAM: private unnamed_addr constant [12 x i8] c"param_ann_{{.}}\00", section "llvm.metadata"
+// PARAM: private unnamed_addr constant [12 x i8] c"param_ann_{{.}}\00", section "llvm.metadata"
+
+int foo(int v __attribute__((annotate("param_ann_2"))) __attribute__((annotate("param_ann_3"))));
+int foo(int v __attribute__((annotate("param_ann_0"))) __attribute__((annotate("param_ann_1")))) {
+ return v + 1;
+// PARAM: define {{.*}}@foo
+// PARAM: bitcast i32* %v.addr to i8*
+// PARAM-NEXT: call void @llvm.var.annotation(
+// PARAM-NEXT: bitcast i32* %v.addr to i8*
+// PARAM-NEXT: call void @llvm.var.annotation(
+// PARAM-NEXT: bitcast i32* %v.addr to i8*
+// PARAM-NEXT: call void @llvm.var.annotation(
+// PARAM-NEXT: bitcast i32* %v.addr to i8*
+// PARAM-NEXT: call void @llvm.var.annotation(
+}
+
+int main(int argc, char **argv) {
+ int localvar __attribute__((annotate("localvar_ann_0"))) __attribute__((annotate("localvar_ann_1"))) = 3;
+// LOCAL: %localvar1 = bitcast i32* %localvar to i8*
+// LOCAL-NEXT: call void @llvm.var.annotation(i8* %localvar1, i8* getelementptr inbounds ([15 x i8]* @{{.*}}), i8* getelementptr inbounds ({{.*}}), i32 32)
+// LOCAL-NEXT: %localvar2 = bitcast i32* %localvar to i8*
+// LOCAL-NEXT: call void @llvm.var.annotation(i8* %localvar2, i8* getelementptr inbounds ([15 x i8]* @{{.*}}), i8* getelementptr inbounds ({{.*}}), i32 32)
+ int undefvar __attribute__((annotate("undefvar_ann_0")));
+// UNDEF: %undefvar3 = bitcast i32* %undefvar to i8*
+// UNDEF-NEXT: call void @llvm.var.annotation(i8* %undefvar3, i8* getelementptr inbounds ([15 x i8]* @{{.*}}), i8* getelementptr inbounds ({{.*}}), i32 37)
+ localvar += argc;
+ undefvar = localvar;
+ return undefvar + localvar;
+}
--
1.7.4.2
More information about the cfe-commits
mailing list