summaryrefslogtreecommitdiff
path: root/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
-rw-r--r--lib/AsmParser/LLParser.cpp206
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;