diff options
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 73 |
1 files changed, 54 insertions, 19 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 8083a07..cdad077 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -39,6 +39,27 @@ bool LLParser::Run() { /// ValidateEndOfModule - Do final validity and sanity checks at the end of the /// module. bool LLParser::ValidateEndOfModule() { + // Handle any instruction metadata forward references. + if (!ForwardRefInstMetadata.empty()) { + for (DenseMap<Instruction*, std::vector<MDRef> >::iterator + I = ForwardRefInstMetadata.begin(), E = ForwardRefInstMetadata.end(); + I != E; ++I) { + Instruction *Inst = I->first; + const std::vector<MDRef> &MDList = I->second; + + for (unsigned i = 0, e = MDList.size(); i != e; ++i) { + unsigned SlotNo = MDList[i].MDSlot; + + if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0) + return Error(MDList[i].Loc, "use of undefined metadata '!" + + utostr(SlotNo) + "'"); + Inst->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]); + } + } + ForwardRefInstMetadata.clear(); + } + + // Update auto-upgraded malloc calls to "malloc". // FIXME: Remove in LLVM 3.0. if (MallocF) { @@ -472,18 +493,30 @@ bool LLParser::ParseMDString(MDString *&Result) { // MDNode: // ::= '!' MDNodeNumber +// +/// This version of ParseMDNodeID returns the slot number and null in the case +/// of a forward reference. +bool LLParser::ParseMDNodeID(MDNode *&Result, unsigned &SlotNo) { + // !{ ..., !42, ... } + if (ParseUInt32(SlotNo)) return true; + + // Check existing MDNode. + if (SlotNo < NumberedMetadata.size() && NumberedMetadata[SlotNo] != 0) + Result = NumberedMetadata[SlotNo]; + else + Result = 0; + return false; +} + bool LLParser::ParseMDNodeID(MDNode *&Result) { // !{ ..., !42, ... } unsigned MID = 0; - if (ParseUInt32(MID)) return true; + if (ParseMDNodeID(Result, MID)) return true; - // Check existing MDNode. - if (MID < NumberedMetadata.size() && NumberedMetadata[MID] != 0) { - Result = NumberedMetadata[MID]; - return false; - } + // If not a forward reference, just return it now. + if (Result) return false; - // Create MDNode forward reference. + // Otherwise, create MDNode forward reference. // FIXME: This is not unique enough! std::string FwdRefName = "llvm.mdnode.fwdref." + utostr(MID); @@ -1078,9 +1111,7 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { /// ParseInstructionMetadata /// ::= !dbg !42 (',' !dbg !57)* -bool LLParser:: -ParseInstructionMetadata(SmallVectorImpl<std::pair<unsigned, - MDNode *> > &Result){ +bool LLParser::ParseInstructionMetadata(Instruction *Inst) { do { if (Lex.getKind() != lltok::MetadataVar) return TokError("expected metadata after comma"); @@ -1089,12 +1120,21 @@ ParseInstructionMetadata(SmallVectorImpl<std::pair<unsigned, Lex.Lex(); MDNode *Node; + unsigned NodeID; + SMLoc Loc = Lex.getLoc(); if (ParseToken(lltok::exclaim, "expected '!' here") || - ParseMDNodeID(Node)) + ParseMDNodeID(Node, NodeID)) return true; unsigned MDK = M->getMDKindID(Name.c_str()); - Result.push_back(std::make_pair(MDK, Node)); + if (Node) { + // If we got the node, add it to the instruction. + Inst->setMetadata(MDK, Node); + } else { + MDRef R = { Loc, MDK, NodeID }; + // Otherwise, remember that this should be resolved later. + ForwardRefInstMetadata[Inst].push_back(R); + } // If this is the end of the list, we're done. } while (EatIfPresent(lltok::comma)); @@ -2896,22 +2936,17 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { // With a normal result, we check to see if the instruction is followed by // a comma and metadata. if (EatIfPresent(lltok::comma)) - if (ParseInstructionMetadata(MetadataOnInst)) + if (ParseInstructionMetadata(Inst)) return true; break; case InstExtraComma: // If the instruction parser ate an extra comma at the end of it, it // *must* be followed by metadata. - if (ParseInstructionMetadata(MetadataOnInst)) + if (ParseInstructionMetadata(Inst)) return true; break; } - // Set metadata attached with this instruction. - for (unsigned i = 0, e = MetadataOnInst.size(); i != e; ++i) - Inst->setMetadata(MetadataOnInst[i].first, MetadataOnInst[i].second); - MetadataOnInst.clear(); - BB->getInstList().push_back(Inst); // Set the name on the instruction. |