Make sure that the Attribute object represents one attribute only.
authorBill Wendling <isanbard@gmail.com>
Thu, 31 Jan 2013 00:29:54 +0000 (00:29 +0000)
committerBill Wendling <isanbard@gmail.com>
Thu, 31 Jan 2013 00:29:54 +0000 (00:29 +0000)
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

include/llvm/IR/Attributes.h
lib/AsmParser/LLParser.cpp
lib/AsmParser/LLParser.h
lib/IR/Attributes.cpp

index 1b8195ff0522086d0ede98ceaf2226139720d08f..29eaec1d0df8d56fadeb9b70e84a12f4aa582340 100644 (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.
index a38f9ea4db97ad42da63a8cba2947d0def935fb4..491022245ea32a56701629789b08be8074963bad 100644 (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));
     }
   }
index f255897ce3515f39ba5fc7e4931575fc22a278bc..d8de77908cc93335335b1967e600b5cf6fd99745 100644 (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);
index 75ba93a106d4fefe1e6728a5ebefa78c72e84176..98c12b5d85590d13d7a512bb57f449153f62fa9a 100644 (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;