//===----------------------------------------------------------------------===//
#include "LLParser.h"
-#include "llvm/AutoUpgrade.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Operator.h"
-#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/AutoUpgrade.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
I != E; ++I) {
Instruction *Inst = I->first;
const std::vector<MDRef> &MDList = I->second;
-
+
for (unsigned i = 0, e = MDList.size(); i != e; ++i) {
unsigned SlotNo = MDList[i].MDSlot;
-
+
if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0)
return Error(MDList[i].Loc, "use of undefined metadata '!" +
Twine(SlotNo) + "'");
}
ForwardRefInstMetadata.clear();
}
-
-
+
+
// If there are entries in ForwardRefBlockAddresses at this point, they are
// references after the function was defined. Resolve those now.
while (!ForwardRefBlockAddresses.empty()) {
TheFn = M->getFunction(Fn.StrVal);
else if (Fn.UIntVal < NumberedVals.size())
TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]);
-
+
if (TheFn == 0)
return Error(Fn.Loc, "unknown function referenced by blockaddress");
-
+
// Resolve all these references.
- if (ResolveForwardRefBlockAddresses(TheFn,
+ if (ResolveForwardRefBlockAddresses(TheFn,
ForwardRefBlockAddresses.begin()->second,
0))
return true;
-
+
ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin());
}
-
+
for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i)
if (NumberedTypes[i].second.isValid())
return Error(NumberedTypes[i].second,
return false;
}
-bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn,
+bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn,
std::vector<std::pair<ValID, GlobalValue*> > &Refs,
PerFunctionState *PFS) {
// Loop over all the references, resolving them.
Res = dyn_cast_or_null<BasicBlock>(
TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal));
}
-
+
if (Res == 0)
return Error(Refs[i].first.Loc,
"referenced value is not a basic block");
-
+
// Get the BlockAddress for this and update references to use it.
BlockAddress *BA = BlockAddress::get(TheFn, Res);
Refs[i].second->replaceAllUsesWith(BA);
/// toplevelentity
/// ::= 'deplibs' '=' '[' ']'
/// ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']'
+/// FIXME: Remove in 4.0. Currently parse, but ignore.
bool LLParser::ParseDepLibs() {
assert(Lex.getKind() == lltok::kw_deplibs);
Lex.Lex();
if (EatIfPresent(lltok::rsquare))
return false;
- std::string Str;
- if (ParseStringConstant(Str)) return true;
- M->addLibrary(Str);
-
- while (EatIfPresent(lltok::comma)) {
+ do {
+ std::string Str;
if (ParseStringConstant(Str)) return true;
- M->addLibrary(Str);
- }
+ } while (EatIfPresent(lltok::comma));
return ParseToken(lltok::rsquare, "expected ']' at end of list");
}
if (TypeID >= NumberedTypes.size())
NumberedTypes.resize(TypeID+1);
-
+
Type *Result = 0;
if (ParseStructDefinition(TypeLoc, "",
NumberedTypes[TypeID], Result)) return true;
-
+
if (!isa<StructType>(Result)) {
std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID];
if (Entry.first)
if (ParseToken(lltok::equal, "expected '=' after name") ||
ParseToken(lltok::kw_type, "expected 'type' after name"))
return true;
-
+
Type *Result = 0;
if (ParseStructDefinition(NameLoc, Name,
NamedTypes[Name], Result)) return true;
-
+
if (!isa<StructType>(Result)) {
std::pair<Type*, LocTy> &Entry = NamedTypes[Name];
if (Entry.first)
Entry.first = Result;
Entry.second = SMLoc();
}
-
+
return false;
}
// Otherwise, create MDNode forward reference.
MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef<Value*>());
ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
-
+
if (NumberedMetadata.size() <= MID)
NumberedMetadata.resize(MID+1);
NumberedMetadata[MID] = FwdNode;
do {
if (ParseToken(lltok::exclaim, "Expected '!' here"))
return true;
-
+
MDNode *N = 0;
if (ParseMDNodeID(N)) return true;
NMD->addOperand(N);
return true;
MDNode *Init = MDNode::get(Context, Elts);
-
+
// See if this was forward referenced, if so, handle it.
std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator
FI = ForwardRefMDNodes.find(MetadataID);
Temp->replaceAllUsesWith(Init);
MDNode::deleteTemporary(Temp);
ForwardRefMDNodes.erase(FI);
-
+
assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");
} else {
if (MetadataID >= NumberedMetadata.size())
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
else
FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
- GlobalValue::ExternalWeakLinkage, 0, Name);
+ GlobalValue::ExternalWeakLinkage, 0, Name,
+ 0, GlobalVariable::NotThreadLocal,
+ PTy->getAddressSpace());
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
ParseToken(lltok::rparen, "expected ')' in address space");
}
-/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
-/// indicates what kind of attribute list this is: 0: function arg, 1: result,
-/// 2: function attr.
-bool LLParser::ParseOptionalAttrs(Attributes::Builder &B, unsigned AttrKind) {
- LocTy AttrLoc = Lex.getLoc();
+/// ParseOptionalFuncAttrs - Parse a potentially empty list of function attributes.
+bool LLParser::ParseOptionalFuncAttrs(AttrBuilder &B) {
bool HaveError = false;
B.clear();
switch (Token) {
default: // End of attributes.
return HaveError;
- case lltok::kw_zeroext: B.addZExtAttr(); break;
- case lltok::kw_signext: B.addSExtAttr(); break;
- case lltok::kw_inreg: B.addInRegAttr(); break;
- case lltok::kw_sret: B.addStructRetAttr(); break;
- case lltok::kw_noalias: B.addNoAliasAttr(); break;
- case lltok::kw_nocapture: B.addNoCaptureAttr(); break;
- case lltok::kw_byval: B.addByValAttr(); break;
- case lltok::kw_nest: B.addNestAttr(); break;
-
- case lltok::kw_noreturn: B.addNoReturnAttr(); break;
- case lltok::kw_nounwind: B.addNoUnwindAttr(); break;
- case lltok::kw_uwtable: B.addUWTableAttr(); break;
- case lltok::kw_returns_twice: B.addReturnsTwiceAttr(); break;
- case lltok::kw_noinline: B.addNoInlineAttr(); break;
- case lltok::kw_readnone: B.addReadNoneAttr(); break;
- case lltok::kw_readonly: B.addReadOnlyAttr(); break;
- case lltok::kw_inlinehint: B.addInlineHintAttr(); break;
- case lltok::kw_alwaysinline: B.addAlwaysInlineAttr(); break;
- case lltok::kw_optsize: B.addOptimizeForSizeAttr(); break;
- case lltok::kw_ssp: B.addStackProtectAttr(); break;
- case lltok::kw_sspreq: B.addStackProtectReqAttr(); break;
- case lltok::kw_noredzone: B.addNoRedZoneAttr(); break;
- case lltok::kw_noimplicitfloat: B.addNoImplicitFloatAttr(); break;
- case lltok::kw_naked: B.addNakedAttr(); break;
- case lltok::kw_nonlazybind: B.addNonLazyBindAttr(); break;
- case lltok::kw_address_safety: B.addAddressSafetyAttr(); break;
-
case lltok::kw_alignstack: {
unsigned Alignment;
if (ParseOptionalStackAlignment(Alignment))
B.addStackAlignmentAttr(Alignment);
continue;
}
-
case lltok::kw_align: {
+ // As a hack, we allow "align 2" on functions as a synonym for "alignstack
+ // 2".
unsigned Alignment;
if (ParseOptionalAlignment(Alignment))
return true;
B.addAlignmentAttr(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_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_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); 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_uwtable: B.addAttribute(Attribute::UWTable); break;
+ case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
+
+ // Error handling.
+ case lltok::kw_zeroext:
+ case lltok::kw_signext:
+ case lltok::kw_inreg:
+ HaveError |= Error(Lex.getLoc(), "invalid use of attribute on a function");
+ break;
+ case lltok::kw_sret: case lltok::kw_noalias:
+ case lltok::kw_nocapture: case lltok::kw_byval:
+ case lltok::kw_nest:
+ HaveError |=
+ Error(Lex.getLoc(), "invalid use of parameter-only attribute on a function");
+ break;
}
- // Perform some error checking.
+ Lex.Lex();
+ }
+}
+
+/// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes.
+bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
+ bool HaveError = false;
+
+ B.clear();
+
+ while (1) {
+ lltok::Kind Token = Lex.getKind();
switch (Token) {
- default:
- if (AttrKind == 2)
- HaveError |= Error(AttrLoc, "invalid use of attribute on a function");
- break;
- case lltok::kw_align:
- // As a hack, we allow "align 2" on functions as a synonym for
- // "alignstack 2".
+ default: // End of attributes.
+ return HaveError;
+ case lltok::kw_align: {
+ unsigned Alignment;
+ if (ParseOptionalAlignment(Alignment))
+ return true;
+ B.addAlignmentAttr(Alignment);
+ continue;
+ }
+ case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break;
+ case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
+ 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_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:
+ HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
break;
+ }
- // Parameter Only:
- case lltok::kw_sret:
- case lltok::kw_nocapture:
- case lltok::kw_byval:
- case lltok::kw_nest:
- if (AttrKind != 0)
- HaveError |= Error(AttrLoc, "invalid use of parameter-only attribute");
+ Lex.Lex();
+ }
+}
+
+/// ParseOptionalReturnAttrs - Parse a potentially empty list of return attributes.
+bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
+ bool HaveError = false;
+
+ B.clear();
+
+ while (1) {
+ lltok::Kind Token = Lex.getKind();
+ switch (Token) {
+ default: // End of attributes.
+ return HaveError;
+ case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
+ case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
+ case lltok::kw_signext: B.addAttribute(Attribute::SExt); 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:
+ HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute");
break;
- // Function Only:
- case lltok::kw_noreturn:
- case lltok::kw_nounwind:
- case lltok::kw_readnone:
- case lltok::kw_readonly:
- case lltok::kw_noinline:
- 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_inlinehint:
- case lltok::kw_alignstack:
- case lltok::kw_uwtable:
- case lltok::kw_nonlazybind:
- case lltok::kw_returns_twice:
- case lltok::kw_address_safety:
- if (AttrKind != 2)
- HaveError |= Error(AttrLoc, "invalid use of function-only attribute");
+ 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_align:
+ case lltok::kw_noduplicate:
+ HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
break;
}
/// ::= /*empty*/
/// ::= 'ccc'
/// ::= 'fastcc'
+/// ::= 'kw_intel_ocl_bicc'
/// ::= 'coldcc'
/// ::= 'x86_stdcallcc'
/// ::= 'x86_fastcallcc'
case lltok::kw_ptx_device: CC = CallingConv::PTX_Device; break;
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_cc: {
unsigned ArbitraryCC;
Lex.Lex();
}
/// ParseOptionalCommaAlign
-/// ::=
+/// ::=
/// ::= ',' align 4
///
/// This returns with AteExtraComma set to true if it ate an excess comma at the
AteExtraComma = true;
return false;
}
-
+
if (Lex.getKind() != lltok::kw_align)
return Error(Lex.getLoc(), "expected metadata or 'align'");
bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices,
bool &AteExtraComma) {
AteExtraComma = false;
-
+
if (Lex.getKind() != lltok::comma)
return TokError("expected ',' as start of index list");
case lltok::LocalVar: {
// Type ::= %foo
std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()];
-
+
// If the type hasn't been defined yet, create a forward definition and
// remember where that forward def'n was seen (in case it never is defined).
if (Entry.first == 0) {
if (Lex.getUIntVal() >= NumberedTypes.size())
NumberedTypes.resize(Lex.getUIntVal()+1);
std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()];
-
+
// If the type hasn't been defined yet, create a forward definition and
// remember where that forward def'n was seen (in case it never is defined).
if (Entry.first == 0) {
// Parse the argument.
LocTy ArgLoc;
Type *ArgTy = 0;
- Attributes::Builder ArgAttrs;
+ AttrBuilder ArgAttrs;
Value *V;
if (ParseType(ArgTy, ArgLoc))
return true;
// Otherwise, handle normal operands.
- if (ParseOptionalAttrs(ArgAttrs, 0) || ParseValue(ArgTy, V, PFS))
+ if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
return true;
- ArgList.push_back(ParamInfo(ArgLoc, V, Attributes::get(ArgAttrs)));
+ ArgList.push_back(ParamInfo(ArgLoc, V, Attribute::get(V->getContext(),
+ ArgAttrs)));
}
Lex.Lex(); // Lex the ')'.
} else {
LocTy TypeLoc = Lex.getLoc();
Type *ArgTy = 0;
- Attributes::Builder Attrs;
+ AttrBuilder Attrs;
std::string Name;
if (ParseType(ArgTy) ||
- ParseOptionalAttrs(Attrs, 0)) return true;
+ ParseOptionalParamAttrs(Attrs)) return true;
if (ArgTy->isVoidTy())
return Error(TypeLoc, "argument can not have void type");
if (!FunctionType::isValidArgumentType(ArgTy))
return Error(TypeLoc, "invalid type for function argument");
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attributes::get(Attrs), Name));
+ ArgList.push_back(ArgInfo(TypeLoc, ArgTy,
+ Attribute::get(ArgTy->getContext(),
+ Attrs), Name));
while (EatIfPresent(lltok::comma)) {
// Handle ... at end of arg list.
// Otherwise must be an argument type.
TypeLoc = Lex.getLoc();
- if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true;
+ if (ParseType(ArgTy) || ParseOptionalParamAttrs(Attrs)) return true;
if (ArgTy->isVoidTy())
return Error(TypeLoc, "argument can not have void type");
if (!ArgTy->isFirstClassType())
return Error(TypeLoc, "invalid type for function argument");
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attributes::get(Attrs), Name));
+ ArgList.push_back(ArgInfo(TypeLoc, ArgTy,
+ Attribute::get(ArgTy->getContext(), Attrs),
+ Name));
}
}
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)
+ if (ArgList[i].Attrs.hasAttributes())
return Error(ArgList[i].Loc,
"argument attributes invalid in function type");
}
bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) {
SmallVector<Type*, 8> Elts;
if (ParseStructBody(Elts)) return true;
-
+
Result = StructType::get(Context, Elts, Packed);
return false;
}
// If the type was already defined, diagnose the redefinition.
if (Entry.first && !Entry.second.isValid())
return Error(TypeLoc, "redefinition of type");
-
+
// If we have opaque, just return without filling in the definition for the
// struct. This counts as a definition as far as the .ll file goes.
if (EatIfPresent(lltok::kw_opaque)) {
// This type is being defined, so clear the location to indicate this.
Entry.second = SMLoc();
-
+
// If this type number has never been uttered, create it.
if (Entry.first == 0)
Entry.first = StructType::create(Context, Name);
ResultTy = Entry.first;
return false;
}
-
+
// If the type starts with '<', then it is either a packed struct or a vector.
bool isPacked = EatIfPresent(lltok::less);
if (Lex.getKind() != lltok::lbrace) {
if (Entry.first)
return Error(TypeLoc, "forward references to non-struct type");
-
+
ResultTy = 0;
if (isPacked)
return ParseArrayVectorType(ResultTy, true);
return ParseType(ResultTy);
}
-
+
// This type is being defined, so clear the location to indicate this.
Entry.second = SMLoc();
-
+
// If this type number has never been uttered, create it.
if (Entry.first == 0)
Entry.first = StructType::create(Context, Name);
-
+
StructType *STy = cast<StructType>(Entry.first);
-
+
SmallVector<Type*, 8> Body;
if (ParseStructBody(Body) ||
(isPacked && ParseToken(lltok::greater, "expected '>' in packed struct")))
return true;
-
+
STy->setBody(Body, isPacked);
ResultTy = STy;
return false;
if ((unsigned)Size != Size)
return Error(SizeLoc, "size too large for vector");
if (!VectorType::isValidElementType(EltTy))
- return Error(TypeLoc,
- "vector element type must be fp, integer or a pointer to these types");
+ return Error(TypeLoc, "invalid vector element type");
Result = VectorType::get(EltTy, unsigned(Size));
} else {
if (!ArrayType::isValidElementType(EltTy))
FunctionID.Kind = ValID::t_GlobalID;
FunctionID.UIntVal = FunctionNumber;
}
-
+
std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >::iterator
FRBAI = P.ForwardRefBlockAddresses.find(FunctionID);
if (FRBAI != P.ForwardRefBlockAddresses.end()) {
// Resolve all these references.
if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this))
return true;
-
+
P.ForwardRefBlockAddresses.erase(FRBAI);
}
}
-
+
if (!ForwardRefVals.empty())
return P.Error(ForwardRefVals.begin()->second.second,
"use of undefined value '%" + ForwardRefVals.begin()->first +
ValID Fn, Label;
LocTy FnLoc, LabelLoc;
-
+
if (ParseToken(lltok::lparen, "expected '(' in block address expression") ||
ParseValID(Fn) ||
ParseToken(lltok::comma, "expected comma in block address expression")||
ParseValID(Label) ||
ParseToken(lltok::rparen, "expected ')' in block address expression"))
return true;
-
+
if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
return Error(Fn.Loc, "expected function name in blockaddress");
if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName)
return Error(Label.Loc, "expected basic block name in blockaddress");
-
+
// Make a global variable as a placeholder for this reference.
GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context),
false, GlobalValue::InternalLinkage,
ID.Kind = ValID::t_Constant;
return false;
}
-
+
case lltok::kw_trunc:
case lltok::kw_zext:
case lltok::kw_sext:
return (V == 0);
case ValID::t_InlineAsm: {
PointerType *PTy = dyn_cast<PointerType>(Ty);
- FunctionType *FTy =
+ FunctionType *FTy =
PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
return Error(ID.Loc, "invalid type for inline asm constraint string");
"initializer with struct type has wrong # elements");
if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct))
return Error(ID.Loc, "packed'ness of initializer and type don't match");
-
+
// Verify that the elements are compatible with the structtype.
for (unsigned i = 0, e = ID.UIntVal; i != e; ++i)
if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i))
return Error(ID.Loc, "element " + Twine(i) +
" of struct initializer doesn't match struct element type");
-
+
V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts,
ID.UIntVal));
} else
unsigned Linkage;
unsigned Visibility;
- Attributes::Builder RetAttrs;
+ AttrBuilder RetAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc = Lex.getLoc();
if (ParseOptionalLinkage(Linkage) ||
ParseOptionalVisibility(Visibility) ||
ParseOptionalCallingConv(CC) ||
- ParseOptionalAttrs(RetAttrs, 1) ||
+ ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/))
return true;
SmallVector<ArgInfo, 8> ArgList;
bool isVarArg;
- Attributes::Builder FuncAttrs;
+ AttrBuilder FuncAttrs;
std::string Section;
unsigned Alignment;
std::string GC;
if (ParseArgumentList(ArgList, isVarArg) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
&UnnamedAddrLoc) ||
- ParseOptionalAttrs(FuncAttrs, 2) ||
+ ParseOptionalFuncAttrs(FuncAttrs) ||
(EatIfPresent(lltok::kw_section) &&
ParseStringConstant(Section)) ||
ParseOptionalAlignment(Alignment) ||
// If the alignment was parsed as an attribute, move to the alignment field.
if (FuncAttrs.hasAlignmentAttr()) {
Alignment = FuncAttrs.getAlignment();
- FuncAttrs.removeAlignmentAttr();
+ FuncAttrs.removeAttribute(Attribute::Alignment);
}
// Okay, if we got here, the function is syntactically valid. Convert types
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs)));
+ Attrs.push_back(
+ AttributeWithIndex::get(AttributeSet::ReturnIndex,
+ Attribute::get(RetType->getContext(),
+ RetAttrs)));
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
ParamTypeList.push_back(ArgList[i].Ty);
}
if (FuncAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FuncAttrs)));
+ Attrs.push_back(
+ AttributeWithIndex::get(AttributeSet::FunctionIndex,
+ Attribute::get(RetType->getContext(),
+ FuncAttrs)));
- AttrListPtr PAL = AttrListPtr::get(Attrs);
+ AttributeSet PAL = AttributeSet::get(Context, Attrs);
- if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) &&
- !RetType->isVoidTy())
+ if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy())
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
FunctionType *FT =
ForwardRefVals.find(FunctionName);
if (FRVI != ForwardRefVals.end()) {
Fn = M->getFunction(FunctionName);
+ if (!Fn)
+ return Error(FRVI->second.second, "invalid forward reference to "
+ "function as global value!");
if (Fn->getType() != PFT)
return Error(FRVI->second.second, "invalid forward reference to "
"function '" + FunctionName + "' with wrong type!");
-
+
ForwardRefVals.erase(FRVI);
} else if ((Fn = M->getFunction(FunctionName))) {
// Reject redefinitions.
int FunctionNumber = -1;
if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1;
-
+
PerFunctionState PFS(*this, Fn, FunctionNumber);
// We need at least one basic block.
if (Lex.getKind() == lltok::rbrace)
return TokError("function body requires at least one basic block");
-
+
while (Lex.getKind() != lltok::rbrace)
if (ParseBasicBlock(PFS)) return true;
// *must* be followed by metadata.
if (ParseInstructionMetadata(Inst, &PFS))
return true;
- break;
+ break;
}
// Set the name on the instruction.
bool NUW = EatIfPresent(lltok::kw_nuw);
bool NSW = EatIfPresent(lltok::kw_nsw);
if (!NUW) NUW = EatIfPresent(lltok::kw_nuw);
-
+
if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true;
-
+
if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
return false;
}
case lltok::kw_fadd:
case lltok::kw_fsub:
- case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
+ case lltok::kw_fmul:
+ case lltok::kw_fdiv:
+ case lltok::kw_frem: {
+ FastMathFlags FMF = EatFastMathFlagsIfPresent();
+ int Res = ParseArithmetic(Inst, PFS, KeywordVal, 2);
+ if (Res != 0)
+ return Res;
+ if (FMF.any())
+ Inst->setFastMathFlags(FMF);
+ return 0;
+ }
case lltok::kw_sdiv:
case lltok::kw_udiv:
case lltok::kw_urem:
case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1);
- case lltok::kw_fdiv:
- case lltok::kw_frem: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
case lltok::kw_and:
case lltok::kw_or:
case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal);
if (ParseType(Ty, true /*void allowed*/)) return true;
Type *ResType = PFS.getFunction().getReturnType();
-
+
if (Ty->isVoidTy()) {
if (!ResType->isVoidTy())
return Error(TypeLoc, "value doesn't match function result type '" +
getTypeString(ResType) + "'");
-
+
Inst = ReturnInst::Create(Context);
return false;
}
if (ResType != RV->getType())
return Error(TypeLoc, "value doesn't match function result type '" +
getTypeString(ResType) + "'");
-
+
Inst = ReturnInst::Create(Context, RV);
return false;
}
ParseToken(lltok::comma, "expected ',' after case value") ||
ParseTypeAndBasicBlock(DestBB, PFS))
return true;
-
+
if (!SeenCases.insert(Constant))
return Error(CondLoc, "duplicate case value in switch");
if (!isa<ConstantInt>(Constant))
ParseToken(lltok::comma, "expected ',' after indirectbr address") ||
ParseToken(lltok::lsquare, "expected '[' with indirectbr"))
return true;
-
+
if (!Address->getType()->isPointerTy())
return Error(AddrLoc, "indirectbr address must have pointer type");
-
+
// Parse the destination list.
SmallVector<BasicBlock*, 16> DestList;
-
+
if (Lex.getKind() != lltok::rsquare) {
BasicBlock *DestBB;
if (ParseTypeAndBasicBlock(DestBB, PFS))
return true;
DestList.push_back(DestBB);
-
+
while (EatIfPresent(lltok::comma)) {
if (ParseTypeAndBasicBlock(DestBB, PFS))
return true;
DestList.push_back(DestBB);
}
}
-
+
if (ParseToken(lltok::rsquare, "expected ']' at end of block list"))
return true;
/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
- Attributes::Builder RetAttrs, FnAttrs;
+ AttrBuilder RetAttrs, FnAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
BasicBlock *NormalBB, *UnwindBB;
if (ParseOptionalCallingConv(CC) ||
- ParseOptionalAttrs(RetAttrs, 1) ||
+ ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
- ParseOptionalAttrs(FnAttrs, 2) ||
+ ParseOptionalFuncAttrs(FnAttrs) ||
ParseToken(lltok::kw_to, "expected 'to' in invoke") ||
ParseTypeAndBasicBlock(NormalBB, PFS) ||
ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
Value *Callee;
if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
- // Set up the Attributes for the function.
+ // Set up the Attribute for the function.
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs)));
+ Attrs.push_back(
+ AttributeWithIndex::get(AttributeSet::ReturnIndex,
+ Attribute::get(Callee->getContext(),
+ RetAttrs)));
SmallVector<Value*, 8> Args;
return Error(CallLoc, "not enough parameters specified for call");
if (FnAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FnAttrs)));
+ Attrs.push_back(
+ AttributeWithIndex::get(AttributeSet::FunctionIndex,
+ Attribute::get(Callee->getContext(),
+ FnAttrs)));
- // Finish off the Attributes and check them
- AttrListPtr PAL = AttrListPtr::get(Attrs);
+ // Finish off the Attribute and check them
+ AttributeSet PAL = AttributeSet::get(Context, Attrs);
InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args);
II->setCallingConv(CC);
/// ParameterList OptionalAttrs
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
bool isTail) {
- Attributes::Builder RetAttrs, FnAttrs;
+ AttrBuilder RetAttrs, FnAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
ParseOptionalCallingConv(CC) ||
- ParseOptionalAttrs(RetAttrs, 1) ||
+ ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
- ParseOptionalAttrs(FnAttrs, 2))
+ ParseOptionalFuncAttrs(FnAttrs))
return true;
// If RetType is a non-function pointer type, then this is the short syntax
Value *Callee;
if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
- // Set up the Attributes for the function.
+ // Set up the Attribute for the function.
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs)));
+ Attrs.push_back(
+ AttributeWithIndex::get(AttributeSet::ReturnIndex,
+ Attribute::get(Callee->getContext(),
+ RetAttrs)));
SmallVector<Value*, 8> Args;
return Error(CallLoc, "not enough parameters specified for call");
if (FnAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FnAttrs)));
+ Attrs.push_back(
+ AttributeWithIndex::get(AttributeSet::FunctionIndex,
+ Attribute::get(Callee->getContext(),
+ FnAttrs)));
- // Finish off the Attributes and check them
- AttrListPtr PAL = AttrListPtr::get(Attrs);
+ // Finish off the Attribute and check them
+ AttributeSet PAL = AttributeSet::get(Context, Attrs);
CallInst *CI = CallInst::Create(Callee, Args);
CI->setTailCall(isTail);
/// ParseLoad
/// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)?
-/// ::= 'load' 'atomic' 'volatile'? TypeAndValue
+/// ::= 'load' 'atomic' 'volatile'? TypeAndValue
/// 'singlethread'? AtomicOrdering (',' 'align' i32)?
int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val; LocTy Loc;
Indices.push_back(Val);
}
- if (Val && Val->getType()->isVectorTy() && Indices.size() != 1)
- return Error(EltLoc, "vector getelementptrs must have a single index");
-
if (!GetElementPtrInst::getIndexedType(Ptr->getType(), Indices))
return Error(Loc, "invalid getelementptr indices");
Inst = GetElementPtrInst::Create(Ptr, Indices);
ParseTypeAndValue(Val1, Loc1, PFS) ||
ParseIndexList(Indices, AteExtraComma))
return true;
-
+
if (!Val0->getType()->isAggregateType())
return Error(Loc0, "insertvalue operand must be aggregate type");
Elts.push_back(0);
continue;
}
-
+
Value *V = 0;
if (ParseTypeAndValue(V, PFS)) return true;
Elts.push_back(V);