diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 1b8195ff052..29eaec1d0df 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -41,13 +41,13 @@ class Type; class Attribute { public: /// This enumeration lists the attributes that can be associated with - /// parameters, function results or the function itself. + /// parameters, function results, or the function itself. /// - /// Note: uwtable is about the ABI or the user mandating an entry in the - /// unwind table. The nounwind attribute is about an exception passing by the - /// function. + /// Note: The `uwtable' attribute is about the ABI or the user mandating an + /// entry in the unwind table. The `nounwind' attribute is about an exception + /// passing by the function. /// - /// In a theoretical system that uses tables for profiling and sjlj for + /// In a theoretical system that uses tables for profiling and SjLj for /// exceptions, they would be fully independent. In a normal system that uses /// tables for both, the semantics are: /// @@ -181,12 +181,11 @@ private: friend class AttrBuilder; friend class AttributeSetImpl; - /// \brief The attributes that we are managing. This can be null to represent + /// \brief The attributes that we are managing. This can be null to represent /// the empty attributes list. AttributeSetImpl *pImpl; - /// \brief The attributes for the specified index are returned. Attributes - /// for the result are denoted with Idx = 0. + /// \brief The attributes for the specified index are returned. AttributeSetNode *getAttributes(unsigned Idx) const; /// \brief Create an AttributeSet with the specified parameters in it. diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index a38f9ea4db9..491022245ea 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -1472,6 +1472,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, if (ParseToken(lltok::lparen, "expected '(' in call")) return true; + unsigned AttrIndex = 1; while (Lex.getKind() != lltok::rparen) { // If this isn't the first argument, we need a comma. if (!ArgList.empty() && @@ -1489,8 +1490,9 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, // Otherwise, handle normal operands. if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS)) return true; - ArgList.push_back(ParamInfo(ArgLoc, V, Attribute::get(V->getContext(), - ArgAttrs))); + ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(), + AttrIndex++, + ArgAttrs))); } Lex.Lex(); // Lex the ')'. @@ -1539,9 +1541,10 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, if (!FunctionType::isValidArgumentType(ArgTy)) return Error(TypeLoc, "invalid type for function argument"); + unsigned AttrIndex = 1; ArgList.push_back(ArgInfo(TypeLoc, ArgTy, - Attribute::get(ArgTy->getContext(), - Attrs), Name)); + AttributeSet::get(ArgTy->getContext(), + AttrIndex++, Attrs), Name)); while (EatIfPresent(lltok::comma)) { // Handle ... at end of arg list. @@ -1568,7 +1571,8 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, return Error(TypeLoc, "invalid type for function argument"); ArgList.push_back(ArgInfo(TypeLoc, ArgTy, - Attribute::get(ArgTy->getContext(), Attrs), + AttributeSet::get(ArgTy->getContext(), + AttrIndex++, Attrs), Name)); } } @@ -1593,7 +1597,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { if (!ArgList[i].Name.empty()) return Error(ArgList[i].Loc, "argument name invalid in function type"); - if (ArgList[i].Attrs.hasAttributes()) + if (ArgList[i].Attrs.hasAttributes(i + 1)) return Error(ArgList[i].Loc, "argument attributes invalid in function type"); } @@ -2822,8 +2826,8 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { ParamTypeList.push_back(ArgList[i].Ty); - if (ArgList[i].Attrs.hasAttributes()) { - AttrBuilder B(ArgList[i].Attrs); + if (ArgList[i].Attrs.hasAttributes(i + 1)) { + AttrBuilder B(ArgList[i].Attrs, i + 1); Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); } } @@ -3382,8 +3386,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes()) { - AttrBuilder B(ArgList[i].Attrs); + if (ArgList[i].Attrs.hasAttributes(i + 1)) { + AttrBuilder B(ArgList[i].Attrs, i + 1); Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); } } @@ -3784,8 +3788,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes()) { - AttrBuilder B(ArgList[i].Attrs); + if (ArgList[i].Attrs.hasAttributes(i + 1)) { + AttrBuilder B(ArgList[i].Attrs, i + 1); Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); } } diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index f255897ce35..d8de77908cc 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -326,8 +326,8 @@ namespace llvm { struct ParamInfo { LocTy Loc; Value *V; - Attribute Attrs; - ParamInfo(LocTy loc, Value *v, Attribute attrs) + AttributeSet Attrs; + ParamInfo(LocTy loc, Value *v, AttributeSet attrs) : Loc(loc), V(v), Attrs(attrs) {} }; bool ParseParameterList(SmallVectorImpl &ArgList, @@ -347,9 +347,9 @@ namespace llvm { struct ArgInfo { LocTy Loc; Type *Ty; - Attribute Attrs; + AttributeSet Attrs; std::string Name; - ArgInfo(LocTy L, Type *ty, Attribute Attr, const std::string &N) + ArgInfo(LocTy L, Type *ty, AttributeSet Attr, const std::string &N) : Loc(L), Ty(ty), Attrs(Attr), Name(N) {} }; bool ParseArgumentList(SmallVectorImpl &ArgList, bool &isVarArg); diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 75ba93a106d..98c12b5d855 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -40,6 +40,9 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { if (!B.hasAttributes()) return Attribute(); + assert(std::distance(B.begin(), B.end()) == 1 && + "The Attribute object should represent one attribute only!"); + // Otherwise, build a key to look up the existing attributes. LLVMContextImpl *pImpl = Context.pImpl; FoldingSetNodeID ID;