Bring llvm.annotation* intrinsics support back to where it was in llvm-gcc: can
annotate global, local variables, struct fields, or arbitrary statements (using the __builtin_annotation), rdar://8037476. llvm-svn: 139423
This commit is contained in:
parent
5bfb0e0a85
commit
5a6b6987dc
|
@ -131,7 +131,7 @@ def AnalyzerNoReturn : InheritableAttr {
|
|||
let Spellings = ["analyzer_noreturn"];
|
||||
}
|
||||
|
||||
def Annotate : InheritableAttr {
|
||||
def Annotate : InheritableParamAttr {
|
||||
let Spellings = ["annotate"];
|
||||
let Args = [StringArgument<"Annotation">];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<
|
||||
|
|
|
@ -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<StringLiteral>(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
|
||||
|
|
|
@ -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<AnnotateAttr>()) {
|
||||
SourceManager &SM = CGM.getContext().getSourceManager();
|
||||
llvm::Constant *Ann =
|
||||
CGM.EmitAnnotateAttr(GV, AA, SM.getExpansionLineNumber(D.getLocation()));
|
||||
CGM.AddAnnotation(Ann);
|
||||
}
|
||||
if (D.hasAttr<AnnotateAttr>())
|
||||
CGM.AddGlobalAnnotations(&D, GV);
|
||||
|
||||
if (const SectionAttr *SA = D.getAttr<SectionAttr>())
|
||||
GV->setSection(SA->getName());
|
||||
|
@ -853,6 +848,9 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
|
|||
DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder);
|
||||
}
|
||||
|
||||
if (D.hasAttr<AnnotateAttr>())
|
||||
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<AnnotateAttr>())
|
||||
EmitVarAnnotations(&D, DeclPtr);
|
||||
}
|
||||
|
|
|
@ -1875,6 +1875,9 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr,
|
|||
CGM.getTypes().ConvertTypeForMem(type),
|
||||
field->getName());
|
||||
|
||||
if (field->hasAttr<AnnotateAttr>())
|
||||
addr = EmitFieldAnnotations(field, addr);
|
||||
|
||||
unsigned alignment = getContext().getDeclAlign(field).getQuantity();
|
||||
LValue LV = MakeAddrLValue(addr, type, alignment);
|
||||
LV.getQuals().addCVRQualifiers(cvr);
|
||||
|
|
|
@ -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<AnnotateAttr>() && "no annotate attribute");
|
||||
// FIXME We create a new bitcast for every annotation because that's what
|
||||
// llvm-gcc was doing.
|
||||
for (specific_attr_iterator<AnnotateAttr>
|
||||
ai = D->specific_attr_begin<AnnotateAttr>(),
|
||||
ae = D->specific_attr_end<AnnotateAttr>(); 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<AnnotateAttr>() && "no annotate attribute");
|
||||
llvm::Type *VTy = V->getType();
|
||||
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
|
||||
CGM.Int8PtrTy);
|
||||
|
||||
for (specific_attr_iterator<AnnotateAttr>
|
||||
ai = D->specific_attr_begin<AnnotateAttr>(),
|
||||
ae = D->specific_attr_end<AnnotateAttr>(); 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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -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<llvm::Constant*>::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<AnnotateAttr>() && "no annotate attribute");
|
||||
// Get the struct elements for these annotations.
|
||||
for (specific_attr_iterator<AnnotateAttr>
|
||||
ai = D->specific_attr_begin<AnnotateAttr>(),
|
||||
ae = D->specific_attr_end<AnnotateAttr>(); 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<llvm::GlobalValue>(Entry)->eraseFromParent();
|
||||
}
|
||||
|
||||
if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) {
|
||||
SourceManager &SM = Context.getSourceManager();
|
||||
AddAnnotation(EmitAnnotateAttr(
|
||||
GV, AA, SM.getExpansionLineNumber(D->getLocation())));
|
||||
}
|
||||
if (D->hasAttr<AnnotateAttr>())
|
||||
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<DestructorAttr>())
|
||||
AddGlobalDtor(Fn, DA->getPriority());
|
||||
if (D->hasAttr<AnnotateAttr>())
|
||||
AddGlobalAnnotations(D, Fn);
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
||||
|
|
|
@ -260,8 +260,12 @@ class CodeGenModule : public CodeGenTypeCache {
|
|||
llvm::DenseMap<GlobalDecl, StringRef> MangledDeclNames;
|
||||
llvm::BumpPtrAllocator MangledNamesAllocator;
|
||||
|
||||
/// Global annotations.
|
||||
std::vector<llvm::Constant*> Annotations;
|
||||
|
||||
/// Map used to get unique annotation strings.
|
||||
llvm::StringMap<llvm::Constant*> AnnotationStrings;
|
||||
|
||||
llvm::StringMap<llvm::Constant*> CFConstantStringMap;
|
||||
llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap;
|
||||
llvm::DenseMap<const Decl*, llvm::Value*> 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<const CXXRecordDecl*> 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);
|
||||
|
|
|
@ -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<StringLiteral>(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
|
||||
|
|
|
@ -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<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();
|
||||
|
|
|
@ -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<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()));
|
||||
}
|
||||
|
|
|
@ -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 <stdio.h>
|
||||
|
||||
/* Global variable with attribute */
|
||||
|
|
|
@ -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 }]
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
|
@ -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 }
|
|
@ -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;
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue