diff options
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 206 |
1 files changed, 109 insertions, 97 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 4cd986e143b6c..58ea9296afda4 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -130,10 +130,9 @@ bool LLParser::ValidateEndOfModule() { B.merge(NumberedAttrBuilders[Attr]); if (Function *Fn = dyn_cast<Function>(V)) { - AttributeSet AS = Fn->getAttributes(); - AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); - AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, - AS.getFnAttributes()); + AttributeList AS = Fn->getAttributes(); + AttrBuilder FnAttrs(AS.getFnAttributes()); + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex); FnAttrs.merge(B); @@ -144,32 +143,27 @@ bool LLParser::ValidateEndOfModule() { FnAttrs.removeAttribute(Attribute::Alignment); } - AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, - AttributeSet::get(Context, - AttributeSet::FunctionIndex, - FnAttrs)); + AS = AS.addAttributes( + Context, AttributeList::FunctionIndex, + AttributeList::get(Context, AttributeList::FunctionIndex, FnAttrs)); Fn->setAttributes(AS); } else if (CallInst *CI = dyn_cast<CallInst>(V)) { - AttributeSet AS = CI->getAttributes(); - AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); - AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, - AS.getFnAttributes()); + AttributeList AS = CI->getAttributes(); + AttrBuilder FnAttrs(AS.getFnAttributes()); + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex); FnAttrs.merge(B); - AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, - AttributeSet::get(Context, - AttributeSet::FunctionIndex, - FnAttrs)); + AS = AS.addAttributes( + Context, AttributeList::FunctionIndex, + AttributeList::get(Context, AttributeList::FunctionIndex, FnAttrs)); CI->setAttributes(AS); } else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) { - AttributeSet AS = II->getAttributes(); - AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); - AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, - AS.getFnAttributes()); + AttributeList AS = II->getAttributes(); + AttrBuilder FnAttrs(AS.getFnAttributes()); + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex); FnAttrs.merge(B); - AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, - AttributeSet::get(Context, - AttributeSet::FunctionIndex, - FnAttrs)); + AS = AS.addAttributes( + Context, AttributeList::FunctionIndex, + AttributeList::get(Context, AttributeList::FunctionIndex, FnAttrs)); II->setAttributes(AS); } else { llvm_unreachable("invalid object with forward attribute group reference"); @@ -1855,6 +1849,34 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment, return false; } +/// ParseOptionalCommaAddrSpace +/// ::= +/// ::= ',' addrspace(1) +/// +/// This returns with AteExtraComma set to true if it ate an excess comma at the +/// end. +bool LLParser::ParseOptionalCommaAddrSpace(unsigned &AddrSpace, + LocTy &Loc, + bool &AteExtraComma) { + AteExtraComma = false; + while (EatIfPresent(lltok::comma)) { + // Metadata at the end is an early exit. + if (Lex.getKind() == lltok::MetadataVar) { + AteExtraComma = true; + return false; + } + + Loc = Lex.getLoc(); + if (Lex.getKind() != lltok::kw_addrspace) + return Error(Lex.getLoc(), "expected metadata or 'addrspace'"); + + if (ParseOptionalAddrSpace(AddrSpace)) + return true; + } + + return false; +} + bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg, Optional<unsigned> &HowManyArg) { Lex.Lex(); @@ -2098,7 +2120,6 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, if (ParseToken(lltok::lparen, "expected '(' in call")) return true; - unsigned AttrIndex = 1; while (Lex.getKind() != lltok::rparen) { // If this isn't the first argument, we need a comma. if (!ArgList.empty() && @@ -2132,9 +2153,8 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS)) return true; } - ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(), - AttrIndex++, - ArgAttrs))); + ArgList.push_back(ParamInfo( + ArgLoc, V, AttributeSet::get(V->getContext(), ArgAttrs))); } if (IsMustTailCall && InVarArgsFunc) @@ -2239,9 +2259,8 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, if (!FunctionType::isValidArgumentType(ArgTy)) return Error(TypeLoc, "invalid type for function argument"); - unsigned AttrIndex = 1; - ArgList.emplace_back(TypeLoc, ArgTy, AttributeSet::get(ArgTy->getContext(), - AttrIndex++, Attrs), + ArgList.emplace_back(TypeLoc, ArgTy, + AttributeSet::get(ArgTy->getContext(), Attrs), std::move(Name)); while (EatIfPresent(lltok::comma)) { @@ -2268,10 +2287,9 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, if (!ArgTy->isFirstClassType()) return Error(TypeLoc, "invalid type for function argument"); - ArgList.emplace_back( - TypeLoc, ArgTy, - AttributeSet::get(ArgTy->getContext(), AttrIndex++, Attrs), - std::move(Name)); + ArgList.emplace_back(TypeLoc, ArgTy, + AttributeSet::get(ArgTy->getContext(), Attrs), + std::move(Name)); } } @@ -2295,7 +2313,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { if (!ArgList[i].Name.empty()) return Error(ArgList[i].Loc, "argument name invalid in function type"); - if (ArgList[i].Attrs.hasAttributes(i + 1)) + if (ArgList[i].Attrs.hasAttributes()) return Error(ArgList[i].Loc, "argument attributes invalid in function type"); } @@ -3908,7 +3926,8 @@ bool LLParser::ParseDIBasicType(MDNode *&Result, bool IsDistinct) { /// 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) +/// align: 32, offset: 0, flags: 0, extraData: !3, +/// dwarfAddressSpace: 3) bool LLParser::ParseDIDerivedType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(tag, DwarfTagField, ); \ @@ -3921,14 +3940,20 @@ bool LLParser::ParseDIDerivedType(MDNode *&Result, bool IsDistinct) { OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ - OPTIONAL(extraData, MDField, ); + OPTIONAL(extraData, MDField, ); \ + OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS + Optional<unsigned> DWARFAddressSpace; + if (dwarfAddressSpace.Val != UINT32_MAX) + DWARFAddressSpace = dwarfAddressSpace.Val; + 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)); + offset.Val, DWARFAddressSpace, flags.Val, + extraData.Val)); return false; } @@ -4029,7 +4054,8 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { OPTIONAL(imports, MDField, ); \ OPTIONAL(macros, MDField, ); \ OPTIONAL(dwoId, MDUnsignedField, ); \ - OPTIONAL(splitDebugInlining, MDBoolField, = true); + OPTIONAL(splitDebugInlining, MDBoolField, = true); \ + OPTIONAL(debugInfoForProfiling, MDBoolField, = false); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4037,7 +4063,7 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val, runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val, - splitDebugInlining.Val); + splitDebugInlining.Val, debugInfoForProfiling.Val); return false; } @@ -4589,6 +4615,9 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { C = cast<Constant>(V); return false; } + case ValID::t_Null: + C = Constant::getNullValue(Ty); + return false; default: return Error(Loc, "expected a constant value"); } @@ -4735,25 +4764,14 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { std::vector<Type*> ParamTypeList; SmallVector<AttributeSet, 8> Attrs; - if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeSet::get(RetType->getContext(), - AttributeSet::ReturnIndex, - RetAttrs)); - for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { ParamTypeList.push_back(ArgList[i].Ty); - if (ArgList[i].Attrs.hasAttributes(i + 1)) { - AttrBuilder B(ArgList[i].Attrs, i + 1); - Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); - } + Attrs.push_back(ArgList[i].Attrs); } - if (FuncAttrs.hasAttributes()) - Attrs.push_back(AttributeSet::get(RetType->getContext(), - AttributeSet::FunctionIndex, - FuncAttrs)); - - AttributeSet PAL = AttributeSet::get(Context, Attrs); + AttributeList PAL = + AttributeList::get(Context, AttributeSet::get(Context, FuncAttrs), + AttributeSet::get(Context, RetAttrs), Attrs); if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy()) return Error(RetTypeLoc, "functions with 'sret' argument must return void"); @@ -5363,13 +5381,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return true; // Set up the Attribute for the function. - SmallVector<AttributeSet, 8> Attrs; - if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeSet::get(RetType->getContext(), - AttributeSet::ReturnIndex, - RetAttrs)); - - SmallVector<Value*, 8> Args; + SmallVector<Value *, 8> Args; + SmallVector<AttributeSet, 8> ArgAttrs; // Loop through FunctionType's arguments and ensure they are specified // correctly. Also, gather any parameter attributes. @@ -5387,26 +5400,19 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes(i + 1)) { - AttrBuilder B(ArgList[i].Attrs, i + 1); - Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); - } + ArgAttrs.push_back(ArgList[i].Attrs); } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs.hasAttributes()) { - if (FnAttrs.hasAlignmentAttr()) - return Error(CallLoc, "invoke instructions may not have an alignment"); - - Attrs.push_back(AttributeSet::get(RetType->getContext(), - AttributeSet::FunctionIndex, - FnAttrs)); - } + if (FnAttrs.hasAlignmentAttr()) + return Error(CallLoc, "invoke instructions may not have an alignment"); // Finish off the Attribute and check them - AttributeSet PAL = AttributeSet::get(Context, Attrs); + AttributeList PAL = + AttributeList::get(Context, AttributeSet::get(Context, FnAttrs), + AttributeSet::get(Context, RetAttrs), ArgAttrs); InvokeInst *II = InvokeInst::Create(Ty, Callee, NormalBB, UnwindBB, Args, BundleList); @@ -5968,10 +5974,6 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, // Set up the Attribute for the function. SmallVector<AttributeSet, 8> Attrs; - if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeSet::get(RetType->getContext(), - AttributeSet::ReturnIndex, - RetAttrs)); SmallVector<Value*, 8> Args; @@ -5991,26 +5993,19 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes(i + 1)) { - AttrBuilder B(ArgList[i].Attrs, i + 1); - Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); - } + Attrs.push_back(ArgList[i].Attrs); } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs.hasAttributes()) { - if (FnAttrs.hasAlignmentAttr()) - return Error(CallLoc, "call instructions may not have an alignment"); - - Attrs.push_back(AttributeSet::get(RetType->getContext(), - AttributeSet::FunctionIndex, - FnAttrs)); - } + if (FnAttrs.hasAlignmentAttr()) + return Error(CallLoc, "call instructions may not have an alignment"); // Finish off the Attribute and check them - AttributeSet PAL = AttributeSet::get(Context, Attrs); + AttributeList PAL = + AttributeList::get(Context, AttributeSet::get(Context, FnAttrs), + AttributeSet::get(Context, RetAttrs), Attrs); CallInst *CI = CallInst::Create(Ty, Callee, Args, BundleList); CI->setTailCallKind(TCK); @@ -6032,8 +6027,9 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, /// (',' 'align' i32)? int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { Value *Size = nullptr; - LocTy SizeLoc, TyLoc; + LocTy SizeLoc, TyLoc, ASLoc; unsigned Alignment = 0; + unsigned AddrSpace = 0; Type *Ty = nullptr; bool IsInAlloca = EatIfPresent(lltok::kw_inalloca); @@ -6047,12 +6043,21 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { bool AteExtraComma = false; if (EatIfPresent(lltok::comma)) { if (Lex.getKind() == lltok::kw_align) { - if (ParseOptionalAlignment(Alignment)) return true; + if (ParseOptionalAlignment(Alignment)) + return true; + if (ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma)) + return true; + } else if (Lex.getKind() == lltok::kw_addrspace) { + ASLoc = Lex.getLoc(); + if (ParseOptionalAddrSpace(AddrSpace)) + return true; } else if (Lex.getKind() == lltok::MetadataVar) { AteExtraComma = true; } else { if (ParseTypeAndValue(Size, SizeLoc, PFS) || - ParseOptionalCommaAlign(Alignment, AteExtraComma)) + ParseOptionalCommaAlign(Alignment, AteExtraComma) || + (!AteExtraComma && + ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))) return true; } } @@ -6060,7 +6065,14 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { if (Size && !Size->getType()->isIntegerTy()) return Error(SizeLoc, "element count must have integer type"); - AllocaInst *AI = new AllocaInst(Ty, Size, Alignment); + const DataLayout &DL = M->getDataLayout(); + unsigned AS = DL.getAllocaAddrSpace(); + if (AS != AddrSpace) { + // TODO: In the future it should be possible to specify addrspace per-alloca. + return Error(ASLoc, "address space must match datalayout"); + } + + AllocaInst *AI = new AllocaInst(Ty, AS, Size, Alignment); AI->setUsedWithInAlloca(IsInAlloca); AI->setSwiftError(IsSwiftError); Inst = AI; |