diff options
-rw-r--r-- | include/llvm/Metadata.h | 9 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 3 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 56 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.h | 2 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 2 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 2 | ||||
-rw-r--r-- | lib/VMCore/Metadata.cpp | 23 | ||||
-rw-r--r-- | test/Feature/md_on_instruction.ll | 8 | ||||
-rw-r--r-- | test/Feature/md_on_instruction2.ll | 10 |
9 files changed, 75 insertions, 40 deletions
diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 883de23..2f740a6 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -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); diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 315048c..16e0bd7 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -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); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index b2b6b75..9e80159 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -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; diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 7c516fa..97bf2f3 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -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); diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index dd6359a..bfcb58e 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -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} diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index a8b3d05..60c5b3e 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -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); diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index ddd5103..8ae7d30 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -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; diff --git a/test/Feature/md_on_instruction.ll b/test/Feature/md_on_instruction.ll index 3fa0b61..d765cd8 100644 --- a/test/Feature/md_on_instruction.ll +++ b/test/Feature/md_on_instruction.ll @@ -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 diff --git a/test/Feature/md_on_instruction2.ll b/test/Feature/md_on_instruction2.ll index f5bd513..da9e49e 100644 --- a/test/Feature/md_on_instruction2.ll +++ b/test/Feature/md_on_instruction2.ll @@ -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 |