Add support for embedded metadata to LLVM. This introduces two new types of
Constant, MDString and MDNode which can only be used by globals with a name
that starts with "llvm." or as arguments to a function with the same naming
restriction.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68420 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 95e6c90..d4815d8 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -265,6 +265,7 @@
   case ';':
     SkipLineComment();
     return LexToken();
+  case '!': return lltok::Metadata;
   case '0': case '1': case '2': case '3': case '4':
   case '5': case '6': case '7': case '8': case '9':
   case '-':
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 7800b8f..177161e 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -1561,6 +1561,29 @@
     ID.StrVal = Lex.getStrVal();
     ID.Kind = ValID::t_LocalName;
     break;
+  case lltok::Metadata: {  // !{...} MDNode, !"foo" MDString
+    ID.Kind = ValID::t_Constant;
+    Lex.Lex();
+    if (Lex.getKind() == lltok::lbrace) {
+      // MDNode:
+      //  ::= '!' '{' TypeAndValue (',' TypeAndValue)* '}'
+      SmallVector<Constant*, 16> Elts;
+      if (ParseMDNodeVector(Elts) ||
+          ParseToken(lltok::rbrace, "expected end of metadata node"))
+        return true;
+    
+      ID.ConstantVal = MDNode::get(&Elts[0], Elts.size());
+      return false;
+    }
+
+    // MDString:
+    //   ::= '!' STRINGCONSTANT
+    std::string Str;
+    if (ParseStringConstant(Str)) return true;
+
+    ID.ConstantVal = MDString::get(Str.data(), Str.data() + Str.size());
+    return false;
+  }
   case lltok::APSInt:
     ID.APSIntVal = Lex.getAPSIntVal(); 
     ID.Kind = ValID::t_APSInt;
@@ -1661,7 +1684,7 @@
                      "array element #" + utostr(i) +
                      " is not of type '" +Elts[0]->getType()->getDescription());
     }
-          
+    
     ID.ConstantVal = ConstantArray::get(ATy, &Elts[0], Elts.size());
     ID.Kind = ValID::t_Constant;
     return false;
@@ -3221,3 +3244,21 @@
   Inst = InsertValueInst::Create(Val0, Val1, Indices.begin(), Indices.end());
   return false;
 }
+
+//===----------------------------------------------------------------------===//
+// Embedded metadata.
+//===----------------------------------------------------------------------===//
+
+/// ParseMDNodeVector
+///   ::= TypeAndValue (',' TypeAndValue)*
+bool LLParser::ParseMDNodeVector(SmallVectorImpl<Constant*> &Elts) {
+  assert(Lex.getKind() == lltok::lbrace);
+  Lex.Lex();
+  do {
+    Constant *C;
+    if (ParseGlobalTypeAndValue(C)) return true;
+    Elts.push_back(C);
+  } while (EatIfPresent(lltok::comma));
+
+  return false;
+}
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 3fc2fd2..44f4c2a 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -27,6 +27,8 @@
   class Instruction;
   class Constant;
   class GlobalValue;
+  class MDString;
+  class MDNode;
   struct ValID;
 
   class LLParser {
@@ -156,6 +158,7 @@
     bool ParseGlobalValue(const Type *Ty, Constant *&V);
     bool ParseGlobalTypeAndValue(Constant *&V);
     bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
+    bool ParseMDNodeVector(SmallVectorImpl<Constant*> &);
 
 
     // Function Semantic Analysis.
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index ec3769b..35cb4db 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -115,6 +115,9 @@
     LocalVar,          // %foo %"foo"
     StringConstant,    // "foo"
 
+    // Metadata valued tokens.
+    Metadata,          // !"foo" !{i8 42}
+
     // Type valued tokens (TyVal).
     Type,