IR: Remove MDNodeFwdDecl
[oota-llvm.git] / lib / AsmParser / LLParser.cpp
index 5090cfb8a508e21b0fe9fa4010b6df534e1d9572..ce195381cfbca7505dd74eb8d801f77d7f227f4b 100644 (file)
@@ -531,7 +531,7 @@ bool LLParser::ParseMDNodeID(MDNode *&Result) {
   }
 
   // Otherwise, create MDNode forward reference.
-  MDNodeFwdDecl *FwdNode = MDNode::getTemporary(Context, None);
+  MDTuple *FwdNode = MDTuple::getTemporary(Context, None);
   ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
 
   if (NumberedMetadata.size() <= MID)
@@ -587,14 +587,17 @@ bool LLParser::ParseStandaloneMetadata() {
     return TokError("unexpected type in metadata definition");
 
   bool IsDistinct = EatIfPresent(lltok::kw_distinct);
-  if (ParseToken(lltok::exclaim, "Expected '!' here") ||
-      ParseMDTuple(Init, IsDistinct))
+  if (Lex.getKind() == lltok::MetadataVar) {
+    if (ParseSpecializedMDNode(Init, IsDistinct))
+      return true;
+  } else if (ParseToken(lltok::exclaim, "Expected '!' here") ||
+             ParseMDTuple(Init, IsDistinct))
     return true;
 
   // See if this was forward referenced, if so, handle it.
   auto FI = ForwardRefMDNodes.find(MetadataID);
   if (FI != ForwardRefMDNodes.end()) {
-    auto *Temp = FI->second.first;
+    MDTuple *Temp = FI->second.first;
     Temp->replaceAllUsesWith(Init);
     MDNode::deleteTemporary(Temp);
     ForwardRefMDNodes.erase(FI);
@@ -1490,24 +1493,11 @@ bool LLParser::ParseInstructionMetadata(Instruction *Inst,
     unsigned MDK = M->getMDKindID(Name);
     Lex.Lex();
 
-    if (ParseToken(lltok::exclaim, "expected '!' here"))
+    MDNode *N;
+    if (ParseMDNode(N))
       return true;
 
-    // This code is similar to that of ParseMetadata.  However, only MDNodes
-    // are supported here.
-    if (Lex.getKind() == lltok::lbrace) {
-      MDNode *N;
-      if (ParseMDTuple(N))
-        return true;
-      Inst->setMetadata(MDK, N);
-    } else {
-      MDNode *Node;
-      if (ParseMDNodeID(Node))
-        return true;
-      // If we got the node, add it to the instruction.
-      Inst->setMetadata(MDK, Node);
-    }
-
+    Inst->setMetadata(MDK, N);
     if (MDK == LLVMContext::MD_tbaa)
       InstsWithTBAATag.push_back(Inst);
 
@@ -2908,10 +2898,131 @@ bool LLParser::ParseMDTuple(MDNode *&MD, bool IsDistinct) {
   if (ParseMDNodeVector(Elts))
     return true;
 
-  MD = (IsDistinct ? MDNode::getDistinct : MDNode::get)(Context, Elts);
+  MD = (IsDistinct ? MDTuple::getDistinct : MDTuple::get)(Context, Elts);
+  return false;
+}
+
+/// MDNode:
+///  ::= !{ ... }
+///  ::= !7
+///  ::= !MDLocation(...)
+bool LLParser::ParseMDNode(MDNode *&N) {
+  if (Lex.getKind() == lltok::MetadataVar)
+    return ParseSpecializedMDNode(N);
+
+  return ParseToken(lltok::exclaim, "expected '!' here") ||
+         ParseMDNodeTail(N);
+}
+
+bool LLParser::ParseMDNodeTail(MDNode *&N) {
+  // !{ ... }
+  if (Lex.getKind() == lltok::lbrace)
+    return ParseMDTuple(N);
+
+  // !42
+  return ParseMDNodeID(N);
+}
+
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
+                            MDUnsignedField<uint32_t> &Result) {
+  if (Result.Seen)
+    return Error(Loc,
+                 "field '" + Name + "' cannot be specified more than once");
+
+  if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
+    return TokError("expected unsigned integer");
+  uint64_t Val64 = Lex.getAPSIntVal().getLimitedValue(Result.Max + 1ull);
+
+  if (Val64 > Result.Max)
+    return TokError("value for '" + Name + "' too large, limit is " +
+                    Twine(Result.Max));
+  Result.assign(Val64);
+  Lex.Lex();
+  return false;
+}
+
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
+  if (Result.Seen)
+    return Error(Loc,
+                 "field '" + Name + "' cannot be specified more than once");
+
+  Metadata *MD;
+  if (ParseMetadata(MD, nullptr))
+    return true;
+
+  Result.assign(MD);
   return false;
 }
 
+template <class ParserTy>
+bool LLParser::ParseMDFieldsImpl(ParserTy parseField) {
+  assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+  Lex.Lex();
+
+  if (ParseToken(lltok::lparen, "expected '(' here"))
+    return true;
+  if (EatIfPresent(lltok::rparen))
+    return false;
+
+  do {
+    if (Lex.getKind() != lltok::LabelStr)
+      return TokError("expected field label here");
+
+    if (parseField())
+      return true;
+  } while (EatIfPresent(lltok::comma));
+
+  return ParseToken(lltok::rparen, "expected ')' here");
+}
+
+bool LLParser::ParseSpecializedMDNode(MDNode *&N, bool IsDistinct) {
+  assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+#define DISPATCH_TO_PARSER(CLASS)                                              \
+  if (Lex.getStrVal() == #CLASS)                                               \
+    return Parse##CLASS(N, IsDistinct);
+
+  DISPATCH_TO_PARSER(MDLocation);
+#undef DISPATCH_TO_PARSER
+
+  return TokError("expected metadata type");
+}
+
+#define PARSE_MD_FIELD(NAME)                                                   \
+  do {                                                                         \
+    if (Lex.getStrVal() == #NAME) {                                            \
+      LocTy Loc = Lex.getLoc();                                                \
+      Lex.Lex();                                                               \
+      if (ParseMDField(Loc, #NAME, NAME))                                      \
+        return true;                                                           \
+      return false;                                                            \
+    }                                                                          \
+  } while (0)
+
+/// ParseMDLocationFields:
+///   ::= !MDLocation(line: 43, column: 8, scope: !5, inlinedAt: !6)
+bool LLParser::ParseMDLocation(MDNode *&Result, bool IsDistinct) {
+  MDUnsignedField<uint32_t> line(0, ~0u >> 8);
+  MDUnsignedField<uint32_t> column(0, ~0u >> 16);
+  MDField scope;
+  MDField inlinedAt;
+  if (ParseMDFieldsImpl([&]() -> bool {
+        PARSE_MD_FIELD(line);
+        PARSE_MD_FIELD(column);
+        PARSE_MD_FIELD(scope);
+        PARSE_MD_FIELD(inlinedAt);
+        return TokError(Twine("invalid field '") + Lex.getStrVal() + "'");
+      }))
+    return true;
+
+  if (!scope.Seen)
+    return TokError("missing required field 'scope'");
+
+  auto get = (IsDistinct ? MDLocation::getDistinct : MDLocation::get);
+  Result = get(Context, line.Val, column.Val, scope.Val, inlinedAt.Val);
+  return false;
+}
+#undef PARSE_MD_FIELD
+
 /// ParseMetadataAsValue
 ///  ::= metadata i32 %local
 ///  ::= metadata i32 @global
@@ -2956,7 +3067,16 @@ bool LLParser::ParseValueAsMetadata(Metadata *&MD, PerFunctionState *PFS) {
 ///  ::= !42
 ///  ::= !{...}
 ///  ::= !"string"
+///  ::= !MDLocation(...)
 bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
+  if (Lex.getKind() == lltok::MetadataVar) {
+    MDNode *N;
+    if (ParseSpecializedMDNode(N))
+      return true;
+    MD = N;
+    return false;
+  }
+
   // ValueAsMetadata:
   // <type> <value>
   if (Lex.getKind() != lltok::exclaim)
@@ -2966,32 +3086,23 @@ bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
   assert(Lex.getKind() == lltok::exclaim && "Expected '!' here");
   Lex.Lex();
 
-  // MDNode:
-  // !{ ... }
-  if (Lex.getKind() == lltok::lbrace) {
-    MDNode *N;
-    if (ParseMDTuple(N))
-      return true;
-    MD = N;
-    return false;
-  }
-
-  // Standalone metadata reference
-  // !42
-  if (Lex.getKind() == lltok::APSInt) {
-    MDNode *N;
-    if (ParseMDNodeID(N))
+  // MDString:
+  //   ::= '!' STRINGCONSTANT
+  if (Lex.getKind() == lltok::StringConstant) {
+    MDString *S;
+    if (ParseMDString(S))
       return true;
-    MD = N;
+    MD = S;
     return false;
   }
 
-  // MDString:
-  //   ::= '!' STRINGCONSTANT
-  MDString *S;
-  if (ParseMDString(S))
+  // MDNode:
+  // !{ ... }
+  // !7
+  MDNode *N;
+  if (ParseMDNodeTail(N))
     return true;
-  MD = S;
+  MD = N;
   return false;
 }