if (TriggerError) return 0;
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) {
- GenerateError("Invalid use of a composite type");
+ GenerateError("Invalid use of a non-first-class type");
return 0;
}
GenerateError("Cannot declare global vars of function type");
return 0;
}
+ if (Ty == Type::LabelTy) {
+ GenerateError("Cannot declare global vars of label type");
+ return 0;
+ }
const PointerType *PTy = PointerType::get(Ty, AddressSpace);
llvm::PATypeHolder *TypeVal;
llvm::Value *ValueVal;
std::vector<llvm::Value*> *ValueList;
+ std::vector<unsigned> *ConstantList;
llvm::ArgListType *ArgList;
llvm::TypeWithAttrs TypeWithAttrs;
llvm::TypeWithAttrsList *TypeWithAttrsList;
%type <PHIList> PHIList
%type <ParamList> ParamList // For call param lists & GEP indices
%type <ValueList> IndexList // For GEP indices
+%type <ConstantList> ConstantIndexList // For insertvalue/extractvalue indices
%type <TypeList> TypeListI
%type <TypeWithAttrsList> ArgTypeList ArgTypeListI
%type <TypeWithAttrs> ArgType
%token <OtherOpVal> PHI_TOK SELECT VAARG
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
%token <OtherOpVal> GETRESULT
+%token <OtherOpVal> EXTRACTVALUE INSERTVALUE
// Function Attributes
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
}
| '[' EUINT64VAL 'x' Types ']' { // Sized array type?
- $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, (unsigned)$2)));
+ $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, $2)));
delete $4;
CHECK_FOR_ERROR
}
CHECK_FOR_ERROR
}
| INTTYPE TRUETOK { // Boolean constants
- assert(cast<IntegerType>($1)->getBitWidth() == 1 && "Not Bool?");
+ if (cast<IntegerType>($1)->getBitWidth() != 1)
+ GEN_ERROR("Constant true must have type i1");
$$ = ConstantInt::getTrue();
CHECK_FOR_ERROR
}
| INTTYPE FALSETOK { // Boolean constants
- assert(cast<IntegerType>($1)->getBitWidth() == 1 && "Not Bool?");
+ if (cast<IntegerType>($1)->getBitWidth() != 1)
+ GEN_ERROR("Constant false must have type i1");
$$ = ConstantInt::getFalse();
CHECK_FOR_ERROR
}
GEN_ERROR("Invalid shufflevector operands");
$$ = ConstantExpr::getShuffleVector($3, $5, $7);
CHECK_FOR_ERROR
+ }
+ | EXTRACTVALUE '(' ConstVal ConstantIndexList ')' {
+ if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
+ GEN_ERROR("ExtractValue requires an aggregate operand");
+
+ $$ = ConstantExpr::getExtractValue($3, &(*$4)[0], $4->size());
+ delete $4;
+ CHECK_FOR_ERROR
+ }
+ | INSERTVALUE '(' ConstVal ',' ConstVal ConstantIndexList ')' {
+ if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
+ GEN_ERROR("InsertValue requires an aggregate operand");
+
+ $$ = ConstantExpr::getInsertValue($3, $5, &(*$6)[0], $6->size());
+ delete $6;
+ CHECK_FOR_ERROR
};
ArgListH : ArgListH ',' Types OptParamAttrs OptLocalName {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
- if (*$3 == Type::VoidTy)
- GEN_ERROR("void typed arguments are invalid");
+ if (!(*$3)->isFirstClassType())
+ GEN_ERROR("Argument types must be first-class");
ArgListEntry E; E.Attrs = $4; E.Ty = $3; E.Name = $5;
$$ = $1;
$1->push_back(E);
| Types OptParamAttrs OptLocalName {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
- if (*$1 == Type::VoidTy)
- GEN_ERROR("void typed arguments are invalid");
+ if (!(*$1)->isFirstClassType())
+ GEN_ERROR("Argument types must be first-class");
ArgListEntry E; E.Attrs = $2; E.Ty = $1; E.Name = $3;
$$ = new ArgListType;
$$->push_back(E);
| '<' ConstVector '>' { // Nonempty unsized packed vector
const Type *ETy = (*$2)[0]->getType();
int NumElements = $2->size();
+
+ if (!ETy->isInteger() && !ETy->isFloatingPoint())
+ GEN_ERROR("Invalid vector element type: " + ETy->getDescription());
VectorType* pt = VectorType::get(ETy, NumElements);
- PATypeHolder* PTy = new PATypeHolder(
- HandleUpRefs(
- VectorType::get(
- ETy,
- NumElements)
- )
- );
+ PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt));
// Verify all elements are correct type!
for (unsigned i = 0; i < $2->size(); i++) {
delete PTy; delete $2;
CHECK_FOR_ERROR
}
+ | '[' ConstVector ']' { // Nonempty unsized arr
+ const Type *ETy = (*$2)[0]->getType();
+ int NumElements = $2->size();
+
+ if (!ETy->isFirstClassType())
+ GEN_ERROR("Invalid array element type: " + ETy->getDescription());
+
+ ArrayType *ATy = ArrayType::get(ETy, NumElements);
+ PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(ATy));
+
+ // Verify all elements are correct type!
+ for (unsigned i = 0; i < $2->size(); i++) {
+ if (ETy != (*$2)[i]->getType())
+ GEN_ERROR("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '"+
+ (*$2)[i]->getType()->getDescription() + "'.");
+ }
+
+ $$ = ValID::create(ConstantArray::get(ATy, *$2));
+ delete PTy; delete $2;
+ CHECK_FOR_ERROR
+ }
+ | '[' ']' {
+ $$ = ValID::createUndef();
+ CHECK_FOR_ERROR
+ }
+ | 'c' STRINGCONSTANT {
+ int NumElements = $2->length();
+ const Type *ETy = Type::Int8Ty;
+
+ ArrayType *ATy = ArrayType::get(ETy, NumElements);
+
+ std::vector<Constant*> Vals;
+ for (unsigned i = 0; i < $2->length(); ++i)
+ Vals.push_back(ConstantInt::get(ETy, (*$2)[i]));
+ delete $2;
+ $$ = ValID::create(ConstantArray::get(ATy, Vals));
+ CHECK_FOR_ERROR
+ }
+ | '{' ConstVector '}' {
+ std::vector<const Type*> Elements($2->size());
+ for (unsigned i = 0, e = $2->size(); i != e; ++i)
+ Elements[i] = (*$2)[i]->getType();
+
+ const StructType *STy = StructType::get(Elements);
+ PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy));
+
+ $$ = ValID::create(ConstantStruct::get(STy, *$2));
+ delete PTy; delete $2;
+ CHECK_FOR_ERROR
+ }
+ | '{' '}' {
+ const StructType *STy = StructType::get(std::vector<const Type*>());
+ $$ = ValID::create(ConstantStruct::get(STy, std::vector<Constant*>()));
+ CHECK_FOR_ERROR
+ }
+ | '<' '{' ConstVector '}' '>' {
+ std::vector<const Type*> Elements($3->size());
+ for (unsigned i = 0, e = $3->size(); i != e; ++i)
+ Elements[i] = (*$3)[i]->getType();
+
+ const StructType *STy = StructType::get(Elements, /*isPacked=*/true);
+ PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy));
+
+ $$ = ValID::create(ConstantStruct::get(STy, *$3));
+ delete PTy; delete $3;
+ CHECK_FOR_ERROR
+ }
+ | '<' '{' '}' '>' {
+ const StructType *STy = StructType::get(std::vector<const Type*>(),
+ /*isPacked=*/true);
+ $$ = ValID::create(ConstantStruct::get(STy, std::vector<Constant*>()));
+ CHECK_FOR_ERROR
+ }
| ConstExpr {
$$ = ValID::create($1);
CHECK_FOR_ERROR
$$ = BranchInst::Create(tmpBB);
} // Conditional Branch...
| BR INTTYPE ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
- assert(cast<IntegerType>($2)->getBitWidth() == 1 && "Not Bool?");
+ if (cast<IntegerType>($2)->getBitWidth() != 1)
+ GEN_ERROR("Branch condition must have type i1");
BasicBlock* tmpBBA = getBBVal($6);
CHECK_FOR_ERROR
BasicBlock* tmpBBB = getBBVal($9);
}
;
+ConstantIndexList // Used for insertvalue and extractvalue instructions
+ : ',' EUINT64VAL {
+ $$ = new std::vector<unsigned>();
+ if ((unsigned)$2 != $2)
+ GEN_ERROR("Index " + utostr($2) + " is not valid for insertvalue or extractvalue.");
+ $$->push_back($2);
+ }
+ | ConstantIndexList ',' EUINT64VAL {
+ $$ = $1;
+ if ((unsigned)$3 != $3)
+ GEN_ERROR("Index " + utostr($3) + " is not valid for insertvalue or extractvalue.");
+ $$->push_back($3);
+ CHECK_FOR_ERROR
+ }
+ ;
+
OptTailCall : TAIL CALL {
$$ = true;
CHECK_FOR_ERROR
| MALLOC Types ',' INTTYPE ValueRef OptCAlign {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+ if ($4 != Type::Int32Ty)
+ GEN_ERROR("Malloc array size is not a 32-bit integer!");
Value* tmpVal = getVal($4, $5);
CHECK_FOR_ERROR
$$ = new MallocInst(*$2, tmpVal, $6);
| ALLOCA Types ',' INTTYPE ValueRef OptCAlign {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+ if ($4 != Type::Int32Ty)
+ GEN_ERROR("Alloca array size is not a 32-bit integer!");
Value* tmpVal = getVal($4, $5);
CHECK_FOR_ERROR
$$ = new AllocaInst(*$2, tmpVal, $6);
$$ = new StoreInst($3, tmpVal, $1, $7);
delete $5;
}
-| GETRESULT Types ValueRef ',' EUINT64VAL {
+ | GETRESULT Types ValueRef ',' EUINT64VAL {
Value *TmpVal = getVal($2->get(), $3);
if (!GetResultInst::isValidOperands(TmpVal, $5))
GEN_ERROR("Invalid getresult operands");
$$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end());
delete $2;
delete $4;
+ }
+ | EXTRACTVALUE Types ValueRef ConstantIndexList {
+ if (!UpRefs.empty())
+ GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+ if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
+ GEN_ERROR("extractvalue insn requires an aggregate operand");
+
+ if (!ExtractValueInst::getIndexedType(*$2, $4->begin(), $4->end()))
+ GEN_ERROR("Invalid extractvalue indices for type '" +
+ (*$2)->getDescription()+ "'");
+ Value* tmpVal = getVal(*$2, $3);
+ CHECK_FOR_ERROR
+ $$ = ExtractValueInst::Create(tmpVal, $4->begin(), $4->end());
+ delete $2;
+ delete $4;
+ }
+ | INSERTVALUE Types ValueRef ',' Types ValueRef ConstantIndexList {
+ if (!UpRefs.empty())
+ GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+ if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
+ GEN_ERROR("extractvalue insn requires an aggregate operand");
+
+ if (ExtractValueInst::getIndexedType(*$2, $7->begin(), $7->end()) != $5->get())
+ GEN_ERROR("Invalid insertvalue indices for type '" +
+ (*$2)->getDescription()+ "'");
+ Value* aggVal = getVal(*$2, $3);
+ Value* tmpVal = getVal(*$5, $6);
+ CHECK_FOR_ERROR
+ $$ = InsertValueInst::Create(aggVal, tmpVal, $7->begin(), $7->end());
+ delete $2;
+ delete $5;
+ delete $7;
};