Each instruction is allowed to have *multiple* different
authorChris Lattner <sabre@nondot.org>
Tue, 29 Dec 2009 21:25:40 +0000 (21:25 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 29 Dec 2009 21:25:40 +0000 (21:25 +0000)
metadata objects on them.  Though the entire compiler supports this,
the asmparser didn't.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92270 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AsmParser/LLParser.cpp
test/Assembler/metadata.ll

index 351245d8e871058300ef536b243e20d8b8f203e3..3a2d24440dc19894094fe4fa0173295473daefca 100644 (file)
@@ -1105,24 +1105,33 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
 
 /// ParseOptionalCustomMetadata
 ///   ::= /* empty */
-///   ::= !dbg !42
+///   ::= !dbg !42 (',' !dbg !57)*
 bool LLParser::ParseOptionalCustomMetadata() {
   if (Lex.getKind() != lltok::NamedOrCustomMD)
     return false;
 
-  std::string Name = Lex.getStrVal();
-  Lex.Lex();
+  while (1) {
+    std::string Name = Lex.getStrVal();
+    Lex.Lex();
 
-  if (Lex.getKind() != lltok::Metadata)
-    return TokError("Expected '!' here");
-  Lex.Lex();
+    if (Lex.getKind() != lltok::Metadata)
+      return TokError("expected '!' here");
+    Lex.Lex();
 
-  MetadataBase *Node;
-  if (ParseMDNode(Node)) return true;
+    MetadataBase *Node;
+    if (ParseMDNode(Node)) return true;
 
-  unsigned MDK = M->getMDKindID(Name.c_str());
-  MDsOnInst.push_back(std::make_pair(MDK, cast<MDNode>(Node)));
-  return false;
+    unsigned MDK = M->getMDKindID(Name.c_str());
+    MDsOnInst.push_back(std::make_pair(MDK, cast<MDNode>(Node)));
+
+    // If this is the end of the list, we're done.
+    if (!EatIfPresent(lltok::comma))
+      return false;
+
+    // The next value must be a custom metadata id.
+    if (Lex.getKind() != lltok::NamedOrCustomMD)
+      return TokError("expected more custom metadata ids");
+  }
 }
 
 /// ParseOptionalAlignment
@@ -3008,9 +3017,9 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) {
 //===----------------------------------------------------------------------===//
 
 /// ParseRet - Parse a return instruction.
-///   ::= 'ret' void (',' !dbg, !1)
-///   ::= 'ret' TypeAndValue (',' !dbg, !1)
-///   ::= 'ret' TypeAndValue (',' TypeAndValue)+  (',' !dbg, !1)
+///   ::= 'ret' void (',' !dbg, !1)*
+///   ::= 'ret' TypeAndValue (',' !dbg, !1)*
+///   ::= 'ret' TypeAndValue (',' TypeAndValue)+  (',' !dbg, !1)*
 ///         [[obsolete: LLVM 3.0]]
 bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
                         PerFunctionState &PFS) {
@@ -3031,8 +3040,8 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
       if (ParseOptionalCustomMetadata()) return true;
     } else {
       // The normal case is one return value.
-      // FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring use
-      // of 'ret {i32,i32} {i32 1, i32 2}'
+      // FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring
+      // use of 'ret {i32,i32} {i32 1, i32 2}'
       SmallVector<Value*, 8> RVs;
       RVs.push_back(RV);
 
index 5346d133445fcaaadbd71f821b363a0e050f923c..57e1dae1cae9126d1cef298d7a53b534f9390a83 100644 (file)
@@ -1,7 +1,8 @@
-; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | grep {ret void, !foo !0}
+; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | grep {ret void, !bar !1, !foo !0}
 define void @test() {
-  ret void, !foo !0
-;, !bar !1
+  add i32 2, 1, !bar !0
+  add i32 1, 2, !foo !1
+  ret void, !foo !0, !bar !1
 }
 
 !0 = metadata !{i32 662302, i32 26, metadata !1, null}