#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
+#include "llvm/MDNode.h"
#include "llvm/Module.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/SmallPtrSet.h"
t_LocalName, t_GlobalName, // Name in StrVal.
t_APSInt, t_APFloat, // Value in APSIntVal/APFloatVal.
t_Null, t_Undef, t_Zero, // No value.
+ t_EmptyArray, // No value: []
t_Constant, // Value in ConstantVal.
t_InlineAsm // Value in StrVal/StrVal2/UIntVal.
} Kind;
// optional leading prefixes, the production is:
// GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
// OptionalAddrSpace ('constant'|'global') ...
+ case lltok::kw_private: // OptionalLinkage
case lltok::kw_internal: // OptionalLinkage
case lltok::kw_weak: // OptionalLinkage
+ case lltok::kw_weak_odr: // OptionalLinkage
case lltok::kw_linkonce: // OptionalLinkage
+ case lltok::kw_linkonce_odr: // OptionalLinkage
case lltok::kw_appending: // OptionalLinkage
case lltok::kw_dllexport: // OptionalLinkage
case lltok::kw_common: // OptionalLinkage
unsigned TypeID = NumberedTypes.size();
- // We don't allow assigning names to void type
- if (Ty == Type::VoidTy)
- return Error(TypeLoc, "can't assign name to the void type");
-
// See if this type was previously referenced.
std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
FI = ForwardRefTypeIDs.find(TypeID);
if (FI != ForwardRefTypeIDs.end()) {
+ if (FI->second.first.get() == Ty)
+ return Error(TypeLoc, "self referential type is invalid");
+
cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty);
Ty = FI->second.first.get();
ForwardRefTypeIDs.erase(FI);
ParseType(Ty))
return true;
- // We don't allow assigning names to void type
- if (Ty == Type::VoidTy)
- return Error(NameLoc, "can't assign name '" + Name + "' to the void type");
-
// Set the type name, checking for conflicts as we do so.
bool AlreadyExists = M->addTypeName(Name, Ty);
if (!AlreadyExists) return false;
std::map<std::string, std::pair<PATypeHolder, LocTy> >::iterator
FI = ForwardRefTypes.find(Name);
if (FI != ForwardRefTypes.end()) {
+ if (FI->second.first.get() == Ty)
+ return Error(NameLoc, "self referential type is invalid");
+
cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty);
Ty = FI->second.first.get();
ForwardRefTypes.erase(FI);
IsConstant = true;
else if (Lex.getKind() == lltok::kw_global)
IsConstant = false;
- else
+ else {
+ IsConstant = false;
return TokError("expected 'global' or 'constant'");
+ }
Lex.Lex();
return false;
}
/// ParseAlias:
/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
/// Aliasee
-/// ::= TypeAndValue | 'bitcast' '(' TypeAndValue 'to' Type ')'
+/// ::= TypeAndValue
+/// ::= 'bitcast' '(' TypeAndValue 'to' Type ')'
+/// ::= 'getelementptr' '(' ... ')'
///
/// Everything through visibility has already been parsed.
///
return true;
if (Linkage != GlobalValue::ExternalLinkage &&
- Linkage != GlobalValue::WeakLinkage &&
- Linkage != GlobalValue::InternalLinkage)
+ Linkage != GlobalValue::WeakAnyLinkage &&
+ Linkage != GlobalValue::WeakODRLinkage &&
+ Linkage != GlobalValue::InternalLinkage &&
+ Linkage != GlobalValue::PrivateLinkage)
return Error(LinkageLoc, "invalid linkage type for alias");
Constant *Aliasee;
LocTy AliaseeLoc = Lex.getLoc();
- if (Lex.getKind() != lltok::kw_bitcast) {
+ if (Lex.getKind() != lltok::kw_bitcast &&
+ Lex.getKind() != lltok::kw_getelementptr) {
if (ParseGlobalTypeAndValue(Aliasee)) return true;
} else {
// The bitcast dest type is not present, it is implied by the dest type.
}
if (isa<FunctionType>(Ty) || Ty == Type::LabelTy)
- return Error(TyLoc, "invald type for global variable");
+ return Error(TyLoc, "invalid type for global variable");
GlobalVariable *GV = 0;
// See if the global was forward referenced, if so, use the global.
- if (!Name.empty() && (GV = M->getGlobalVariable(Name, true))) {
- if (!ForwardRefVals.erase(Name))
+ if (!Name.empty()) {
+ if ((GV = M->getGlobalVariable(Name, true)) &&
+ !ForwardRefVals.erase(Name))
return Error(NameLoc, "redefinition of global '@" + Name + "'");
} else {
std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator
// Otherwise, create a new forward reference for this value and remember it.
GlobalValue *FwdVal;
- if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType()))
+ if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
+ // Function types can return opaque but functions can't.
+ if (isa<OpaqueType>(FT->getReturnType())) {
+ Error(Loc, "function may not return opaque type");
+ return 0;
+ }
+
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
- else
+ } else {
FwdVal = new GlobalVariable(PTy->getElementType(), false,
GlobalValue::ExternalWeakLinkage, 0, Name, M);
+ }
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
// Otherwise, create a new forward reference for this value and remember it.
GlobalValue *FwdVal;
- if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType()))
+ if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
+ // Function types can return opaque but functions can't.
+ if (isa<OpaqueType>(FT->getReturnType())) {
+ Error(Loc, "function may not return opaque type");
+ return 0;
+ }
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M);
- else
+ } else {
FwdVal = new GlobalVariable(PTy->getElementType(), false,
GlobalValue::ExternalWeakLinkage, 0, "", M);
+ }
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
return FwdVal;
/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
/// indicates what kind of attribute list this is: 0: function arg, 1: result,
/// 2: function attr.
+/// 3: function arg after value: FIXME: REMOVE IN LLVM 3.0
bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
Attrs = Attribute::None;
LocTy AttrLoc = Lex.getLoc();
switch (Lex.getKind()) {
case lltok::kw_sext:
case lltok::kw_zext:
- // Treat these as signext/zeroext unless they are function attrs.
+ // Treat these as signext/zeroext if they occur in the argument list after
+ // the value, as in "call i8 @foo(i8 10 sext)". If they occur before the
+ // value, as in "call i8 @foo(i8 sext (" then it is part of a constant
+ // expr.
// FIXME: REMOVE THIS IN LLVM 3.0
- if (AttrKind != 2) {
+ if (AttrKind == 3) {
if (Lex.getKind() == lltok::kw_sext)
Attrs |= Attribute::SExt;
else
if (AttrKind != 2 && (Attrs & Attribute::FunctionOnly))
return Error(AttrLoc, "invalid use of function-only attribute");
- if (AttrKind != 0 && (Attrs & Attribute::ParameterOnly))
+ if (AttrKind != 0 && AttrKind != 3 && (Attrs & Attribute::ParameterOnly))
return Error(AttrLoc, "invalid use of parameter-only attribute");
return false;
- case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break;
- case lltok::kw_signext: Attrs |= Attribute::SExt; break;
- case lltok::kw_inreg: Attrs |= Attribute::InReg; break;
- case lltok::kw_sret: Attrs |= Attribute::StructRet; break;
- case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break;
- case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break;
- case lltok::kw_byval: Attrs |= Attribute::ByVal; break;
- case lltok::kw_nest: Attrs |= Attribute::Nest; break;
-
- case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break;
- case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break;
- case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
- case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
- case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
- case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
- case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
- case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
- case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break;
-
+ case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break;
+ case lltok::kw_signext: Attrs |= Attribute::SExt; break;
+ case lltok::kw_inreg: Attrs |= Attribute::InReg; break;
+ case lltok::kw_sret: Attrs |= Attribute::StructRet; break;
+ case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break;
+ case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break;
+ case lltok::kw_byval: Attrs |= Attribute::ByVal; break;
+ case lltok::kw_nest: Attrs |= Attribute::Nest; break;
+
+ case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break;
+ case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break;
+ case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
+ case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
+ case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
+ case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
+ case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
+ case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
+ case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break;
+ case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break;
+ case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
case lltok::kw_align: {
unsigned Alignment;
/// ParseOptionalLinkage
/// ::= /*empty*/
+/// ::= 'private'
/// ::= 'internal'
/// ::= 'weak'
+/// ::= 'weak_odr'
/// ::= 'linkonce'
+/// ::= 'linkonce_odr'
/// ::= 'appending'
/// ::= 'dllexport'
/// ::= 'common'
bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
HasLinkage = false;
switch (Lex.getKind()) {
- default: Res = GlobalValue::ExternalLinkage; return false;
- case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break;
- case lltok::kw_weak: Res = GlobalValue::WeakLinkage; break;
- case lltok::kw_linkonce: Res = GlobalValue::LinkOnceLinkage; break;
- case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break;
- case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break;
- case lltok::kw_common: Res = GlobalValue::CommonLinkage; break;
- case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break;
- case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break;
- case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break;
+ default: Res = GlobalValue::ExternalLinkage; return false;
+ case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break;
+ case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break;
+ case lltok::kw_weak: Res = GlobalValue::WeakAnyLinkage; break;
+ case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break;
+ case lltok::kw_linkonce: Res = GlobalValue::LinkOnceAnyLinkage; break;
+ case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break;
+ case lltok::kw_available_externally:
+ Res = GlobalValue::AvailableExternallyLinkage;
+ break;
+ case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break;
+ case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break;
+ case lltok::kw_common: Res = GlobalValue::CommonLinkage; break;
+ case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break;
+ case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break;
+ case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break;
}
Lex.Lex();
HasLinkage = true;
/// ::= 'coldcc'
/// ::= 'x86_stdcallcc'
/// ::= 'x86_fastcallcc'
+/// ::= 'arm_apcscc'
+/// ::= 'arm_aapcscc'
+/// ::= 'arm_aapcs_vfpcc'
/// ::= 'cc' UINT
-///
+///
bool LLParser::ParseOptionalCallingConv(unsigned &CC) {
switch (Lex.getKind()) {
default: CC = CallingConv::C; return false;
case lltok::kw_coldcc: CC = CallingConv::Cold; break;
case lltok::kw_x86_stdcallcc: CC = CallingConv::X86_StdCall; break;
case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break;
+ case lltok::kw_arm_apcscc: CC = CallingConv::ARM_APCS; break;
+ case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break;
+ case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
case lltok::kw_cc: Lex.Lex(); return ParseUInt32(CC);
}
Lex.Lex();
Alignment = 0;
if (!EatIfPresent(lltok::kw_align))
return false;
- return ParseUInt32(Alignment);
+ LocTy AlignLoc = Lex.getLoc();
+ if (ParseUInt32(Alignment)) return true;
+ if (!isPowerOf2_32(Alignment))
+ return Error(AlignLoc, "alignment is not a power of two");
+ return false;
}
/// ParseOptionalCommaAlignment
//===----------------------------------------------------------------------===//
/// ParseType - Parse and resolve a full type.
-bool LLParser::ParseType(PATypeHolder &Result) {
+bool LLParser::ParseType(PATypeHolder &Result, bool AllowVoid) {
+ LocTy TypeLoc = Lex.getLoc();
if (ParseTypeRec(Result)) return true;
// Verify no unresolved uprefs.
if (!UpRefs.empty())
return Error(UpRefs.back().Loc, "invalid unresolved type up reference");
+ if (!AllowVoid && Result.get() == Type::VoidTy)
+ return Error(TypeLoc, "void type only allowed for function results");
+
return false;
}
case lltok::star:
if (Result.get() == Type::LabelTy)
return TokError("basic block pointers are invalid");
+ if (Result.get() == Type::VoidTy)
+ return TokError("pointers to void are invalid; use i8* instead");
+ if (!PointerType::isValidElementType(Result.get()))
+ return TokError("pointer to this type is invalid");
Result = HandleUpRefs(PointerType::getUnqual(Result.get()));
Lex.Lex();
break;
case lltok::kw_addrspace: {
if (Result.get() == Type::LabelTy)
return TokError("basic block pointers are invalid");
+ if (Result.get() == Type::VoidTy)
+ return TokError("pointers to void are invalid; use i8* instead");
+ if (!PointerType::isValidElementType(Result.get()))
+ return TokError("pointer to this type is invalid");
unsigned AddrSpace;
if (ParseOptionalAddrSpace(AddrSpace) ||
ParseToken(lltok::star, "expected '*' in address space"))
ParseValue(ArgTy, V, PFS) ||
// FIXME: Should not allow attributes after the argument, remove this in
// LLVM 3.0.
- ParseOptionalAttrs(ArgAttrs2, 0))
+ ParseOptionalAttrs(ArgAttrs2, 3))
return true;
ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2));
}
-/// ParseArgumentList
+/// ParseArgumentList - Parse the argument list for a function type or function
+/// prototype. If 'inType' is true then we are parsing a FunctionType.
/// ::= '(' ArgTypeListI ')'
/// ArgTypeListI
/// ::= /*empty*/
/// ::= '...'
/// ::= ArgTypeList ',' '...'
/// ::= ArgType (',' ArgType)*
+///
bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
- bool &isVarArg) {
+ bool &isVarArg, bool inType) {
isVarArg = false;
assert(Lex.getKind() == lltok::lparen);
Lex.Lex(); // eat the (.
unsigned Attrs;
std::string Name;
- if (ParseTypeRec(ArgTy) ||
+ // If we're parsing a type, use ParseTypeRec, because we allow recursive
+ // types (such as a function returning a pointer to itself). If parsing a
+ // function prototype, we require fully resolved types.
+ if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
ParseOptionalAttrs(Attrs, 0)) return true;
+ if (ArgTy == Type::VoidTy)
+ return Error(TypeLoc, "argument can not have void type");
+
if (Lex.getKind() == lltok::LocalVar ||
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
Name = Lex.getStrVal();
Lex.Lex();
}
- if (!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy))
+ if (!FunctionType::isValidArgumentType(ArgTy))
return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
// Otherwise must be an argument type.
TypeLoc = Lex.getLoc();
- if (ParseTypeRec(ArgTy) ||
+ if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
ParseOptionalAttrs(Attrs, 0)) return true;
+ if (ArgTy == Type::VoidTy)
+ return Error(TypeLoc, "argument can not have void type");
+
if (Lex.getKind() == lltok::LocalVar ||
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
Name = Lex.getStrVal();
bool LLParser::ParseFunctionType(PATypeHolder &Result) {
assert(Lex.getKind() == lltok::lparen);
+ if (!FunctionType::isValidReturnType(Result))
+ return TokError("invalid function return type");
+
std::vector<ArgInfo> ArgList;
bool isVarArg;
unsigned Attrs;
- if (ParseArgumentList(ArgList, isVarArg) ||
+ if (ParseArgumentList(ArgList, isVarArg, true) ||
// FIXME: Allow, but ignore attributes on function types!
// FIXME: Remove in LLVM 3.0
ParseOptionalAttrs(Attrs, 2))
}
std::vector<PATypeHolder> ParamsList;
+ LocTy EltTyLoc = Lex.getLoc();
if (ParseTypeRec(Result)) return true;
ParamsList.push_back(Result);
+ if (Result == Type::VoidTy)
+ return Error(EltTyLoc, "struct element can not have void type");
+ if (!StructType::isValidElementType(Result))
+ return Error(EltTyLoc, "invalid element type for struct");
+
while (EatIfPresent(lltok::comma)) {
+ EltTyLoc = Lex.getLoc();
if (ParseTypeRec(Result)) return true;
+
+ if (Result == Type::VoidTy)
+ return Error(EltTyLoc, "struct element can not have void type");
+ if (!StructType::isValidElementType(Result))
+ return Error(EltTyLoc, "invalid element type for struct");
+
ParamsList.push_back(Result);
}
PATypeHolder EltTy(Type::VoidTy);
if (ParseTypeRec(EltTy)) return true;
+ if (EltTy == Type::VoidTy)
+ return Error(TypeLoc, "array and vector element type cannot be void");
+
if (ParseToken(isVector ? lltok::greater : lltok::rsquare,
"expected end of sequential type"))
return true;
if (isVector) {
+ if (Size == 0)
+ return Error(SizeLoc, "zero element vector is illegal");
if ((unsigned)Size != Size)
return Error(SizeLoc, "size too large for vector");
- if (!EltTy->isFloatingPoint() && !EltTy->isInteger())
+ if (!VectorType::isValidElementType(EltTy))
return Error(TypeLoc, "vector element type must be fp or integer");
Result = VectorType::get(EltTy, unsigned(Size));
} else {
- if (!EltTy->isFirstClassType() && !isa<OpaqueType>(EltTy))
+ if (!ArrayType::isValidElementType(EltTy))
return Error(TypeLoc, "invalid array element type");
Result = HandleUpRefs(ArrayType::get(EltTy, Size));
}
ID.StrVal = Lex.getStrVal();
ID.Kind = ValID::t_LocalName;
break;
+ case lltok::Metadata: { // !{...} MDNode, !"foo" MDString
+ ID.Kind = ValID::t_Constant;
+ Lex.Lex();
+ if (Lex.getKind() == lltok::lbrace) {
+ SmallVector<Value*, 16> Elts;
+ if (ParseMDNodeVector(Elts) ||
+ ParseToken(lltok::rbrace, "expected end of metadata node"))
+ return true;
+
+ ID.ConstantVal = MDNode::get(Elts.data(), Elts.size());
+ return false;
+ }
+
+ // MDString:
+ // ::= '!' STRINGCONSTANT
+ std::string Str;
+ if (ParseStringConstant(Str)) return true;
+
+ ID.ConstantVal = MDString::get(Str.data(), Str.data() + Str.size());
+ return false;
+ }
case lltok::APSInt:
ID.APSIntVal = Lex.getAPSIntVal();
ID.Kind = ValID::t_APSInt;
ParseToken(lltok::rbrace, "expected end of struct constant"))
return true;
- ID.ConstantVal = ConstantStruct::get(&Elts[0], Elts.size(), false);
+ ID.ConstantVal = ConstantStruct::get(Elts.data(), Elts.size(), false);
ID.Kind = ValID::t_Constant;
return false;
}
return true;
if (isPackedStruct) {
- ID.ConstantVal = ConstantStruct::get(&Elts[0], Elts.size(), true);
+ ID.ConstantVal = ConstantStruct::get(Elts.data(), Elts.size(), true);
ID.Kind = ValID::t_Constant;
return false;
}
"vector element #" + utostr(i) +
" is not of type '" + Elts[0]->getType()->getDescription());
- ID.ConstantVal = ConstantVector::get(&Elts[0], Elts.size());
+ ID.ConstantVal = ConstantVector::get(Elts.data(), Elts.size());
ID.Kind = ValID::t_Constant;
return false;
}
if (Elts.empty()) {
// Use undef instead of an array because it's inconvenient to determine
// the element type at this point, there being no elements to examine.
- ID.Kind = ValID::t_Undef;
+ ID.Kind = ValID::t_EmptyArray;
return false;
}
"array element #" + utostr(i) +
" is not of type '" +Elts[0]->getType()->getDescription());
}
-
- ID.ConstantVal = ConstantArray::get(ATy, &Elts[0], Elts.size());
+
+ ID.ConstantVal = ConstantArray::get(ATy, Elts.data(), Elts.size());
ID.Kind = ValID::t_Constant;
return false;
}
Lex.Lex();
if (ParseToken(lltok::lparen, "expected '(' after constantexpr cast") ||
ParseGlobalTypeAndValue(SrcVal) ||
- ParseToken(lltok::kw_to, "expected 'to' int constantexpr cast") ||
+ ParseToken(lltok::kw_to, "expected 'to' in constantexpr cast") ||
ParseType(DestTy) ||
ParseToken(lltok::rparen, "expected ')' at end of constantexpr cast"))
return true;
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for extractvalue");
- ID.ConstantVal = ConstantExpr::getExtractValue(Val,
- &Indices[0], Indices.size());
+ ID.ConstantVal =
+ ConstantExpr::getExtractValue(Val, Indices.data(), Indices.size());
ID.Kind = ValID::t_Constant;
return false;
}
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for insertvalue");
- ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1,
- &Indices[0], Indices.size());
+ ID.ConstantVal =
+ ConstantExpr::getInsertValue(Val0, Val1, Indices.data(), Indices.size());
ID.Kind = ValID::t_Constant;
return false;
}
ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1);
} else if (Opc == Instruction::VFCmp) {
// FIXME: REMOVE VFCMP Support
+ if (!Val0->getType()->isFPOrFPVector() ||
+ !isa<VectorType>(Val0->getType()))
+ return Error(ID.Loc, "vfcmp requires vector floating point operands");
ID.ConstantVal = ConstantExpr::getVFCmp(Pred, Val0, Val1);
} else if (Opc == Instruction::VICmp) {
- // FIXME: REMOVE VFCMP Support
+ // FIXME: REMOVE VICMP Support
+ if (!Val0->getType()->isIntOrIntVector() ||
+ !isa<VectorType>(Val0->getType()))
+ return Error(ID.Loc, "vicmp requires vector floating point operands");
ID.ConstantVal = ConstantExpr::getVICmp(Pred, Val0, Val1);
}
ID.Kind = ValID::t_Constant;
// Binary Operators.
case lltok::kw_add:
+ case lltok::kw_fadd:
case lltok::kw_sub:
+ case lltok::kw_fsub:
case lltok::kw_mul:
+ case lltok::kw_fmul:
case lltok::kw_udiv:
case lltok::kw_sdiv:
case lltok::kw_fdiv:
&Ignored);
}
V = ConstantFP::get(ID.APFloatVal);
+
+ if (V->getType() != Ty)
+ return Error(ID.Loc, "floating point constant does not have type '" +
+ Ty->getDescription() + "'");
+
return false;
case ValID::t_Null:
if (!isa<PointerType>(Ty))
V = ConstantPointerNull::get(cast<PointerType>(Ty));
return false;
case ValID::t_Undef:
+ // FIXME: LabelTy should not be a first-class type.
+ if ((!Ty->isFirstClassType() || Ty == Type::LabelTy) &&
+ !isa<OpaqueType>(Ty))
+ return Error(ID.Loc, "invalid type for undef constant");
+ V = UndefValue::get(Ty);
+ return false;
+ case ValID::t_EmptyArray:
+ if (!isa<ArrayType>(Ty) || cast<ArrayType>(Ty)->getNumElements() != 0)
+ return Error(ID.Loc, "invalid empty array initializer");
V = UndefValue::get(Ty);
return false;
case ValID::t_Zero:
- if (!Ty->isFirstClassType())
+ // FIXME: LabelTy should not be a first-class type.
+ if (!Ty->isFirstClassType() || Ty == Type::LabelTy)
return Error(ID.Loc, "invalid type for null constant");
V = Constant::getNullValue(Ty);
return false;
V = PFS.GetVal(ID.UIntVal, Ty, ID.Loc);
else if (ID.Kind == ValID::t_LocalName)
V = PFS.GetVal(ID.StrVal, Ty, ID.Loc);
- else if (ID.Kind == ValID::ValID::t_InlineAsm) {
+ else if (ID.Kind == ValID::t_InlineAsm) {
const PointerType *PTy = dyn_cast<PointerType>(Ty);
const FunctionType *FTy =
PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
ParseOptionalVisibility(Visibility) ||
ParseOptionalCallingConv(CC) ||
ParseOptionalAttrs(RetAttrs, 1) ||
- ParseType(RetType, RetTypeLoc))
+ ParseType(RetType, RetTypeLoc, true /*void allowed*/))
return true;
// Verify that the linkage is ok.
if (isDefine)
return Error(LinkageLoc, "invalid linkage for function definition");
break;
+ case GlobalValue::PrivateLinkage:
case GlobalValue::InternalLinkage:
- case GlobalValue::LinkOnceLinkage:
- case GlobalValue::WeakLinkage:
+ case GlobalValue::AvailableExternallyLinkage:
+ case GlobalValue::LinkOnceAnyLinkage:
+ case GlobalValue::LinkOnceODRLinkage:
+ case GlobalValue::WeakAnyLinkage:
+ case GlobalValue::WeakODRLinkage:
case GlobalValue::DLLExportLinkage:
if (!isDefine)
return Error(LinkageLoc, "invalid linkage for function declaration");
return Error(LinkageLoc, "invalid function linkage type");
}
- if (!FunctionType::isValidReturnType(RetType))
+ if (!FunctionType::isValidReturnType(RetType) ||
+ isa<OpaqueType>(RetType))
return Error(RetTypeLoc, "invalid function return type");
- if (Lex.getKind() != lltok::GlobalVar)
+ LocTy NameLoc = Lex.getLoc();
+
+ std::string FunctionName;
+ if (Lex.getKind() == lltok::GlobalVar) {
+ FunctionName = Lex.getStrVal();
+ } else if (Lex.getKind() == lltok::GlobalID) { // @42 is ok.
+ unsigned NameID = Lex.getUIntVal();
+
+ if (NameID != NumberedVals.size())
+ return TokError("function expected to be numbered '%" +
+ utostr(NumberedVals.size()) + "'");
+ } else {
return TokError("expected function name");
+ }
- LocTy NameLoc = Lex.getLoc();
- std::string FunctionName = Lex.getStrVal();
Lex.Lex();
if (Lex.getKind() != lltok::lparen)
unsigned Alignment;
std::string GC;
- if (ParseArgumentList(ArgList, isVarArg) ||
+ if (ParseArgumentList(ArgList, isVarArg, false) ||
ParseOptionalAttrs(FuncAttrs, 2) ||
(EatIfPresent(lltok::kw_section) &&
ParseStringConstant(Section)) ||
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
+ if (PAL.paramHasAttr(1, Attribute::StructRet) &&
+ RetType != Type::VoidTy)
+ return Error(RetTypeLoc, "functions with 'sret' argument must return void");
+
const FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg);
const PointerType *PFT = PointerType::getUnqual(FT);
if (Token == lltok::Eof)
return TokError("found end of file when expecting more instructions");
LocTy Loc = Lex.getLoc();
+ unsigned KeywordVal = Lex.getUIntVal();
Lex.Lex(); // Eat the keyword.
switch (Token) {
case lltok::kw_add:
case lltok::kw_sub:
case lltok::kw_mul:
+ // API compatibility: Accept either integer or floating-point types.
+ return ParseArithmetic(Inst, PFS, KeywordVal, 0);
+ case lltok::kw_fadd:
+ case lltok::kw_fsub:
+ case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
+
case lltok::kw_udiv:
case lltok::kw_sdiv:
- case lltok::kw_fdiv:
case lltok::kw_urem:
- case lltok::kw_srem:
- case lltok::kw_frem: return ParseArithmetic(Inst, PFS, Lex.getUIntVal());
+ 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_shl:
case lltok::kw_lshr:
case lltok::kw_ashr:
case lltok::kw_and:
case lltok::kw_or:
- case lltok::kw_xor: return ParseLogical(Inst, PFS, Lex.getUIntVal());
+ case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal);
case lltok::kw_icmp:
case lltok::kw_fcmp:
case lltok::kw_vicmp:
- case lltok::kw_vfcmp: return ParseCompare(Inst, PFS, Lex.getUIntVal());
+ case lltok::kw_vfcmp: return ParseCompare(Inst, PFS, KeywordVal);
// Casts.
case lltok::kw_trunc:
case lltok::kw_zext:
case lltok::kw_fptoui:
case lltok::kw_fptosi:
case lltok::kw_inttoptr:
- case lltok::kw_ptrtoint: return ParseCast(Inst, PFS, Lex.getUIntVal());
+ case lltok::kw_ptrtoint: return ParseCast(Inst, PFS, KeywordVal);
// Other.
case lltok::kw_select: return ParseSelect(Inst, PFS);
- case lltok::kw_va_arg: return ParseVAArg(Inst, PFS);
+ case lltok::kw_va_arg: return ParseVA_Arg(Inst, PFS);
case lltok::kw_extractelement: return ParseExtractElement(Inst, PFS);
case lltok::kw_insertelement: return ParseInsertElement(Inst, PFS);
case lltok::kw_shufflevector: return ParseShuffleVector(Inst, PFS);
case lltok::kw_tail: return ParseCall(Inst, PFS, true);
// Memory.
case lltok::kw_alloca:
- case lltok::kw_malloc: return ParseAlloc(Inst, PFS, Lex.getUIntVal());
+ case lltok::kw_malloc: return ParseAlloc(Inst, PFS, KeywordVal);
case lltok::kw_free: return ParseFree(Inst, PFS);
case lltok::kw_load: return ParseLoad(Inst, PFS, false);
case lltok::kw_store: return ParseStore(Inst, PFS, false);
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
PerFunctionState &PFS) {
PATypeHolder Ty(Type::VoidTy);
- if (ParseType(Ty)) return true;
+ if (ParseType(Ty, true /*void allowed*/)) return true;
if (Ty == Type::VoidTy) {
Inst = ReturnInst::Create();
Value *NormalBB, *UnwindBB;
if (ParseOptionalCallingConv(CC) ||
ParseOptionalAttrs(RetAttrs, 1) ||
- ParseType(RetType, RetTypeLoc) ||
+ ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
ParseOptionalAttrs(FnAttrs, 2) ||
//===----------------------------------------------------------------------===//
/// ParseArithmetic
-/// ::= ArithmeticOps TypeAndValue ',' Value {
+/// ::= ArithmeticOps TypeAndValue ',' Value
+///
+/// If OperandType is 0, then any FP or integer operand is allowed. If it is 1,
+/// then any integer operand is allowed, if it is 2, any fp operand is allowed.
bool LLParser::ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
- unsigned Opc) {
+ unsigned Opc, unsigned OperandType) {
LocTy Loc; Value *LHS, *RHS;
if (ParseTypeAndValue(LHS, Loc, PFS) ||
ParseToken(lltok::comma, "expected ',' in arithmetic operation") ||
ParseValue(LHS->getType(), RHS, PFS))
return true;
- if (!isa<IntegerType>(LHS->getType()) && !LHS->getType()->isFloatingPoint() &&
- !isa<VectorType>(LHS->getType()))
- return Error(Loc, "instruction requires integer, fp, or vector operands");
+ bool Valid;
+ switch (OperandType) {
+ default: assert(0 && "Unknown operand type!");
+ case 0: // int or FP.
+ Valid = LHS->getType()->isIntOrIntVector() ||
+ LHS->getType()->isFPOrFPVector();
+ break;
+ case 1: Valid = LHS->getType()->isIntOrIntVector(); break;
+ case 2: Valid = LHS->getType()->isFPOrFPVector(); break;
+ }
+
+ if (!Valid)
+ return Error(Loc, "invalid operand type for instruction");
Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
return false;
return Error(Loc, "icmp requires integer operands");
Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
} else if (Opc == Instruction::VFCmp) {
+ if (!LHS->getType()->isFPOrFPVector() || !isa<VectorType>(LHS->getType()))
+ return Error(Loc, "vfcmp requires vector floating point operands");
Inst = new VFCmpInst(CmpInst::Predicate(Pred), LHS, RHS);
} else if (Opc == Instruction::VICmp) {
+ if (!LHS->getType()->isIntOrIntVector() || !isa<VectorType>(LHS->getType()))
+ return Error(Loc, "vicmp requires vector floating point operands");
Inst = new VICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
}
return false;
ParseType(DestTy))
return true;
- if (!CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy))
+ if (!CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy)) {
+ CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy);
return Error(Loc, "invalid cast opcode for cast from '" +
Op->getType()->getDescription() + "' to '" +
DestTy->getDescription() + "'");
+ }
Inst = CastInst::Create((Instruction::CastOps)Opc, Op, DestTy);
return false;
}
return false;
}
-/// ParseVAArg
-/// ::= 'vaarg' TypeAndValue ',' Type
-bool LLParser::ParseVAArg(Instruction *&Inst, PerFunctionState &PFS) {
+/// ParseVA_Arg
+/// ::= 'va_arg' TypeAndValue ',' Type
+bool LLParser::ParseVA_Arg(Instruction *&Inst, PerFunctionState &PFS) {
Value *Op;
PATypeHolder EltTy(Type::VoidTy);
+ LocTy TypeLoc;
if (ParseTypeAndValue(Op, PFS) ||
ParseToken(lltok::comma, "expected ',' after vaarg operand") ||
- ParseType(EltTy))
+ ParseType(EltTy, TypeLoc))
return true;
+
+ if (!EltTy->isFirstClassType())
+ return Error(TypeLoc, "va_arg requires operand with first class type");
Inst = new VAArgInst(Op, EltTy);
return false;
if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
ParseOptionalCallingConv(CC) ||
ParseOptionalAttrs(RetAttrs, 1) ||
- ParseType(RetType, RetTypeLoc) ||
+ ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
ParseOptionalAttrs(FnAttrs, 2))
Value *Callee;
if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true;
- // Check for call to invalid intrinsic to avoid crashing later.
- if (Function *F = dyn_cast<Function>(Callee)) {
- if (F->hasName() && F->getNameLen() >= 5 &&
- !strncmp(F->getValueName()->getKeyData(), "llvm.", 5) &&
- !F->getIntrinsicID(true))
- return Error(CallLoc, "Call to invalid LLVM intrinsic function '" +
- F->getNameStr() + "'");
- }
-
// FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional
// function attributes.
unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg;
}
/// ParseLoad
-/// ::= 'volatile'? 'load' TypeAndValue (',' 'align' uint)?
+/// ::= 'volatile'? 'load' TypeAndValue (',' 'align' i32)?
bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
bool isVolatile) {
Value *Val; LocTy Loc;
}
/// ParseStore
-/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' uint)?
+/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' i32)?
bool LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS,
bool isVolatile) {
Value *Val, *Ptr; LocTy Loc, PtrLoc;
}
/// ParseGetResult
-/// ::= 'getresult' TypeAndValue ',' uint
+/// ::= 'getresult' TypeAndValue ',' i32
/// FIXME: Remove support for getresult in LLVM 3.0
bool LLParser::ParseGetResult(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val; LocTy ValLoc, EltLoc;
Inst = InsertValueInst::Create(Val0, Val1, Indices.begin(), Indices.end());
return false;
}
+
+//===----------------------------------------------------------------------===//
+// Embedded metadata.
+//===----------------------------------------------------------------------===//
+
+/// ParseMDNodeVector
+/// ::= Element (',' Element)*
+/// Element
+/// ::= 'null' | TypeAndValue
+bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts) {
+ assert(Lex.getKind() == lltok::lbrace);
+ Lex.Lex();
+ do {
+ Value *V;
+ if (Lex.getKind() == lltok::kw_null) {
+ Lex.Lex();
+ V = 0;
+ } else {
+ Constant *C;
+ if (ParseGlobalTypeAndValue(C)) return true;
+ V = C;
+ }
+ Elts.push_back(V);
+ } while (EatIfPresent(lltok::comma));
+
+ return false;
+}