Create FunctionType::isValidArgumentType to go along with isValidReturnType.

Also create isValidElementType for ArrayType, PointerType, StructType and
VectorType.

Make LLParser use them. This closes up some holes like an assertion failure on:

  %x = type {label}

but largely doesn't change any semantics. The only thing we accept now which
we didn't before is vectors of opaque type such as "<4 x opaque>". The opaque
can be resolved to an int or float when linking.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73016 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky
2009-06-07 07:26:46 +00:00
parent 9dcc26b6a0
commit a5f54a06b0
4 changed files with 95 additions and 31 deletions

View File

@ -159,6 +159,10 @@ public:
/// 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]; }
@ -232,6 +236,10 @@ public:
/// 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; }
@ -331,6 +339,10 @@ public:
///
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.
@ -391,6 +403,10 @@ public:
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; }
@ -431,6 +447,10 @@ public:
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; }

View File

@ -205,7 +205,7 @@ public:
inline bool isAbstract() const { return Abstract; }
/// canLosslesslyBitCastTo - Return true if this type could be converted
/// with a lossless BitCast to type 'Ty'. For example, uint to int. BitCasts
/// with a lossless BitCast to type 'Ty'. For example, i8* to i32*. BitCasts
/// are valid for types of the same size only where no re-interpretation of
/// the bits is done.
/// @brief Determine if this type could be losslessly bitcast to Ty

View File

@ -1043,6 +1043,8 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
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;
@ -1053,6 +1055,8 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
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"))
@ -1149,9 +1153,7 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
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));
@ -1247,6 +1249,8 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
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();
@ -1254,6 +1258,8 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
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);
}
@ -1301,11 +1307,11 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
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));
}

View File

@ -135,8 +135,8 @@ bool Type::isFPOrFPVector() const {
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
@ -318,6 +318,17 @@ bool FunctionType::isValidReturnType(const Type *RetTy) {
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)
@ -331,11 +342,8 @@ FunctionType::FunctionType(const Type *Result,
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();
}
@ -352,12 +360,8 @@ StructType::StructType(const std::vector<const Type*> &Types, bool isPacked)
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();
}
@ -379,8 +383,7 @@ VectorType::VectorType(const Type *ElType, unsigned NumEl)
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");
}
@ -1051,12 +1054,7 @@ static ManagedStatic<TypeMap<ArrayValType, ArrayType> > ArrayTypes;
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);
@ -1071,6 +1069,18 @@ ArrayType *ArrayType::get(const Type *ElementType, uint64_t NumElements) {
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...
@ -1115,6 +1125,14 @@ VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) {
return PT;
}
bool VectorType::isValidElementType(const Type *ElemTy) {
if (ElemTy->isInteger() || ElemTy->isFloatingPoint() ||
isa<OpaqueType>(ElemTy))
return true;
return false;
}
//===----------------------------------------------------------------------===//
// Struct Type Factory...
//
@ -1181,6 +1199,17 @@ StructType *StructType::get(const Type *type, ...) {
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;
}
//===----------------------------------------------------------------------===//
@ -1217,10 +1246,7 @@ PointerType *PointerType::get(const Type *ValueType, unsigned AddressSpace) {
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);
@ -1239,6 +1265,18 @@ PointerType *Type::getPointerTo(unsigned addrs) const {
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
//===----------------------------------------------------------------------===//