diff options
author | Devang Patel <dpatel@apple.com> | 2009-07-08 19:23:54 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2009-07-08 19:23:54 +0000 |
commit | 1c7eea60d3cbada2bae54c42fa178078a3ace9b3 (patch) | |
tree | 3c6d1e99703f2abbca80d33853e256ffaf0f5432 | |
parent | 59ae6b99872953761dfda5984801d23a66692673 (diff) | |
download | external_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.cpp | 35 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.h | 2 | ||||
-rw-r--r-- | test/Feature/mdnode4.ll | 5 |
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} |