aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2009-07-08 19:23:54 +0000
committerDevang Patel <dpatel@apple.com>2009-07-08 19:23:54 +0000
commit1c7eea60d3cbada2bae54c42fa178078a3ace9b3 (patch)
tree3c6d1e99703f2abbca80d33853e256ffaf0f5432
parent59ae6b99872953761dfda5984801d23a66692673 (diff)
downloadexternal_llvm-1c7eea60d3cbada2bae54c42fa178078a3ace9b3.zip
external_llvm-1c7eea60d3cbada2bae54c42fa178078a3ace9b3.tar.gz
external_llvm-1c7eea60d3cbada2bae54c42fa178078a3ace9b3.tar.bz2
Support MDNode forward reference.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75031 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AsmParser/LLParser.cpp35
-rw-r--r--lib/AsmParser/LLParser.h2
-rw-r--r--test/Feature/mdnode4.ll5
3 files changed, 39 insertions, 3 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 3927cf1..44eb5b8 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -84,6 +84,12 @@ bool LLParser::ValidateEndOfModule() {
"use of undefined value '@" +
utostr(ForwardRefValIDs.begin()->first) + "'");
+ if (!ForwardRefMDNodes.empty())
+ return Error(ForwardRefMDNodes.begin()->second.second,
+ "use of undefined metadata '!" +
+ utostr(ForwardRefMDNodes.begin()->first) + "'");
+
+
// Look for intrinsic functions and CallInst that need to be upgraded
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove
@@ -382,6 +388,14 @@ bool LLParser::ParseStandaloneMetadata() {
return true;
MetadataCache[MetadataID] = Init;
+ std::map<unsigned, std::pair<Constant *, LocTy> >::iterator
+ FI = ForwardRefMDNodes.find(MetadataID);
+ if (FI != ForwardRefMDNodes.end()) {
+ Constant *FwdNode = FI->second.first;
+ FwdNode->replaceAllUsesWith(Init);
+ ForwardRefMDNodes.erase(FI);
+ }
+
return false;
}
@@ -1632,9 +1646,24 @@ bool LLParser::ParseValID(ValID &ID) {
unsigned MID = 0;
if (!ParseUInt32(MID)) {
std::map<unsigned, Constant *>::iterator I = MetadataCache.find(MID);
- if (I == MetadataCache.end())
- return TokError("Unknown metadata reference");
- ID.ConstantVal = I->second;
+ if (I != MetadataCache.end())
+ ID.ConstantVal = I->second;
+ else {
+ std::map<unsigned, std::pair<Constant *, LocTy> >::iterator
+ FI = ForwardRefMDNodes.find(MID);
+ if (FI != ForwardRefMDNodes.end())
+ ID.ConstantVal = FI->second.first;
+ else {
+ // Create MDNode forward reference
+ SmallVector<Value *, 1> Elts;
+ std::string FwdRefName = "llvm.mdnode.fwdref." + MID;
+ Elts.push_back(Context.getMDString(FwdRefName));
+ MDNode *FwdNode = Context.getMDNode(Elts.data(), Elts.size());
+ ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
+ ID.ConstantVal = FwdNode;
+ }
+ }
+
return false;
}
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 1f053c2..30a49cd 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -46,6 +46,8 @@ namespace llvm {
std::vector<PATypeHolder> NumberedTypes;
/// MetadataCache - This map keeps track of parsed metadata constants.
std::map<unsigned, Constant *> MetadataCache;
+ std::map<unsigned, std::pair<Constant *, LocTy> > ForwardRefMDNodes;
+
struct UpRefRecord {
/// Loc - This is the location of the upref.
LocTy Loc;
diff --git a/test/Feature/mdnode4.ll b/test/Feature/mdnode4.ll
new file mode 100644
index 0000000..c054949
--- /dev/null
+++ b/test/Feature/mdnode4.ll
@@ -0,0 +1,5 @@
+; Test forward MDNode reference
+; RUN: llvm-as < %s | llvm-dis -f -o /dev/null
+
+@llvm.blah = constant metadata !{metadata !1}
+!1 = constant metadata !{i32 23, i32 24}