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;
}
/// Run: module ::= toplevelentity*
-Module *LLParser::Run() {
- M = new Module(Lex.getFilename());
-
+bool LLParser::Run() {
// Prime the lexer.
Lex.Lex();
- if (ParseTopLevelEntities() ||
- ValidateEndOfModule()) {
- delete M;
- return 0;
- }
-
- return M;
+ return ParseTopLevelEntities() ||
+ ValidateEndOfModule();
}
/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
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
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 (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;
}
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;
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)
// 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);
//===----------------------------------------------------------------------===//
/// 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;