/// type.
static bool isValidReturnType(const Type *RetTy);
+ /// isValidArgumentType - Return true if the specified type is valid as an
+ /// argument type.
+ static bool isValidArgumentType(const Type *ArgTy);
+
inline bool isVarArg() const { return isVarArgs; }
inline const Type *getReturnType() const { return ContainedTys[0]; }
/// an empty struct, pass NULL, NULL.
static StructType *get(const Type *type, ...) END_WITH_NULL;
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
// Iterator access to the elements
typedef Type::subtype_iterator element_iterator;
element_iterator element_begin() const { return ContainedTys; }
///
static ArrayType *get(const Type *ElementType, uint64_t NumElements);
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
inline uint64_t getNumElements() const { return NumElements; }
// Implement the AbstractTypeUser interface.
return VectorType::get(EltTy, VTy->getNumElements());
}
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
/// @brief Return the number of elements in the Vector type.
inline unsigned getNumElements() const { return NumElements; }
return PointerType::get(ElementType, 0);
}
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
/// @brief Return the address space of the Pointer type.
inline unsigned getAddressSpace() const { return AddressSpace; }
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;
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"))
Lex.Lex();
}
- if ((!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy)) ||
- (isa<PointerType>(ArgTy) &&
- cast<PointerType>(ArgTy)->getElementType() == Type::MetadataTy))
+ if (!FunctionType::isValidArgumentType(ArgTy))
return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
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 (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);
}
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));
}
return cast<VectorType>(this)->getElementType()->isFloatingPoint();
}
-// canLosslesllyBitCastTo - Return true if this type can be converted to
-// 'Ty' without any reinterpretation of bits. For example, uint to int.
+// canLosslesslyBitCastTo - Return true if this type can be converted to
+// 'Ty' without any reinterpretation of bits. For example, i8* to i32*.
//
bool Type::canLosslesslyBitCastTo(const Type *Ty) const {
// Identity cast means no change so return true
return true;
}
+/// isValidArgumentType - Return true if the specified type is valid as an
+/// argument type.
+bool FunctionType::isValidArgumentType(const Type *ArgTy) {
+ if ((!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy)) ||
+ (isa<PointerType>(ArgTy) &&
+ cast<PointerType>(ArgTy)->getElementType() == Type::MetadataTy))
+ return false;
+
+ return true;
+}
+
FunctionType::FunctionType(const Type *Result,
const std::vector<const Type*> &Params,
bool IsVarArgs)
new (&ContainedTys[0]) PATypeHandle(Result, this);
for (unsigned i = 0; i != Params.size(); ++i) {
- assert((Params[i]->isFirstClassType() || isa<OpaqueType>(Params[i])) &&
- "Function arguments must be value types!");
- assert((!isa<PointerType>(Params[i]) ||
- cast<PointerType>(Params[i])->getElementType() != Type::MetadataTy)
- && "Attempt to use metadata* as function argument type!");
+ assert(isValidArgumentType(Params[i]) &&
+ "Not a valid type for function argument!");
new (&ContainedTys[i+1]) PATypeHandle(Params[i], this);
isAbstract |= Params[i]->isAbstract();
}
bool isAbstract = false;
for (unsigned i = 0; i < Types.size(); ++i) {
assert(Types[i] && "<null> type for structure field!");
- assert(Types[i] != Type::VoidTy && "Void type for structure field!");
- assert(Types[i] != Type::LabelTy && "Label type for structure field!");
- assert(Types[i] != Type::MetadataTy && "Metadata type for structure field");
- assert((!isa<PointerType>(Types[i]) ||
- cast<PointerType>(Types[i])->getElementType() != Type::MetadataTy)
- && "Type 'metadata*' is invalid for structure field.");
+ assert(isValidElementType(Types[i]) &&
+ "Invalid type for structure element!");
new (&ContainedTys[i]) PATypeHandle(Types[i], this);
isAbstract |= Types[i]->isAbstract();
}
NumElements = NumEl;
setAbstract(ElType->isAbstract());
assert(NumEl > 0 && "NumEl of a VectorType must be greater than 0");
- assert((ElType->isInteger() || ElType->isFloatingPoint() ||
- isa<OpaqueType>(ElType)) &&
+ assert(isValidElementType(ElType) &&
"Elements of a VectorType must be a primitive type");
}
ArrayType *ArrayType::get(const Type *ElementType, uint64_t NumElements) {
assert(ElementType && "Can't get array of <null> types!");
- assert(ElementType != Type::VoidTy && "Array of void is not valid!");
- assert(ElementType != Type::LabelTy && "Array of labels is not valid!");
- assert(ElementType != Type::MetadataTy && "Array of metadata is not valid!");
- assert((!isa<PointerType>(ElementType) ||
- cast<PointerType>(ElementType)->getElementType() != Type::MetadataTy)
- && "Array of metadata* is not valid!");
+ assert(isValidElementType(ElementType) && "Invalid type for array element!");
ArrayValType AVT(ElementType, NumElements);
ArrayType *AT = ArrayTypes->get(AVT);
return AT;
}
+bool ArrayType::isValidElementType(const Type *ElemTy) {
+ if (ElemTy == Type::VoidTy || ElemTy == Type::LabelTy ||
+ ElemTy == Type::MetadataTy)
+ return false;
+
+ if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy))
+ if (PTy->getElementType() == Type::MetadataTy)
+ return false;
+
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// Vector Type Factory...
return PT;
}
+bool VectorType::isValidElementType(const Type *ElemTy) {
+ if (ElemTy->isInteger() || ElemTy->isFloatingPoint() ||
+ isa<OpaqueType>(ElemTy))
+ return true;
+
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Struct Type Factory...
//
return llvm::StructType::get(StructFields);
}
+bool StructType::isValidElementType(const Type *ElemTy) {
+ if (ElemTy == Type::VoidTy || ElemTy == Type::LabelTy ||
+ ElemTy == Type::MetadataTy)
+ return false;
+
+ if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy))
+ if (PTy->getElementType() == Type::MetadataTy)
+ return false;
+
+ return true;
+}
//===----------------------------------------------------------------------===//
assert(ValueType && "Can't get a pointer to <null> type!");
assert(ValueType != Type::VoidTy &&
"Pointer to void is not valid, use i8* instead!");
- assert(ValueType != Type::LabelTy && "Pointer to label is not valid!");
- assert((!isa<PointerType>(ValueType) ||
- cast<PointerType>(ValueType)->getElementType() != Type::MetadataTy)
- && "Pointer to metadata* is not valid!");
+ assert(isValidElementType(ValueType) && "Invalid type for pointer element!");
PointerValType PVT(ValueType, AddressSpace);
PointerType *PT = PointerTypes->get(PVT);
return PointerType::get(this, addrs);
}
+bool PointerType::isValidElementType(const Type *ElemTy) {
+ if (ElemTy == Type::VoidTy || ElemTy == Type::LabelTy)
+ return false;
+
+ if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy))
+ if (PTy->getElementType() == Type::MetadataTy)
+ return false;
+
+ return true;
+}
+
+
//===----------------------------------------------------------------------===//
// Derived Type Refinement Functions
//===----------------------------------------------------------------------===//