This started as a small change, I swear. Unfortunately, lots of things call the...
[oota-llvm.git] / lib / AsmParser / LLParser.cpp
index 3927cf1e9e98792bba061e4ed6e3d48ad675d2f7..64212f61934991fe6654ee63d8081be6e9a7be0b 100644 (file)
@@ -84,6 +84,12 @@ bool LLParser::ValidateEndOfModule() {
                  "use of undefined value '@" +
                  utostr(ForwardRefValIDs.begin()->first) + "'");
   
+  if (!ForwardRefMDNodes.empty())
+    return Error(ForwardRefMDNodes.begin()->second.second,
+                 "use of undefined metadata '!" +
+                 utostr(ForwardRefMDNodes.begin()->first) + "'");
+  
+
   // Look for intrinsic functions and CallInst that need to be upgraded
   for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
     UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove
@@ -371,10 +377,8 @@ bool LLParser::ParseStandaloneMetadata() {
     return true;
 
   LocTy TyLoc;
-  bool IsConstant;    
   PATypeHolder Ty(Type::VoidTy);
-  if (ParseGlobalType(IsConstant) ||
-      ParseType(Ty, TyLoc))
+  if (ParseType(Ty, TyLoc))
     return true;
   
   Constant *Init = 0;
@@ -382,6 +386,14 @@ bool LLParser::ParseStandaloneMetadata() {
       return true;
 
   MetadataCache[MetadataID] = Init;
+  std::map<unsigned, std::pair<Constant *, LocTy> >::iterator
+    FI = ForwardRefMDNodes.find(MetadataID);
+  if (FI != ForwardRefMDNodes.end()) {
+    Constant *FwdNode = FI->second.first;
+    FwdNode->replaceAllUsesWith(Init);
+    ForwardRefMDNodes.erase(FI);
+  }
+
   return false;
 }
 
@@ -1632,9 +1644,24 @@ bool LLParser::ParseValID(ValID &ID) {
     unsigned MID = 0;
     if (!ParseUInt32(MID)) {
       std::map<unsigned, Constant *>::iterator I = MetadataCache.find(MID);
-      if (I == MetadataCache.end())
-       return TokError("Unknown metadata reference");
-      ID.ConstantVal = I->second;
+      if (I != MetadataCache.end()) 
+        ID.ConstantVal = I->second;
+      else {
+        std::map<unsigned, std::pair<Constant *, LocTy> >::iterator
+          FI = ForwardRefMDNodes.find(MID);
+        if (FI != ForwardRefMDNodes.end()) 
+          ID.ConstantVal = FI->second.first;
+        else {
+          // Create MDNode forward reference
+          SmallVector<Value *, 1> Elts;
+          std::string FwdRefName = "llvm.mdnode.fwdref." + utostr(MID);
+          Elts.push_back(Context.getMDString(FwdRefName));
+          MDNode *FwdNode = Context.getMDNode(Elts.data(), Elts.size());
+          ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
+          ID.ConstantVal = FwdNode;
+        }
+      }
+
       return false;
     }
     
@@ -2860,13 +2887,13 @@ bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS,
   if (Opc == Instruction::FCmp) {
     if (!LHS->getType()->isFPOrFPVector())
       return Error(Loc, "fcmp requires floating point operands");
-    Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS);
+    Inst = new FCmpInst(Context, CmpInst::Predicate(Pred), LHS, RHS);
   } else {
     assert(Opc == Instruction::ICmp && "Unknown opcode for CmpInst!");
     if (!LHS->getType()->isIntOrIntVector() &&
         !isa<PointerType>(LHS->getType()))
       return Error(Loc, "icmp requires integer operands");
-    Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
+    Inst = new ICmpInst(Context, CmpInst::Predicate(Pred), LHS, RHS);
   }
   return false;
 }