diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index d2de30a439b1..9289bd286eda 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -131,7 +131,7 @@ def AnalyzerNoReturn : InheritableAttr { let Spellings = ["analyzer_noreturn"]; } -def Annotate : InheritableAttr { +def Annotate : InheritableParamAttr { let Spellings = ["annotate"]; let Args = [StringArgument<"Annotation">]; } diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index b8916d23e0e8..eb5c604294b3 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -741,5 +741,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/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 49d7bed09ac4..bd18b2f63f1e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4420,6 +4420,9 @@ def err_return_in_block_expression : Error< def err_block_returning_array_function : Error< "block cannot return %select{array|function}0 type %1">; +// Builtin annotation string. +def err_builtin_annotation_not_string_constant : Error< + "__builtin_annotation requires a non wide string constant">; // CFString checking def err_cfstring_literal_not_string_constant : Error< diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 642bf15e1b47..18c2bd3fe7a9 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -991,6 +991,17 @@ 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: { + llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); + llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, + AnnVal->getType()); + + // Get the annotation string, go through casts. Sema requires this to be a + // non-wide string literal, potentially casted, so the cast<> is safe. + const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); + llvm::StringRef Str = cast(AnnotationStrExpr)->getString(); + return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); + } } // If this is an alias for a libm function (e.g. __builtin_sin) turn it into diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 5fa99a513adc..9ecc72781cfa 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -271,13 +271,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, GV->setAlignment(getContext().getDeclAlign(&D).getQuantity()); - // FIXME: Merge attribute handling. - if (const AnnotateAttr *AA = D.getAttr()) { - SourceManager &SM = CGM.getContext().getSourceManager(); - llvm::Constant *Ann = - CGM.EmitAnnotateAttr(GV, AA, SM.getExpansionLineNumber(D.getLocation())); - CGM.AddAnnotation(Ann); - } + if (D.hasAttr()) + CGM.AddGlobalAnnotations(&D, GV); if (const SectionAttr *SA = D.getAttr()) GV->setSection(SA->getName()); @@ -853,6 +848,9 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder); } + if (D.hasAttr()) + EmitVarAnnotations(&D, emission.Address); + return emission; } @@ -1502,4 +1500,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg, // Emit debug info for param declaration. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitDeclareOfArgVariable(&D, DeclPtr, ArgNo, Builder); + + if (D.hasAttr()) + EmitVarAnnotations(&D, DeclPtr); } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index daaf7a588714..7ae95331ad5f 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1875,6 +1875,9 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr, CGM.getTypes().ConvertTypeForMem(type), field->getName()); + if (field->hasAttr()) + addr = EmitFieldAnnotations(field, addr); + unsigned alignment = getContext().getDeclAlign(field).getQuantity(); LValue LV = MakeAddrLValue(addr, type, alignment); LV.getQuals().addCVRQualifiers(cvr); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index a16f10e6541e..b4b2eb16adab 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1018,3 +1018,50 @@ void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) { // In theory, we could try to duplicate the peepholes now, but whatever. protection.Inst->eraseFromParent(); } + +llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Value *AnnotationFn, + llvm::Value *AnnotatedVal, + llvm::StringRef AnnotationStr, + SourceLocation Location) { + llvm::Value *Args[4] = { + AnnotatedVal, + Builder.CreateBitCast(CGM.EmitAnnotationString(AnnotationStr), Int8PtrTy), + Builder.CreateBitCast(CGM.EmitAnnotationUnit(Location), Int8PtrTy), + CGM.EmitAnnotationLineNo(Location) + }; + return Builder.CreateCall(AnnotationFn, Args); +} + +void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) { + assert(D->hasAttr() && "no annotate attribute"); + // FIXME We create a new bitcast for every annotation because that's what + // llvm-gcc was doing. + for (specific_attr_iterator + ai = D->specific_attr_begin(), + ae = D->specific_attr_end(); ai != ae; ++ai) + EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation), + Builder.CreateBitCast(V, CGM.Int8PtrTy, V->getName()), + (*ai)->getAnnotation(), D->getLocation()); +} + +llvm::Value *CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, + llvm::Value *V) { + assert(D->hasAttr() && "no annotate attribute"); + llvm::Type *VTy = V->getType(); + llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation, + CGM.Int8PtrTy); + + for (specific_attr_iterator + ai = D->specific_attr_begin(), + ae = D->specific_attr_end(); ai != ae; ++ai) { + // FIXME Always emit the cast inst so we can differentiate between + // annotation on the first field of a struct and annotation on the struct + // itself. + if (VTy != CGM.Int8PtrTy) + V = Builder.Insert(new llvm::BitCastInst(V, CGM.Int8PtrTy)); + V = EmitAnnotationCall(F, V, (*ai)->getAnnotation(), D->getLocation()); + V = Builder.CreateBitCast(V, VTy); + } + + return V; +} diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 36dcffcd4c02..702aca8aca73 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2271,6 +2271,23 @@ public: void EmitCXXThrowExpr(const CXXThrowExpr *E); + //===--------------------------------------------------------------------===// + // Annotations Emission + //===--------------------------------------------------------------------===// + + /// Emit an annotation call (intrinsic or builtin). + llvm::Value *EmitAnnotationCall(llvm::Value *AnnotationFn, + llvm::Value *AnnotatedVal, + llvm::StringRef AnnotationStr, + SourceLocation Location); + + /// Emit local annotations for the local variable V, declared by D. + void EmitVarAnnotations(const VarDecl *D, llvm::Value *V); + + /// Emit field annotations for the given field & value. Returns the + /// annotation result. + llvm::Value *EmitFieldAnnotations(const FieldDecl *D, llvm::Value *V); + //===--------------------------------------------------------------------===// // Internal Helpers //===--------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 6df03c886fea..67757a22c5fc 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -44,6 +44,8 @@ using namespace clang; using namespace CodeGen; +static const char AnnotationSection[] = "llvm.metadata"; + static CGCXXABI &createCXXABI(CodeGenModule &CGM) { switch (CGM.getContext().getTargetInfo().getCXXABI()) { case CXXABI_ARM: return *CreateARMCXXABI(CGM); @@ -131,7 +133,7 @@ void CodeGenModule::Release() { AddGlobalCtor(ObjCInitFunction); EmitCtorList(GlobalCtors, "llvm.global_ctors"); EmitCtorList(GlobalDtors, "llvm.global_dtors"); - EmitAnnotations(); + EmitGlobalAnnotations(); EmitLLVMUsed(); SimplifyPersonality(); @@ -382,22 +384,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); @@ -642,54 +628,78 @@ 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. -/// +void CodeGenModule::EmitGlobalAnnotations() { + 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(getModule(), + Array->getType(), false, llvm::GlobalValue::AppendingLinkage, Array, + "llvm.global.annotations"); + gv->setSection(AnnotationSection); +} + +llvm::Constant *CodeGenModule::EmitAnnotationString(llvm::StringRef Str) { + llvm::StringMap::iterator i = AnnotationStrings.find(Str); + if (i != AnnotationStrings.end()) + return i->second; + + // Not found yet, create a new global. + llvm::Constant *s = llvm::ConstantArray::get(getLLVMContext(), Str, true); + llvm::GlobalValue *gv = new llvm::GlobalVariable(getModule(), s->getType(), + true, llvm::GlobalValue::PrivateLinkage, s, ".str"); + gv->setSection(AnnotationSection); + gv->setUnnamedAddr(true); + AnnotationStrings[Str] = gv; + return gv; +} + +llvm::Constant *CodeGenModule::EmitAnnotationUnit(SourceLocation Loc) { + SourceManager &SM = getContext().getSourceManager(); + PresumedLoc PLoc = SM.getPresumedLoc(Loc); + if (PLoc.isValid()) + return EmitAnnotationString(PLoc.getFilename()); + return EmitAnnotationString(SM.getBufferName(Loc)); +} + +llvm::Constant *CodeGenModule::EmitAnnotationLineNo(SourceLocation L) { + SourceManager &SM = getContext().getSourceManager(); + PresumedLoc PLoc = SM.getPresumedLoc(L); + unsigned LineNo = PLoc.isValid() ? PLoc.getLine() : + SM.getExpansionLineNumber(L); + return llvm::ConstantInt::get(Int32Ty, LineNo); +} + 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. - 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); + SourceLocation L) { + // 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), - llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LineNo) + llvm::ConstantExpr::getBitCast(GV, Int8PtrTy), + llvm::ConstantExpr::getBitCast(AnnoGV, Int8PtrTy), + llvm::ConstantExpr::getBitCast(UnitGV, Int8PtrTy), + LineNoCst }; return llvm::ConstantStruct::getAnon(Fields); } +void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D, + llvm::GlobalValue *GV) { + assert(D->hasAttr() && "no annotate attribute"); + // 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())); +} + bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { // Never defer when EmitAllDecls is specified. if (Features.EmitAllDecls) @@ -1297,11 +1307,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { cast(Entry)->eraseFromParent(); } - if (const AnnotateAttr *AA = D->getAttr()) { - SourceManager &SM = Context.getSourceManager(); - AddAnnotation(EmitAnnotateAttr( - GV, AA, SM.getExpansionLineNumber(D->getLocation()))); - } + if (D->hasAttr()) + AddGlobalAnnotations(D, GV); GV->setInitializer(Init); @@ -1530,6 +1537,8 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { AddGlobalCtor(Fn, CA->getPriority()); if (const DestructorAttr *DA = D->getAttr()) AddGlobalDtor(Fn, DA->getPriority()); + if (D->hasAttr()) + AddGlobalAnnotations(D, Fn); } void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 3e5de655abae..7d0d95141ab2 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -260,8 +260,12 @@ class CodeGenModule : public CodeGenTypeCache { llvm::DenseMap MangledDeclNames; llvm::BumpPtrAllocator MangledNamesAllocator; + /// Global annotations. std::vector Annotations; + /// Map used to get unique annotation strings. + llvm::StringMap AnnotationStrings; + llvm::StringMap CFConstantStringMap; llvm::StringMap ConstantStringMap; llvm::DenseMap StaticLocalDeclMap; @@ -598,8 +602,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) { @@ -643,9 +645,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, StringRef error); @@ -733,6 +732,33 @@ public: std::vector DeferredVTables; + /// Emit all the global annotations. + void EmitGlobalAnnotations(); + + /// Emit an annotation string. + llvm::Constant *EmitAnnotationString(llvm::StringRef Str); + + /// Emit the annotation's translation unit. + llvm::Constant *EmitAnnotationUnit(SourceLocation Loc); + + /// Emit the annotation line number. + llvm::Constant *EmitAnnotationLineNo(SourceLocation L); + + /// 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); + + /// Add global annotations that are set on D, for the global GV. Those + /// annotations are emitted during finalization of the LLVM code. + void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); + private: llvm::GlobalValue *GetGlobalValue(StringRef Ref); @@ -818,8 +844,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/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 68e25e7f4e5a..f0dd68759812 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -88,6 +88,19 @@ static bool checkArgCount(Sema &S, CallExpr *call, unsigned desiredArgCount) { << call->getArg(1)->getSourceRange(); } +/// CheckBuiltinAnnotationString - Checks that string argument to the builtin +/// annotation is a non wide string literal. +static bool CheckBuiltinAnnotationString(Sema &S, Expr *Arg) { + Arg = Arg->IgnoreParenCasts(); + StringLiteral *Literal = dyn_cast(Arg); + if (!Literal || !Literal->isAscii()) { + S.Diag(Arg->getLocStart(), diag::err_builtin_annotation_not_string_constant) + << Arg->getSourceRange(); + return true; + } + return false; +} + ExprResult Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { ExprResult TheCallResult(Owned(TheCall)); @@ -184,6 +197,10 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case Builtin::BI__sync_lock_release: case Builtin::BI__sync_swap: return SemaBuiltinAtomicOverloaded(move(TheCallResult)); + case Builtin::BI__builtin_annotation: + if (CheckBuiltinAnnotationString(*this, TheCall->getArg(1))) + return ExprError(); + break; } // Since the target specific builtins for each arch overlap, only check those @@ -640,7 +657,6 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { return move(TheCallResult); } - /// CheckObjCString - Checks that the argument to the builtin /// CFString constructor is correct /// Note: It might also make sense to do the UTF-16 conversion here (would diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 355378eded78..d6137e5dba38 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1461,8 +1461,14 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { static bool DeclHasAttr(const Decl *D, const Attr *A) { const OwnershipAttr *OA = dyn_cast(A); + const AnnotateAttr *Ann = dyn_cast(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(*i)->getAnnotation()) + return true; + continue; + } // FIXME: Don't hardcode this check if (OA && isa(*i)) return OA->getOwnKind() == cast(*i)->getOwnKind(); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 624ac086db16..2f2e280f714d 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2484,6 +2484,14 @@ static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; return; } + + // Don't duplicate annotations that are already set. + for (specific_attr_iterator + i = D->specific_attr_begin(), + e = D->specific_attr_end(); i != e; ++i) { + if ((*i)->getAnnotation() == SE->getString()) + return; + } D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString())); } diff --git a/clang/test/CodeGen/2007-06-15-AnnotateAttribute.c b/clang/test/CodeGen/2007-06-15-AnnotateAttribute.c index 324b97557553..a51400288c2b 100644 --- a/clang/test/CodeGen/2007-06-15-AnnotateAttribute.c +++ b/clang/test/CodeGen/2007-06-15-AnnotateAttribute.c @@ -1,7 +1,6 @@ // RUN: %clang_cc1 -emit-llvm %s -o - | grep llvm.global.annotations // RUN: %clang_cc1 -emit-llvm %s -o - | grep llvm.var.annotation | count 3 -// XFAIL: * #include /* Global variable with attribute */ diff --git a/clang/test/CodeGen/annotate.c b/clang/test/CodeGen/annotate.c deleted file mode 100644 index 9ed187d1d170..000000000000 --- a/clang/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 { i8*, i8*, i8*, i32 }] diff --git a/clang/test/CodeGen/annotations-builtin.c b/clang/test/CodeGen/annotations-builtin.c new file mode 100644 index 000000000000..42421a0a5200 --- /dev/null +++ b/clang/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/clang/test/CodeGen/annotations-field.c b/clang/test/CodeGen/annotations-field.c new file mode 100644 index 000000000000..6b443675850c --- /dev/null +++ b/clang/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/clang/test/CodeGen/annotations-global.c b/clang/test/CodeGen/annotations-global.c new file mode 100644 index 000000000000..2782525ed915 --- /dev/null +++ b/clang/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 = appending global [10 x { i8*, i8*, i8*, i32 }] {{.*}}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 = appending global [10 x { i8*, i8*, i8*, i32 }] {{.*}}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 = appending global [10 x { i8*, i8*, i8*, i32 }] {{.*}}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 = appending global [10 x { i8*, i8*, i8*, i32 }] {{.*}}i8* @a.bar{{.*}}i8* @a.bar{{.*}}, section "llvm.metadata" diff --git a/clang/test/CodeGen/annotations-loc.c b/clang/test/CodeGen/annotations-loc.c new file mode 100644 index 000000000000..4644f0e1d2ca --- /dev/null +++ b/clang/test/CodeGen/annotations-loc.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// END. +# 1 "t.c" +# 1 "" +# 1 "" +# 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/clang/test/CodeGen/annotations-var.c b/clang/test/CodeGen/annotations-var.c new file mode 100644 index 000000000000..97a10ac31519 --- /dev/null +++ b/clang/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; +} diff --git a/clang/test/Sema/annotate.c b/clang/test/Sema/annotate.c index 6f81491f1ffa..5b2727752bbd 100644 --- a/clang/test/Sema/annotate.c +++ b/clang/test/Sema/annotate.c @@ -4,4 +4,7 @@ void __attribute__((annotate("foo"))) foo(float *a) { __attribute__((annotate("bar"))) int x; __attribute__((annotate(1))) int y; // expected-error {{argument to annotate attribute was not a string literal}} __attribute__((annotate("bar", 1))) int z; // expected-error {{attribute takes one argument}} + int u = __builtin_annotation(z, (char*) 0); // expected-error {{__builtin_annotation requires a non wide string constant}} + int v = __builtin_annotation(z, (char*) L"bar"); // expected-error {{__builtin_annotation requires a non wide string constant}} + int w = __builtin_annotation(z, "foo"); }