mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-22 10:24:26 +00:00
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:
@ -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; }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Reference in New Issue
Block a user