X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FAsmParser%2FLLParser.cpp;h=3471a2dbd05cd53d85f3d5980dea2ee2880afb7a;hp=925af4e17e13097a280fc45c79bc6a799ead89f3;hb=9889174eadb0f269ef132b3bd34a9f6fe3baa642;hpb=317ccafdbd0a10a57b9866c5bf3808b970ebb9ea diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 925af4e17e1..3471a2dbd05 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -13,6 +13,8 @@ #include "LLParser.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/AsmParser/SlotMapping.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constants.h" @@ -47,6 +49,32 @@ bool LLParser::Run() { ValidateEndOfModule(); } +bool LLParser::parseStandaloneConstantValue(Constant *&C, + const SlotMapping *Slots) { + restoreParsingState(Slots); + Lex.Lex(); + + Type *Ty = nullptr; + if (ParseType(Ty) || parseConstantValue(Ty, C)) + return true; + if (Lex.getKind() != lltok::Eof) + return Error(Lex.getLoc(), "expected end of string"); + return false; +} + +void LLParser::restoreParsingState(const SlotMapping *Slots) { + if (!Slots) + return; + NumberedVals = Slots->GlobalValues; + NumberedMetadata = Slots->MetadataNodes; + for (const auto &I : Slots->NamedTypes) + NamedTypes.insert( + std::make_pair(I.getKey(), std::make_pair(I.second, LocTy()))); + for (const auto &I : Slots->Types) + NumberedTypes.insert( + std::make_pair(I.first, std::make_pair(I.second, LocTy()))); +} + /// ValidateEndOfModule - Do final validity and sanity checks at the end of the /// module. bool LLParser::ValidateEndOfModule() { @@ -157,10 +185,22 @@ bool LLParser::ValidateEndOfModule() { // 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 + UpgradeCallsToIntrinsic(&*FI++); // must be post-increment, as we remove UpgradeDebugInfo(*M); + if (!Slots) + return false; + // Initialize the slot mapping. + // Because by this point we've parsed and validated everything, we can "steal" + // the mapping from LLParser as it doesn't need it anymore. + Slots->GlobalValues = std::move(NumberedVals); + Slots->MetadataNodes = std::move(NumberedMetadata); + for (const auto &I : NamedTypes) + Slots->NamedTypes.insert(std::make_pair(I.getKey(), I.second.first)); + for (const auto &I : NumberedTypes) + Slots->Types.insert(std::make_pair(I.first, I.second.first)); + return false; } @@ -189,7 +229,7 @@ bool LLParser::ParseTopLevelEntities() { // The Global variable production with no name can have many different // optional leading prefixes, the production is: // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass - // OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr + // OptionalThreadLocal OptionalAddrSpace OptionalUnnamedAddr // ('constant'|'global') ... case lltok::kw_private: // OptionalLinkage case lltok::kw_internal: // OptionalLinkage @@ -360,13 +400,14 @@ bool LLParser::ParseDeclare() { } /// toplevelentity -/// ::= 'define' FunctionHeader '{' ... +/// ::= 'define' FunctionHeader (!dbg !56)* '{' ... bool LLParser::ParseDefine() { assert(Lex.getKind() == lltok::kw_define); Lex.Lex(); Function *F; return ParseFunctionHeader(F, true) || + ParseOptionalFunctionMetadata(*F) || ParseFunctionBody(*F); } @@ -563,10 +604,7 @@ bool LLParser::ParseNamedMetadata() { NMD->addOperand(N); } while (EatIfPresent(lltok::comma)); - if (ParseToken(lltok::rbrace, "expected end of metadata node")) - return true; - - return false; + return ParseToken(lltok::rbrace, "expected end of metadata node"); } /// ParseStandaloneMetadata: @@ -617,12 +655,12 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { /// ParseAlias: /// ::= GlobalVar '=' OptionalLinkage OptionalVisibility /// OptionalDLLStorageClass OptionalThreadLocal -/// OptionalUnNammedAddr 'alias' Aliasee +/// OptionalUnnamedAddr 'alias' Aliasee /// /// Aliasee /// ::= TypeAndValue /// -/// Everything through OptionalUnNammedAddr has already been parsed. +/// Everything through OptionalUnnamedAddr has already been parsed. /// bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility, unsigned DLLStorageClass, @@ -640,6 +678,12 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, return Error(NameLoc, "symbol with local linkage must have default visibility"); + Type *Ty; + LocTy ExplicitTypeLoc = Lex.getLoc(); + if (ParseType(Ty) || + ParseToken(lltok::comma, "expected comma after alias's type")) + return true; + Constant *Aliasee; LocTy AliaseeLoc = Lex.getLoc(); if (Lex.getKind() != lltok::kw_bitcast && @@ -662,9 +706,31 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, auto *PTy = dyn_cast(AliaseeType); if (!PTy) return Error(AliaseeLoc, "An alias must have pointer type"); - Type *Ty = PTy->getElementType(); unsigned AddrSpace = PTy->getAddressSpace(); + if (Ty != PTy->getElementType()) + return Error( + ExplicitTypeLoc, + "explicit pointee type doesn't match operand's pointee type"); + + GlobalValue *GVal = nullptr; + + // See if the alias was forward referenced, if so, prepare to replace the + // forward reference. + if (!Name.empty()) { + GVal = M->getNamedValue(Name); + if (GVal) { + if (!ForwardRefVals.erase(Name)) + return Error(NameLoc, "redefinition of global '@" + Name + "'"); + } + } else { + auto I = ForwardRefValIDs.find(NumberedVals.size()); + if (I != ForwardRefValIDs.end()) { + GVal = I->second.first; + ForwardRefValIDs.erase(I); + } + } + // Okay, create the alias but do not insert it into the module yet. std::unique_ptr GA( GlobalAlias::create(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage, @@ -674,27 +740,20 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); GA->setUnnamedAddr(UnnamedAddr); - // See if this value already exists in the symbol table. If so, it is either - // a redefinition or a definition of a forward reference. - if (GlobalValue *Val = M->getNamedValue(Name)) { - // See if this was a redefinition. If so, there is no entry in - // ForwardRefVals. - std::map >::iterator - I = ForwardRefVals.find(Name); - if (I == ForwardRefVals.end()) - return Error(NameLoc, "redefinition of global named '@" + Name + "'"); - - // Otherwise, this was a definition of forward ref. Verify that types - // agree. - if (Val->getType() != GA->getType()) - return Error(NameLoc, - "forward reference and definition of alias have different types"); + if (Name.empty()) + NumberedVals.push_back(GA.get()); + + if (GVal) { + // Verify that types agree. + if (GVal->getType() != GA->getType()) + return Error( + ExplicitTypeLoc, + "forward reference and definition of alias have different types"); // If they agree, just RAUW the old value with the alias and remove the // forward ref info. - Val->replaceAllUsesWith(GA.get()); - Val->eraseFromParent(); - ForwardRefVals.erase(I); + GVal->replaceAllUsesWith(GA.get()); + GVal->eraseFromParent(); } // Insert into the module, we know its name won't collide now. @@ -709,13 +768,13 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, /// ParseGlobal /// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace +/// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace /// OptionalExternallyInitialized GlobalType Type Const /// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace +/// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace /// OptionalExternallyInitialized GlobalType Type Const /// -/// Everything up to and including OptionalUnNammedAddr has been parsed +/// Everything up to and including OptionalUnnamedAddr has been parsed /// already. /// bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, @@ -759,12 +818,11 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, if (!Name.empty()) { GVal = M->getNamedValue(Name); if (GVal) { - if (!ForwardRefVals.erase(Name) || !isa(GVal)) + if (!ForwardRefVals.erase(Name)) return Error(NameLoc, "redefinition of global '@" + Name + "'"); } } else { - std::map >::iterator - I = ForwardRefValIDs.find(NumberedVals.size()); + auto I = ForwardRefValIDs.find(NumberedVals.size()); if (I != ForwardRefValIDs.end()) { GVal = I->second.first; ForwardRefValIDs.erase(I); @@ -777,7 +835,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, Name, nullptr, GlobalVariable::NotThreadLocal, AddrSpace); } else { - if (GVal->getType()->getElementType() != Ty) + if (GVal->getValueType() != Ty) return Error(TyLoc, "forward reference and definition of global have different types"); @@ -895,14 +953,8 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, } // Target-dependent attributes: case lltok::StringConstant: { - std::string Attr = Lex.getStrVal(); - Lex.Lex(); - std::string Val; - if (EatIfPresent(lltok::equal) && - ParseStringConstant(Val)) + if (ParseStringAttribute(B)) return true; - - B.addAttribute(Attr, Val); continue; } @@ -938,33 +990,47 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, B.addStackAlignmentAttr(Alignment); continue; } - case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break; - case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break; - case lltok::kw_cold: B.addAttribute(Attribute::Cold); break; - case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break; - case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break; - case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break; - case lltok::kw_naked: B.addAttribute(Attribute::Naked); break; - case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break; - case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break; - case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break; - case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break; - case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break; - case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break; - case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; - case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; - case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break; - case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break; - case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; - case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break; - case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break; - case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break; - case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break; - case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break; - case lltok::kw_sanitize_address: B.addAttribute(Attribute::SanitizeAddress); break; - case lltok::kw_sanitize_thread: B.addAttribute(Attribute::SanitizeThread); break; - case lltok::kw_sanitize_memory: B.addAttribute(Attribute::SanitizeMemory); break; - case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; + case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break; + case lltok::kw_argmemonly: B.addAttribute(Attribute::ArgMemOnly); break; + case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break; + case lltok::kw_cold: B.addAttribute(Attribute::Cold); break; + case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break; + case lltok::kw_inaccessiblememonly: + B.addAttribute(Attribute::InaccessibleMemOnly); break; + case lltok::kw_inaccessiblemem_or_argmemonly: + B.addAttribute(Attribute::InaccessibleMemOrArgMemOnly); break; + case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break; + case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break; + case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break; + case lltok::kw_naked: B.addAttribute(Attribute::Naked); break; + case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break; + case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break; + case lltok::kw_noimplicitfloat: + B.addAttribute(Attribute::NoImplicitFloat); break; + case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break; + case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break; + case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break; + case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; + case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break; + case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; + case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break; + case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break; + case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; + case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break; + case lltok::kw_returns_twice: + B.addAttribute(Attribute::ReturnsTwice); break; + case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break; + case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break; + case lltok::kw_sspstrong: + B.addAttribute(Attribute::StackProtectStrong); break; + case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break; + case lltok::kw_sanitize_address: + B.addAttribute(Attribute::SanitizeAddress); break; + case lltok::kw_sanitize_thread: + B.addAttribute(Attribute::SanitizeThread); break; + case lltok::kw_sanitize_memory: + B.addAttribute(Attribute::SanitizeMemory); break; + case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; // Error handling. case lltok::kw_inreg: @@ -976,6 +1042,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, break; case lltok::kw_byval: case lltok::kw_dereferenceable: + case lltok::kw_dereferenceable_or_null: case lltok::kw_inalloca: case lltok::kw_nest: case lltok::kw_noalias: @@ -997,6 +1064,17 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, // GlobalValue Reference/Resolution Routines. //===----------------------------------------------------------------------===// +static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy, + const std::string &Name) { + if (auto *FT = dyn_cast(PTy->getElementType())) + return Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); + else + return new GlobalVariable(*M, PTy->getElementType(), false, + GlobalValue::ExternalWeakLinkage, nullptr, Name, + nullptr, GlobalVariable::NotThreadLocal, + PTy->getAddressSpace()); +} + /// GetGlobalVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. @@ -1015,8 +1093,7 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, // If this is a forward reference for the value, see if we already created a // forward ref record. if (!Val) { - std::map >::iterator - I = ForwardRefVals.find(Name); + auto I = ForwardRefVals.find(Name); if (I != ForwardRefVals.end()) Val = I->second.first; } @@ -1030,15 +1107,7 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, } // Otherwise, create a new forward reference for this value and remember it. - GlobalValue *FwdVal; - if (FunctionType *FT = dyn_cast(PTy->getElementType())) - FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); - else - FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, nullptr, Name, - nullptr, GlobalVariable::NotThreadLocal, - PTy->getAddressSpace()); - + GlobalValue *FwdVal = createGlobalFwdRef(M, PTy, Name); ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; } @@ -1055,8 +1124,7 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { // If this is a forward reference for the value, see if we already created a // forward ref record. if (!Val) { - std::map >::iterator - I = ForwardRefValIDs.find(ID); + auto I = ForwardRefValIDs.find(ID); if (I != ForwardRefValIDs.end()) Val = I->second.first; } @@ -1070,13 +1138,7 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { } // Otherwise, create a new forward reference for this value and remember it. - GlobalValue *FwdVal; - if (FunctionType *FT = dyn_cast(PTy->getElementType())) - FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M); - else - FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, nullptr, ""); - + GlobalValue *FwdVal = createGlobalFwdRef(M, PTy, ""); ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); return FwdVal; } @@ -1199,6 +1261,19 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) { ParseToken(lltok::rparen, "expected ')' in address space"); } +/// ParseStringAttribute +/// := StringConstant +/// := StringConstant '=' StringConstant +bool LLParser::ParseStringAttribute(AttrBuilder &B) { + std::string Attr = Lex.getStrVal(); + Lex.Lex(); + std::string Val; + if (EatIfPresent(lltok::equal) && ParseStringConstant(Val)) + return true; + B.addAttribute(Attr, Val); + return false; +} + /// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes. bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { bool HaveError = false; @@ -1210,6 +1285,11 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { switch (Token) { default: // End of attributes. return HaveError; + case lltok::StringConstant: { + if (ParseStringAttribute(B)) + return true; + continue; + } case lltok::kw_align: { unsigned Alignment; if (ParseOptionalAlignment(Alignment)) @@ -1220,11 +1300,18 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break; case lltok::kw_dereferenceable: { uint64_t Bytes; - if (ParseOptionalDereferenceableBytes(Bytes)) + if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes)) return true; B.addDereferenceableAttr(Bytes); continue; } + case lltok::kw_dereferenceable_or_null: { + uint64_t Bytes; + if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes)) + return true; + B.addDereferenceableOrNullAttr(Bytes); + continue; + } case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break; case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; @@ -1240,6 +1327,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_alignstack: case lltok::kw_alwaysinline: + case lltok::kw_argmemonly: case lltok::kw_builtin: case lltok::kw_inlinehint: case lltok::kw_jumptable: @@ -1262,6 +1350,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_ssp: case lltok::kw_sspreq: case lltok::kw_sspstrong: + case lltok::kw_safestack: case lltok::kw_uwtable: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; @@ -1282,13 +1371,32 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { switch (Token) { default: // End of attributes. return HaveError; + case lltok::StringConstant: { + if (ParseStringAttribute(B)) + return true; + continue; + } case lltok::kw_dereferenceable: { uint64_t Bytes; - if (ParseOptionalDereferenceableBytes(Bytes)) + if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes)) return true; B.addDereferenceableAttr(Bytes); continue; } + case lltok::kw_dereferenceable_or_null: { + uint64_t Bytes; + if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes)) + return true; + B.addDereferenceableOrNullAttr(Bytes); + continue; + } + case lltok::kw_align: { + unsigned Alignment; + if (ParseOptionalAlignment(Alignment)) + return true; + B.addAlignmentAttr(Alignment); + continue; + } case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break; @@ -1296,7 +1404,6 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; // Error handling. - case lltok::kw_align: case lltok::kw_byval: case lltok::kw_inalloca: case lltok::kw_nest: @@ -1308,6 +1415,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_alignstack: case lltok::kw_alwaysinline: + case lltok::kw_argmemonly: case lltok::kw_builtin: case lltok::kw_cold: case lltok::kw_inlinehint: @@ -1331,6 +1439,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_ssp: case lltok::kw_sspreq: case lltok::kw_sspstrong: + case lltok::kw_safestack: case lltok::kw_uwtable: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; @@ -1437,6 +1546,10 @@ bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) { /// ::= 'preserve_mostcc' /// ::= 'preserve_allcc' /// ::= 'ghccc' +/// ::= 'x86_intrcc' +/// ::= 'hhvmcc' +/// ::= 'hhvm_ccc' +/// ::= 'cxx_fast_tlscc' /// ::= 'cc' UINT /// bool LLParser::ParseOptionalCallingConv(unsigned &CC) { @@ -1465,6 +1578,10 @@ bool LLParser::ParseOptionalCallingConv(unsigned &CC) { 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_x86_intrcc: CC = CallingConv::X86_INTR; break; + case lltok::kw_hhvmcc: CC = CallingConv::HHVM; break; + case lltok::kw_hhvm_ccc: CC = CallingConv::HHVM_C; break; + case lltok::kw_cxx_fast_tlscc: CC = CallingConv::CXX_FAST_TLS; break; case lltok::kw_cc: { Lex.Lex(); return ParseUInt32(CC); @@ -1475,31 +1592,53 @@ bool LLParser::ParseOptionalCallingConv(unsigned &CC) { return false; } +/// ParseMetadataAttachment +/// ::= !dbg !42 +bool LLParser::ParseMetadataAttachment(unsigned &Kind, MDNode *&MD) { + assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata attachment"); + + std::string Name = Lex.getStrVal(); + Kind = M->getMDKindID(Name); + Lex.Lex(); + + return ParseMDNode(MD); +} + /// ParseInstructionMetadata /// ::= !dbg !42 (',' !dbg !57)* -bool LLParser::ParseInstructionMetadata(Instruction *Inst, - PerFunctionState *PFS) { +bool LLParser::ParseInstructionMetadata(Instruction &Inst) { do { if (Lex.getKind() != lltok::MetadataVar) return TokError("expected metadata after comma"); - std::string Name = Lex.getStrVal(); - unsigned MDK = M->getMDKindID(Name); - Lex.Lex(); - + unsigned MDK; MDNode *N; - if (ParseMDNode(N)) + if (ParseMetadataAttachment(MDK, N)) return true; - Inst->setMetadata(MDK, N); + Inst.setMetadata(MDK, N); if (MDK == LLVMContext::MD_tbaa) - InstsWithTBAATag.push_back(Inst); + InstsWithTBAATag.push_back(&Inst); // If this is the end of the list, we're done. } while (EatIfPresent(lltok::comma)); return false; } +/// ParseOptionalFunctionMetadata +/// ::= (!dbg !57)* +bool LLParser::ParseOptionalFunctionMetadata(Function &F) { + while (Lex.getKind() == lltok::MetadataVar) { + unsigned MDK; + MDNode *N; + if (ParseMetadataAttachment(MDK, N)) + return true; + + F.setMetadata(MDK, N); + } + return false; +} + /// ParseOptionalAlignment /// ::= /* empty */ /// ::= 'align' 4 @@ -1516,12 +1655,19 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) { return false; } -/// ParseOptionalDereferenceableBytes +/// ParseOptionalDerefAttrBytes /// ::= /* empty */ -/// ::= 'dereferenceable' '(' 4 ')' -bool LLParser::ParseOptionalDereferenceableBytes(uint64_t &Bytes) { +/// ::= AttrKind '(' 4 ')' +/// +/// where AttrKind is either 'dereferenceable' or 'dereferenceable_or_null'. +bool LLParser::ParseOptionalDerefAttrBytes(lltok::Kind AttrKind, + uint64_t &Bytes) { + assert((AttrKind == lltok::kw_dereferenceable || + AttrKind == lltok::kw_dereferenceable_or_null) && + "contract!"); + Bytes = 0; - if (!EatIfPresent(lltok::kw_dereferenceable)) + if (!EatIfPresent(AttrKind)) return false; LocTy ParenLoc = Lex.getLoc(); if (!EatIfPresent(lltok::lparen)) @@ -1818,7 +1964,59 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, return false; } +/// ParseOptionalOperandBundles +/// ::= /*empty*/ +/// ::= '[' OperandBundle [, OperandBundle ]* ']' +/// +/// OperandBundle +/// ::= bundle-tag '(' ')' +/// ::= bundle-tag '(' Type Value [, Type Value ]* ')' +/// +/// bundle-tag ::= String Constant +bool LLParser::ParseOptionalOperandBundles( + SmallVectorImpl &BundleList, PerFunctionState &PFS) { + LocTy BeginLoc = Lex.getLoc(); + if (!EatIfPresent(lltok::lsquare)) + return false; + + while (Lex.getKind() != lltok::rsquare) { + // If this isn't the first operand bundle, we need a comma. + if (!BundleList.empty() && + ParseToken(lltok::comma, "expected ',' in input list")) + return true; + + std::string Tag; + if (ParseStringConstant(Tag)) + return true; + + if (ParseToken(lltok::lparen, "expected '(' in operand bundle")) + return true; + + std::vector Inputs; + while (Lex.getKind() != lltok::rparen) { + // If this isn't the first input, we need a comma. + if (!Inputs.empty() && + ParseToken(lltok::comma, "expected ',' in input list")) + return true; + + Type *Ty = nullptr; + Value *Input = nullptr; + if (ParseType(Ty) || ParseValue(Ty, Input, PFS)) + return true; + Inputs.push_back(Input); + } + BundleList.emplace_back(std::move(Tag), std::move(Inputs)); + + Lex.Lex(); // Lex the ')'. + } + + if (BundleList.empty()) + return Error(BeginLoc, "operand bundle set must not be empty"); + + Lex.Lex(); // Lex the ']'. + return false; +} /// ParseArgumentList - Parse the argument list for a function type or function /// prototype. @@ -1861,9 +2059,9 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, return Error(TypeLoc, "invalid type for function argument"); unsigned AttrIndex = 1; - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, - AttributeSet::get(ArgTy->getContext(), - AttrIndex++, Attrs), Name)); + ArgList.emplace_back(TypeLoc, ArgTy, AttributeSet::get(ArgTy->getContext(), + AttrIndex++, Attrs), + std::move(Name)); while (EatIfPresent(lltok::comma)) { // Handle ... at end of arg list. @@ -1889,10 +2087,10 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, if (!ArgTy->isFirstClassType()) return Error(TypeLoc, "invalid type for function argument"); - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, - AttributeSet::get(ArgTy->getContext(), - AttrIndex++, Attrs), - Name)); + ArgList.emplace_back( + TypeLoc, ArgTy, + AttributeSet::get(ArgTy->getContext(), AttrIndex++, Attrs), + std::move(Name)); } } @@ -2081,31 +2279,29 @@ LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f, : P(p), F(f), FunctionNumber(functionNumber) { // Insert unnamed arguments into the NumberedVals list. - for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); - AI != E; ++AI) - if (!AI->hasName()) - NumberedVals.push_back(AI); + for (Argument &A : F.args()) + if (!A.hasName()) + NumberedVals.push_back(&A); } LLParser::PerFunctionState::~PerFunctionState() { // If there were any forward referenced non-basicblock values, delete them. - for (std::map >::iterator - I = ForwardRefVals.begin(), E = ForwardRefVals.end(); I != E; ++I) - if (!isa(I->second.first)) { - I->second.first->replaceAllUsesWith( - UndefValue::get(I->second.first->getType())); - delete I->second.first; - I->second.first = nullptr; - } - for (std::map >::iterator - I = ForwardRefValIDs.begin(), E = ForwardRefValIDs.end(); I != E; ++I) - if (!isa(I->second.first)) { - I->second.first->replaceAllUsesWith( - UndefValue::get(I->second.first->getType())); - delete I->second.first; - I->second.first = nullptr; - } + for (const auto &P : ForwardRefVals) { + if (isa(P.second.first)) + continue; + P.second.first->replaceAllUsesWith( + UndefValue::get(P.second.first->getType())); + delete P.second.first; + } + + for (const auto &P : ForwardRefValIDs) { + if (isa(P.second.first)) + continue; + P.second.first->replaceAllUsesWith( + UndefValue::get(P.second.first->getType())); + delete P.second.first; + } } bool LLParser::PerFunctionState::FinishFunction() { @@ -2124,16 +2320,15 @@ bool LLParser::PerFunctionState::FinishFunction() { /// GetVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. -Value *LLParser::PerFunctionState::GetVal(const std::string &Name, - Type *Ty, LocTy Loc) { +Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty, + LocTy Loc) { // Look this name up in the normal function symbol table. Value *Val = F.getValueSymbolTable().lookup(Name); // If this is a forward reference for the value, see if we already created a // forward ref record. if (!Val) { - std::map >::iterator - I = ForwardRefVals.find(Name); + auto I = ForwardRefVals.find(Name); if (I != ForwardRefVals.end()) Val = I->second.first; } @@ -2157,25 +2352,24 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, // Otherwise, create a new forward reference for this value and remember it. Value *FwdVal; - if (Ty->isLabelTy()) + if (Ty->isLabelTy()) { FwdVal = BasicBlock::Create(F.getContext(), Name, &F); - else + } else { FwdVal = new Argument(Ty, Name); + } ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; } -Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, - LocTy Loc) { +Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc) { // Look this name up in the normal function symbol table. Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr; // If this is a forward reference for the value, see if we already created a // forward ref record. if (!Val) { - std::map >::iterator - I = ForwardRefValIDs.find(ID); + auto I = ForwardRefValIDs.find(ID); if (I != ForwardRefValIDs.end()) Val = I->second.first; } @@ -2198,10 +2392,11 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, // Otherwise, create a new forward reference for this value and remember it. Value *FwdVal; - if (Ty->isLabelTy()) + if (Ty->isLabelTy()) { FwdVal = BasicBlock::Create(F.getContext(), "", &F); - else + } else { FwdVal = new Argument(Ty); + } ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); return FwdVal; @@ -2230,14 +2425,15 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, return P.Error(NameLoc, "instruction expected to be numbered '%" + Twine(NumberedVals.size()) + "'"); - std::map >::iterator FI = - ForwardRefValIDs.find(NameID); + auto FI = ForwardRefValIDs.find(NameID); if (FI != ForwardRefValIDs.end()) { - if (FI->second.first->getType() != Inst->getType()) + Value *Sentinel = FI->second.first; + if (Sentinel->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + getTypeString(FI->second.first->getType()) + "'"); - FI->second.first->replaceAllUsesWith(Inst); - delete FI->second.first; + + Sentinel->replaceAllUsesWith(Inst); + delete Sentinel; ForwardRefValIDs.erase(FI); } @@ -2246,14 +2442,15 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, } // Otherwise, the instruction had a name. Resolve forward refs and set it. - std::map >::iterator - FI = ForwardRefVals.find(NameStr); + auto FI = ForwardRefVals.find(NameStr); if (FI != ForwardRefVals.end()) { - if (FI->second.first->getType() != Inst->getType()) + Value *Sentinel = FI->second.first; + if (Sentinel->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + getTypeString(FI->second.first->getType()) + "'"); - FI->second.first->replaceAllUsesWith(Inst); - delete FI->second.first; + + Sentinel->replaceAllUsesWith(Inst); + delete Sentinel; ForwardRefVals.erase(FI); } @@ -2356,6 +2553,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { case lltok::kw_null: ID.Kind = ValID::t_Null; break; case lltok::kw_undef: ID.Kind = ValID::t_Undef; break; case lltok::kw_zeroinitializer: ID.Kind = ValID::t_Zero; break; + case lltok::kw_none: ID.Kind = ValID::t_None; break; case lltok::lbrace: { // ValID ::= '{' ConstVector '}' @@ -2365,9 +2563,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ParseToken(lltok::rbrace, "expected end of struct constant")) return true; - ID.ConstantStructElts = new Constant*[Elts.size()]; + ID.ConstantStructElts = make_unique(Elts.size()); ID.UIntVal = Elts.size(); - memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0])); + memcpy(ID.ConstantStructElts.get(), Elts.data(), + Elts.size() * sizeof(Elts[0])); ID.Kind = ValID::t_ConstantStruct; return false; } @@ -2386,8 +2585,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; if (isPackedStruct) { - ID.ConstantStructElts = new Constant*[Elts.size()]; - memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0])); + ID.ConstantStructElts = make_unique(Elts.size()); + memcpy(ID.ConstantStructElts.get(), Elts.data(), + Elts.size() * sizeof(Elts[0])); ID.UIntVal = Elts.size(); ID.Kind = ValID::t_PackedConstantStruct; return false; @@ -2512,7 +2712,12 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (!F) { // Make a global variable as a placeholder for this reference. - GlobalValue *&FwdRef = ForwardRefBlockAddresses[Fn][Label]; + GlobalValue *&FwdRef = + ForwardRefBlockAddresses.insert(std::make_pair( + std::move(Fn), + std::map())) + .first->second.insert(std::make_pair(std::move(Label), nullptr)) + .first->second; if (!FwdRef) FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false, GlobalValue::InternalLinkage, nullptr, ""); @@ -2772,11 +2977,23 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { unsigned Opc = Lex.getUIntVal(); SmallVector Elts; bool InBounds = false; + Type *Ty; Lex.Lex(); + if (Opc == Instruction::GetElementPtr) InBounds = EatIfPresent(lltok::kw_inbounds); - if (ParseToken(lltok::lparen, "expected '(' in constantexpr") || - ParseGlobalValueVector(Elts) || + + if (ParseToken(lltok::lparen, "expected '(' in constantexpr")) + return true; + + LocTy ExplicitTypeLoc = Lex.getLoc(); + if (Opc == Instruction::GetElementPtr) { + if (ParseType(Ty) || + ParseToken(lltok::comma, "expected comma after getelementptr's type")) + return true; + } + + if (ParseGlobalValueVector(Elts) || ParseToken(lltok::rparen, "expected ')' in constantexpr")) return true; @@ -2787,6 +3004,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { Type *BaseType = Elts[0]->getType(); auto *BasePointerType = cast(BaseType->getScalarType()); + if (Ty != BasePointerType->getElementType()) + return Error( + ExplicitTypeLoc, + "explicit pointee type doesn't match operand's pointee type"); ArrayRef Indices(Elts.begin() + 1, Elts.end()); for (Constant *Val : Indices) { @@ -2796,8 +3017,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (ValTy->isVectorTy() != BaseType->isVectorTy()) return Error(ID.Loc, "getelementptr index type missmatch"); if (ValTy->isVectorTy()) { - unsigned ValNumEl = cast(ValTy)->getNumElements(); - unsigned PtrNumEl = cast(BaseType)->getNumElements(); + unsigned ValNumEl = ValTy->getVectorNumElements(); + unsigned PtrNumEl = BaseType->getVectorNumElements(); if (ValNumEl != PtrNumEl) return Error( ID.Loc, @@ -2805,13 +3026,14 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { } } - if (!Indices.empty() && !BasePointerType->getElementType()->isSized()) + SmallPtrSet Visited; + if (!Indices.empty() && !Ty->isSized(&Visited)) return Error(ID.Loc, "base element of getelementptr must be sized"); - if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), Indices)) + if (!GetElementPtrInst::getIndexedType(Ty, Indices)) return Error(ID.Loc, "invalid getelementptr indices"); - ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], Indices, - InBounds); + ID.ConstantVal = + ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, InBounds); } else if (Opc == Instruction::Select) { if (Elts.size() != 3) return Error(ID.Loc, "expected three operands to select"); @@ -2927,7 +3149,7 @@ bool LLParser::ParseMDTuple(MDNode *&MD, bool IsDistinct) { /// MDNode: /// ::= !{ ... } /// ::= !7 -/// ::= !MDLocation(...) +/// ::= !DILocation(...) bool LLParser::ParseMDNode(MDNode *&N) { if (Lex.getKind() == lltok::MetadataVar) return ParseSpecializedMDNode(N); @@ -2979,6 +3201,11 @@ struct DwarfTagField : public MDUnsignedField { DwarfTagField(dwarf::Tag DefaultTag) : MDUnsignedField(DefaultTag, dwarf::DW_TAG_hi_user) {} }; +struct DwarfMacinfoTypeField : public MDUnsignedField { + DwarfMacinfoTypeField() : MDUnsignedField(0, dwarf::DW_MACINFO_vendor_ext) {} + DwarfMacinfoTypeField(dwarf::MacinfoRecordType DefaultType) + : MDUnsignedField(DefaultType, dwarf::DW_MACINFO_vendor_ext) {} +}; struct DwarfAttEncodingField : public MDUnsignedField { DwarfAttEncodingField() : MDUnsignedField(0, dwarf::DW_ATE_hi_user) {} }; @@ -3007,13 +3234,17 @@ struct MDBoolField : public MDFieldImpl { MDBoolField(bool Default = false) : ImplTy(Default) {} }; struct MDField : public MDFieldImpl { - MDField() : ImplTy(nullptr) {} + bool AllowNull; + + MDField(bool AllowNull = true) : ImplTy(nullptr), AllowNull(AllowNull) {} }; struct MDConstant : public MDFieldImpl { MDConstant() : ImplTy(nullptr) {} }; -struct MDStringField : public MDFieldImpl { - MDStringField() : ImplTy(std::string()) {} +struct MDStringField : public MDFieldImpl { + bool AllowEmpty; + MDStringField(bool AllowEmpty = true) + : ImplTy(nullptr), AllowEmpty(AllowEmpty) {} }; struct MDFieldList : public MDFieldImpl> { MDFieldList() : ImplTy(SmallVector()) {} @@ -3066,6 +3297,26 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) { return false; } +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, + DwarfMacinfoTypeField &Result) { + if (Lex.getKind() == lltok::APSInt) + return ParseMDField(Loc, Name, static_cast(Result)); + + if (Lex.getKind() != lltok::DwarfMacinfo) + return TokError("expected DWARF macinfo type"); + + unsigned Macinfo = dwarf::getMacinfo(Lex.getStrVal()); + if (Macinfo == dwarf::DW_MACINFO_invalid) + return TokError( + "invalid DWARF macinfo type" + Twine(" '") + Lex.getStrVal() + "'"); + assert(Macinfo <= Result.Max && "Expected valid DWARF macinfo type"); + + Result.assign(Macinfo); + Lex.Lex(); + return false; +} + template <> bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfVirtualityField &Result) { @@ -3138,7 +3389,7 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) { if (Lex.getKind() != lltok::DIFlag) return TokError("expected debug info flag"); - Val = DIDescriptor::getFlag(Lex.getStrVal()); + Val = DINode::getFlag(Lex.getStrVal()); if (!Val) return TokError(Twine("invalid debug info flag flag '") + Lex.getStrVal() + "'"); @@ -3198,6 +3449,8 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) { template <> bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) { if (Lex.getKind() == lltok::kw_null) { + if (!Result.AllowNull) + return TokError("'" + Name + "' cannot be null"); Lex.Lex(); Result.assign(nullptr); return false; @@ -3223,11 +3476,15 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDConstant &Result) { template <> bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result) { + LocTy ValueLoc = Lex.getLoc(); std::string S; if (ParseStringConstant(S)) return true; - Result.assign(std::move(S)); + if (!Result.AllowEmpty && S.empty()) + return Error(ValueLoc, "'" + Name + "' cannot be empty"); + + Result.assign(S.empty() ? nullptr : MDString::get(Context, S)); return false; } @@ -3314,25 +3571,25 @@ bool LLParser::ParseSpecializedMDNode(MDNode *&N, bool IsDistinct) { #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) { +/// ParseDILocationFields: +/// ::= !DILocation(line: 43, column: 8, scope: !5, inlinedAt: !6) +bool LLParser::ParseDILocation(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(line, LineField, ); \ OPTIONAL(column, ColumnField, ); \ - REQUIRED(scope, MDField, ); \ + REQUIRED(scope, MDField, (/* AllowNull */ false)); \ 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); + Result = GET_OR_DISTINCT( + DILocation, (Context, line.Val, column.Val, scope.Val, inlinedAt.Val)); return false; } -/// ParseGenericDebugNode: -/// ::= !GenericDebugNode(tag: 15, header: "...", operands: {...}) -bool LLParser::ParseGenericDebugNode(MDNode *&Result, bool IsDistinct) { +/// ParseGenericDINode: +/// ::= !GenericDINode(tag: 15, header: "...", operands: {...}) +bool LLParser::ParseGenericDINode(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(tag, DwarfTagField, ); \ OPTIONAL(header, MDStringField, ); \ @@ -3340,40 +3597,40 @@ bool LLParser::ParseGenericDebugNode(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(GenericDebugNode, + Result = GET_OR_DISTINCT(GenericDINode, (Context, tag.Val, header.Val, operands.Val)); return false; } -/// ParseMDSubrange: -/// ::= !MDSubrange(count: 30, lowerBound: 2) -bool LLParser::ParseMDSubrange(MDNode *&Result, bool IsDistinct) { +/// ParseDISubrange: +/// ::= !DISubrange(count: 30, lowerBound: 2) +bool LLParser::ParseDISubrange(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)); + Result = GET_OR_DISTINCT(DISubrange, (Context, count.Val, lowerBound.Val)); return false; } -/// ParseMDEnumerator: -/// ::= !MDEnumerator(value: 30, name: "SomeKind") -bool LLParser::ParseMDEnumerator(MDNode *&Result, bool IsDistinct) { +/// ParseDIEnumerator: +/// ::= !DIEnumerator(value: 30, name: "SomeKind") +bool LLParser::ParseDIEnumerator(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)); + Result = GET_OR_DISTINCT(DIEnumerator, (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) { +/// ParseDIBasicType: +/// ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32) +bool LLParser::ParseDIBasicType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \ OPTIONAL(name, MDStringField, ); \ @@ -3383,16 +3640,16 @@ bool LLParser::ParseMDBasicType(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(MDBasicType, (Context, tag.Val, name.Val, size.Val, + Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val, align.Val, encoding.Val)); return false; } -/// ParseMDDerivedType: -/// ::= !MDDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0, +/// ParseDIDerivedType: +/// ::= !DIDerivedType(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) { +bool LLParser::ParseDIDerivedType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(tag, DwarfTagField, ); \ OPTIONAL(name, MDStringField, ); \ @@ -3408,14 +3665,14 @@ bool LLParser::ParseMDDerivedType(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(MDDerivedType, + Result = GET_OR_DISTINCT(DIDerivedType, (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) { +bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(tag, DwarfTagField, ); \ OPTIONAL(name, MDStringField, ); \ @@ -3436,47 +3693,50 @@ bool LLParser::ParseMDCompositeType(MDNode *&Result, bool IsDistinct) { #undef VISIT_MD_FIELDS Result = GET_OR_DISTINCT( - MDCompositeType, + DICompositeType, (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) { +bool LLParser::ParseDISubroutineType(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)); + Result = GET_OR_DISTINCT(DISubroutineType, (Context, flags.Val, types.Val)); return false; } -/// ParseMDFileType: -/// ::= !MDFileType(filename: "path/to/file", directory: "/path/to/dir") -bool LLParser::ParseMDFile(MDNode *&Result, bool IsDistinct) { +/// ParseDIFileType: +/// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir") +bool LLParser::ParseDIFile(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)); + Result = GET_OR_DISTINCT(DIFile, (Context, filename.Val, directory.Val)); return false; } -/// ParseMDCompileUnit: -/// ::= !MDCompileUnit(language: DW_LANG_C99, file: !0, producer: "clang", +/// ParseDICompileUnit: +/// ::= !DICompileUnit(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) { +/// globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd) +bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { + if (!IsDistinct) + return Lex.Error("missing 'distinct', required for !DICompileUnit"); + #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(language, DwarfLangField, ); \ - REQUIRED(file, MDField, ); \ + REQUIRED(file, MDField, (/* AllowNull */ false)); \ OPTIONAL(producer, MDStringField, ); \ OPTIONAL(isOptimized, MDBoolField, ); \ OPTIONAL(flags, MDStringField, ); \ @@ -3487,31 +3747,33 @@ bool LLParser::ParseMDCompileUnit(MDNode *&Result, bool IsDistinct) { OPTIONAL(retainedTypes, MDField, ); \ OPTIONAL(subprograms, MDField, ); \ OPTIONAL(globals, MDField, ); \ - OPTIONAL(imports, MDField, ); + OPTIONAL(imports, MDField, ); \ + OPTIONAL(macros, MDField, ); \ + OPTIONAL(dwoId, MDUnsignedField, ); 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)); + Result = DICompileUnit::getDistinct( + 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, macros.Val, + dwoId.Val); return false; } -/// ParseMDSubprogram: -/// ::= !MDSubprogram(scope: !0, name: "foo", linkageName: "_Zfoo", +/// ParseDISubprogram: +/// ::= !DISubprogram(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) { +/// isOptimized: false, templateParams: !4, declaration: !5, +/// variables: !6) +bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { + auto Loc = Lex.getLoc(); #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(scope, MDField, ); \ - REQUIRED(name, MDStringField, ); \ + OPTIONAL(name, MDStringField, ); \ OPTIONAL(linkageName, MDStringField, ); \ OPTIONAL(file, MDField, ); \ OPTIONAL(line, LineField, ); \ @@ -3524,27 +3786,31 @@ bool LLParser::ParseMDSubprogram(MDNode *&Result, bool IsDistinct) { 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 + if (isDefinition.Val && !IsDistinct) + return Lex.Error( + Loc, + "missing 'distinct', required for !DISubprogram when 'isDefinition'"); + 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)); + DISubprogram, + (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, 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) { +/// ParseDILexicalBlock: +/// ::= !DILexicalBlock(scope: !0, file: !2, line: 7, column: 9) +bool LLParser::ParseDILexicalBlock(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ - REQUIRED(scope, MDField, ); \ + REQUIRED(scope, MDField, (/* AllowNull */ false)); \ OPTIONAL(file, MDField, ); \ OPTIONAL(line, LineField, ); \ OPTIONAL(column, ColumnField, ); @@ -3552,28 +3818,28 @@ bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) { #undef VISIT_MD_FIELDS Result = GET_OR_DISTINCT( - MDLexicalBlock, (Context, scope.Val, file.Val, line.Val, column.Val)); + DILexicalBlock, (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) { +/// ParseDILexicalBlockFile: +/// ::= !DILexicalBlockFile(scope: !0, file: !2, discriminator: 9) +bool LLParser::ParseDILexicalBlockFile(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ - REQUIRED(scope, MDField, ); \ + REQUIRED(scope, MDField, (/* AllowNull */ false)); \ OPTIONAL(file, MDField, ); \ REQUIRED(discriminator, MDUnsignedField, (0, UINT32_MAX)); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(MDLexicalBlockFile, + Result = GET_OR_DISTINCT(DILexicalBlockFile, (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) { +/// ParseDINamespace: +/// ::= !DINamespace(scope: !0, file: !2, name: "SomeNamespace", line: 9) +bool LLParser::ParseDINamespace(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(scope, MDField, ); \ OPTIONAL(file, MDField, ); \ @@ -3582,14 +3848,65 @@ bool LLParser::ParseMDNamespace(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(MDNamespace, + Result = GET_OR_DISTINCT(DINamespace, (Context, scope.Val, file.Val, name.Val, line.Val)); return false; } -/// ParseMDTemplateTypeParameter: -/// ::= !MDTemplateTypeParameter(name: "Ty", type: !1) -bool LLParser::ParseMDTemplateTypeParameter(MDNode *&Result, bool IsDistinct) { +/// ParseDIMacro: +/// ::= !DIMacro(macinfo: type, line: 9, name: "SomeMacro", value: "SomeValue") +bool LLParser::ParseDIMacro(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(type, DwarfMacinfoTypeField, ); \ + REQUIRED(line, LineField, ); \ + REQUIRED(name, MDStringField, ); \ + OPTIONAL(value, MDStringField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(DIMacro, + (Context, type.Val, line.Val, name.Val, value.Val)); + return false; +} + +/// ParseDIMacroFile: +/// ::= !DIMacroFile(line: 9, file: !2, nodes: !3) +bool LLParser::ParseDIMacroFile(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(type, DwarfMacinfoTypeField, (dwarf::DW_MACINFO_start_file)); \ + REQUIRED(line, LineField, ); \ + REQUIRED(file, MDField, ); \ + OPTIONAL(nodes, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(DIMacroFile, + (Context, type.Val, line.Val, file.Val, nodes.Val)); + return false; +} + + +/// ParseDIModule: +/// ::= !DIModule(scope: !0, name: "SomeModule", configMacros: "-DNDEBUG", +/// includePath: "/usr/include", isysroot: "/") +bool LLParser::ParseDIModule(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(scope, MDField, ); \ + REQUIRED(name, MDStringField, ); \ + OPTIONAL(configMacros, MDStringField, ); \ + OPTIONAL(includePath, MDStringField, ); \ + OPTIONAL(isysroot, MDStringField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(DIModule, (Context, scope.Val, name.Val, + configMacros.Val, includePath.Val, isysroot.Val)); + return false; +} + +/// ParseDITemplateTypeParameter: +/// ::= !DITemplateTypeParameter(name: "Ty", type: !1) +bool LLParser::ParseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(name, MDStringField, ); \ REQUIRED(type, MDField, ); @@ -3597,14 +3914,14 @@ bool LLParser::ParseMDTemplateTypeParameter(MDNode *&Result, bool IsDistinct) { #undef VISIT_MD_FIELDS Result = - GET_OR_DISTINCT(MDTemplateTypeParameter, (Context, name.Val, type.Val)); + GET_OR_DISTINCT(DITemplateTypeParameter, (Context, name.Val, type.Val)); return false; } -/// ParseMDTemplateValueParameter: -/// ::= !MDTemplateValueParameter(tag: DW_TAG_template_value_parameter, +/// ParseDITemplateValueParameter: +/// ::= !DITemplateValueParameter(tag: DW_TAG_template_value_parameter, /// name: "V", type: !1, value: i32 7) -bool LLParser::ParseMDTemplateValueParameter(MDNode *&Result, bool IsDistinct) { +bool LLParser::ParseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_template_value_parameter)); \ OPTIONAL(name, MDStringField, ); \ @@ -3613,20 +3930,20 @@ bool LLParser::ParseMDTemplateValueParameter(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(MDTemplateValueParameter, + Result = GET_OR_DISTINCT(DITemplateValueParameter, (Context, tag.Val, name.Val, type.Val, value.Val)); return false; } -/// ParseMDGlobalVariable: -/// ::= !MDGlobalVariable(scope: !0, name: "foo", linkageName: "foo", +/// ParseDIGlobalVariable: +/// ::= !DIGlobalVariable(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) { +bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \ OPTIONAL(scope, MDField, ); \ - REQUIRED(name, MDStringField, ); \ OPTIONAL(linkageName, MDStringField, ); \ OPTIONAL(file, MDField, ); \ OPTIONAL(line, LineField, ); \ @@ -3638,40 +3955,39 @@ bool LLParser::ParseMDGlobalVariable(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(MDGlobalVariable, + Result = GET_OR_DISTINCT(DIGlobalVariable, (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) { +/// ParseDILocalVariable: +/// ::= !DILocalVariable(arg: 7, scope: !0, name: "foo", +/// file: !1, line: 7, type: !2, arg: 2, flags: 7) +/// ::= !DILocalVariable(scope: !0, name: "foo", +/// file: !1, line: 7, type: !2, arg: 2, flags: 7) +bool LLParser::ParseDILocalVariable(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ - REQUIRED(tag, DwarfTagField, ); \ - OPTIONAL(scope, MDField, ); \ + REQUIRED(scope, MDField, (/* AllowNull */ false)); \ OPTIONAL(name, MDStringField, ); \ + OPTIONAL(arg, MDUnsignedField, (0, UINT16_MAX)); \ OPTIONAL(file, MDField, ); \ OPTIONAL(line, LineField, ); \ OPTIONAL(type, MDField, ); \ - OPTIONAL(arg, MDUnsignedField, (0, UINT8_MAX)); \ - OPTIONAL(flags, DIFlagField, ); \ - OPTIONAL(inlinedAt, MDField, ); + OPTIONAL(flags, DIFlagField, ); 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)); + Result = GET_OR_DISTINCT(DILocalVariable, + (Context, scope.Val, name.Val, file.Val, line.Val, + type.Val, arg.Val, flags.Val)); return false; } -/// ParseMDExpression: -/// ::= !MDExpression(0, 7, -1) -bool LLParser::ParseMDExpression(MDNode *&Result, bool IsDistinct) { +/// ParseDIExpression: +/// ::= !DIExpression(0, 7, -1) +bool LLParser::ParseDIExpression(MDNode *&Result, bool IsDistinct) { assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name"); Lex.Lex(); @@ -3703,16 +4019,16 @@ bool LLParser::ParseMDExpression(MDNode *&Result, bool IsDistinct) { if (ParseToken(lltok::rparen, "expected ')' here")) return true; - Result = GET_OR_DISTINCT(MDExpression, (Context, Elements)); + Result = GET_OR_DISTINCT(DIExpression, (Context, Elements)); return false; } -/// ParseMDObjCProperty: -/// ::= !MDObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo", +/// ParseDIObjCProperty: +/// ::= !DIObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo", /// getter: "getFoo", attributes: 7, type: !2) -bool LLParser::ParseMDObjCProperty(MDNode *&Result, bool IsDistinct) { +bool LLParser::ParseDIObjCProperty(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ - REQUIRED(name, MDStringField, ); \ + OPTIONAL(name, MDStringField, ); \ OPTIONAL(file, MDField, ); \ OPTIONAL(line, LineField, ); \ OPTIONAL(setter, MDStringField, ); \ @@ -3722,16 +4038,16 @@ bool LLParser::ParseMDObjCProperty(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(MDObjCProperty, + Result = GET_OR_DISTINCT(DIObjCProperty, (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, +/// ParseDIImportedEntity: +/// ::= !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1, /// line: 7, name: "foo") -bool LLParser::ParseMDImportedEntity(MDNode *&Result, bool IsDistinct) { +bool LLParser::ParseDIImportedEntity(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(tag, DwarfTagField, ); \ REQUIRED(scope, MDField, ); \ @@ -3741,7 +4057,7 @@ bool LLParser::ParseMDImportedEntity(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(MDImportedEntity, (Context, tag.Val, scope.Val, + Result = GET_OR_DISTINCT(DIImportedEntity, (Context, tag.Val, scope.Val, entity.Val, line.Val, name.Val)); return false; } @@ -3796,7 +4112,7 @@ bool LLParser::ParseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg, /// ::= !42 /// ::= !{...} /// ::= !"string" -/// ::= !MDLocation(...) +/// ::= !DILocation(...) bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) { if (Lex.getKind() == lltok::MetadataVar) { MDNode *N; @@ -3855,13 +4171,11 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, V = PFS->GetVal(ID.StrVal, Ty, ID.Loc); return V == nullptr; case ValID::t_InlineAsm: { - PointerType *PTy = dyn_cast(Ty); - FunctionType *FTy = - PTy ? dyn_cast(PTy->getElementType()) : nullptr; - if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2)) + if (!ID.FTy || !InlineAsm::Verify(ID.FTy, ID.StrVal2)) return Error(ID.Loc, "invalid type for inline asm constraint string"); - V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1, - (ID.UIntVal>>1)&1, (InlineAsm::AsmDialect(ID.UIntVal>>2))); + V = InlineAsm::get(ID.FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1, + (ID.UIntVal >> 1) & 1, + (InlineAsm::AsmDialect(ID.UIntVal >> 2))); return false; } case ValID::t_GlobalName: @@ -3921,6 +4235,11 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, return Error(ID.Loc, "invalid type for null constant"); V = Constant::getNullValue(Ty); return false; + case ValID::t_None: + if (!Ty->isTokenTy()) + return Error(ID.Loc, "invalid type for none constant"); + V = Constant::getNullValue(Ty); + return false; case ValID::t_Constant: if (ID.ConstantVal->getType() != Ty) return Error(ID.Loc, "constant expression type mismatch"); @@ -3942,8 +4261,8 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, return Error(ID.Loc, "element " + Twine(i) + " of struct initializer doesn't match struct element type"); - V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts, - ID.UIntVal)); + V = ConstantStruct::get( + ST, makeArrayRef(ID.ConstantStructElts.get(), ID.UIntVal)); } else return Error(ID.Loc, "constant expression type mismatch"); return false; @@ -3951,11 +4270,35 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, llvm_unreachable("Invalid ValID"); } +bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { + C = nullptr; + ValID ID; + auto Loc = Lex.getLoc(); + if (ParseValID(ID, /*PFS=*/nullptr)) + return true; + switch (ID.Kind) { + case ValID::t_APSInt: + case ValID::t_APFloat: + case ValID::t_Undef: + case ValID::t_Constant: + case ValID::t_ConstantStruct: + case ValID::t_PackedConstantStruct: { + Value *V; + if (ConvertValIDToValue(Ty, ID, V, /*PFS=*/nullptr)) + return true; + assert(isa(V) && "Expected a constant value"); + C = cast(V); + return false; + } + default: + return Error(Loc, "expected a constant value"); + } +} + bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) { V = nullptr; ValID ID; - return ParseValID(ID, PFS) || - ConvertValIDToValue(Ty, ID, V, PFS); + return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS); } bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) { @@ -3979,7 +4322,7 @@ bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, /// FunctionHeader /// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs /// OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection -/// OptionalAlign OptGC OptionalPrefix OptionalPrologue +/// OptionalAlign OptGC OptionalPrefix OptionalPrologue OptPersonalityFn bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { // Parse the linkage. LocTy LinkageLoc = Lex.getLoc(); @@ -4061,6 +4404,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { LocTy UnnamedAddrLoc; Constant *Prefix = nullptr; Constant *Prologue = nullptr; + Constant *PersonalityFn = nullptr; Comdat *C; if (ParseArgumentList(ArgList, isVarArg) || @@ -4077,7 +4421,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { (EatIfPresent(lltok::kw_prefix) && ParseGlobalTypeAndValue(Prefix)) || (EatIfPresent(lltok::kw_prologue) && - ParseGlobalTypeAndValue(Prologue))) + ParseGlobalTypeAndValue(Prologue)) || + (EatIfPresent(lltok::kw_personality) && + ParseGlobalTypeAndValue(PersonalityFn))) return true; if (FuncAttrs.contains(Attribute::Builtin)) @@ -4125,8 +4471,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (!FunctionName.empty()) { // If this was a definition of a forward reference, remove the definition // from the forward reference table and fill in the forward ref. - std::map >::iterator FRVI = - ForwardRefVals.find(FunctionName); + auto FRVI = ForwardRefVals.find(FunctionName); if (FRVI != ForwardRefVals.end()) { Fn = M->getFunction(FunctionName); if (!Fn) @@ -4148,8 +4493,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { } else { // If this is a definition of a forward referenced function, make sure the // types agree. - std::map >::iterator I - = ForwardRefValIDs.find(NumberedVals.size()); + auto I = ForwardRefValIDs.find(NumberedVals.size()); if (I != ForwardRefValIDs.end()) { Fn = cast(I->second.first); if (Fn->getType() != PFT) @@ -4176,6 +4520,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Fn->setAlignment(Alignment); Fn->setSection(Section); Fn->setComdat(C); + Fn->setPersonalityFn(PersonalityFn); if (!GC.empty()) Fn->setGC(GC.c_str()); Fn->setPrefixData(Prefix); Fn->setPrologueData(Prologue); @@ -4335,7 +4680,7 @@ 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(Inst, &PFS)) + if (ParseInstructionMetadata(*Inst)) return true; break; case InstExtraComma: @@ -4343,7 +4688,7 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { // If the instruction parser ate an extra comma at the end of it, it // *must* be followed by metadata. - if (ParseInstructionMetadata(Inst, &PFS)) + if (ParseInstructionMetadata(*Inst)) return true; break; } @@ -4380,6 +4725,11 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS); case lltok::kw_invoke: return ParseInvoke(Inst, PFS); case lltok::kw_resume: return ParseResume(Inst, PFS); + case lltok::kw_cleanupret: return ParseCleanupRet(Inst, PFS); + case lltok::kw_catchret: return ParseCatchRet(Inst, PFS); + case lltok::kw_catchswitch: return ParseCatchSwitch(Inst, PFS); + case lltok::kw_catchpad: return ParseCatchPad(Inst, PFS); + case lltok::kw_cleanuppad: return ParseCleanupPad(Inst, PFS); // Binary Operators. case lltok::kw_add: case lltok::kw_sub: @@ -4425,8 +4775,17 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_and: case lltok::kw_or: case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal); - case lltok::kw_icmp: - case lltok::kw_fcmp: return ParseCompare(Inst, PFS, KeywordVal); + case lltok::kw_icmp: return ParseCompare(Inst, PFS, KeywordVal); + case lltok::kw_fcmp: { + FastMathFlags FMF = EatFastMathFlagsIfPresent(); + int Res = ParseCompare(Inst, PFS, KeywordVal); + if (Res != 0) + return Res; + if (FMF.any()) + Inst->setFastMathFlags(FMF); + return 0; + } + // Casts. case lltok::kw_trunc: case lltok::kw_zext: @@ -4453,6 +4812,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_call: return ParseCall(Inst, PFS, CallInst::TCK_None); case lltok::kw_tail: return ParseCall(Inst, PFS, CallInst::TCK_Tail); case lltok::kw_musttail: return ParseCall(Inst, PFS, CallInst::TCK_MustTail); + case lltok::kw_notail: return ParseCall(Inst, PFS, CallInst::TCK_NoTail); // Memory. case lltok::kw_alloca: return ParseAlloc(Inst, PFS); case lltok::kw_load: return ParseLoad(Inst, PFS); @@ -4671,15 +5031,15 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { LocTy RetTypeLoc; ValID CalleeID; SmallVector ArgList; + SmallVector BundleList; BasicBlock *NormalBB, *UnwindBB; - if (ParseOptionalCallingConv(CC) || - ParseOptionalReturnAttrs(RetAttrs) || + if (ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || - ParseValID(CalleeID) || - ParseParameterList(ArgList, PFS) || + ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, NoBuiltinLoc) || + ParseOptionalOperandBundles(BundleList, PFS) || ParseToken(lltok::kw_to, "expected 'to' in invoke") || ParseTypeAndBasicBlock(NormalBB, PFS) || ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") || @@ -4689,10 +5049,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. - PointerType *PFTy = nullptr; - FunctionType *Ty = nullptr; - if (!(PFTy = dyn_cast(RetType)) || - !(Ty = dyn_cast(PFTy->getElementType()))) { + FunctionType *Ty = dyn_cast(RetType); + if (!Ty) { // Pull out the types of all of the arguments... std::vector ParamTypes; for (unsigned i = 0, e = ArgList.size(); i != e; ++i) @@ -4702,12 +5060,14 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return Error(RetTypeLoc, "Invalid result type for LLVM function"); Ty = FunctionType::get(RetType, ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); } + CalleeID.FTy = Ty; + // Look up the callee. Value *Callee; - if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; + if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS)) + return true; // Set up the Attribute for the function. SmallVector Attrs; @@ -4755,7 +5115,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { // Finish off the Attribute and check them AttributeSet PAL = AttributeSet::get(Context, Attrs); - InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args); + InvokeInst *II = + InvokeInst::Create(Ty, Callee, NormalBB, UnwindBB, Args, BundleList); II->setCallingConv(CC); II->setAttributes(PAL); ForwardRefAttrGroups[II] = FwdRefAttrGrps; @@ -4775,6 +5136,183 @@ bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) { return false; } +bool LLParser::ParseExceptionArgs(SmallVectorImpl &Args, + PerFunctionState &PFS) { + if (ParseToken(lltok::lsquare, "expected '[' in catchpad/cleanuppad")) + return true; + + while (Lex.getKind() != lltok::rsquare) { + // If this isn't the first argument, we need a comma. + if (!Args.empty() && + ParseToken(lltok::comma, "expected ',' in argument list")) + return true; + + // Parse the argument. + LocTy ArgLoc; + Type *ArgTy = nullptr; + if (ParseType(ArgTy, ArgLoc)) + return true; + + Value *V; + if (ArgTy->isMetadataTy()) { + if (ParseMetadataAsValue(V, PFS)) + return true; + } else { + if (ParseValue(ArgTy, V, PFS)) + return true; + } + Args.push_back(V); + } + + Lex.Lex(); // Lex the ']'. + return false; +} + +/// ParseCleanupRet +/// ::= 'cleanupret' from Value unwind ('to' 'caller' | TypeAndValue) +bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { + Value *CleanupPad = nullptr; + + if (ParseToken(lltok::kw_from, "expected 'from' after cleanupret")) + return true; + + if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS)) + return true; + + if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret")) + return true; + + BasicBlock *UnwindBB = nullptr; + if (Lex.getKind() == lltok::kw_to) { + Lex.Lex(); + if (ParseToken(lltok::kw_caller, "expected 'caller' in cleanupret")) + return true; + } else { + if (ParseTypeAndBasicBlock(UnwindBB, PFS)) { + return true; + } + } + + Inst = CleanupReturnInst::Create(CleanupPad, UnwindBB); + return false; +} + +/// ParseCatchRet +/// ::= 'catchret' from Parent Value 'to' TypeAndValue +bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { + Value *CatchPad = nullptr; + + if (ParseToken(lltok::kw_from, "expected 'from' after catchret")) + return true; + + if (ParseValue(Type::getTokenTy(Context), CatchPad, PFS)) + return true; + + BasicBlock *BB; + if (ParseToken(lltok::kw_to, "expected 'to' in catchret") || + ParseTypeAndBasicBlock(BB, PFS)) + return true; + + Inst = CatchReturnInst::Create(CatchPad, BB); + return false; +} + +/// ParseCatchSwitch +/// ::= 'catchswitch' within Parent +bool LLParser::ParseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) { + Value *ParentPad; + LocTy BBLoc; + + if (ParseToken(lltok::kw_within, "expected 'within' after catchswitch")) + return true; + + if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar && + Lex.getKind() != lltok::LocalVarID) + return TokError("expected scope value for catchswitch"); + + if (ParseValue(Type::getTokenTy(Context), ParentPad, PFS)) + return true; + + if (ParseToken(lltok::lsquare, "expected '[' with catchswitch labels")) + return true; + + SmallVector Table; + do { + BasicBlock *DestBB; + if (ParseTypeAndBasicBlock(DestBB, PFS)) + return true; + Table.push_back(DestBB); + } while (EatIfPresent(lltok::comma)); + + if (ParseToken(lltok::rsquare, "expected ']' after catchswitch labels")) + return true; + + if (ParseToken(lltok::kw_unwind, + "expected 'unwind' after catchswitch scope")) + return true; + + BasicBlock *UnwindBB = nullptr; + if (EatIfPresent(lltok::kw_to)) { + if (ParseToken(lltok::kw_caller, "expected 'caller' in catchswitch")) + return true; + } else { + if (ParseTypeAndBasicBlock(UnwindBB, PFS)) + return true; + } + + auto *CatchSwitch = + CatchSwitchInst::Create(ParentPad, UnwindBB, Table.size()); + for (BasicBlock *DestBB : Table) + CatchSwitch->addHandler(DestBB); + Inst = CatchSwitch; + return false; +} + +/// ParseCatchPad +/// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue +bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { + Value *CatchSwitch = nullptr; + + if (ParseToken(lltok::kw_within, "expected 'within' after catchpad")) + return true; + + if (Lex.getKind() != lltok::LocalVar && Lex.getKind() != lltok::LocalVarID) + return TokError("expected scope value for catchpad"); + + if (ParseValue(Type::getTokenTy(Context), CatchSwitch, PFS)) + return true; + + SmallVector Args; + if (ParseExceptionArgs(Args, PFS)) + return true; + + Inst = CatchPadInst::Create(CatchSwitch, Args); + return false; +} + +/// ParseCleanupPad +/// ::= 'cleanuppad' within Parent ParamList +bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { + Value *ParentPad = nullptr; + + if (ParseToken(lltok::kw_within, "expected 'within' after cleanuppad")) + return true; + + if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar && + Lex.getKind() != lltok::LocalVarID) + return TokError("expected scope value for cleanuppad"); + + if (ParseValue(Type::getTokenTy(Context), ParentPad, PFS)) + return true; + + SmallVector Args; + if (ParseExceptionArgs(Args, PFS)) + return true; + + Inst = CleanupPadInst::Create(ParentPad, Args); + return false; +} + //===----------------------------------------------------------------------===// // Binary Operators. //===----------------------------------------------------------------------===// @@ -5029,14 +5567,11 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { /// ::= 'filter' TypeAndValue ( ',' TypeAndValue )* bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { Type *Ty = nullptr; LocTy TyLoc; - Value *PersFn; LocTy PersFnLoc; - if (ParseType(Ty, TyLoc) || - ParseToken(lltok::kw_personality, "expected 'personality'") || - ParseTypeAndValue(PersFn, PersFnLoc, PFS)) + if (ParseType(Ty, TyLoc)) return true; - LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, 0); + std::unique_ptr LP(LandingPadInst::Create(Ty, 0)); LP->setCleanup(EatIfPresent(lltok::kw_cleanup)); while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){ @@ -5050,10 +5585,8 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { Value *V; LocTy VLoc; - if (ParseTypeAndValue(V, VLoc, PFS)) { - delete LP; + if (ParseTypeAndValue(V, VLoc, PFS)) return true; - } // A 'catch' type expects a non-array constant. A filter clause expects an // array constant. @@ -5065,20 +5598,25 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { Error(VLoc, "'filter' clause has an invalid type"); } - LP->addClause(cast(V)); + Constant *CV = dyn_cast(V); + if (!CV) + return Error(VLoc, "clause argument must be a constant"); + LP->addClause(CV); } - Inst = LP; + Inst = LP.release(); return false; } /// ParseCall -/// ::= 'call' OptionalCallingConv OptionalAttrs Type Value -/// ParameterList OptionalAttrs -/// ::= 'tail' 'call' OptionalCallingConv OptionalAttrs Type Value -/// ParameterList OptionalAttrs -/// ::= 'musttail' 'call' OptionalCallingConv OptionalAttrs Type Value -/// ParameterList OptionalAttrs +/// ::= 'call' OptionalFastMathFlags OptionalCallingConv +/// OptionalAttrs Type Value ParameterList OptionalAttrs +/// ::= 'tail' 'call' OptionalFastMathFlags OptionalCallingConv +/// OptionalAttrs Type Value ParameterList OptionalAttrs +/// ::= 'musttail' 'call' OptionalFastMathFlags OptionalCallingConv +/// OptionalAttrs Type Value ParameterList OptionalAttrs +/// ::= 'notail' 'call' OptionalFastMathFlags OptionalCallingConv +/// OptionalAttrs Type Value ParameterList OptionalAttrs bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, CallInst::TailCallKind TCK) { AttrBuilder RetAttrs, FnAttrs; @@ -5089,27 +5627,34 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, LocTy RetTypeLoc; ValID CalleeID; SmallVector ArgList; + SmallVector BundleList; LocTy CallLoc = Lex.getLoc(); - if ((TCK != CallInst::TCK_None && - ParseToken(lltok::kw_call, "expected 'tail call'")) || - ParseOptionalCallingConv(CC) || - ParseOptionalReturnAttrs(RetAttrs) || + if (TCK != CallInst::TCK_None && + ParseToken(lltok::kw_call, + "expected 'tail call', 'musttail call', or 'notail call'")) + return true; + + FastMathFlags FMF = EatFastMathFlagsIfPresent(); + + if (ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS, TCK == CallInst::TCK_MustTail, PFS.getFunction().isVarArg()) || - ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, - BuiltinLoc)) + ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, BuiltinLoc) || + ParseOptionalOperandBundles(BundleList, PFS)) return true; + if (FMF.any() && !RetType->isFPOrFPVectorTy()) + return Error(CallLoc, "fast-math-flags specified for call without " + "floating-point scalar or vector return type"); + // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. - PointerType *PFTy = nullptr; - FunctionType *Ty = nullptr; - if (!(PFTy = dyn_cast(RetType)) || - !(Ty = dyn_cast(PFTy->getElementType()))) { + FunctionType *Ty = dyn_cast(RetType); + if (!Ty) { // Pull out the types of all of the arguments... std::vector ParamTypes; for (unsigned i = 0, e = ArgList.size(); i != e; ++i) @@ -5119,12 +5664,14 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return Error(RetTypeLoc, "Invalid result type for LLVM function"); Ty = FunctionType::get(RetType, ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); } + CalleeID.FTy = Ty; + // Look up the callee. Value *Callee; - if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; + if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS)) + return true; // Set up the Attribute for the function. SmallVector Attrs; @@ -5172,9 +5719,11 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, // Finish off the Attribute and check them AttributeSet PAL = AttributeSet::get(Context, Attrs); - CallInst *CI = CallInst::Create(Callee, Args); + CallInst *CI = CallInst::Create(Ty, Callee, Args, BundleList); CI->setTailCallKind(TCK); CI->setCallingConv(CC); + if (FMF.any()) + CI->setFastMathFlags(FMF); CI->setAttributes(PAL); ForwardRefAttrGroups[CI] = FwdRefAttrGrps; Inst = CI; @@ -5245,7 +5794,7 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) { Lex.Lex(); } - Type *Ty = nullptr; + Type *Ty; LocTy ExplicitTypeLoc = Lex.getLoc(); if (ParseType(Ty) || ParseToken(lltok::comma, "expected comma after load's type") || @@ -5254,8 +5803,7 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) { ParseOptionalCommaAlign(Alignment, AteExtraComma)) return true; - if (!Val->getType()->isPointerTy() || - !cast(Val->getType())->getElementType()->isFirstClassType()) + if (!Val->getType()->isPointerTy() || !Ty->isFirstClassType()) return Error(Loc, "load operand must be a pointer to a first class type"); if (isAtomic && !Alignment) return Error(Loc, "atomic load must have explicit non-zero alignment"); @@ -5266,7 +5814,7 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) { return Error(ExplicitTypeLoc, "explicit pointee type doesn't match operand's pointee type"); - Inst = new LoadInst(Val, "", isVolatile, Alignment, Ordering, Scope); + Inst = new LoadInst(Ty, Val, "", isVolatile, Alignment, Ordering, Scope); return AteExtraComma ? InstExtraComma : InstNormal; } @@ -5459,23 +6007,22 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { ParseTypeAndValue(Ptr, Loc, PFS)) return true; - Type *PtrTy = Ptr->getType(); - if (VectorType *VT = dyn_cast(PtrTy)) - PtrTy = VT->getElementType(); - SequentialType *SeqPtrTy = dyn_cast(PtrTy); - if (!SeqPtrTy) - return Error(Loc, "pointer type is not valid"); - if (Ty != SeqPtrTy->getElementType()) - return Error(ExplicitTypeLoc, - "explicit pointee type doesn't match operand's pointee type"); - Type *BaseType = Ptr->getType(); PointerType *BasePointerType = dyn_cast(BaseType->getScalarType()); if (!BasePointerType) return Error(Loc, "base of getelementptr must be a pointer"); + if (Ty != BasePointerType->getElementType()) + return Error(ExplicitTypeLoc, + "explicit pointee type doesn't match operand's pointee type"); + SmallVector Indices; bool AteExtraComma = false; + // GEP returns a vector of pointers if at least one of parameters is a vector. + // All vector parameters should have the same vector width. + unsigned GEPWidth = BaseType->isVectorTy() ? + BaseType->getVectorNumElements() : 0; + while (EatIfPresent(lltok::comma)) { if (Lex.getKind() == lltok::MetadataVar) { AteExtraComma = true; @@ -5484,24 +6031,24 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { if (ParseTypeAndValue(Val, EltLoc, PFS)) return true; if (!Val->getType()->getScalarType()->isIntegerTy()) return Error(EltLoc, "getelementptr index must be an integer"); - if (Val->getType()->isVectorTy() != Ptr->getType()->isVectorTy()) - return Error(EltLoc, "getelementptr index type missmatch"); + if (Val->getType()->isVectorTy()) { - unsigned ValNumEl = cast(Val->getType())->getNumElements(); - unsigned PtrNumEl = cast(Ptr->getType())->getNumElements(); - if (ValNumEl != PtrNumEl) + unsigned ValNumEl = Val->getType()->getVectorNumElements(); + if (GEPWidth && GEPWidth != ValNumEl) return Error(EltLoc, "getelementptr vector index has a wrong number of elements"); + GEPWidth = ValNumEl; } Indices.push_back(Val); } - if (!Indices.empty() && !BasePointerType->getElementType()->isSized()) + SmallPtrSet Visited; + if (!Indices.empty() && !Ty->isSized(&Visited)) return Error(Loc, "base element of getelementptr must be sized"); - if (!GetElementPtrInst::getIndexedType(BaseType, Indices)) + if (!GetElementPtrInst::getIndexedType(Ty, Indices)) return Error(Loc, "invalid getelementptr indices"); - Inst = GetElementPtrInst::Create(Ptr, Indices); + Inst = GetElementPtrInst::Create(Ty, Ptr, Indices); if (InBounds) cast(Inst)->setIsInBounds(true); return AteExtraComma ? InstExtraComma : InstNormal;