diff options
author | Stephen Hines <srhines@google.com> | 2015-03-23 12:10:34 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2015-03-23 12:10:34 -0700 |
commit | ebe69fe11e48d322045d5949c83283927a0d790b (patch) | |
tree | c92f1907a6b8006628a4b01615f38264d29834ea /lib/AsmParser | |
parent | b7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff) | |
download | external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.zip external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.gz external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.bz2 |
Update aosp/master LLVM for rebase to r230699.
Change-Id: I2b5be30509658cb8266be782de0ab24f9099f9b9
Diffstat (limited to 'lib/AsmParser')
-rw-r--r-- | lib/AsmParser/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 168 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.h | 1 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 1236 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.h | 48 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 14 | ||||
-rw-r--r-- | lib/AsmParser/Parser.cpp | 2 |
7 files changed, 1206 insertions, 266 deletions
diff --git a/lib/AsmParser/CMakeLists.txt b/lib/AsmParser/CMakeLists.txt index 985ebe2..7866837 100644 --- a/lib/AsmParser/CMakeLists.txt +++ b/lib/AsmParser/CMakeLists.txt @@ -3,4 +3,7 @@ add_llvm_library(LLVMAsmParser LLLexer.cpp LLParser.cpp Parser.cpp + + ADDITIONAL_HEADER_DIRS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/Analysis ) diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 6523bce..3bf090a 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -78,13 +78,15 @@ uint64_t LLLexer::HexIntToVal(const char *Buffer, const char *End) { void LLLexer::HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]) { Pair[0] = 0; - for (int i=0; i<16; i++, Buffer++) { - assert(Buffer != End); - Pair[0] *= 16; - Pair[0] += hexDigitValue(*Buffer); + if (End - Buffer >= 16) { + for (int i = 0; i < 16; i++, Buffer++) { + assert(Buffer != End); + Pair[0] *= 16; + Pair[0] += hexDigitValue(*Buffer); + } } Pair[1] = 0; - for (int i=0; i<16 && Buffer != End; i++, Buffer++) { + for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) { Pair[1] *= 16; Pair[1] += hexDigitValue(*Buffer); } @@ -239,7 +241,7 @@ lltok::Kind LLLexer::LexToken() { case ')': return lltok::rparen; case ',': return lltok::comma; case '*': return lltok::star; - case '\\': return lltok::backslash; + case '|': return lltok::bar; } } @@ -255,46 +257,7 @@ void LLLexer::SkipLineComment() { /// GlobalVar @[-a-zA-Z$._][-a-zA-Z$._0-9]* /// GlobalVarID @[0-9]+ lltok::Kind LLLexer::LexAt() { - // Handle AtStringConstant: @\"[^\"]*\" - if (CurPtr[0] == '"') { - ++CurPtr; - - while (1) { - int CurChar = getNextChar(); - - if (CurChar == EOF) { - Error("end of file in global variable name"); - return lltok::Error; - } - if (CurChar == '"') { - StrVal.assign(TokStart+2, CurPtr-1); - UnEscapeLexed(StrVal); - if (StringRef(StrVal).find_first_of(0) != StringRef::npos) { - Error("Null bytes are not allowed in names"); - return lltok::Error; - } - return lltok::GlobalVar; - } - } - } - - // Handle GlobalVarName: @[-a-zA-Z$._][-a-zA-Z$._0-9]* - if (ReadVarName()) - return lltok::GlobalVar; - - // Handle GlobalVarID: @[0-9]+ - if (isdigit(static_cast<unsigned char>(CurPtr[0]))) { - for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr) - /*empty*/; - - uint64_t Val = atoull(TokStart+1, CurPtr); - if ((unsigned)Val != Val) - Error("invalid value number (too large)!"); - UIntVal = unsigned(Val); - return lltok::GlobalID; - } - - return lltok::Error; + return LexVar(lltok::GlobalVar, lltok::GlobalID); } lltok::Kind LLLexer::LexDollar() { @@ -370,22 +333,35 @@ bool LLLexer::ReadVarName() { return false; } -/// LexPercent - Lex all tokens that start with a % character: -/// LocalVar ::= %\"[^\"]*\" -/// LocalVar ::= %[-a-zA-Z$._][-a-zA-Z$._0-9]* -/// LocalVarID ::= %[0-9]+ -lltok::Kind LLLexer::LexPercent() { - // Handle LocalVarName: %\"[^\"]*\" +lltok::Kind LLLexer::LexVar(lltok::Kind Var, lltok::Kind VarID) { + // Handle StringConstant: \"[^\"]*\" if (CurPtr[0] == '"') { ++CurPtr; - return ReadString(lltok::LocalVar); + + while (1) { + int CurChar = getNextChar(); + + if (CurChar == EOF) { + Error("end of file in global variable name"); + return lltok::Error; + } + if (CurChar == '"') { + StrVal.assign(TokStart+2, CurPtr-1); + UnEscapeLexed(StrVal); + if (StringRef(StrVal).find_first_of(0) != StringRef::npos) { + Error("Null bytes are not allowed in names"); + return lltok::Error; + } + return Var; + } + } } - // Handle LocalVarName: %[-a-zA-Z$._][-a-zA-Z$._0-9]* + // Handle VarName: [-a-zA-Z$._][-a-zA-Z$._0-9]* if (ReadVarName()) - return lltok::LocalVar; + return Var; - // Handle LocalVarID: %[0-9]+ + // Handle VarID: [0-9]+ if (isdigit(static_cast<unsigned char>(CurPtr[0]))) { for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr) /*empty*/; @@ -394,12 +370,19 @@ lltok::Kind LLLexer::LexPercent() { if ((unsigned)Val != Val) Error("invalid value number (too large)!"); UIntVal = unsigned(Val); - return lltok::LocalVarID; + return VarID; } - return lltok::Error; } +/// LexPercent - Lex all tokens that start with a % character: +/// LocalVar ::= %\"[^\"]*\" +/// LocalVar ::= %[-a-zA-Z$._][-a-zA-Z$._0-9]* +/// LocalVarID ::= %[0-9]+ +lltok::Kind LLLexer::LexPercent() { + return LexVar(lltok::LocalVar, lltok::LocalVarID); +} + /// LexQuote - Lex all tokens that start with a " character: /// QuoteLabel "[^"]+": /// StringConstant "[^"]*" @@ -410,7 +393,12 @@ lltok::Kind LLLexer::LexQuote() { if (CurPtr[0] == ':') { ++CurPtr; - kind = lltok::LabelStr; + if (StringRef(StrVal).find_first_of(0) != StringRef::npos) { + Error("Null bytes are not allowed in names"); + kind = lltok::Error; + } else { + kind = lltok::LabelStr; + } } return kind; @@ -499,11 +487,11 @@ lltok::Kind LLLexer::LexIdentifier() { if (!KeywordEnd) KeywordEnd = CurPtr; CurPtr = KeywordEnd; --StartChar; - unsigned Len = CurPtr-StartChar; -#define KEYWORD(STR) \ - do { \ - if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR))) \ - return lltok::kw_##STR; \ + StringRef Keyword(StartChar, CurPtr - StartChar); +#define KEYWORD(STR) \ + do { \ + if (Keyword == #STR) \ + return lltok::kw_##STR; \ } while (0) KEYWORD(true); KEYWORD(false); @@ -573,6 +561,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(inteldialect); KEYWORD(gc); KEYWORD(prefix); + KEYWORD(prologue); KEYWORD(ccc); KEYWORD(fastcc); @@ -596,6 +585,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(anyregcc); KEYWORD(preserve_mostcc); KEYWORD(preserve_allcc); + KEYWORD(ghccc); KEYWORD(cc); KEYWORD(c); @@ -665,6 +655,9 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(x); KEYWORD(blockaddress); + // Metadata types. + KEYWORD(distinct); + // Use-list order directives. KEYWORD(uselistorder); KEYWORD(uselistorder_bb); @@ -676,9 +669,13 @@ lltok::Kind LLLexer::LexIdentifier() { #undef KEYWORD // Keywords for types. -#define TYPEKEYWORD(STR, LLVMTY) \ - if (Len == strlen(STR) && !memcmp(StartChar, STR, strlen(STR))) { \ - TyVal = LLVMTY; return lltok::Type; } +#define TYPEKEYWORD(STR, LLVMTY) \ + do { \ + if (Keyword == STR) { \ + TyVal = LLVMTY; \ + return lltok::Type; \ + } \ + } while (false) TYPEKEYWORD("void", Type::getVoidTy(Context)); TYPEKEYWORD("half", Type::getHalfTy(Context)); TYPEKEYWORD("float", Type::getFloatTy(Context)); @@ -692,9 +689,13 @@ lltok::Kind LLLexer::LexIdentifier() { #undef TYPEKEYWORD // Keywords for instructions. -#define INSTKEYWORD(STR, Enum) \ - if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR))) { \ - UIntVal = Instruction::Enum; return lltok::kw_##STR; } +#define INSTKEYWORD(STR, Enum) \ + do { \ + if (Keyword == #STR) { \ + UIntVal = Instruction::Enum; \ + return lltok::kw_##STR; \ + } \ + } while (false) INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd); INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub); @@ -746,6 +747,25 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(landingpad, LandingPad); #undef INSTKEYWORD +#define DWKEYWORD(TYPE, TOKEN) \ + do { \ + if (Keyword.startswith("DW_" #TYPE "_")) { \ + StrVal.assign(Keyword.begin(), Keyword.end()); \ + return lltok::TOKEN; \ + } \ + } while (false) + DWKEYWORD(TAG, DwarfTag); + DWKEYWORD(ATE, DwarfAttEncoding); + DWKEYWORD(VIRTUALITY, DwarfVirtuality); + DWKEYWORD(LANG, DwarfLang); + DWKEYWORD(OP, DwarfOp); +#undef DWKEYWORD + + if (Keyword.startswith("DIFlag")) { + StrVal.assign(Keyword.begin(), Keyword.end()); + return lltok::DIFlag; + } + // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by // the CFE to avoid forcing it to deal with 64-bit numbers. if ((TokStart[0] == 'u' || TokStart[0] == 's') && @@ -753,7 +773,13 @@ lltok::Kind LLLexer::LexIdentifier() { isxdigit(static_cast<unsigned char>(TokStart[3]))) { int len = CurPtr-TokStart-3; uint32_t bits = len * 4; - APInt Tmp(bits, StringRef(TokStart+3, len), 16); + StringRef HexStr(TokStart + 3, len); + if (!std::all_of(HexStr.begin(), HexStr.end(), isxdigit)) { + // Bad token, return it as an error. + CurPtr = TokStart+3; + return lltok::Error; + } + APInt Tmp(bits, HexStr, 16); uint32_t activeBits = Tmp.getActiveBits(); if (activeBits > 0 && activeBits < bits) Tmp = Tmp.trunc(activeBits); diff --git a/lib/AsmParser/LLLexer.h b/lib/AsmParser/LLLexer.h index 219827f..3343168 100644 --- a/lib/AsmParser/LLLexer.h +++ b/lib/AsmParser/LLLexer.h @@ -82,6 +82,7 @@ namespace llvm { lltok::Kind LexDollar(); lltok::Kind LexExclaim(); lltok::Kind LexPercent(); + lltok::Kind LexVar(lltok::Kind Var, lltok::Kind VarID); lltok::Kind LexQuote(); lltok::Kind Lex0x(); lltok::Kind LexHash(); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 2c835f9..9e7354e 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -16,6 +16,8 @@ #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" @@ -23,6 +25,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/IR/ValueSymbolTable.h" +#include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" @@ -47,27 +50,6 @@ 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] == nullptr) - return Error(MDList[i].Loc, "use of undefined metadata '!" + - Twine(SlotNo) + "'"); - Inst->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]); - } - } - ForwardRefInstMetadata.clear(); - } - for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++) UpgradeInstWithTBAATag(InstsWithTBAATag[I]); @@ -136,10 +118,10 @@ bool LLParser::ValidateEndOfModule() { return Error(ForwardRefBlockAddresses.begin()->first.Loc, "expected function name in blockaddress"); - for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) - if (NumberedTypes[i].second.isValid()) - return Error(NumberedTypes[i].second, - "use of undefined type '%" + Twine(i) + "'"); + for (const auto &NT : NumberedTypes) + if (NT.second.second.isValid()) + return Error(NT.second.second, + "use of undefined type '%" + Twine(NT.first) + "'"); for (StringMap<std::pair<Type*, LocTy> >::iterator I = NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) @@ -167,6 +149,11 @@ bool LLParser::ValidateEndOfModule() { "use of undefined metadata '!" + Twine(ForwardRefMDNodes.begin()->first) + "'"); + // Resolve metadata cycles. + for (auto &N : NumberedMetadata) { + if (N.second && !N.second->isResolved()) + N.second->resolveCycles(); + } // Look for intrinsic functions and CallInst that need to be upgraded for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) @@ -319,9 +306,6 @@ bool LLParser::ParseUnnamedType() { ParseToken(lltok::kw_type, "expected 'type' after '='")) return true; - if (TypeID >= NumberedTypes.size()) - NumberedTypes.resize(TypeID+1); - Type *Result = nullptr; if (ParseStructDefinition(TypeLoc, "", NumberedTypes[TypeID], Result)) return true; @@ -535,37 +519,24 @@ 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] != nullptr) - Result = NumberedMetadata[SlotNo]; - else - Result = nullptr; - return false; -} - bool LLParser::ParseMDNodeID(MDNode *&Result) { // !{ ..., !42, ... } unsigned MID = 0; - if (ParseMDNodeID(Result, MID)) return true; + if (ParseUInt32(MID)) + return true; // If not a forward reference, just return it now. - if (Result) return false; + if (NumberedMetadata.count(MID)) { + Result = NumberedMetadata[MID]; + return false; + } // Otherwise, create MDNode forward reference. - MDNode *FwdNode = MDNode::getTemporary(Context, None); - ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc()); + auto &FwdRef = ForwardRefMDNodes[MID]; + FwdRef = std::make_pair(MDTuple::getTemporary(Context, None), Lex.getLoc()); - if (NumberedMetadata.size() <= MID) - NumberedMetadata.resize(MID+1); - NumberedMetadata[MID] = FwdNode; - Result = FwdNode; + Result = FwdRef.first.get(); + NumberedMetadata[MID].reset(Result); return false; } @@ -605,37 +576,34 @@ bool LLParser::ParseStandaloneMetadata() { Lex.Lex(); unsigned MetadataID = 0; - LocTy TyLoc; - Type *Ty = nullptr; - SmallVector<Value *, 16> Elts; + MDNode *Init; if (ParseUInt32(MetadataID) || - ParseToken(lltok::equal, "expected '=' here") || - ParseType(Ty, TyLoc) || - ParseToken(lltok::exclaim, "Expected '!' here") || - ParseToken(lltok::lbrace, "Expected '{' here") || - ParseMDNodeVector(Elts, nullptr) || - ParseToken(lltok::rbrace, "expected end of metadata node")) + ParseToken(lltok::equal, "expected '=' here")) return true; - MDNode *Init = MDNode::get(Context, Elts); + // Detect common error, from old metadata syntax. + if (Lex.getKind() == lltok::Type) + return TokError("unexpected type in metadata definition"); + + bool IsDistinct = EatIfPresent(lltok::kw_distinct); + if (Lex.getKind() == lltok::MetadataVar) { + if (ParseSpecializedMDNode(Init, IsDistinct)) + return true; + } else if (ParseToken(lltok::exclaim, "Expected '!' here") || + ParseMDTuple(Init, IsDistinct)) + return true; // See if this was forward referenced, if so, handle it. - std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator - FI = ForwardRefMDNodes.find(MetadataID); + auto FI = ForwardRefMDNodes.find(MetadataID); if (FI != ForwardRefMDNodes.end()) { - MDNode *Temp = FI->second.first; - Temp->replaceAllUsesWith(Init); - MDNode::deleteTemporary(Temp); + FI->second.first->replaceAllUsesWith(Init); ForwardRefMDNodes.erase(FI); assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work"); } else { - if (MetadataID >= NumberedMetadata.size()) - NumberedMetadata.resize(MetadataID+1); - - if (NumberedMetadata[MetadataID] != nullptr) + if (NumberedMetadata.count(MetadataID)) return TokError("Metadata id is already used"); - NumberedMetadata[MetadataID] = Init; + NumberedMetadata[MetadataID].reset(Init); } return false; @@ -782,36 +750,39 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, return true; } - if (Ty->isFunctionTy() || Ty->isLabelTy()) + if (Ty->isFunctionTy() || !PointerType::isValidElementType(Ty)) return Error(TyLoc, "invalid type for global variable"); - GlobalVariable *GV = nullptr; + GlobalValue *GVal = nullptr; // See if the global was forward referenced, if so, use the global. if (!Name.empty()) { - if (GlobalValue *GVal = M->getNamedValue(Name)) { + GVal = M->getNamedValue(Name); + if (GVal) { if (!ForwardRefVals.erase(Name) || !isa<GlobalValue>(GVal)) return Error(NameLoc, "redefinition of global '@" + Name + "'"); - GV = cast<GlobalVariable>(GVal); } } else { std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator I = ForwardRefValIDs.find(NumberedVals.size()); if (I != ForwardRefValIDs.end()) { - GV = cast<GlobalVariable>(I->second.first); + GVal = I->second.first; ForwardRefValIDs.erase(I); } } - if (!GV) { + GlobalVariable *GV; + if (!GVal) { GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, nullptr, Name, nullptr, GlobalVariable::NotThreadLocal, AddrSpace); } else { - if (GV->getType()->getElementType() != Ty) + if (GVal->getType()->getElementType() != Ty) return Error(TyLoc, "forward reference and definition of global have different types"); + GV = cast<GlobalVariable>(GVal); + // Move the forward-reference to the correct spot in the module. M->getGlobalList().splice(M->global_end(), M->getGlobalList(), GV); } @@ -845,7 +816,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, GV->setAlignment(Alignment); } else { Comdat *C; - if (parseOptionalComdat(C)) + if (parseOptionalComdat(Name, C)) return true; if (C) GV->setComdat(C); @@ -864,7 +835,9 @@ bool LLParser::ParseUnnamedAttrGrp() { LocTy AttrGrpLoc = Lex.getLoc(); Lex.Lex(); - assert(Lex.getKind() == lltok::AttrGrpID); + if (Lex.getKind() != lltok::AttrGrpID) + return TokError("expected attribute group id"); + unsigned VarID = Lex.getUIntVal(); std::vector<unsigned> unused; LocTy BuiltinLoc; @@ -1443,7 +1416,7 @@ bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) { /// ::= /*empty*/ /// ::= 'ccc' /// ::= 'fastcc' -/// ::= 'kw_intel_ocl_bicc' +/// ::= 'intel_ocl_bicc' /// ::= 'coldcc' /// ::= 'x86_stdcallcc' /// ::= 'x86_fastcallcc' @@ -1463,6 +1436,7 @@ bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) { /// ::= 'anyregcc' /// ::= 'preserve_mostcc' /// ::= 'preserve_allcc' +/// ::= 'ghccc' /// ::= 'cc' UINT /// bool LLParser::ParseOptionalCallingConv(unsigned &CC) { @@ -1490,6 +1464,7 @@ bool LLParser::ParseOptionalCallingConv(unsigned &CC) { case lltok::kw_anyregcc: CC = CallingConv::AnyReg; break; case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break; case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break; + case lltok::kw_ghccc: CC = CallingConv::GHC; break; case lltok::kw_cc: { Lex.Lex(); return ParseUInt32(CC); @@ -1512,36 +1487,11 @@ bool LLParser::ParseInstructionMetadata(Instruction *Inst, unsigned MDK = M->getMDKindID(Name); Lex.Lex(); - MDNode *Node; - SMLoc Loc = Lex.getLoc(); - - if (ParseToken(lltok::exclaim, "expected '!' here")) + MDNode *N; + if (ParseMDNode(N)) return true; - // This code is similar to that of ParseMetadataValue, however it needs to - // have special-case code for a forward reference; see the comments on - // ForwardRefInstMetadata for details. Also, MDStrings are not supported - // at the top level here. - if (Lex.getKind() == lltok::lbrace) { - ValID ID; - if (ParseMetadataListValue(ID, PFS)) - return true; - assert(ID.Kind == ValID::t_MDNode); - Inst->setMetadata(MDK, ID.MDNodeVal); - } else { - unsigned NodeID = 0; - if (ParseMDNodeID(Node, NodeID)) - return true; - 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); - } - } - + Inst->setMetadata(MDK, N); if (MDK == LLVMContext::MD_tbaa) InstsWithTBAATag.push_back(Inst); @@ -1684,6 +1634,7 @@ bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices, while (EatIfPresent(lltok::comma)) { if (Lex.getKind() == lltok::MetadataVar) { + if (Indices.empty()) return TokError("expected index"); AteExtraComma = true; return false; } @@ -1700,11 +1651,11 @@ bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices, //===----------------------------------------------------------------------===// /// ParseType - Parse a type. -bool LLParser::ParseType(Type *&Result, bool AllowVoid) { +bool LLParser::ParseType(Type *&Result, const Twine &Msg, bool AllowVoid) { SMLoc TypeLoc = Lex.getLoc(); switch (Lex.getKind()) { default: - return TokError("expected type"); + return TokError(Msg); case lltok::Type: // Type ::= 'float' | 'void' (etc) Result = Lex.getTyVal(); @@ -1748,8 +1699,6 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { case lltok::LocalVarID: { // Type ::= %4 - if (Lex.getUIntVal() >= NumberedTypes.size()) - NumberedTypes.resize(Lex.getUIntVal()+1); std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()]; // If the type hasn't been defined yet, create a forward definition and @@ -1848,9 +1797,14 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, if (ParseType(ArgTy, ArgLoc)) return true; - // Otherwise, handle normal operands. - if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS)) - return true; + if (ArgTy->isMetadataTy()) { + if (ParseMetadataAsValue(V, PFS)) + return true; + } else { + // Otherwise, handle normal operands. + if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS)) + return true; + } ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(), AttrIndex++, ArgAttrs))); @@ -2383,8 +2337,6 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ID.StrVal = Lex.getStrVal(); ID.Kind = ValID::t_LocalName; break; - case lltok::exclaim: // !42, !{...}, or !"foo" - return ParseMetadataValue(ID, PFS); case lltok::APSInt: ID.APSIntVal = Lex.getAPSIntVal(); ID.Kind = ValID::t_APSInt; @@ -2657,8 +2609,15 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; if (!Val0->getType()->isAggregateType()) return Error(ID.Loc, "insertvalue operand must be aggregate type"); - if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices)) + Type *IndexedType = + ExtractValueInst::getIndexedType(Val0->getType(), Indices); + if (!IndexedType) return Error(ID.Loc, "invalid indices for insertvalue"); + if (IndexedType != Val1->getType()) + return Error(ID.Loc, "insertvalue operand and field disagree in type: '" + + getTypeString(Val1->getType()) + + "' instead of '" + getTypeString(IndexedType) + + "'"); ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1, Indices); ID.Kind = ValID::t_Constant; return false; @@ -2824,11 +2783,33 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (Opc == Instruction::GetElementPtr) { if (Elts.size() == 0 || !Elts[0]->getType()->getScalarType()->isPointerTy()) - return Error(ID.Loc, "getelementptr requires pointer operand"); + return Error(ID.Loc, "base of getelementptr must be a pointer"); + + Type *BaseType = Elts[0]->getType(); + auto *BasePointerType = cast<PointerType>(BaseType->getScalarType()); ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); + for (Constant *Val : Indices) { + Type *ValTy = Val->getType(); + if (!ValTy->getScalarType()->isIntegerTy()) + return Error(ID.Loc, "getelementptr index must be an integer"); + if (ValTy->isVectorTy() != BaseType->isVectorTy()) + return Error(ID.Loc, "getelementptr index type missmatch"); + if (ValTy->isVectorTy()) { + unsigned ValNumEl = cast<VectorType>(ValTy)->getNumElements(); + unsigned PtrNumEl = cast<VectorType>(BaseType)->getNumElements(); + if (ValNumEl != PtrNumEl) + return Error( + ID.Loc, + "getelementptr vector index has a wrong number of elements"); + } + } + + if (!Indices.empty() && !BasePointerType->getElementType()->isSized()) + return Error(ID.Loc, "base element of getelementptr must be sized"); + if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), Indices)) - return Error(ID.Loc, "invalid indices for getelementptr"); + return Error(ID.Loc, "invalid getelementptr indices"); ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], Indices, InBounds); } else if (Opc == Instruction::Select) { @@ -2888,16 +2869,26 @@ bool LLParser::ParseGlobalTypeAndValue(Constant *&V) { ParseGlobalValue(Ty, V); } -bool LLParser::parseOptionalComdat(Comdat *&C) { +bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) { C = nullptr; + + LocTy KwLoc = Lex.getLoc(); if (!EatIfPresent(lltok::kw_comdat)) return false; - if (Lex.getKind() != lltok::ComdatVar) - return TokError("expected comdat variable"); - LocTy Loc = Lex.getLoc(); - StringRef Name = Lex.getStrVal(); - C = getComdat(Name, Loc); - Lex.Lex(); + + if (EatIfPresent(lltok::lparen)) { + if (Lex.getKind() != lltok::ComdatVar) + return TokError("expected comdat variable"); + C = getComdat(Lex.getStrVal(), Lex.getLoc()); + Lex.Lex(); + if (ParseToken(lltok::rparen, "expected ')' after comdat var")) + return true; + } else { + if (GlobalName.empty()) + return TokError("comdat cannot be unnamed"); + C = getComdat(GlobalName, KwLoc); + } + return false; } @@ -2924,45 +2915,921 @@ bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) { return false; } -bool LLParser::ParseMetadataListValue(ValID &ID, PerFunctionState *PFS) { - assert(Lex.getKind() == lltok::lbrace); - Lex.Lex(); - - SmallVector<Value*, 16> Elts; - if (ParseMDNodeVector(Elts, PFS) || - ParseToken(lltok::rbrace, "expected end of metadata node")) +bool LLParser::ParseMDTuple(MDNode *&MD, bool IsDistinct) { + SmallVector<Metadata *, 16> Elts; + if (ParseMDNodeVector(Elts)) return true; - ID.MDNodeVal = MDNode::get(Context, Elts); - ID.Kind = ValID::t_MDNode; + MD = (IsDistinct ? MDTuple::getDistinct : MDTuple::get)(Context, Elts); return false; } -/// ParseMetadataValue -/// ::= !42 -/// ::= !{...} -/// ::= !"string" -bool LLParser::ParseMetadataValue(ValID &ID, PerFunctionState *PFS) { - assert(Lex.getKind() == lltok::exclaim); - Lex.Lex(); +/// MDNode: +/// ::= !{ ... } +/// ::= !7 +/// ::= !MDLocation(...) +bool LLParser::ParseMDNode(MDNode *&N) { + if (Lex.getKind() == lltok::MetadataVar) + return ParseSpecializedMDNode(N); - // MDNode: + return ParseToken(lltok::exclaim, "expected '!' here") || + ParseMDNodeTail(N); +} + +bool LLParser::ParseMDNodeTail(MDNode *&N) { // !{ ... } if (Lex.getKind() == lltok::lbrace) - return ParseMetadataListValue(ID, PFS); + return ParseMDTuple(N); - // Standalone metadata reference // !42 - if (Lex.getKind() == lltok::APSInt) { - if (ParseMDNodeID(ID.MDNodeVal)) return true; - ID.Kind = ValID::t_MDNode; + return ParseMDNodeID(N); +} + +namespace { + +/// Structure to represent an optional metadata field. +template <class FieldTy> struct MDFieldImpl { + typedef MDFieldImpl ImplTy; + FieldTy Val; + bool Seen; + + void assign(FieldTy Val) { + Seen = true; + this->Val = std::move(Val); + } + + explicit MDFieldImpl(FieldTy Default) + : Val(std::move(Default)), Seen(false) {} +}; + +struct MDUnsignedField : public MDFieldImpl<uint64_t> { + uint64_t Max; + + MDUnsignedField(uint64_t Default = 0, uint64_t Max = UINT64_MAX) + : ImplTy(Default), Max(Max) {} +}; +struct LineField : public MDUnsignedField { + LineField() : MDUnsignedField(0, UINT32_MAX) {} +}; +struct ColumnField : public MDUnsignedField { + ColumnField() : MDUnsignedField(0, UINT16_MAX) {} +}; +struct DwarfTagField : public MDUnsignedField { + DwarfTagField() : MDUnsignedField(0, dwarf::DW_TAG_hi_user) {} +}; +struct DwarfAttEncodingField : public MDUnsignedField { + DwarfAttEncodingField() : MDUnsignedField(0, dwarf::DW_ATE_hi_user) {} +}; +struct DwarfVirtualityField : public MDUnsignedField { + DwarfVirtualityField() : MDUnsignedField(0, dwarf::DW_VIRTUALITY_max) {} +}; +struct DwarfLangField : public MDUnsignedField { + DwarfLangField() : MDUnsignedField(0, dwarf::DW_LANG_hi_user) {} +}; + +struct DIFlagField : public MDUnsignedField { + DIFlagField() : MDUnsignedField(0, UINT32_MAX) {} +}; + +struct MDSignedField : public MDFieldImpl<int64_t> { + int64_t Min; + int64_t Max; + + MDSignedField(int64_t Default = 0) + : ImplTy(Default), Min(INT64_MIN), Max(INT64_MAX) {} + MDSignedField(int64_t Default, int64_t Min, int64_t Max) + : ImplTy(Default), Min(Min), Max(Max) {} +}; + +struct MDBoolField : public MDFieldImpl<bool> { + MDBoolField(bool Default = false) : ImplTy(Default) {} +}; +struct MDField : public MDFieldImpl<Metadata *> { + MDField() : ImplTy(nullptr) {} +}; +struct MDConstant : public MDFieldImpl<ConstantAsMetadata *> { + MDConstant() : ImplTy(nullptr) {} +}; +struct MDStringField : public MDFieldImpl<std::string> { + MDStringField() : ImplTy(std::string()) {} +}; +struct MDFieldList : public MDFieldImpl<SmallVector<Metadata *, 4>> { + MDFieldList() : ImplTy(SmallVector<Metadata *, 4>()) {} +}; + +} // end namespace + +namespace llvm { + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, + MDUnsignedField &Result) { + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) + return TokError("expected unsigned integer"); + + auto &U = Lex.getAPSIntVal(); + if (U.ugt(Result.Max)) + return TokError("value for '" + Name + "' too large, limit is " + + Twine(Result.Max)); + Result.assign(U.getZExtValue()); + assert(Result.Val <= Result.Max && "Expected value in range"); + Lex.Lex(); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, LineField &Result) { + return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result)); +} +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, ColumnField &Result) { + return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result)); +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) { + if (Lex.getKind() == lltok::APSInt) + return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result)); + + if (Lex.getKind() != lltok::DwarfTag) + return TokError("expected DWARF tag"); + + unsigned Tag = dwarf::getTag(Lex.getStrVal()); + if (Tag == dwarf::DW_TAG_invalid) + return TokError("invalid DWARF tag" + Twine(" '") + Lex.getStrVal() + "'"); + assert(Tag <= Result.Max && "Expected valid DWARF tag"); + + Result.assign(Tag); + Lex.Lex(); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, + DwarfVirtualityField &Result) { + if (Lex.getKind() == lltok::APSInt) + return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result)); + + if (Lex.getKind() != lltok::DwarfVirtuality) + return TokError("expected DWARF virtuality code"); + + unsigned Virtuality = dwarf::getVirtuality(Lex.getStrVal()); + if (!Virtuality) + return TokError("invalid DWARF virtuality code" + Twine(" '") + + Lex.getStrVal() + "'"); + assert(Virtuality <= Result.Max && "Expected valid DWARF virtuality code"); + Result.assign(Virtuality); + Lex.Lex(); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfLangField &Result) { + if (Lex.getKind() == lltok::APSInt) + return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result)); + + if (Lex.getKind() != lltok::DwarfLang) + return TokError("expected DWARF language"); + + unsigned Lang = dwarf::getLanguage(Lex.getStrVal()); + if (!Lang) + return TokError("invalid DWARF language" + Twine(" '") + Lex.getStrVal() + + "'"); + assert(Lang <= Result.Max && "Expected valid DWARF language"); + Result.assign(Lang); + Lex.Lex(); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, + DwarfAttEncodingField &Result) { + if (Lex.getKind() == lltok::APSInt) + return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result)); + + if (Lex.getKind() != lltok::DwarfAttEncoding) + return TokError("expected DWARF type attribute encoding"); + + unsigned Encoding = dwarf::getAttributeEncoding(Lex.getStrVal()); + if (!Encoding) + return TokError("invalid DWARF type attribute encoding" + Twine(" '") + + Lex.getStrVal() + "'"); + assert(Encoding <= Result.Max && "Expected valid DWARF language"); + Result.assign(Encoding); + Lex.Lex(); + return false; +} + +/// DIFlagField +/// ::= uint32 +/// ::= DIFlagVector +/// ::= DIFlagVector '|' DIFlagFwdDecl '|' uint32 '|' DIFlagPublic +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) { + assert(Result.Max == UINT32_MAX && "Expected only 32-bits"); + + // Parser for a single flag. + auto parseFlag = [&](unsigned &Val) { + if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) + return ParseUInt32(Val); + + if (Lex.getKind() != lltok::DIFlag) + return TokError("expected debug info flag"); + + Val = DIDescriptor::getFlag(Lex.getStrVal()); + if (!Val) + return TokError(Twine("invalid debug info flag flag '") + + Lex.getStrVal() + "'"); + Lex.Lex(); + return false; + }; + + // Parse the flags and combine them together. + unsigned Combined = 0; + do { + unsigned Val; + if (parseFlag(Val)) + return true; + Combined |= Val; + } while (EatIfPresent(lltok::bar)); + + Result.assign(Combined); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, + MDSignedField &Result) { + if (Lex.getKind() != lltok::APSInt) + return TokError("expected signed integer"); + + auto &S = Lex.getAPSIntVal(); + if (S < Result.Min) + return TokError("value for '" + Name + "' too small, limit is " + + Twine(Result.Min)); + if (S > Result.Max) + return TokError("value for '" + Name + "' too large, limit is " + + Twine(Result.Max)); + Result.assign(S.getExtValue()); + assert(Result.Val >= Result.Min && "Expected value in range"); + assert(Result.Val <= Result.Max && "Expected value in range"); + Lex.Lex(); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) { + switch (Lex.getKind()) { + default: + return TokError("expected 'true' or 'false'"); + case lltok::kw_true: + Result.assign(true); + break; + case lltok::kw_false: + Result.assign(false); + break; + } + Lex.Lex(); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) { + if (Lex.getKind() == lltok::kw_null) { + Lex.Lex(); + Result.assign(nullptr); return false; } + Metadata *MD; + if (ParseMetadata(MD, nullptr)) + return true; + + Result.assign(MD); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDConstant &Result) { + Metadata *MD; + if (ParseValueAsMetadata(MD, "expected constant", nullptr)) + return true; + + Result.assign(cast<ConstantAsMetadata>(MD)); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result) { + std::string S; + if (ParseStringConstant(S)) + return true; + + Result.assign(std::move(S)); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) { + SmallVector<Metadata *, 4> MDs; + if (ParseMDNodeVector(MDs)) + return true; + + Result.assign(std::move(MDs)); + return false; +} + +} // end namespace llvm + +template <class ParserTy> +bool LLParser::ParseMDFieldsImplBody(ParserTy parseField) { + do { + if (Lex.getKind() != lltok::LabelStr) + return TokError("expected field label here"); + + if (parseField()) + return true; + } while (EatIfPresent(lltok::comma)); + + return false; +} + +template <class ParserTy> +bool LLParser::ParseMDFieldsImpl(ParserTy parseField, LocTy &ClosingLoc) { + assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name"); + Lex.Lex(); + + if (ParseToken(lltok::lparen, "expected '(' here")) + return true; + if (Lex.getKind() != lltok::rparen) + if (ParseMDFieldsImplBody(parseField)) + return true; + + ClosingLoc = Lex.getLoc(); + return ParseToken(lltok::rparen, "expected ')' here"); +} + +template <class FieldTy> +bool LLParser::ParseMDField(StringRef Name, FieldTy &Result) { + if (Result.Seen) + return TokError("field '" + Name + "' cannot be specified more than once"); + + LocTy Loc = Lex.getLoc(); + Lex.Lex(); + return ParseMDField(Loc, Name, Result); +} + +bool LLParser::ParseSpecializedMDNode(MDNode *&N, bool IsDistinct) { + assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name"); + +#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \ + if (Lex.getStrVal() == #CLASS) \ + return Parse##CLASS(N, IsDistinct); +#include "llvm/IR/Metadata.def" + + return TokError("expected metadata type"); +} + +#define DECLARE_FIELD(NAME, TYPE, INIT) TYPE NAME INIT +#define NOP_FIELD(NAME, TYPE, INIT) +#define REQUIRE_FIELD(NAME, TYPE, INIT) \ + if (!NAME.Seen) \ + return Error(ClosingLoc, "missing required field '" #NAME "'"); +#define PARSE_MD_FIELD(NAME, TYPE, DEFAULT) \ + if (Lex.getStrVal() == #NAME) \ + return ParseMDField(#NAME, NAME); +#define PARSE_MD_FIELDS() \ + VISIT_MD_FIELDS(DECLARE_FIELD, DECLARE_FIELD) \ + do { \ + LocTy ClosingLoc; \ + if (ParseMDFieldsImpl([&]() -> bool { \ + VISIT_MD_FIELDS(PARSE_MD_FIELD, PARSE_MD_FIELD) \ + return TokError(Twine("invalid field '") + Lex.getStrVal() + "'"); \ + }, ClosingLoc)) \ + return true; \ + VISIT_MD_FIELDS(NOP_FIELD, REQUIRE_FIELD) \ + } while (false) +#define GET_OR_DISTINCT(CLASS, ARGS) \ + (IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS) + +/// ParseMDLocationFields: +/// ::= !MDLocation(line: 43, column: 8, scope: !5, inlinedAt: !6) +bool LLParser::ParseMDLocation(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(column, ColumnField, ); \ + REQUIRED(scope, MDField, ); \ + OPTIONAL(inlinedAt, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + auto get = (IsDistinct ? MDLocation::getDistinct : MDLocation::get); + Result = get(Context, line.Val, column.Val, scope.Val, inlinedAt.Val); + return false; +} + +/// ParseGenericDebugNode: +/// ::= !GenericDebugNode(tag: 15, header: "...", operands: {...}) +bool LLParser::ParseGenericDebugNode(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(tag, DwarfTagField, ); \ + OPTIONAL(header, MDStringField, ); \ + OPTIONAL(operands, MDFieldList, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(GenericDebugNode, + (Context, tag.Val, header.Val, operands.Val)); + return false; +} + +/// ParseMDSubrange: +/// ::= !MDSubrange(count: 30, lowerBound: 2) +bool LLParser::ParseMDSubrange(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(count, MDSignedField, (-1, -1, INT64_MAX)); \ + OPTIONAL(lowerBound, MDSignedField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDSubrange, (Context, count.Val, lowerBound.Val)); + return false; +} + +/// ParseMDEnumerator: +/// ::= !MDEnumerator(value: 30, name: "SomeKind") +bool LLParser::ParseMDEnumerator(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(name, MDStringField, ); \ + REQUIRED(value, MDSignedField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDEnumerator, (Context, value.Val, name.Val)); + return false; +} + +/// ParseMDBasicType: +/// ::= !MDBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32) +bool LLParser::ParseMDBasicType(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(tag, DwarfTagField, ); \ + OPTIONAL(name, MDStringField, ); \ + OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(encoding, DwarfAttEncodingField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDBasicType, (Context, tag.Val, name.Val, size.Val, + align.Val, encoding.Val)); + return false; +} + +/// ParseMDDerivedType: +/// ::= !MDDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0, +/// line: 7, scope: !1, baseType: !2, size: 32, +/// align: 32, offset: 0, flags: 0, extraData: !3) +bool LLParser::ParseMDDerivedType(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(tag, DwarfTagField, ); \ + OPTIONAL(name, MDStringField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(scope, MDField, ); \ + REQUIRED(baseType, MDField, ); \ + OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(flags, DIFlagField, ); \ + OPTIONAL(extraData, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDDerivedType, + (Context, tag.Val, name.Val, file.Val, line.Val, + scope.Val, baseType.Val, size.Val, align.Val, + offset.Val, flags.Val, extraData.Val)); + return false; +} + +bool LLParser::ParseMDCompositeType(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(tag, DwarfTagField, ); \ + OPTIONAL(name, MDStringField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(scope, MDField, ); \ + OPTIONAL(baseType, MDField, ); \ + OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(flags, DIFlagField, ); \ + OPTIONAL(elements, MDField, ); \ + OPTIONAL(runtimeLang, DwarfLangField, ); \ + OPTIONAL(vtableHolder, MDField, ); \ + OPTIONAL(templateParams, MDField, ); \ + OPTIONAL(identifier, MDStringField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT( + MDCompositeType, + (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, + size.Val, align.Val, offset.Val, flags.Val, elements.Val, + runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val)); + return false; +} + +bool LLParser::ParseMDSubroutineType(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(flags, DIFlagField, ); \ + REQUIRED(types, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDSubroutineType, (Context, flags.Val, types.Val)); + return false; +} + +/// ParseMDFileType: +/// ::= !MDFileType(filename: "path/to/file", directory: "/path/to/dir") +bool LLParser::ParseMDFile(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(filename, MDStringField, ); \ + REQUIRED(directory, MDStringField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDFile, (Context, filename.Val, directory.Val)); + return false; +} + +/// ParseMDCompileUnit: +/// ::= !MDCompileUnit(language: DW_LANG_C99, file: !0, producer: "clang", +/// isOptimized: true, flags: "-O2", runtimeVersion: 1, +/// splitDebugFilename: "abc.debug", emissionKind: 1, +/// enums: !1, retainedTypes: !2, subprograms: !3, +/// globals: !4, imports: !5) +bool LLParser::ParseMDCompileUnit(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(language, DwarfLangField, ); \ + REQUIRED(file, MDField, ); \ + OPTIONAL(producer, MDStringField, ); \ + OPTIONAL(isOptimized, MDBoolField, ); \ + OPTIONAL(flags, MDStringField, ); \ + OPTIONAL(runtimeVersion, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(splitDebugFilename, MDStringField, ); \ + OPTIONAL(emissionKind, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(enums, MDField, ); \ + OPTIONAL(retainedTypes, MDField, ); \ + OPTIONAL(subprograms, MDField, ); \ + OPTIONAL(globals, MDField, ); \ + OPTIONAL(imports, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDCompileUnit, + (Context, language.Val, file.Val, producer.Val, + isOptimized.Val, flags.Val, runtimeVersion.Val, + splitDebugFilename.Val, emissionKind.Val, enums.Val, + retainedTypes.Val, subprograms.Val, globals.Val, + imports.Val)); + return false; +} + +/// ParseMDSubprogram: +/// ::= !MDSubprogram(scope: !0, name: "foo", linkageName: "_Zfoo", +/// file: !1, line: 7, type: !2, isLocal: false, +/// isDefinition: true, scopeLine: 8, containingType: !3, +/// virtuality: DW_VIRTUALTIY_pure_virtual, +/// virtualIndex: 10, flags: 11, +/// isOptimized: false, function: void ()* @_Z3foov, +/// templateParams: !4, declaration: !5, variables: !6) +bool LLParser::ParseMDSubprogram(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(scope, MDField, ); \ + REQUIRED(name, MDStringField, ); \ + OPTIONAL(linkageName, MDStringField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(type, MDField, ); \ + OPTIONAL(isLocal, MDBoolField, ); \ + OPTIONAL(isDefinition, MDBoolField, (true)); \ + OPTIONAL(scopeLine, LineField, ); \ + OPTIONAL(containingType, MDField, ); \ + OPTIONAL(virtuality, DwarfVirtualityField, ); \ + OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(flags, DIFlagField, ); \ + OPTIONAL(isOptimized, MDBoolField, ); \ + OPTIONAL(function, MDConstant, ); \ + OPTIONAL(templateParams, MDField, ); \ + OPTIONAL(declaration, MDField, ); \ + OPTIONAL(variables, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT( + MDSubprogram, (Context, scope.Val, name.Val, linkageName.Val, file.Val, + line.Val, type.Val, isLocal.Val, isDefinition.Val, + scopeLine.Val, containingType.Val, virtuality.Val, + virtualIndex.Val, flags.Val, isOptimized.Val, function.Val, + templateParams.Val, declaration.Val, variables.Val)); + return false; +} + +/// ParseMDLexicalBlock: +/// ::= !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 9) +bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(scope, MDField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(column, ColumnField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT( + MDLexicalBlock, (Context, scope.Val, file.Val, line.Val, column.Val)); + return false; +} + +/// ParseMDLexicalBlockFile: +/// ::= !MDLexicalBlockFile(scope: !0, file: !2, discriminator: 9) +bool LLParser::ParseMDLexicalBlockFile(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(scope, MDField, ); \ + OPTIONAL(file, MDField, ); \ + REQUIRED(discriminator, MDUnsignedField, (0, UINT32_MAX)); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDLexicalBlockFile, + (Context, scope.Val, file.Val, discriminator.Val)); + return false; +} + +/// ParseMDNamespace: +/// ::= !MDNamespace(scope: !0, file: !2, name: "SomeNamespace", line: 9) +bool LLParser::ParseMDNamespace(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(scope, MDField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(name, MDStringField, ); \ + OPTIONAL(line, LineField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDNamespace, + (Context, scope.Val, file.Val, name.Val, line.Val)); + return false; +} + +/// ParseMDTemplateTypeParameter: +/// ::= !MDTemplateTypeParameter(name: "Ty", type: !1) +bool LLParser::ParseMDTemplateTypeParameter(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(name, MDStringField, ); \ + REQUIRED(type, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = + GET_OR_DISTINCT(MDTemplateTypeParameter, (Context, name.Val, type.Val)); + return false; +} + +/// ParseMDTemplateValueParameter: +/// ::= !MDTemplateValueParameter(tag: DW_TAG_template_value_parameter, +/// name: "V", type: !1, value: i32 7) +bool LLParser::ParseMDTemplateValueParameter(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(tag, DwarfTagField, ); \ + OPTIONAL(name, MDStringField, ); \ + REQUIRED(type, MDField, ); \ + REQUIRED(value, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDTemplateValueParameter, + (Context, tag.Val, name.Val, type.Val, value.Val)); + return false; +} + +/// ParseMDGlobalVariable: +/// ::= !MDGlobalVariable(scope: !0, name: "foo", linkageName: "foo", +/// file: !1, line: 7, type: !2, isLocal: false, +/// isDefinition: true, variable: i32* @foo, +/// declaration: !3) +bool LLParser::ParseMDGlobalVariable(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(scope, MDField, ); \ + REQUIRED(name, MDStringField, ); \ + OPTIONAL(linkageName, MDStringField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(type, MDField, ); \ + OPTIONAL(isLocal, MDBoolField, ); \ + OPTIONAL(isDefinition, MDBoolField, (true)); \ + OPTIONAL(variable, MDConstant, ); \ + OPTIONAL(declaration, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDGlobalVariable, + (Context, scope.Val, name.Val, linkageName.Val, + file.Val, line.Val, type.Val, isLocal.Val, + isDefinition.Val, variable.Val, declaration.Val)); + return false; +} + +/// ParseMDLocalVariable: +/// ::= !MDLocalVariable(tag: DW_TAG_arg_variable, scope: !0, name: "foo", +/// file: !1, line: 7, type: !2, arg: 2, flags: 7, +/// inlinedAt: !3) +bool LLParser::ParseMDLocalVariable(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(tag, DwarfTagField, ); \ + OPTIONAL(scope, MDField, ); \ + OPTIONAL(name, MDStringField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(type, MDField, ); \ + OPTIONAL(arg, MDUnsignedField, (0, UINT8_MAX)); \ + OPTIONAL(flags, DIFlagField, ); \ + OPTIONAL(inlinedAt, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT( + MDLocalVariable, (Context, tag.Val, scope.Val, name.Val, file.Val, + line.Val, type.Val, arg.Val, flags.Val, inlinedAt.Val)); + return false; +} + +/// ParseMDExpression: +/// ::= !MDExpression(0, 7, -1) +bool LLParser::ParseMDExpression(MDNode *&Result, bool IsDistinct) { + assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name"); + Lex.Lex(); + + if (ParseToken(lltok::lparen, "expected '(' here")) + return true; + + SmallVector<uint64_t, 8> Elements; + if (Lex.getKind() != lltok::rparen) + do { + if (Lex.getKind() == lltok::DwarfOp) { + if (unsigned Op = dwarf::getOperationEncoding(Lex.getStrVal())) { + Lex.Lex(); + Elements.push_back(Op); + continue; + } + return TokError(Twine("invalid DWARF op '") + Lex.getStrVal() + "'"); + } + + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) + return TokError("expected unsigned integer"); + + auto &U = Lex.getAPSIntVal(); + if (U.ugt(UINT64_MAX)) + return TokError("element too large, limit is " + Twine(UINT64_MAX)); + Elements.push_back(U.getZExtValue()); + Lex.Lex(); + } while (EatIfPresent(lltok::comma)); + + if (ParseToken(lltok::rparen, "expected ')' here")) + return true; + + Result = GET_OR_DISTINCT(MDExpression, (Context, Elements)); + return false; +} + +/// ParseMDObjCProperty: +/// ::= !MDObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo", +/// getter: "getFoo", attributes: 7, type: !2) +bool LLParser::ParseMDObjCProperty(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(name, MDStringField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(setter, MDStringField, ); \ + OPTIONAL(getter, MDStringField, ); \ + OPTIONAL(attributes, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(type, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDObjCProperty, + (Context, name.Val, file.Val, line.Val, setter.Val, + getter.Val, attributes.Val, type.Val)); + return false; +} + +/// ParseMDImportedEntity: +/// ::= !MDImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1, +/// line: 7, name: "foo") +bool LLParser::ParseMDImportedEntity(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(tag, DwarfTagField, ); \ + REQUIRED(scope, MDField, ); \ + OPTIONAL(entity, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(name, MDStringField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDImportedEntity, (Context, tag.Val, scope.Val, + entity.Val, line.Val, name.Val)); + return false; +} + +#undef PARSE_MD_FIELD +#undef NOP_FIELD +#undef REQUIRE_FIELD +#undef DECLARE_FIELD + +/// ParseMetadataAsValue +/// ::= metadata i32 %local +/// ::= metadata i32 @global +/// ::= metadata i32 7 +/// ::= metadata !0 +/// ::= metadata !{...} +/// ::= metadata !"string" +bool LLParser::ParseMetadataAsValue(Value *&V, PerFunctionState &PFS) { + // Note: the type 'metadata' has already been parsed. + Metadata *MD; + if (ParseMetadata(MD, &PFS)) + return true; + + V = MetadataAsValue::get(Context, MD); + return false; +} + +/// ParseValueAsMetadata +/// ::= i32 %local +/// ::= i32 @global +/// ::= i32 7 +bool LLParser::ParseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg, + PerFunctionState *PFS) { + Type *Ty; + LocTy Loc; + if (ParseType(Ty, TypeMsg, Loc)) + return true; + if (Ty->isMetadataTy()) + return Error(Loc, "invalid metadata-value-metadata roundtrip"); + + Value *V; + if (ParseValue(Ty, V, PFS)) + return true; + + MD = ValueAsMetadata::get(V); + return false; +} + +/// ParseMetadata +/// ::= i32 %local +/// ::= i32 @global +/// ::= i32 7 +/// ::= !42 +/// ::= !{...} +/// ::= !"string" +/// ::= !MDLocation(...) +bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) { + if (Lex.getKind() == lltok::MetadataVar) { + MDNode *N; + if (ParseSpecializedMDNode(N)) + return true; + MD = N; + return false; + } + + // ValueAsMetadata: + // <type> <value> + if (Lex.getKind() != lltok::exclaim) + return ParseValueAsMetadata(MD, "expected metadata operand", PFS); + + // '!'. + assert(Lex.getKind() == lltok::exclaim && "Expected '!' here"); + Lex.Lex(); + // MDString: // ::= '!' STRINGCONSTANT - if (ParseMDString(ID.MDStringVal)) return true; - ID.Kind = ValID::t_MDString; + if (Lex.getKind() == lltok::StringConstant) { + MDString *S; + if (ParseMDString(S)) + return true; + MD = S; + return false; + } + + // MDNode: + // !{ ... } + // !7 + MDNode *N; + if (ParseMDNodeTail(N)) + return true; + MD = N; return false; } @@ -2995,16 +3862,6 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, (ID.UIntVal>>1)&1, (InlineAsm::AsmDialect(ID.UIntVal>>2))); return false; } - case ValID::t_MDNode: - if (!Ty->isMetadataTy()) - return Error(ID.Loc, "metadata value must have metadata type"); - V = ID.MDNodeVal; - return false; - case ValID::t_MDString: - if (!Ty->isMetadataTy()) - return Error(ID.Loc, "metadata value must have metadata type"); - V = ID.MDStringVal; - return false; case ValID::t_GlobalName: V = GetGlobalVal(ID.StrVal, Ty, ID.Loc); return V == nullptr; @@ -3120,7 +3977,7 @@ bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, /// FunctionHeader /// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs /// OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection -/// OptionalAlign OptGC OptionalPrefix +/// OptionalAlign OptGC OptionalPrefix OptionalPrologue bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { // Parse the linkage. LocTy LinkageLoc = Lex.getLoc(); @@ -3201,6 +4058,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { bool UnnamedAddr; LocTy UnnamedAddrLoc; Constant *Prefix = nullptr; + Constant *Prologue = nullptr; Comdat *C; if (ParseArgumentList(ArgList, isVarArg) || @@ -3210,12 +4068,14 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { BuiltinLoc) || (EatIfPresent(lltok::kw_section) && ParseStringConstant(Section)) || - parseOptionalComdat(C) || + parseOptionalComdat(FunctionName, C) || ParseOptionalAlignment(Alignment) || (EatIfPresent(lltok::kw_gc) && ParseStringConstant(GC)) || (EatIfPresent(lltok::kw_prefix) && - ParseGlobalTypeAndValue(Prefix))) + ParseGlobalTypeAndValue(Prefix)) || + (EatIfPresent(lltok::kw_prologue) && + ParseGlobalTypeAndValue(Prologue))) return true; if (FuncAttrs.contains(Attribute::Builtin)) @@ -3316,6 +4176,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Fn->setComdat(C); if (!GC.empty()) Fn->setGC(GC.c_str()); Fn->setPrefixData(Prefix); + Fn->setPrologueData(Prologue); ForwardRefAttrGroups[Fn] = FwdRefAttrGrps; // Add all of the arguments we parsed to the function. @@ -3878,10 +4739,14 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs.hasAttributes()) + if (FnAttrs.hasAttributes()) { + if (FnAttrs.hasAlignmentAttr()) + return Error(CallLoc, "invoke instructions may not have an alignment"); + Attrs.push_back(AttributeSet::get(RetType->getContext(), AttributeSet::FunctionIndex, FnAttrs)); + } // Finish off the Attribute and check them AttributeSet PAL = AttributeSet::get(Context, Attrs); @@ -4291,10 +5156,14 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs.hasAttributes()) + if (FnAttrs.hasAttributes()) { + if (FnAttrs.hasAlignmentAttr()) + return Error(CallLoc, "call instructions may not have an alignment"); + Attrs.push_back(AttributeSet::get(RetType->getContext(), AttributeSet::FunctionIndex, FnAttrs)); + } // Finish off the Attribute and check them AttributeSet PAL = AttributeSet::get(Context, Attrs); @@ -4316,13 +5185,16 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, /// ::= 'alloca' 'inalloca'? Type (',' TypeAndValue)? (',' 'align' i32)? int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { Value *Size = nullptr; - LocTy SizeLoc; + LocTy SizeLoc, TyLoc; unsigned Alignment = 0; Type *Ty = nullptr; bool IsInAlloca = EatIfPresent(lltok::kw_inalloca); - if (ParseType(Ty)) return true; + if (ParseType(Ty, TyLoc)) return true; + + if (Ty->isFunctionTy() || !PointerType::isValidElementType(Ty)) + return Error(TyLoc, "invalid type for alloca"); bool AteExtraComma = false; if (EatIfPresent(lltok::comma)) { @@ -4642,8 +5514,13 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { if (!Val0->getType()->isAggregateType()) return Error(Loc0, "insertvalue operand must be aggregate type"); - if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices)) + Type *IndexedType = ExtractValueInst::getIndexedType(Val0->getType(), Indices); + if (!IndexedType) return Error(Loc0, "invalid indices for insertvalue"); + if (IndexedType != Val1->getType()) + return Error(Loc1, "insertvalue operand and field disagree in type: '" + + getTypeString(Val1->getType()) + "' instead of '" + + getTypeString(IndexedType) + "'"); Inst = InsertValueInst::Create(Val0, Val1, Indices); return AteExtraComma ? InstExtraComma : InstNormal; } @@ -4653,13 +5530,15 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { //===----------------------------------------------------------------------===// /// ParseMDNodeVector -/// ::= Element (',' Element)* +/// ::= { Element (',' Element)* } /// Element /// ::= 'null' | TypeAndValue -bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts, - PerFunctionState *PFS) { +bool LLParser::ParseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) { + if (ParseToken(lltok::lbrace, "expected '{' here")) + return true; + // Check for an empty list. - if (Lex.getKind() == lltok::rbrace) + if (EatIfPresent(lltok::rbrace)) return false; do { @@ -4669,12 +5548,13 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts, continue; } - Value *V = nullptr; - if (ParseTypeAndValue(V, PFS)) return true; - Elts.push_back(V); + Metadata *MD; + if (ParseMetadata(MD, nullptr)) + return true; + Elts.push_back(MD); } while (EatIfPresent(lltok::comma)); - return false; + return ParseToken(lltok::rbrace, "expected end of metadata node"); } //===----------------------------------------------------------------------===// diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index aa62bcc..5e92e57 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -52,8 +52,6 @@ namespace llvm { t_EmptyArray, // No value: [] t_Constant, // Value in ConstantVal. t_InlineAsm, // Value in StrVal/StrVal2/UIntVal. - t_MDNode, // Value in MDNodeVal. - t_MDString, // Value in MDStringVal. t_ConstantStruct, // Value in ConstantStructElts. t_PackedConstantStruct // Value in ConstantStructElts. } Kind; @@ -64,8 +62,6 @@ namespace llvm { APSInt APSIntVal; APFloat APFloatVal; Constant *ConstantVal; - MDNode *MDNodeVal; - MDString *MDStringVal; Constant **ConstantStructElts; ValID() : Kind(t_LocalID), APFloatVal(0.0) {} @@ -106,17 +102,16 @@ namespace llvm { SMLoc Loc; unsigned MDKind, MDSlot; }; - DenseMap<Instruction*, std::vector<MDRef> > ForwardRefInstMetadata; SmallVector<Instruction*, 64> InstsWithTBAATag; // Type resolution handling data structures. The location is set when we // have processed a use of the type but not a definition yet. StringMap<std::pair<Type*, LocTy> > NamedTypes; - std::vector<std::pair<Type*, LocTy> > NumberedTypes; + std::map<unsigned, std::pair<Type*, LocTy> > NumberedTypes; - std::vector<TrackingVH<MDNode> > NumberedMetadata; - std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> > ForwardRefMDNodes; + std::map<unsigned, TrackingMDNodeRef> NumberedMetadata; + std::map<unsigned, std::pair<TempMDTuple, LocTy>> ForwardRefMDNodes; // Global Value reference information. std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals; @@ -270,14 +265,21 @@ namespace llvm { bool ParseNamedMetadata(); bool ParseMDString(MDString *&Result); bool ParseMDNodeID(MDNode *&Result); - bool ParseMDNodeID(MDNode *&Result, unsigned &SlotNo); bool ParseUnnamedAttrGrp(); bool ParseFnAttributeValuePairs(AttrBuilder &B, std::vector<unsigned> &FwdRefAttrGrps, bool inAttrGrp, LocTy &BuiltinLoc); // Type Parsing. - bool ParseType(Type *&Result, bool AllowVoid = false); + bool ParseType(Type *&Result, const Twine &Msg, bool AllowVoid = false); + bool ParseType(Type *&Result, bool AllowVoid = false) { + return ParseType(Result, "expected type", AllowVoid); + } + bool ParseType(Type *&Result, const Twine &Msg, LocTy &Loc, + bool AllowVoid = false) { + Loc = Lex.getLoc(); + return ParseType(Result, Msg, AllowVoid); + } bool ParseType(Type *&Result, LocTy &Loc, bool AllowVoid = false) { Loc = Lex.getLoc(); return ParseType(Result, AllowVoid); @@ -381,12 +383,30 @@ namespace llvm { bool ParseGlobalValue(Type *Ty, Constant *&V); bool ParseGlobalTypeAndValue(Constant *&V); bool ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts); - bool parseOptionalComdat(Comdat *&C); - bool ParseMetadataListValue(ValID &ID, PerFunctionState *PFS); - bool ParseMetadataValue(ValID &ID, PerFunctionState *PFS); - bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS); + bool parseOptionalComdat(StringRef GlobalName, Comdat *&C); + bool ParseMetadataAsValue(Value *&V, PerFunctionState &PFS); + bool ParseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg, + PerFunctionState *PFS); + bool ParseMetadata(Metadata *&MD, PerFunctionState *PFS); + bool ParseMDTuple(MDNode *&MD, bool IsDistinct = false); + bool ParseMDNode(MDNode *&MD); + bool ParseMDNodeTail(MDNode *&MD); + bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &MDs); bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS); + template <class FieldTy> + bool ParseMDField(LocTy Loc, StringRef Name, FieldTy &Result); + template <class FieldTy> bool ParseMDField(StringRef Name, FieldTy &Result); + template <class ParserTy> + bool ParseMDFieldsImplBody(ParserTy parseField); + template <class ParserTy> + bool ParseMDFieldsImpl(ParserTy parseField, LocTy &ClosingLoc); + bool ParseSpecializedMDNode(MDNode *&N, bool IsDistinct = false); + +#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \ + bool Parse##CLASS(MDNode *&Result, bool IsDistinct); +#include "llvm/IR/Metadata.def" + // Function Parsing. struct ArgInfo { LocTy Loc; diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index f9821f7..a7aa17c 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -28,9 +28,8 @@ namespace lltok { lbrace, rbrace, // { } less, greater, // < > lparen, rparen, // ( ) - backslash, // \ (not /) exclaim, // ! - hash, // # + bar, // | kw_x, kw_true, kw_false, @@ -83,6 +82,7 @@ namespace lltok { kw_inteldialect, kw_gc, kw_prefix, + kw_prologue, kw_c, kw_cc, kw_ccc, kw_fastcc, kw_coldcc, @@ -95,6 +95,7 @@ namespace lltok { kw_x86_64_sysvcc, kw_x86_64_win64cc, kw_webkit_jscc, kw_anyregcc, kw_preserve_mostcc, kw_preserve_allcc, + kw_ghccc, // Attributes: kw_attributes, @@ -180,6 +181,9 @@ namespace lltok { kw_extractelement, kw_insertelement, kw_shufflevector, kw_extractvalue, kw_insertvalue, kw_blockaddress, + // Metadata types. + kw_distinct, + // Use-list order directives. kw_uselistorder, kw_uselistorder_bb, @@ -195,6 +199,12 @@ namespace lltok { LocalVar, // %foo %"foo" MetadataVar, // !foo StringConstant, // "foo" + DwarfTag, // DW_TAG_foo + DwarfAttEncoding, // DW_ATE_foo + DwarfVirtuality, // DW_VIRTUALITY_foo + DwarfLang, // DW_LANG_foo + DwarfOp, // DW_OP_foo + DIFlag, // DIFlagFoo // Type valued tokens (TyVal). Type, diff --git a/lib/AsmParser/Parser.cpp b/lib/AsmParser/Parser.cpp index 0815907..ed1a753 100644 --- a/lib/AsmParser/Parser.cpp +++ b/lib/AsmParser/Parser.cpp @@ -38,7 +38,7 @@ std::unique_ptr<Module> llvm::parseAssembly(MemoryBufferRef F, if (parseAssemblyInto(F, *M, Err)) return nullptr; - return std::move(M); + return M; } std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename, |