X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAsmParser%2FLLParser.cpp;h=3471a2dbd05cd53d85f3d5980dea2ee2880afb7a;hb=fbbc16fa87defddc1d6eecb56e609a8ae6438ed1;hp=e8b8e815e6422f302cd99780b01f7fb42b3e7ec8;hpb=9987cb60bac069f6d1af3fced71f8b6284ef87a1;p=oota-llvm.git diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index e8b8e815e64..3471a2dbd05 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -49,7 +49,9 @@ bool LLParser::Run() { ValidateEndOfModule(); } -bool LLParser::parseStandaloneConstantValue(Constant *&C) { +bool LLParser::parseStandaloneConstantValue(Constant *&C, + const SlotMapping *Slots) { + restoreParsingState(Slots); Lex.Lex(); Type *Ty = nullptr; @@ -60,6 +62,19 @@ bool LLParser::parseStandaloneConstantValue(Constant *&C) { 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() { @@ -170,7 +185,7 @@ 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); @@ -181,6 +196,10 @@ bool LLParser::ValidateEndOfModule() { // 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; } @@ -659,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 && @@ -681,11 +706,35 @@ 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"); + 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(PTy, (GlobalValue::LinkageTypes)Linkage, Name, - Aliasee, /*Parent*/ nullptr)); + GlobalAlias::create(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage, + Name, Aliasee, /*Parent*/ nullptr)); GA->setThreadLocalMode(TLM); GA->setVisibility((GlobalValue::VisibilityTypes)Visibility); GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); @@ -694,27 +743,17 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, if (Name.empty()) NumberedVals.push_back(GA.get()); - // 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 (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. @@ -779,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); @@ -957,6 +995,10 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, 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; @@ -969,6 +1011,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, 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; @@ -1021,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. @@ -1039,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; } @@ -1054,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; } @@ -1079,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; } @@ -1094,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; } @@ -1352,6 +1390,13 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { 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; @@ -1359,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: @@ -1502,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) { @@ -1530,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); @@ -1912,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. @@ -2175,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() { @@ -2218,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; } @@ -2251,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; } @@ -2292,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; @@ -2324,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); } @@ -2340,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); } @@ -2450,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 '}' @@ -3097,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) {} }; @@ -3188,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) { @@ -3600,8 +3729,11 @@ bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) { /// isOptimized: true, flags: "-O2", runtimeVersion: 1, /// splitDebugFilename: "abc.debug", emissionKind: 1, /// enums: !1, retainedTypes: !2, subprograms: !3, -/// globals: !4, imports: !5, dwoId: 0x0abcd) +/// 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, (/* AllowNull */ false)); \ @@ -3616,16 +3748,16 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { OPTIONAL(subprograms, MDField, ); \ OPTIONAL(globals, MDField, ); \ OPTIONAL(imports, MDField, ); \ + OPTIONAL(macros, MDField, ); \ OPTIONAL(dwoId, MDUnsignedField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DICompileUnit, - (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, dwoId.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; } @@ -3635,9 +3767,10 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { /// 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) +/// 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, ); \ OPTIONAL(name, MDStringField, ); \ @@ -3653,19 +3786,23 @@ bool LLParser::ParseDISubprogram(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( - 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, 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; } @@ -3716,6 +3853,39 @@ bool LLParser::ParseDINamespace(MDNode *&Result, bool IsDistinct) { return false; } +/// 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: "/") @@ -4001,8 +4171,7 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, V = PFS->GetVal(ID.StrVal, Ty, ID.Loc); return V == nullptr; case ValID::t_InlineAsm: { - assert(ID.FTy); - if (!InlineAsm::Verify(ID.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(ID.FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1, (ID.UIntVal >> 1) & 1, @@ -4066,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"); @@ -4105,6 +4279,7 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { 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: { @@ -4123,8 +4298,7 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { 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) { @@ -4297,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) @@ -4320,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) @@ -4555,10 +4727,9 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, 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_catchpad: return ParseCatchPad(Inst, PFS); - case lltok::kw_terminatepad: return ParseTerminatePad(Inst, PFS); - case lltok::kw_cleanuppad: return ParseCleanupPad(Inst, PFS); - case lltok::kw_catchendpad: return ParseCatchEndPad(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: @@ -4641,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); @@ -4859,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") || @@ -4943,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(Ty, Callee, NormalBB, UnwindBB, Args); + InvokeInst *II = + InvokeInst::Create(Ty, Callee, NormalBB, UnwindBB, Args, BundleList); II->setCallingConv(CC); II->setAttributes(PAL); ForwardRefAttrGroups[II] = FwdRefAttrGrps; @@ -4965,7 +5138,7 @@ bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) { bool LLParser::ParseExceptionArgs(SmallVectorImpl &Args, PerFunctionState &PFS) { - if (ParseToken(lltok::lsquare, "expected '[' in cleanuppad")) + if (ParseToken(lltok::lsquare, "expected '[' in catchpad/cleanuppad")) return true; while (Lex.getKind() != lltok::rsquare) { @@ -4996,16 +5169,15 @@ bool LLParser::ParseExceptionArgs(SmallVectorImpl &Args, } /// ParseCleanupRet -/// ::= 'cleanupret' ('void' | TypeAndValue) unwind ('to' 'caller' | TypeAndValue) +/// ::= 'cleanupret' from Value unwind ('to' 'caller' | TypeAndValue) bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { - Type *RetTy = nullptr; - Value *RetVal = nullptr; - if (ParseType(RetTy, /*AllowVoid=*/true)) + Value *CleanupPad = nullptr; + + if (ParseToken(lltok::kw_from, "expected 'from' after cleanupret")) return true; - if (!RetTy->isVoidTy()) - if (ParseValue(RetTy, RetVal, PFS)) - return true; + if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS)) + return true; if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret")) return true; @@ -5021,100 +5193,123 @@ bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { } } - Inst = CleanupReturnInst::Create(Context, RetVal, UnwindBB); + Inst = CleanupReturnInst::Create(CleanupPad, UnwindBB); return false; } /// ParseCatchRet -/// ::= 'catchret' TypeAndValue +/// ::= '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 (ParseTypeAndBasicBlock(BB, PFS)) + if (ParseToken(lltok::kw_to, "expected 'to' in catchret") || + ParseTypeAndBasicBlock(BB, PFS)) return true; - Inst = CatchReturnInst::Create(BB); + Inst = CatchReturnInst::Create(CatchPad, BB); return false; } -/// ParseCatchPad -/// ::= 'catchpad' Type ParamList 'to' TypeAndValue 'unwind' TypeAndValue -bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { - Type *RetType = nullptr; +/// ParseCatchSwitch +/// ::= 'catchswitch' within Parent +bool LLParser::ParseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) { + Value *ParentPad; + LocTy BBLoc; - SmallVector Args; - if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS)) + if (ParseToken(lltok::kw_within, "expected 'within' after catchswitch")) return true; - BasicBlock *NormalBB, *UnwindBB; - if (ParseToken(lltok::kw_to, "expected 'to' in catchpad") || - ParseTypeAndBasicBlock(NormalBB, PFS) || - ParseToken(lltok::kw_unwind, "expected 'unwind' in catchpad") || - ParseTypeAndBasicBlock(UnwindBB, PFS)) + 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; - Inst = CatchPadInst::Create(RetType, NormalBB, UnwindBB, Args); - return false; -} + if (ParseToken(lltok::lsquare, "expected '[' with catchswitch labels")) + return true; -/// ParseTerminatePad -/// ::= 'terminatepad' ParamList 'to' TypeAndValue -bool LLParser::ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS) { - SmallVector Args; - if (ParseExceptionArgs(Args, PFS)) + 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' in terminatepad")) + if (ParseToken(lltok::kw_unwind, + "expected 'unwind' after catchswitch scope")) return true; BasicBlock *UnwindBB = nullptr; - if (Lex.getKind() == lltok::kw_to) { - Lex.Lex(); - if (ParseToken(lltok::kw_caller, "expected 'caller' in terminatepad")) + if (EatIfPresent(lltok::kw_to)) { + if (ParseToken(lltok::kw_caller, "expected 'caller' in catchswitch")) return true; } else { - if (ParseTypeAndBasicBlock(UnwindBB, PFS)) { + if (ParseTypeAndBasicBlock(UnwindBB, PFS)) return true; - } } - Inst = TerminatePadInst::Create(Context, UnwindBB, Args); + auto *CatchSwitch = + CatchSwitchInst::Create(ParentPad, UnwindBB, Table.size()); + for (BasicBlock *DestBB : Table) + CatchSwitch->addHandler(DestBB); + Inst = CatchSwitch; return false; } -/// ParseCleanupPad -/// ::= 'cleanuppad' ParamList -bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { - Type *RetType = nullptr; +/// 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 (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS)) + if (ParseExceptionArgs(Args, PFS)) return true; - Inst = CleanupPadInst::Create(RetType, Args); + Inst = CatchPadInst::Create(CatchSwitch, Args); return false; } -/// ParseCatchEndPad -/// ::= 'catchendpad' unwind ('to' 'caller' | TypeAndValue) -bool LLParser::ParseCatchEndPad(Instruction *&Inst, PerFunctionState &PFS) { - if (ParseToken(lltok::kw_unwind, "expected 'unwind' in catchendpad")) +/// 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; - BasicBlock *UnwindBB = nullptr; - if (Lex.getKind() == lltok::kw_to) { - Lex.Lex(); - if (Lex.getKind() == lltok::kw_caller) { - Lex.Lex(); - } else { - return true; - } - } else { - if (ParseTypeAndBasicBlock(UnwindBB, PFS)) { - 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; - Inst = CatchEndPadInst::Create(Context, UnwindBB); + SmallVector Args; + if (ParseExceptionArgs(Args, PFS)) + return true; + + Inst = CleanupPadInst::Create(ParentPad, Args); return false; } @@ -5414,12 +5609,14 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { } /// 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; @@ -5430,20 +5627,29 @@ 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. @@ -5513,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(Ty, 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;