X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FAsmParser%2FLLParser.cpp;h=3471a2dbd05cd53d85f3d5980dea2ee2880afb7a;hp=399364e5eb248ac5816c9f1524f17adddf473baf;hb=9889174eadb0f269ef132b3bd34a9f6fe3baa642;hpb=4105a7b5677d25851b26936bf15ca919d3d9eb7c diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 399364e5eb2..3471a2dbd05 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -713,6 +713,24 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, 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, @@ -725,26 +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. - auto 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. @@ -809,7 +818,7 @@ 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 { @@ -986,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; @@ -1533,8 +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) { @@ -1563,8 +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); @@ -2304,7 +2321,7 @@ bool LLParser::PerFunctionState::FinishFunction() { /// 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, OperatorConstraint OC) { + LocTy Loc) { // Look this name up in the normal function symbol table. Value *Val = F.getValueSymbolTable().lookup(Name); @@ -2318,24 +2335,6 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty, // If we have the value in the symbol table or fwd-ref table, return it. if (Val) { - // Check operator constraints. - switch (OC) { - case OC_None: - // no constraint - break; - case OC_CatchPad: - if (!isa(Val)) { - P.Error(Loc, "'%" + Name + "' is not a catchpad"); - return nullptr; - } - break; - case OC_CleanupPad: - if (!isa(Val)) { - P.Error(Loc, "'%" + Name + "' is not a cleanuppad"); - return nullptr; - } - break; - } if (Val->getType() == Ty) return Val; if (Ty->isLabelTy()) P.Error(Loc, "'%" + Name + "' is not a basic block"); @@ -2354,30 +2353,16 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty, // Otherwise, create a new forward reference for this value and remember it. Value *FwdVal; if (Ty->isLabelTy()) { - assert(!OC); FwdVal = BasicBlock::Create(F.getContext(), Name, &F); - } else if (!OC) { - FwdVal = new Argument(Ty, Name); } else { - switch (OC) { - case OC_CatchPad: - FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {}, - Name); - break; - case OC_CleanupPad: - FwdVal = CleanupPadInst::Create(F.getContext(), {}, Name); - break; - default: - llvm_unreachable("unexpected constraint"); - } + FwdVal = new Argument(Ty, Name); } ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; } -Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc, - OperatorConstraint OC) { +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; @@ -2391,24 +2376,6 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc, // If we have the value in the symbol table or fwd-ref table, return it. if (Val) { - // Check operator constraint. - switch (OC) { - case OC_None: - // no constraint - break; - case OC_CatchPad: - if (!isa(Val)) { - P.Error(Loc, "'%" + Twine(ID) + "' is not a catchpad"); - return nullptr; - } - break; - case OC_CleanupPad: - if (!isa(Val)) { - P.Error(Loc, "'%" + Twine(ID) + "' is not a cleanuppad"); - return nullptr; - } - break; - } if (Val->getType() == Ty) return Val; if (Ty->isLabelTy()) P.Error(Loc, "'%" + Twine(ID) + "' is not a basic block"); @@ -2426,21 +2393,9 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc, // Otherwise, create a new forward reference for this value and remember it. Value *FwdVal; if (Ty->isLabelTy()) { - assert(!OC); FwdVal = BasicBlock::Create(F.getContext(), "", &F); - } else if (!OC) { - FwdVal = new Argument(Ty); } else { - switch (OC) { - case OC_CatchPad: - FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {}); - break; - case OC_CleanupPad: - FwdVal = CleanupPadInst::Create(F.getContext(), {}); - break; - default: - llvm_unreachable("unexpected constraint"); - } + FwdVal = new Argument(Ty); } ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); @@ -2476,17 +2431,6 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, if (Sentinel->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + getTypeString(FI->second.first->getType()) + "'"); - // Check operator constraints. We only put cleanuppads or catchpads in - // the forward value map if the value is constrained to match. - if (isa(Sentinel)) { - if (!isa(Inst)) - return P.Error(FI->second.second, - "'%" + Twine(NameID) + "' is not a catchpad"); - } else if (isa(Sentinel)) { - if (!isa(Inst)) - return P.Error(FI->second.second, - "'%" + Twine(NameID) + "' is not a cleanuppad"); - } Sentinel->replaceAllUsesWith(Inst); delete Sentinel; @@ -2504,17 +2448,6 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, if (Sentinel->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + getTypeString(FI->second.first->getType()) + "'"); - // Check operator constraints. We only put cleanuppads or catchpads in - // the forward value map if the value is constrained to match. - if (isa(Sentinel)) { - if (!isa(Inst)) - return P.Error(FI->second.second, - "'%" + NameStr + "' is not a catchpad"); - } else if (isa(Sentinel)) { - if (!isa(Inst)) - return P.Error(FI->second.second, - "'%" + NameStr + "' is not a cleanuppad"); - } Sentinel->replaceAllUsesWith(Inst); delete Sentinel; @@ -3268,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) {} }; @@ -3359,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) { @@ -3771,7 +3729,7 @@ 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"); @@ -3790,6 +3748,7 @@ 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 @@ -3797,7 +3756,8 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { 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, dwoId.Val); + retainedTypes.Val, subprograms.Val, globals.Val, imports.Val, macros.Val, + dwoId.Val); return false; } @@ -3893,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: "/") @@ -4164,30 +4157,18 @@ bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) { //===----------------------------------------------------------------------===// bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, - PerFunctionState *PFS, - OperatorConstraint OC) { + PerFunctionState *PFS) { if (Ty->isFunctionTy()) return Error(ID.Loc, "functions are not values, refer to them as pointers"); - if (OC && ID.Kind != ValID::t_LocalID && ID.Kind != ValID::t_LocalName) { - switch (OC) { - case OC_CatchPad: - return Error(ID.Loc, "Catchpad value required in this position"); - case OC_CleanupPad: - return Error(ID.Loc, "Cleanuppad value required in this position"); - default: - llvm_unreachable("Unexpected constraint kind"); - } - } - switch (ID.Kind) { case ValID::t_LocalID: if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); - V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc, OC); + V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc); return V == nullptr; case ValID::t_LocalName: if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); - V = PFS->GetVal(ID.StrVal, Ty, ID.Loc, OC); + V = PFS->GetVal(ID.StrVal, Ty, ID.Loc); return V == nullptr; case ValID::t_InlineAsm: { if (!ID.FTy || !InlineAsm::Verify(ID.FTy, ID.StrVal2)) @@ -4314,11 +4295,10 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { } } -bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS, - OperatorConstraint OC) { +bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) { V = nullptr; ValID ID; - return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS, OC); + return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS); } bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) { @@ -4747,11 +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_cleanupendpad: return ParseCleanupEndPad(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: @@ -5191,11 +5169,14 @@ bool LLParser::ParseExceptionArgs(SmallVectorImpl &Args, } /// ParseCleanupRet -/// ::= 'cleanupret' Value unwind ('to' 'caller' | TypeAndValue) +/// ::= 'cleanupret' from Value unwind ('to' 'caller' | TypeAndValue) bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { Value *CleanupPad = nullptr; - if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS, OC_CleanupPad)) + 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")) @@ -5212,16 +5193,19 @@ bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { } } - Inst = CleanupReturnInst::Create(cast(CleanupPad), UnwindBB); + Inst = CleanupReturnInst::Create(CleanupPad, UnwindBB); return false; } /// ParseCatchRet -/// ::= 'catchret' Value 'to' TypeAndValue +/// ::= 'catchret' from Parent Value 'to' TypeAndValue bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { Value *CatchPad = nullptr; - if (ParseValue(Type::getTokenTy(Context), CatchPad, PFS, OC_CatchPad)) + if (ParseToken(lltok::kw_from, "expected 'from' after catchret")) + return true; + + if (ParseValue(Type::getTokenTy(Context), CatchPad, PFS)) return true; BasicBlock *BB; @@ -5229,114 +5213,103 @@ bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { ParseTypeAndBasicBlock(BB, PFS)) return true; - Inst = CatchReturnInst::Create(cast(CatchPad), BB); + Inst = CatchReturnInst::Create(CatchPad, BB); return false; } -/// ParseCatchPad -/// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue -bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { - SmallVector Args; - if (ParseExceptionArgs(Args, PFS)) +/// 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; - 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(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) { - SmallVector Args; - if (ParseExceptionArgs(Args, PFS)) +/// 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; - Inst = CleanupPadInst::Create(Context, Args); - return false; -} + if (Lex.getKind() != lltok::LocalVar && Lex.getKind() != lltok::LocalVarID) + return TokError("expected scope value for catchpad"); -/// ParseCatchEndPad -/// ::= 'catchendpad' unwind ('to' 'caller' | TypeAndValue) -bool LLParser::ParseCatchEndPad(Instruction *&Inst, PerFunctionState &PFS) { - if (ParseToken(lltok::kw_unwind, "expected 'unwind' in catchendpad")) + if (ParseValue(Type::getTokenTy(Context), CatchSwitch, PFS)) 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; - } - } + SmallVector Args; + if (ParseExceptionArgs(Args, PFS)) + return true; - Inst = CatchEndPadInst::Create(Context, UnwindBB); + Inst = CatchPadInst::Create(CatchSwitch, Args); return false; } -/// ParseCatchEndPad -/// ::= 'cleanupendpad' Value unwind ('to' 'caller' | TypeAndValue) -bool LLParser::ParseCleanupEndPad(Instruction *&Inst, PerFunctionState &PFS) { - Value *CleanupPad = nullptr; +/// ParseCleanupPad +/// ::= 'cleanuppad' within Parent ParamList +bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { + Value *ParentPad = nullptr; - if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS, OC_CleanupPad)) + if (ParseToken(lltok::kw_within, "expected 'within' after cleanuppad")) return true; - if (ParseToken(lltok::kw_unwind, "expected 'unwind' in catchendpad")) + 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; - 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; - } - } + SmallVector Args; + if (ParseExceptionArgs(Args, PFS)) + return true; - Inst = CleanupEndPadInst::Create(cast(CleanupPad), UnwindBB); + Inst = CleanupPadInst::Create(ParentPad, Args); return false; } @@ -5636,14 +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 -/// ::= 'notail' '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; @@ -5657,10 +5630,14 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, SmallVector BundleList; LocTy CallLoc = Lex.getLoc(); - if ((TCK != CallInst::TCK_None && - ParseToken(lltok::kw_call, - "expected 'tail call', 'musttail call', or 'notail 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, @@ -5669,6 +5646,10 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, 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. @@ -5741,6 +5722,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, 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;