Fix parsing of optional metadata for 'load', 'store' and 'alloc' instructions.
authorDevang Patel <dpatel@apple.com>
Thu, 17 Sep 2009 23:04:48 +0000 (23:04 +0000)
committerDevang Patel <dpatel@apple.com>
Thu, 17 Sep 2009 23:04:48 +0000 (23:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82175 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AsmParser/LLParser.cpp
lib/AsmParser/LLParser.h

index 3c125a01b19d6bf028a5630d281e021088dbdfcf..295329bf970e026611b9f91db6067a04aad7c6ef 100644 (file)
@@ -1025,6 +1025,28 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
   return false;
 }
 
+/// ParseOptionalDbgInfo
+///   ::= /* empty */
+///   ::= 'dbg' !42
+bool LLParser::ParseOptionalDbgInfo() {
+
+  if (!EatIfPresent(lltok::kw_dbg))
+    return false;
+  if (Lex.getKind() != lltok::Metadata)
+    return TokError("Expected '!' here");
+  Lex.Lex();
+  MetadataBase *Node;
+  if (ParseMDNode(Node)) return true;
+  
+  Metadata &TheMetadata = M->getContext().getMetadata();
+  unsigned MDDbgKind = TheMetadata.getMDKind("dbg");
+  if (!MDDbgKind)
+    MDDbgKind = TheMetadata.RegisterMDKind("dbg");
+  MDsOnInst.push_back(std::make_pair(MDDbgKind, cast<MDNode>(Node)));
+  
+  return false;
+}
+
 /// ParseOptionalAlignment
 ///   ::= /* empty */
 ///   ::= 'align' 4
@@ -1039,17 +1061,24 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) {
   return false;
 }
 
-/// ParseOptionalCommaAlignment
-///   ::= /* empty */
-///   ::= ',' 'align' 4
-bool LLParser::ParseOptionalCommaAlignment(unsigned &Alignment) {
-  Alignment = 0;
-  if (!EatIfPresent(lltok::comma))
-    return false;
-  return ParseToken(lltok::kw_align, "expected 'align'") ||
-         ParseUInt32(Alignment);
+/// ParseOptionalInfo
+///   ::= OptionalInfo (',' OptionalInfo)+
+bool LLParser::ParseOptionalInfo(unsigned &Alignment) {
+
+  // FIXME: Handle customized metadata info attached with an instruction.
+  do {
+    if (Lex.getKind() == lltok::kw_dbg) {
+      if (ParseOptionalDbgInfo()) return true;
+    } else if (Lex.getKind() == lltok::kw_align) {
+      if (ParseOptionalAlignment(Alignment)) return true;
+    } else
+      return true;
+  } while (EatIfPresent(lltok::comma));
+  
+  return false;
 }
 
+
 /// ParseIndexList
 ///    ::=  (',' uint32)+
 bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices) {
@@ -2621,26 +2650,18 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
       if (ParseToken(lltok::equal, "expected '=' after instruction name"))
         return true;
     }
-    
+
     if (ParseInstruction(Inst, BB, PFS)) return true;
-    
-    // Parse optional debug info
-    if (Lex.getKind() == lltok::comma) {
-      Lex.Lex();
-      if (Lex.getKind() == lltok::kw_dbg) {
-       Lex.Lex();
-       if (Lex.getKind() != lltok::Metadata)
-         return TokError("Expected '!' here");
-       Lex.Lex();
-       MetadataBase *N = 0;
-       if (ParseMDNode(N)) return true;
-       Metadata &TheMetadata = M->getContext().getMetadata();
-       unsigned MDDbgKind = TheMetadata.getMDKind("dbg");
-       if (!MDDbgKind)
-         MDDbgKind = TheMetadata.RegisterMDKind("dbg");
-       TheMetadata.setMD(MDDbgKind, cast<MDNode>(N), Inst);
-      }
-    }
+    if (EatIfPresent(lltok::comma))
+      ParseOptionalDbgInfo();
+
+    // Set metadata attached with this instruction.
+    Metadata &TheMetadata = M->getContext().getMetadata();
+    for (SmallVector<std::pair<MDKindID, MDNode *>, 2>::iterator 
+          MDI = MDsOnInst.begin(), MDE = MDsOnInst.end(); MDI != MDE; ++MDI) 
+      TheMetadata.setMD(MDI->first, MDI->second, Inst);
+    MDsOnInst.clear();
+
     BB->getInstList().push_back(Inst);
 
     // Set the name on the instruction.
@@ -2820,41 +2841,55 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) {
 //===----------------------------------------------------------------------===//
 
 /// ParseRet - Parse a return instruction.
-///   ::= 'ret' void
-///   ::= 'ret' TypeAndValue
-///   ::= 'ret' TypeAndValue (',' TypeAndValue)+  [[obsolete: LLVM 3.0]]
+///   ::= '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) {
   PATypeHolder Ty(Type::getVoidTy(Context));
   if (ParseType(Ty, true /*void allowed*/)) return true;
   
   if (Ty == Type::getVoidTy(Context)) {
+    if (EatIfPresent(lltok::comma))
+      if (ParseOptionalDbgInfo()) return true;
     Inst = ReturnInst::Create(Context);
     return false;
   }
   
   Value *RV;
   if (ParseValue(Ty, RV, PFS)) return true;
-  
-  // The normal case is one return value.
-  if (Lex.getKind() == lltok::comma) {
-    // 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);
-    
-    while (EatIfPresent(lltok::comma)) {
-      if (ParseTypeAndValue(RV, PFS)) return true;
-      RVs.push_back(RV);
-    }
 
-    RV = UndefValue::get(PFS.getFunction().getReturnType());
-    for (unsigned i = 0, e = RVs.size(); i != e; ++i) {
-      Instruction *I = InsertValueInst::Create(RV, RVs[i], i, "mrv");
-      BB->getInstList().push_back(I);
-      RV = I;
+  if (EatIfPresent(lltok::comma)) {
+    // Parse optional 'dbg'
+    if (Lex.getKind() == lltok::kw_dbg) {
+      if (ParseOptionalDbgInfo()) 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}'
+      SmallVector<Value*, 8> RVs;
+      RVs.push_back(RV);
+      
+      do {
+       // If optional 'dbg' is seen then this is the end of MRV.
+       if (Lex.getKind() == lltok::kw_dbg)
+         break;
+       if (ParseTypeAndValue(RV, PFS)) return true;
+       RVs.push_back(RV);
+      } while (EatIfPresent(lltok::comma));
+
+      RV = UndefValue::get(PFS.getFunction().getReturnType());
+      for (unsigned i = 0, e = RVs.size(); i != e; ++i) {
+       Instruction *I = InsertValueInst::Create(RV, RVs[i], i, "mrv");
+       BB->getInstList().push_back(I);
+       RV = I;
+      }
     }
   }
+  if (EatIfPresent(lltok::comma))
+    if (ParseOptionalDbgInfo()) return true;
+
   Inst = ReturnInst::Create(Context, RV);
   return false;
 }
@@ -3393,8 +3428,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
 //===----------------------------------------------------------------------===//
 
 /// ParseAlloc
-///   ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalAlignment)?
-///   ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalAlignment)?
+///   ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalInfo)?
+///   ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
 bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
                           unsigned Opc) {
   PATypeHolder Ty(Type::getVoidTy(Context));
@@ -3404,11 +3439,12 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
   if (ParseType(Ty)) return true;
 
   if (EatIfPresent(lltok::comma)) {
-    if (Lex.getKind() == lltok::kw_align) {
-      if (ParseOptionalAlignment(Alignment)) return true;
-    } else if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
-               ParseOptionalCommaAlignment(Alignment)) {
-      return true;
+    if (Lex.getKind() == lltok::kw_align || Lex.getKind() == lltok::kw_dbg) {
+      if (ParseOptionalInfo(Alignment)) return true;
+    } else {
+      if (ParseTypeAndValue(Size, SizeLoc, PFS)) return true;
+      if (EatIfPresent(lltok::comma))
+       if (ParseOptionalInfo(Alignment)) return true;
     }
   }
 
@@ -3434,14 +3470,15 @@ bool LLParser::ParseFree(Instruction *&Inst, PerFunctionState &PFS) {
 }
 
 /// ParseLoad
-///   ::= 'volatile'? 'load' TypeAndValue (',' 'align' i32)?
+///   ::= 'volatile'? 'load' TypeAndValue (',' OptionalInfo)?
 bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
                          bool isVolatile) {
   Value *Val; LocTy Loc;
-  unsigned Alignment;
-  if (ParseTypeAndValue(Val, Loc, PFS) ||
-      ParseOptionalCommaAlignment(Alignment))
-    return true;
+  unsigned Alignment = 0;
+  if (ParseTypeAndValue(Val, Loc, PFS)) return true;
+  
+  if (EatIfPresent(lltok::comma))
+    if (ParseOptionalInfo(Alignment)) return true;
 
   if (!isa<PointerType>(Val->getType()) ||
       !cast<PointerType>(Val->getType())->getElementType()->isFirstClassType())
@@ -3456,12 +3493,14 @@ bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
 bool LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS,
                           bool isVolatile) {
   Value *Val, *Ptr; LocTy Loc, PtrLoc;
-  unsigned Alignment;
+  unsigned Alignment = 0;
   if (ParseTypeAndValue(Val, Loc, PFS) ||
       ParseToken(lltok::comma, "expected ',' after store operand") ||
-      ParseTypeAndValue(Ptr, PtrLoc, PFS) ||
-      ParseOptionalCommaAlignment(Alignment))
+      ParseTypeAndValue(Ptr, PtrLoc, PFS))
     return true;
+
+  if (EatIfPresent(lltok::comma))
+    if (ParseOptionalInfo(Alignment)) return true;
   
   if (!isa<PointerType>(Ptr->getType()))
     return Error(PtrLoc, "store operand must be a pointer");
index 545be465f2380e3ff0dc548a6514e7ae7c76cd5f..3420fcf45539e62cd00d31dabfa1048e3c3b0081 100644 (file)
@@ -48,7 +48,7 @@ namespace llvm {
     /// MetadataCache - This map keeps track of parsed metadata constants.
     std::map<unsigned, MetadataBase *> MetadataCache;
     std::map<unsigned, std::pair<MetadataBase *, LocTy> > ForwardRefMDNodes;
-
+    SmallVector<std::pair<MDKindID, MDNode *>, 2> MDsOnInst;
     struct UpRefRecord {
       /// Loc - This is the location of the upref.
       LocTy Loc;
@@ -128,7 +128,8 @@ namespace llvm {
     bool ParseOptionalVisibility(unsigned &Visibility);
     bool ParseOptionalCallingConv(CallingConv::ID &CC);
     bool ParseOptionalAlignment(unsigned &Alignment);
-    bool ParseOptionalCommaAlignment(unsigned &Alignment);
+    bool ParseOptionalDbgInfo();
+    bool ParseOptionalInfo(unsigned &Alignment);
     bool ParseIndexList(SmallVectorImpl<unsigned> &Indices);
 
     // Top-Level Entities