#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-// ValID - Represents a reference of a definition of some sort with no type.
-// There are several cases where we have to parse the value but where the type
-// can depend on later context. This may either
-// be a numeric reference or a symbolic (%var) reference. This is just a
-// discriminated union.
-//
-// Note that I can't implement this class in a straight forward manner with
-// constructors and stuff because it goes in a union.
-//
namespace llvm {
+ /// ValID - Represents a reference of a definition of some sort with no type.
+ /// There are several cases where we have to parse the value but where the
+ /// type can depend on later context. This may either be a numeric reference
+ /// or a symbolic (%var) reference. This is just a discriminated union.
struct ValID {
enum {
t_LocalID, t_GlobalID, // ID in UIntVal.
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;
};
}
-/// Parse: module ::= toplevelentity*
-Module *LLParser::Run() {
- M = new Module(Lex.getFilename());
-
- if (ParseTopLevelEntities() ||
- ValidateEndOfModule()) {
- delete M;
- return 0;
- }
-
- return M;
+/// Run: module ::= toplevelentity*
+bool LLParser::Run() {
+ // Prime the lexer.
+ Lex.Lex();
+
+ return ParseTopLevelEntities() ||
+ ValidateEndOfModule();
}
/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
//===----------------------------------------------------------------------===//
bool LLParser::ParseTopLevelEntities() {
- Lex.Lex();
while (1) {
switch (Lex.getKind()) {
default: return TokError("expected top-level entity");
assert(Lex.getKind() == lltok::kw_module);
Lex.Lex();
- if (ParseToken(lltok::kw_asm, "expected 'module asm'")) return true;
-
- if (Lex.getKind() != lltok::StringConstant)
- return TokError("expected 'module asm \"foo\"'");
+ std::string AsmStr;
+ if (ParseToken(lltok::kw_asm, "expected 'module asm'") ||
+ ParseStringConstant(AsmStr)) return true;
const std::string &AsmSoFar = M->getModuleInlineAsm();
if (AsmSoFar.empty())
- M->setModuleInlineAsm(Lex.getStrVal());
+ M->setModuleInlineAsm(AsmStr);
else
- M->setModuleInlineAsm(AsmSoFar+"\n"+Lex.getStrVal());
- Lex.Lex();
+ M->setModuleInlineAsm(AsmSoFar+"\n"+AsmStr);
return false;
}
/// ::= 'target' 'datalayout' '=' STRINGCONSTANT
bool LLParser::ParseTargetDefinition() {
assert(Lex.getKind() == lltok::kw_target);
+ std::string Str;
switch (Lex.Lex()) {
default: return TokError("unknown target property");
case lltok::kw_triple:
Lex.Lex();
- if (ParseToken(lltok::equal, "expected '=' after target triple"))
+ if (ParseToken(lltok::equal, "expected '=' after target triple") ||
+ ParseStringConstant(Str))
return true;
- if (Lex.getKind() != lltok::StringConstant)
- return TokError("expected string after target triple '='");
- M->setTargetTriple(Lex.getStrVal());
- Lex.Lex();
+ M->setTargetTriple(Str);
return false;
case lltok::kw_datalayout:
Lex.Lex();
- if (ParseToken(lltok::equal, "expected '=' after target datalayout"))
+ if (ParseToken(lltok::equal, "expected '=' after target datalayout") ||
+ ParseStringConstant(Str))
return true;
- if (Lex.getKind() != lltok::StringConstant)
- return TokError("expected string after target datalayout '='");
- M->setDataLayout(Lex.getStrVal());
- Lex.Lex();
+ M->setDataLayout(Str);
return false;
}
}
/// ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']'
bool LLParser::ParseDepLibs() {
assert(Lex.getKind() == lltok::kw_deplibs);
- if (Lex.Lex() != lltok::equal)
- return TokError("expected '=' after deplibs");
-
- if (Lex.Lex() != lltok::lsquare)
- return TokError("expected '=' after deplibs");
+ Lex.Lex();
+ if (ParseToken(lltok::equal, "expected '=' after deplibs") ||
+ ParseToken(lltok::lsquare, "expected '=' after deplibs"))
+ return true;
- if (Lex.Lex() == lltok::rsquare) {
- Lex.Lex();
+ if (EatIfPresent(lltok::rsquare))
return false;
- }
- if (Lex.getKind() != lltok::StringConstant)
- return TokError("expected string in deplib list");
-
- M->addLibrary(Lex.getStrVal());
+ std::string Str;
+ if (ParseStringConstant(Str)) return true;
+ M->addLibrary(Str);
- while (Lex.Lex() == lltok::comma) {
- if (Lex.Lex() != lltok::StringConstant)
- return TokError("expected string in deplibs list");
- M->addLibrary(Lex.getStrVal());
+ while (EatIfPresent(lltok::comma)) {
+ if (ParseStringConstant(Str)) return true;
+ M->addLibrary(Str);
}
- if (Lex.getKind() != lltok::rsquare)
- return TokError("expected ']' at end of list");
- Lex.Lex();
- return false;
+ return ParseToken(lltok::rsquare, "expected ']' at end of list");
}
/// toplevelentity
bool LLParser::ParseNamedType() {
std::string Name = Lex.getStrVal();
LocTy NameLoc = Lex.getLoc();
-
- if (Lex.Lex() != lltok::equal)
- return TokError("expected '=' after name");
- if (Lex.Lex() != lltok::kw_type)
- return TokError("expected 'type' after name");
- Lex.Lex(); // consume 'type'.
+ Lex.Lex(); // eat LocalVar.
PATypeHolder Ty(Type::VoidTy);
- if (ParseType(Ty)) return true;
+
+ if (ParseToken(lltok::equal, "expected '=' after name") ||
+ ParseToken(lltok::kw_type, "expected 'type' after name") ||
+ ParseType(Ty))
+ return true;
// We don't allow assigning names to void type
if (Ty == Type::VoidTy)
Lex.Lex();
Function *F;
- if (ParseFunctionHeader(F, true)) return true;
-
- return ParseFunctionBody(*F);
+ return ParseFunctionHeader(F, true) ||
+ ParseFunctionBody(*F);
}
+/// ParseGlobalType
+/// ::= 'constant'
+/// ::= 'global'
bool LLParser::ParseGlobalType(bool &IsConstant) {
if (Lex.getKind() == lltok::kw_constant)
IsConstant = true;
return false;
}
-bool LLParser::ParseUnsigned(unsigned &Val) {
+/// ParseStringConstant
+/// ::= StringConstant
+bool LLParser::ParseStringConstant(std::string &Result) {
+ if (Lex.getKind() != lltok::StringConstant)
+ return TokError("expected string constant");
+ Result = Lex.getStrVal();
+ Lex.Lex();
+ return false;
+}
+
+/// ParseUInt32
+/// ::= uint32
+bool LLParser::ParseUInt32(unsigned &Val) {
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
return TokError("expected integer");
uint64_t Val64 = Lex.getAPSIntVal().getLimitedValue(0xFFFFFFFFULL+1);
/// := 'addrspace' '(' uint32 ')'
bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) {
AddrSpace = 0;
- bool HasAddrSpace;
- ParseOptionalToken(lltok::kw_addrspace, HasAddrSpace);
- if (!HasAddrSpace)
+ if (!EatIfPresent(lltok::kw_addrspace))
return false;
-
return ParseToken(lltok::lparen, "expected '(' in address space") ||
- ParseUnsigned(AddrSpace) ||
+ ParseUInt32(AddrSpace) ||
ParseToken(lltok::rparen, "expected ')' in address space");
}
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_cc: Lex.Lex(); return ParseUnsigned(CC);
+ case lltok::kw_cc: Lex.Lex(); return ParseUInt32(CC);
}
Lex.Lex();
return false;
/// ::= 'align' 4
bool LLParser::ParseOptionalAlignment(unsigned &Alignment) {
Alignment = 0;
- bool HasAlignment;
- if (ParseOptionalToken(lltok::kw_align, HasAlignment)) return true;
-
- return HasAlignment && ParseUnsigned(Alignment);
+ if (!EatIfPresent(lltok::kw_align))
+ return false;
+ 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
/// ::= ',' 'align' 4
bool LLParser::ParseOptionalCommaAlignment(unsigned &Alignment) {
Alignment = 0;
- bool HasComma;
- ParseOptionalToken(lltok::comma, HasComma);
- if (!HasComma)
+ if (!EatIfPresent(lltok::comma))
return false;
-
return ParseToken(lltok::kw_align, "expected 'align'") ||
- ParseUnsigned(Alignment);
+ ParseUInt32(Alignment);
}
/// ParseIndexList
if (Lex.getKind() != lltok::comma)
return TokError("expected ',' as start of index list");
- while (Lex.getKind() == lltok::comma) {
- Lex.Lex();
+ while (EatIfPresent(lltok::comma)) {
unsigned Idx;
- if (ParseUnsigned(Idx)) return true;
+ if (ParseUInt32(Idx)) return true;
Indices.push_back(Idx);
}
// Verify no unresolved uprefs.
if (!UpRefs.empty())
return Error(UpRefs.back().Loc, "invalid unresolved type up reference");
- // GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
return false;
}
break;
case lltok::less: // Either vector or packed struct.
// TypeRec ::= '<' ... '>'
- if (Lex.Lex() == lltok::lbrace) {
- if (ParseStructType(Result, true))
+ Lex.Lex();
+ if (Lex.getKind() == lltok::lbrace) {
+ if (ParseStructType(Result, true) ||
+ ParseToken(lltok::greater, "expected '>' at end of packed struct"))
return true;
- if (Lex.getKind() != lltok::greater)
- return TokError("expected '>' at end of packed struct");
- Lex.Lex();
} else if (ParseArrayVectorType(Result, true))
return true;
break;
break;
case lltok::backslash: {
// TypeRec ::= '\' 4
- unsigned Val;
Lex.Lex();
- if (ParseUnsigned(Val)) return true;
+ unsigned Val;
+ if (ParseUInt32(Val)) return true;
OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder.
UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT));
Result = OT;
} else {
LocTy TypeLoc = Lex.getLoc();
PATypeHolder ArgTy(Type::VoidTy);
-
- if (ParseTypeRec(ArgTy)) return true;
-
- if (!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy))
- return Error(TypeLoc, "invalid type for function argument");
-
unsigned Attrs;
- if (ParseOptionalAttrs(Attrs, 0)) return true;
-
std::string Name;
+
+ if (ParseTypeRec(ArgTy) ||
+ ParseOptionalAttrs(Attrs, 0)) return true;
+
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))
+ return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
- while (Lex.getKind() == lltok::comma) {
- Lex.Lex(); // eat the comma.
-
+ while (EatIfPresent(lltok::comma)) {
// Handle ... at end of arg list.
- if (Lex.getKind() == lltok::dotdotdot) {
+ if (EatIfPresent(lltok::dotdotdot)) {
isVarArg = true;
- Lex.Lex();
break;
}
// Otherwise must be an argument type.
TypeLoc = Lex.getLoc();
- if (ParseTypeRec(ArgTy)) return true;
- if (!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy))
- return Error(TypeLoc, "invalid type for function argument");
-
- if (ParseOptionalAttrs(Attrs, 0)) return true;
-
+ if (ParseTypeRec(ArgTy) ||
+ ParseOptionalAttrs(Attrs, 0)) return true;
+
if (Lex.getKind() == lltok::LocalVar ||
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
Name = Lex.getStrVal();
} else {
Name = "";
}
+
+ if (!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy))
+ return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
}
}
- if (Lex.getKind() != lltok::rparen)
- return TokError("expected ')' at end of function argument list");
- Lex.Lex();
- return false;
+ return ParseToken(lltok::rparen, "expected ')' at end of argument list");
}
/// ParseFunctionType
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;
assert(Lex.getKind() == lltok::lbrace);
Lex.Lex(); // Consume the '{'
- if (Lex.getKind() == lltok::rbrace) {
+ if (EatIfPresent(lltok::rbrace)) {
Result = StructType::get(std::vector<const Type*>(), Packed);
- Lex.Lex();
return false;
}
if (ParseTypeRec(Result)) return true;
ParamsList.push_back(Result);
- while (Lex.getKind() == lltok::comma) {
- Lex.Lex(); // eat the comma.
-
+ while (EatIfPresent(lltok::comma)) {
if (ParseTypeRec(Result)) return true;
ParamsList.push_back(Result);
}
- if (Lex.getKind() != lltok::rbrace)
- return TokError("expected '}' at end of struct");
- Lex.Lex(); // Consume the '}'
+ if (ParseToken(lltok::rbrace, "expected '}' at end of struct"))
+ return true;
std::vector<const Type*> ParamsListTy;
for (unsigned i = 0, e = ParamsList.size(); i != e; ++i)
LocTy SizeLoc = Lex.getLoc();
uint64_t Size = Lex.getAPSIntVal().getZExtValue();
- if (Lex.Lex() != lltok::kw_x)
- return TokError("expected 'x' after element count");
- Lex.Lex(); // eat the 'x'.
+ Lex.Lex();
+
+ if (ParseToken(lltok::kw_x, "expected 'x' after element count"))
+ return true;
LocTy TypeLoc = Lex.getLoc();
PATypeHolder EltTy(Type::VoidTy);
if (ParseTypeRec(EltTy)) return true;
- if (Lex.getKind() != (isVector ? lltok::greater : lltok::rsquare))
- return TokError("expected end of sequential type");
- Lex.Lex();
+ if (ParseToken(isVector ? lltok::greater : lltok::rsquare,
+ "expected end of sequential type"))
+ return true;
if (isVector) {
if ((unsigned)Size != Size)
// ValID ::= '<' ConstVector '>' --> Vector.
// ValID ::= '<' '{' ConstVector '}' '>' --> Packed Struct.
Lex.Lex();
- bool isPackedStruct;
- ParseOptionalToken(lltok::lbrace, isPackedStruct);
+ bool isPackedStruct = EatIfPresent(lltok::lbrace);
SmallVector<Constant*, 16> Elts;
LocTy FirstEltLoc = Lex.getLoc();
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;
}
ArrayType *ATy = ArrayType::get(Elts[0]->getType(), Elts.size());
// Verify all elements are correct type!
- for (unsigned i = i, e = Elts.size() ; i != e; ++i) {
+ for (unsigned i = 0, e = Elts.size(); i != e; ++i) {
if (Elts[i]->getType() != Elts[0]->getType())
return Error(FirstEltLoc,
"array element #" + utostr(i) +
bool HasSideEffect;
Lex.Lex();
if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
- ParseToken(lltok::StringConstant, "expected asm string"))
- return true;
- ID.StrVal = Lex.getStrVal();
-
- if (ParseToken(lltok::comma, "expected comma in inline asm expression") ||
+ ParseStringConstant(ID.StrVal) ||
+ ParseToken(lltok::comma, "expected comma in inline asm expression") ||
ParseToken(lltok::StringConstant, "expected constraint string"))
return true;
ID.StrVal2 = Lex.getStrVal();
bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&V) {
V = 0;
ValID ID;
- if (ParseValID(ID) ||
- ConvertGlobalValIDToValue(Ty, ID, V))
- return true;
- return false;
+ return ParseValID(ID) ||
+ ConvertGlobalValIDToValue(Ty, ID, V);
}
/// ConvertGlobalValIDToValue - Apply a type to a ValID to get a fully resolved
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)
+ 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;
ParseGlobalValue(Type, V);
}
+/// ParseGlobalValueVector
+/// ::= /*empty*/
+/// ::= TypeAndValue (',' TypeAndValue)*
bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) {
// Empty list.
if (Lex.getKind() == lltok::rbrace ||
if (ParseGlobalTypeAndValue(C)) return true;
Elts.push_back(C);
- while (Lex.getKind() == lltok::comma) {
- Lex.Lex();
+ while (EatIfPresent(lltok::comma)) {
if (ParseGlobalTypeAndValue(C)) return true;
Elts.push_back(C);
}
bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) {
V = 0;
ValID ID;
- if (ParseValID(ID) ||
- ConvertValIDToValue(Ty, ID, V, PFS))
- return true;
- return false;
+ return ParseValID(ID) ||
+ ConvertValIDToValue(Ty, ID, V, PFS);
}
bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState &PFS) {
PATypeHolder T(Type::VoidTy);
- if (ParseType(T)) return true;
- return ParseValue(T, V, PFS);
+ return ParseType(T) ||
+ ParseValue(T, V, PFS);
}
/// FunctionHeader
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 = Lex.getStrVal();
+ Lex.Lex();
- if (Lex.Lex() != lltok::lparen)
+ if (Lex.getKind() != lltok::lparen)
return TokError("expected '(' in function argument list");
std::vector<ArgInfo> ArgList;
bool isVarArg;
- if (ParseArgumentList(ArgList, isVarArg)) return true;
-
unsigned FuncAttrs;
- if (ParseOptionalAttrs(FuncAttrs, 2)) return true;
-
- // Section string.
std::string Section;
- if (Lex.getKind() == lltok::kw_section) {
- if (Lex.Lex() != lltok::StringConstant)
- return TokError("expected section name");
- Section = Lex.getStrVal();
- Lex.Lex();
- }
-
unsigned Alignment;
- if (ParseOptionalAlignment(Alignment)) return true;
+ std::string GC;
+
+ if (ParseArgumentList(ArgList, isVarArg) ||
+ ParseOptionalAttrs(FuncAttrs, 2) ||
+ (EatIfPresent(lltok::kw_section) &&
+ ParseStringConstant(Section)) ||
+ ParseOptionalAlignment(Alignment) ||
+ (EatIfPresent(lltok::kw_gc) &&
+ ParseStringConstant(GC)))
+ return true;
// If the alignment was parsed as an attribute, move to the alignment field.
if (FuncAttrs & Attribute::Alignment) {
FuncAttrs &= ~Attribute::Alignment;
}
- // Optional GC setting.
- std::string GC;
- if (Lex.getKind() == lltok::kw_gc) {
- if (Lex.Lex() != lltok::StringConstant)
- return TokError("expected gc name");
- GC = Lex.getStrVal();
- Lex.Lex();
- }
-
// Okay, if we got here, the function is syntactically valid. Convert types
// and do semantic checks.
std::vector<const Type*> ParamTypeList;
// Binary Operators.
case lltok::kw_add:
case lltok::kw_sub:
- case lltok::kw_mul:
+ case lltok::kw_mul: return ParseArithmetic(Inst, PFS, Lex.getUIntVal(), 0);
+
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, Lex.getUIntVal(), 1);
+ case lltok::kw_fdiv:
+ case lltok::kw_frem: return ParseArithmetic(Inst, PFS, Lex.getUIntVal(), 2);
case lltok::kw_shl:
case lltok::kw_lshr:
case lltok::kw_ashr:
case lltok::kw_ptrtoint: return ParseCast(Inst, PFS, Lex.getUIntVal());
// 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_load: return ParseLoad(Inst, PFS, false);
case lltok::kw_store: return ParseStore(Inst, PFS, false);
case lltok::kw_volatile:
- if (Lex.getKind() == lltok::kw_load) {
- Lex.Lex();
+ if (EatIfPresent(lltok::kw_load))
return ParseLoad(Inst, PFS, true);
- } else if (Lex.getKind() == lltok::kw_store) {
- Lex.Lex();
+ else if (EatIfPresent(lltok::kw_store))
return ParseStore(Inst, PFS, true);
- } else {
+ else
return TokError("expected 'load' or 'store'");
- }
case lltok::kw_getresult: return ParseGetResult(Inst, PFS);
case lltok::kw_getelementptr: return ParseGetElementPtr(Inst, PFS);
case lltok::kw_extractvalue: return ParseExtractValue(Inst, PFS);
SmallVector<Value*, 8> RVs;
RVs.push_back(RV);
- while (Lex.getKind() == lltok::comma) {
- Lex.Lex(); // Eat the comma.
+ while (EatIfPresent(lltok::comma)) {
if (ParseTypeAndValue(RV, PFS)) return true;
RVs.push_back(RV);
}
if (!isa<BasicBlock>(Op1))
return Error(Loc, "true destination of branch must be a basic block");
-
if (!isa<BasicBlock>(Op2))
return Error(Loc2, "true destination of branch must be a basic block");
//===----------------------------------------------------------------------===//
/// 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;
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;
while (1) {
PHIVals.push_back(std::make_pair(Op0, cast<BasicBlock>(Op1)));
- if (Lex.getKind() != lltok::comma)
+ if (!EatIfPresent(lltok::comma))
break;
- if (ParseToken(lltok::comma, 0) ||
- ParseToken(lltok::lsquare, "expected '[' in phi value list") ||
+ if (ParseToken(lltok::lsquare, "expected '[' in phi value list") ||
ParseValue(Ty, Op0, PFS) ||
ParseToken(lltok::comma, "expected ',' after insertelement value") ||
ParseValue(Type::LabelTy, Op1, PFS) ||
Value *Size = 0;
LocTy SizeLoc = 0;
unsigned Alignment = 0;
- bool HasComma;
- if (ParseType(Ty) ||
- ParseOptionalToken(lltok::comma, HasComma))
- return true;
+ if (ParseType(Ty)) return true;
- if (HasComma) {
+ if (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::kw_align) {
if (ParseOptionalAlignment(Alignment)) return true;
- } else {
- if (ParseTypeAndValue(Size, SizeLoc, PFS)) return true;
- if (ParseOptionalCommaAlignment(Alignment))
- return true;
+ } else if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
+ ParseOptionalCommaAlignment(Alignment)) {
+ return true;
}
}
unsigned Element;
if (ParseTypeAndValue(Val, ValLoc, PFS) ||
ParseToken(lltok::comma, "expected ',' after getresult operand") ||
- ParseUnsigned(Element, EltLoc))
+ ParseUInt32(Element, EltLoc))
return true;
if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
/// ::= 'getelementptr' TypeAndValue (',' TypeAndValue)*
bool LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
Value *Ptr, *Val; LocTy Loc, EltLoc;
- if (ParseTypeAndValue(Ptr, Loc, PFS))
- return true;
+ if (ParseTypeAndValue(Ptr, Loc, PFS)) return true;
if (!isa<PointerType>(Ptr->getType()))
return Error(Loc, "base of getelementptr must be a pointer");
SmallVector<Value*, 16> Indices;
- while (Lex.getKind() == lltok::comma) {
- Lex.Lex();
- if (ParseTypeAndValue(Val, EltLoc, PFS))
- return true;
+ while (EatIfPresent(lltok::comma)) {
+ if (ParseTypeAndValue(Val, EltLoc, PFS)) return true;
if (!isa<IntegerType>(Val->getType()))
return Error(EltLoc, "getelementptr index must be an integer");
Indices.push_back(Val);