X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAsmParser%2FLLParser.cpp;h=62a07f5016a66a742c3cad8f17c1a2ffdea45aa8;hb=7a88b655ccad0f128ea1a5e8ca433a8827a24ff3;hp=9a76007bb9946eed996b9a19bf58b001487d366c;hpb=0f7422057e7cf0426f5bb293107b756b5de80523;p=oota-llvm.git diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 9a76007bb99..62a07f5016a 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -102,7 +102,7 @@ bool LLParser::ValidateEndOfModule() { AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, AS.getFnAttributes()); - + FnAttrs.merge(B); AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, AttributeSet::get(Context, AttributeSet::FunctionIndex, @@ -113,7 +113,7 @@ bool LLParser::ValidateEndOfModule() { AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, AS.getFnAttributes()); - + FnAttrs.merge(B); AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, AttributeSet::get(Context, AttributeSet::FunctionIndex, @@ -528,7 +528,7 @@ bool LLParser::ParseMDNodeID(MDNode *&Result) { if (Result) return false; // Otherwise, create MDNode forward reference. - MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef()); + MDNode *FwdNode = MDNode::getTemporary(Context, None); ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc()); if (NumberedMetadata.size() <= MID) @@ -810,11 +810,13 @@ bool LLParser::ParseUnnamedAttrGrp() { assert(Lex.getKind() == lltok::AttrGrpID); unsigned VarID = Lex.getUIntVal(); std::vector unused; + LocTy BuiltinLoc; Lex.Lex(); if (ParseToken(lltok::equal, "expected '=' here") || ParseToken(lltok::lbrace, "expected '{' here") || - ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true) || + ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true, + BuiltinLoc) || ParseToken(lltok::rbrace, "expected end of attribute group")) return true; @@ -828,13 +830,15 @@ bool LLParser::ParseUnnamedAttrGrp() { /// ::= | '=' bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, std::vector &FwdRefAttrGrps, - bool inAttrGrp) { + bool inAttrGrp, LocTy &BuiltinLoc) { bool HaveError = false; B.clear(); while (true) { lltok::Kind Token = Lex.getKind(); + if (Token == lltok::kw_builtin) + BuiltinLoc = Lex.getLoc(); switch (Token) { default: if (!inAttrGrp) return HaveError; @@ -874,10 +878,12 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, // Target-independent attributes: case lltok::kw_align: { - // As a hack, we allow "align 2" on functions as a synonym for "alignstack - // 2". + // As a hack, we allow function alignment to be initially parsed as an + // attribute on a function declaration/definition or added to an attribute + // group and later moved to the alignment field. unsigned Alignment; if (inAttrGrp) { + Lex.Lex(); if (ParseToken(lltok::equal, "expected '=' here") || ParseUInt32(Alignment)) return true; @@ -891,6 +897,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, case lltok::kw_alignstack: { unsigned Alignment; if (inAttrGrp) { + Lex.Lex(); if (ParseToken(lltok::equal, "expected '=' here") || ParseUInt32(Alignment)) return true; @@ -901,26 +908,31 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, B.addStackAlignmentAttr(Alignment); continue; } - case lltok::kw_address_safety: B.addAttribute(Attribute::AddressSafety); break; - case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break; - case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break; - case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break; - case lltok::kw_naked: B.addAttribute(Attribute::Naked); 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_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_uwtable: B.addAttribute(Attribute::UWTable); break; + 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_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_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; // Error handling. case lltok::kw_inreg: @@ -934,6 +946,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, case lltok::kw_nest: case lltok::kw_noalias: case lltok::kw_nocapture: + case lltok::kw_returned: case lltok::kw_sret: HaveError |= Error(Lex.getLoc(), @@ -1146,20 +1159,36 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break; + case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; + case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break; + case lltok::kw_returned: B.addAttribute(Attribute::Returned); break; case lltok::kw_signext: B.addAttribute(Attribute::SExt); break; case lltok::kw_sret: B.addAttribute(Attribute::StructRet); break; case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; - case lltok::kw_noreturn: case lltok::kw_nounwind: - case lltok::kw_uwtable: case lltok::kw_returns_twice: - case lltok::kw_noinline: case lltok::kw_readnone: - case lltok::kw_readonly: case lltok::kw_inlinehint: - case lltok::kw_alwaysinline: case lltok::kw_optsize: - case lltok::kw_ssp: case lltok::kw_sspreq: - case lltok::kw_noredzone: case lltok::kw_noimplicitfloat: - case lltok::kw_naked: case lltok::kw_nonlazybind: - case lltok::kw_address_safety: case lltok::kw_minsize: case lltok::kw_alignstack: + case lltok::kw_alwaysinline: + case lltok::kw_builtin: + case lltok::kw_inlinehint: + case lltok::kw_minsize: + case lltok::kw_naked: + case lltok::kw_nobuiltin: + case lltok::kw_noduplicate: + case lltok::kw_noimplicitfloat: + case lltok::kw_noinline: + case lltok::kw_nonlazybind: + case lltok::kw_noredzone: + case lltok::kw_noreturn: + case lltok::kw_nounwind: + case lltok::kw_optsize: + case lltok::kw_returns_twice: + case lltok::kw_sanitize_address: + case lltok::kw_sanitize_memory: + case lltok::kw_sanitize_thread: + case lltok::kw_ssp: + case lltok::kw_sspreq: + case lltok::kw_sspstrong: + case lltok::kw_uwtable: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; } @@ -1185,24 +1214,45 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; // Error handling. - case lltok::kw_sret: case lltok::kw_nocapture: - case lltok::kw_byval: case lltok::kw_nest: + case lltok::kw_align: + case lltok::kw_byval: + case lltok::kw_nest: + case lltok::kw_nocapture: + case lltok::kw_returned: + case lltok::kw_sret: HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute"); break; - case lltok::kw_noreturn: case lltok::kw_nounwind: - case lltok::kw_uwtable: case lltok::kw_returns_twice: - case lltok::kw_noinline: case lltok::kw_readnone: - case lltok::kw_readonly: case lltok::kw_inlinehint: - case lltok::kw_alwaysinline: case lltok::kw_optsize: - case lltok::kw_ssp: case lltok::kw_sspreq: - case lltok::kw_sspstrong: case lltok::kw_noimplicitfloat: - case lltok::kw_noredzone: case lltok::kw_naked: - case lltok::kw_nonlazybind: case lltok::kw_address_safety: - case lltok::kw_minsize: case lltok::kw_alignstack: - case lltok::kw_align: case lltok::kw_noduplicate: + case lltok::kw_alignstack: + case lltok::kw_alwaysinline: + case lltok::kw_builtin: + case lltok::kw_cold: + case lltok::kw_inlinehint: + case lltok::kw_minsize: + case lltok::kw_naked: + case lltok::kw_nobuiltin: + case lltok::kw_noduplicate: + case lltok::kw_noimplicitfloat: + case lltok::kw_noinline: + case lltok::kw_nonlazybind: + case lltok::kw_noredzone: + case lltok::kw_noreturn: + case lltok::kw_nounwind: + case lltok::kw_optsize: + case lltok::kw_returns_twice: + case lltok::kw_sanitize_address: + case lltok::kw_sanitize_memory: + case lltok::kw_sanitize_thread: + case lltok::kw_ssp: + case lltok::kw_sspreq: + case lltok::kw_sspstrong: + case lltok::kw_uwtable: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; + + case lltok::kw_readnone: + case lltok::kw_readonly: + HaveError |= Error(Lex.getLoc(), "invalid use of attribute on return type"); } Lex.Lex(); @@ -1294,6 +1344,8 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) { /// ::= 'ptx_device' /// ::= 'spir_func' /// ::= 'spir_kernel' +/// ::= 'x86_64_sysvcc' +/// ::= 'x86_64_win64cc' /// ::= 'cc' UINT /// bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { @@ -1314,6 +1366,8 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { case lltok::kw_spir_kernel: CC = CallingConv::SPIR_KERNEL; break; case lltok::kw_spir_func: CC = CallingConv::SPIR_FUNC; break; case lltok::kw_intel_ocl_bicc: CC = CallingConv::Intel_OCL_BI; break; + case lltok::kw_x86_64_sysvcc: CC = CallingConv::X86_64_SysV; break; + case lltok::kw_x86_64_win64cc: CC = CallingConv::X86_64_Win64; break; case lltok::kw_cc: { unsigned ArbitraryCC; Lex.Lex(); @@ -2306,7 +2360,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return false; case lltok::kw_asm: { - // ValID ::= 'asm' SideEffect? AlignStack? STRINGCONSTANT ',' STRINGCONSTANT + // ValID ::= 'asm' SideEffect? AlignStack? IntelDialect? STRINGCONSTANT ',' + // STRINGCONSTANT bool HasSideEffect, AlignStack, AsmDialect; Lex.Lex(); if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) || @@ -2937,6 +2992,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { bool isVarArg; AttrBuilder FuncAttrs; std::vector FwdRefAttrGrps; + LocTy BuiltinLoc; std::string Section; unsigned Alignment; std::string GC; @@ -2946,7 +3002,8 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (ParseArgumentList(ArgList, isVarArg) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || - ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false) || + ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false, + BuiltinLoc) || (EatIfPresent(lltok::kw_section) && ParseStringConstant(Section)) || ParseOptionalAlignment(Alignment) || @@ -2954,6 +3011,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { ParseStringConstant(GC))) return true; + if (FuncAttrs.contains(Attribute::Builtin)) + return Error(BuiltinLoc, "'builtin' attribute not valid on function"); + // If the alignment was parsed as an attribute, move to the alignment field. if (FuncAttrs.hasAlignmentAttr()) { Alignment = FuncAttrs.getAlignment(); @@ -3467,6 +3527,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { LocTy CallLoc = Lex.getLoc(); AttrBuilder RetAttrs, FnAttrs; std::vector FwdRefAttrGrps; + LocTy NoBuiltinLoc; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc; @@ -3479,7 +3540,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || - ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false) || + ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, + NoBuiltinLoc) || ParseToken(lltok::kw_to, "expected 'to' in invoke") || ParseTypeAndBasicBlock(NormalBB, PFS) || ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") || @@ -3874,6 +3936,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, bool isTail) { AttrBuilder RetAttrs, FnAttrs; std::vector FwdRefAttrGrps; + LocTy BuiltinLoc; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc; @@ -3887,7 +3950,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || - ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false)) + ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, + BuiltinLoc)) return true; // If RetType is a non-function pointer type, then this is the short syntax @@ -4210,7 +4274,9 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { if (ParseTypeAndValue(Ptr, Loc, PFS)) return true; - if (!Ptr->getType()->getScalarType()->isPointerTy()) + Type *BaseType = Ptr->getType(); + PointerType *BasePointerType = dyn_cast(BaseType->getScalarType()); + if (!BasePointerType) return Error(Loc, "base of getelementptr must be a pointer"); SmallVector Indices; @@ -4235,7 +4301,10 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Indices.push_back(Val); } - if (!GetElementPtrInst::getIndexedType(Ptr->getType(), Indices)) + if (!Indices.empty() && !BasePointerType->getElementType()->isSized()) + return Error(Loc, "base element of getelementptr must be sized"); + + if (!GetElementPtrInst::getIndexedType(BaseType, Indices)) return Error(Loc, "invalid getelementptr indices"); Inst = GetElementPtrInst::Create(Ptr, Indices); if (InBounds)