mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-27 14:45:50 +00:00
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:
parent
3f8195ea4f
commit
73dee180c8
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user