Parse custom metadata attached with an instruction.
authorDevang Patel <dpatel@apple.com>
Tue, 29 Sep 2009 00:01:14 +0000 (00:01 +0000)
committerDevang Patel <dpatel@apple.com>
Tue, 29 Sep 2009 00:01:14 +0000 (00:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83033 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Metadata.h
lib/AsmParser/LLLexer.cpp
lib/AsmParser/LLParser.cpp
lib/AsmParser/LLParser.h
lib/AsmParser/LLToken.h
lib/VMCore/AsmWriter.cpp
lib/VMCore/Metadata.cpp
test/Feature/md_on_instruction.ll
test/Feature/md_on_instruction2.ll

index 883de23cf1aa31af1a35d48cfe35aef6a704b509..2f740a6c8444418b62300f922d64cfd686e3c4f6 100644 (file)
@@ -305,8 +305,10 @@ public:
 
 //===----------------------------------------------------------------------===//
 /// MetadataContext -
-/// MetadataContext manages metadata used in a context.
-
+/// MetadataContext handles uniquing and assignment of IDs for custom metadata
+/// types. Custom metadata handler names do not contain spaces. And the name
+/// must start with an alphabet. The regular expression used to check name
+/// is [a-zA-Z$._][a-zA-Z$._0-9]*
 class MetadataContext {
 public:
   typedef std::pair<unsigned, WeakVH> MDPairTy;
@@ -330,6 +332,9 @@ public:
   /// is not registered then return 0.
   unsigned getMDKind(const char *Name);
 
+  /// validName - Return true if Name is a valid custom metadata handler name.
+  bool validName(const char *Name);
+
   /// getMD - Get the metadata of given kind attached with an Instruction.
   /// If the metadata is not found then return 0.
   MDNode *getMD(unsigned Kind, const Instruction *Inst);
index 315048c748a8edd8f8c22bc0cbe6614f04f37c84..16e0bd78c906a18e3eda29fdaba28fc35f2c5936 100644 (file)
@@ -434,7 +434,7 @@ lltok::Kind LLLexer::LexMetadata() {
       ++CurPtr;
 
     StrVal.assign(TokStart+1, CurPtr);   // Skip !
-    return lltok::NamedMD;
+    return lltok::NamedOrCustomMD;
   }
   return lltok::Metadata;
 }
@@ -530,7 +530,6 @@ lltok::Kind LLLexer::LexIdentifier() {
   KEYWORD(asm);
   KEYWORD(sideeffect);
   KEYWORD(gc);
-  KEYWORD(dbg);
 
   KEYWORD(ccc);
   KEYWORD(fastcc);
index b2b6b751ee0a0a47379b2dfe401f83c3fe2f9529..9e8015966d5894d5c786faccee0163366c95b6fa 100644 (file)
@@ -125,7 +125,7 @@ bool LLParser::ParseTopLevelEntities() {
     case lltok::GlobalID:   if (ParseUnnamedGlobal()) return true; break;
     case lltok::GlobalVar:  if (ParseNamedGlobal()) return true; break;
     case lltok::Metadata:   if (ParseStandaloneMetadata()) return true; break;
-    case lltok::NamedMD:    if (ParseNamedMetadata()) return true; break;
+    case lltok::NamedOrCustomMD: if (ParseNamedMetadata()) return true; break;
 
     // The Global variable production with no name can have many different
     // optional leading prefixes, the production is:
@@ -461,7 +461,7 @@ bool LLParser::ParseMDNode(MetadataBase *&Node) {
 ///ParseNamedMetadata:
 ///   !foo = !{ !1, !2 }
 bool LLParser::ParseNamedMetadata() {
-  assert(Lex.getKind() == lltok::NamedMD);
+  assert(Lex.getKind() == lltok::NamedOrCustomMD);
   Lex.Lex();
   std::string Name = Lex.getStrVal();
 
@@ -1025,24 +1025,30 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
   return false;
 }
 
-/// ParseOptionalDbgInfo
+/// ParseOptionalCustomMetadata
 ///   ::= /* empty */
-///   ::= 'dbg' !42
-bool LLParser::ParseOptionalDbgInfo() {
+///   ::= !dbg !42
+bool LLParser::ParseOptionalCustomMetadata() {
 
-  if (!EatIfPresent(lltok::kw_dbg))
+  std::string Name;
+  if (Lex.getKind() == lltok::NamedOrCustomMD) {
+    Name = Lex.getStrVal();
+    Lex.Lex();
+  } else
     return false;
+
   if (Lex.getKind() != lltok::Metadata)
     return TokError("Expected '!' here");
   Lex.Lex();
+
   MetadataBase *Node;
   if (ParseMDNode(Node)) return true;
 
   MetadataContext &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)));
+  unsigned MDK = TheMetadata.getMDKind(Name.c_str());
+  if (!MDK)
+    MDK = TheMetadata.RegisterMDKind(Name.c_str());
+  MDsOnInst.push_back(std::make_pair(MDK, cast<MDNode>(Node)));
 
   return false;
 }
@@ -1067,8 +1073,8 @@ 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;
+      if (Lex.getKind() == lltok::NamedOrCustomMD) {
+      if (ParseOptionalCustomMetadata()) return true;
     } else if (Lex.getKind() == lltok::kw_align) {
       if (ParseOptionalAlignment(Alignment)) return true;
     } else
@@ -2653,7 +2659,7 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
 
     if (ParseInstruction(Inst, BB, PFS)) return true;
     if (EatIfPresent(lltok::comma))
-      ParseOptionalDbgInfo();
+      ParseOptionalCustomMetadata();
 
     // Set metadata attached with this instruction.
     MetadataContext &TheMetadata = M->getContext().getMetadata();
@@ -2841,9 +2847,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) {
@@ -2852,7 +2858,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
 
   if (Ty == Type::getVoidTy(Context)) {
     if (EatIfPresent(lltok::comma))
-      if (ParseOptionalDbgInfo()) return true;
+      if (ParseOptionalCustomMetadata()) return true;
     Inst = ReturnInst::Create(Context);
     return false;
   }
@@ -2861,9 +2867,9 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
   if (ParseValue(Ty, RV, PFS)) return true;
 
   if (EatIfPresent(lltok::comma)) {
-    // Parse optional 'dbg'
-    if (Lex.getKind() == lltok::kw_dbg) {
-      if (ParseOptionalDbgInfo()) return true;
+    // Parse optional custom metadata, e.g. !dbg
+    if (Lex.getKind() == lltok::NamedOrCustomMD) {
+      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
@@ -2872,8 +2878,9 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
       RVs.push_back(RV);
 
       do {
-        // If optional 'dbg' is seen then this is the end of MRV.
-        if (Lex.getKind() == lltok::kw_dbg)
+        // If optional custom metadata, e.g. !dbg is seen then this is the 
+        // end of MRV.
+        if (Lex.getKind() == lltok::NamedOrCustomMD)
           break;
         if (ParseTypeAndValue(RV, PFS)) return true;
         RVs.push_back(RV);
@@ -2888,7 +2895,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
     }
   }
   if (EatIfPresent(lltok::comma))
-    if (ParseOptionalDbgInfo()) return true;
+    if (ParseOptionalCustomMetadata()) return true;
 
   Inst = ReturnInst::Create(Context, RV);
   return false;
@@ -3439,7 +3446,8 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
   if (ParseType(Ty)) return true;
 
   if (EatIfPresent(lltok::comma)) {
-    if (Lex.getKind() == lltok::kw_align || Lex.getKind() == lltok::kw_dbg) {
+    if (Lex.getKind() == lltok::kw_align 
+        || Lex.getKind() == lltok::NamedOrCustomMD) {
       if (ParseOptionalInfo(Alignment)) return true;
     } else {
       if (ParseTypeAndValue(Size, SizeLoc, PFS)) return true;
index 7c516fac619573865aae456a31341794d81d59fa..97bf2f309f6d53a5317e8cab805bb0976ef9593b 100644 (file)
@@ -128,7 +128,7 @@ namespace llvm {
     bool ParseOptionalVisibility(unsigned &Visibility);
     bool ParseOptionalCallingConv(CallingConv::ID &CC);
     bool ParseOptionalAlignment(unsigned &Alignment);
-    bool ParseOptionalDbgInfo();
+    bool ParseOptionalCustomMetadata();
     bool ParseOptionalInfo(unsigned &Alignment);
     bool ParseIndexList(SmallVectorImpl<unsigned> &Indices);
 
index dd6359a630b4c32ef481c7f32be517c2ea228fd4..bfcb58e721433cb441091eab1d1d0ca92474015f 100644 (file)
@@ -127,7 +127,7 @@ namespace lltok {
     GlobalVar,         // @foo @"foo"
     LocalVar,          // %foo %"foo"
     StringConstant,    // "foo"
-    NamedMD,           // !foo
+    NamedOrCustomMD,   // !foo
 
     // Metadata valued tokens.
     Metadata,          // !"foo" !{i8 42}
index a8b3d05a032f4c258e0666426f30e74e715ba41c..60c5b3e99b638b875cebf158fa9eaedf825c1ddc 100644 (file)
@@ -2007,7 +2007,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     for (MetadataContext::MDMapTy::const_iterator MI = MDMap->begin(),
            ME = MDMap->end(); MI != ME; ++MI)
       if (const MDNode *MD = dyn_cast_or_null<MDNode>(MI->second))
-        Out << ", " << MDNames[MI->first]
+        Out << ", !" << MDNames[MI->first]
             << " !" << Machine.getMetadataSlot(MD);
 
   printInfoComment(I);
index ddd510347b96028c7eea9ed28ef1881c066b43b2..8ae7d309b31c6d357e762c85eac0f21f7ee9b108 100644 (file)
@@ -260,6 +260,7 @@ NamedMDNode::~NamedMDNode() {
 /// RegisterMDKind - Register a new metadata kind and return its ID.
 /// A metadata kind can be registered only once. 
 unsigned MetadataContext::RegisterMDKind(const char *Name) {
+  assert (validName(Name) && "Invalid custome metadata name!");
   unsigned Count = MDHandlerNames.size();
   StringMap<unsigned>::iterator I = MDHandlerNames.find(Name);
   assert(I == MDHandlerNames.end() && "Already registered MDKind!");
@@ -267,9 +268,31 @@ unsigned MetadataContext::RegisterMDKind(const char *Name) {
   return Count + 1;
 }
 
+/// validName - Return true if Name is a valid custom metadata handler name.
+bool MetadataContext::validName(const char *Name) {
+  if (!Name)
+    return false;
+
+  if (!isalpha(*Name))
+    return false;
+
+  unsigned Length = strlen(Name);  
+  unsigned Count = 1;
+  ++Name;
+  while (Name &&
+         (isalnum(*Name) || *Name == '_' || *Name == '-' || *Name == '.')) {
+    ++Name;
+    ++Count;
+  }
+  if (Length != Count)
+    return false;
+  return true;
+}
+
 /// getMDKind - Return metadata kind. If the requested metadata kind
 /// is not registered then return 0.
 unsigned MetadataContext::getMDKind(const char *Name) {
+  assert (validName(Name) && "Invalid custome metadata name!");
   StringMap<unsigned>::iterator I = MDHandlerNames.find(Name);
   if (I == MDHandlerNames.end())
     return 0;
index 3fa0b6158b9e69f30c89430e20a88fe0820a3ec3..d765cd8fa1e0ecc475bcc4d775db0165428e8f61 100644 (file)
@@ -4,13 +4,13 @@ define i32 @foo() nounwind ssp {
 entry:
   %retval = alloca i32                            ; <i32*> [#uses=2]
   call void @llvm.dbg.func.start(metadata !0)
-  store i32 42, i32* %retval, dbg !3
-  br label %0, dbg !3
+  store i32 42, i32* %retval, !dbg !3
+  br label %0, !dbg !3
 
 ; <label>:0                                       ; preds = %entry
   call void @llvm.dbg.region.end(metadata !0)
-  %1 = load i32* %retval, dbg !3                  ; <i32> [#uses=1]
-  ret i32 %1, dbg !3
+  %1 = load i32* %retval, !dbg !3                  ; <i32> [#uses=1]
+  ret i32 %1, !dbg !3
 }
 
 declare void @llvm.dbg.func.start(metadata) nounwind readnone
index f5bd513e4c649cde3b284e0cc49f87c8aaa9fa97..da9e49ebfb2f33863973f3424098446a4055a16b 100644 (file)
@@ -1,15 +1,15 @@
-; RUN: llvm-as < %s | llvm-dis | grep " dbg " | count 4
+; RUN: llvm-as < %s | llvm-dis | grep " !dbg " | count 4
 define i32 @foo() nounwind ssp {
 entry:
   %retval = alloca i32                            ; <i32*> [#uses=2]
   call void @llvm.dbg.func.start(metadata !0)
-  store i32 42, i32* %retval, dbg !3
-  br label %0, dbg !3
+  store i32 42, i32* %retval, !dbg !3
+  br label %0, !dbg !3
 
 ; <label>:0                                       ; preds = %entry
   call void @llvm.dbg.region.end(metadata !0)
-  %1 = load i32* %retval, dbg !3                  ; <i32> [#uses=1]
-  ret i32 %1, dbg !3
+  %1 = load i32* %retval, !dbg !3                  ; <i32> [#uses=1]
+  ret i32 %1, !dbg !3
 }
 
 declare void @llvm.dbg.func.start(metadata) nounwind readnone