aboutsummaryrefslogtreecommitdiff
path: root/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-04-02 08:54:30 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-04-02 08:54:30 +0000
commit104bd8179fb5f6551c65c94ebcd0a4918b060189 (patch)
treecf5763d092b81cecc168fa28032247ee495d06e2 /lib/AsmParser/LLParser.cpp
parent2f12f10af369d468b14617276446166383d692ed (diff)
downloadsrc-104bd8179fb5f6551c65c94ebcd0a4918b060189.tar.gz
src-104bd8179fb5f6551c65c94ebcd0a4918b060189.zip
Update LLVM to r100181.
Notes
Notes: svn path=/vendor/llvm/dist/; revision=206083
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
-rw-r--r--lib/AsmParser/LLParser.cpp73
1 files changed, 54 insertions, 19 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 8083a07fdbcd..cdad0770a38a 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.