Make sure that the Attribute object represents one attribute only.

Several places were still treating the Attribute object as respresenting
multiple attributes. Those places now use the AttributeSet to represent
multiple attributes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174003 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2013-01-31 00:29:54 +00:00
parent 3f8195ea4f
commit 73dee180c8
4 changed files with 30 additions and 24 deletions

View File

@ -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.

View File

@ -1472,6 +1472,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &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<ParamInfo> &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<ArgInfo> &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<ArgInfo> &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));
}
}

View File

@ -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<ParamInfo> &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<ArgInfo> &ArgList, bool &isVarArg);

View File

@ -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;