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,
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,
if (Result) return false;
// Otherwise, create MDNode forward reference.
- MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef<Value*>());
+ MDNode *FwdNode = MDNode::getTemporary(Context, None);
ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
if (NumberedMetadata.size() <= MID)
assert(Lex.getKind() == lltok::AttrGrpID);
unsigned VarID = Lex.getUIntVal();
std::vector<unsigned> 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;
/// ::= <attr> | <attr> '=' <value>
bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
std::vector<unsigned> &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;
return true;
B.addAttribute(Attr, Val);
- break;
+ continue;
}
// 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;
case lltok::kw_alignstack: {
unsigned Alignment;
if (inAttrGrp) {
+ Lex.Lex();
if (ParseToken(lltok::equal, "expected '=' here") ||
ParseUInt32(Alignment))
return true;
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:
case lltok::kw_nest:
case lltok::kw_noalias:
case lltok::kw_nocapture:
+ case lltok::kw_returned:
case lltok::kw_sret:
HaveError |=
Error(Lex.getLoc(),
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;
}
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();
/// ::= 'ptx_device'
/// ::= 'spir_func'
/// ::= 'spir_kernel'
+/// ::= 'x86_64_sysvcc'
+/// ::= 'x86_64_win64cc'
/// ::= 'cc' UINT
///
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();
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) ||
bool isVarArg;
AttrBuilder FuncAttrs;
std::vector<unsigned> FwdRefAttrGrps;
+ LocTy BuiltinLoc;
std::string Section;
unsigned Alignment;
std::string GC;
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) ||
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();
LocTy CallLoc = Lex.getLoc();
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
+ LocTy NoBuiltinLoc;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
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") ||
bool isTail) {
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
+ LocTy BuiltinLoc;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
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
if (ParseTypeAndValue(Ptr, Loc, PFS)) return true;
- if (!Ptr->getType()->getScalarType()->isPointerTy())
+ Type *BaseType = Ptr->getType();
+ PointerType *BasePointerType = dyn_cast<PointerType>(BaseType->getScalarType());
+ if (!BasePointerType)
return Error(Loc, "base of getelementptr must be a pointer");
SmallVector<Value*, 16> Indices;
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)