Canonicality is a property of qualified types, not unqualified types.

llvm-svn: 84891
This commit is contained in:
John McCall 2009-10-22 20:10:53 +00:00
parent 6b80e6e2b7
commit b692a098c6
7 changed files with 34 additions and 23 deletions

View File

@ -660,7 +660,7 @@ CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
template<typename T> template<typename T>
CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) { CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
assert((Other.isNull() || Other->isCanonical()) && "Type is not canonical!"); assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
assert((Other.isNull() || isa<T>(Other.getTypePtr())) && assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
"Dynamic type does not meet the static type's requires"); "Dynamic type does not meet the static type's requires");
CanQual<T> Result; CanQual<T> Result;

View File

@ -443,6 +443,8 @@ public:
return getTypePtr(); return getTypePtr();
} }
bool isCanonical() const;
/// isNull - Return true if this QualType doesn't point to a type yet. /// isNull - Return true if this QualType doesn't point to a type yet.
bool isNull() const { bool isNull() const {
return Value.getPointer().isNull(); return Value.getPointer().isNull();
@ -702,7 +704,9 @@ protected:
public: public:
TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); } TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
bool isCanonical() const { return CanonicalType.getTypePtr() == this; } bool isCanonicalUnqualified() const {
return CanonicalType.getTypePtr() == this;
}
/// Types are partitioned into 3 broad categories (C99 6.2.5p1): /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types. /// object types, function types, and incomplete types.
@ -2622,6 +2626,13 @@ public:
// Inline function definitions. // Inline function definitions.
inline bool QualType::isCanonical() const {
const Type *T = getTypePtr();
if (hasQualifiers())
return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
return T->isCanonicalUnqualified();
}
inline void QualType::removeConst() { inline void QualType::removeConst() {
removeFastQualifiers(Qualifiers::Const); removeFastQualifiers(Qualifiers::Const);
} }

View File

@ -1151,7 +1151,7 @@ QualType ASTContext::getComplexType(QualType T) {
// If the pointee type isn't canonical, this won't be a canonical type either, // If the pointee type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field. // so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!T->isCanonical()) { if (!T.isCanonical()) {
Canonical = getComplexType(getCanonicalType(T)); Canonical = getComplexType(getCanonicalType(T));
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1188,7 +1188,7 @@ QualType ASTContext::getPointerType(QualType T) {
// If the pointee type isn't canonical, this won't be a canonical type either, // If the pointee type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field. // so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!T->isCanonical()) { if (!T.isCanonical()) {
Canonical = getPointerType(getCanonicalType(T)); Canonical = getPointerType(getCanonicalType(T));
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1218,7 +1218,7 @@ QualType ASTContext::getBlockPointerType(QualType T) {
// If the block pointee type isn't canonical, this won't be a canonical // If the block pointee type isn't canonical, this won't be a canonical
// type either so fill in the canonical type field. // type either so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!T->isCanonical()) { if (!T.isCanonical()) {
Canonical = getBlockPointerType(getCanonicalType(T)); Canonical = getBlockPointerType(getCanonicalType(T));
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1249,7 +1249,7 @@ QualType ASTContext::getLValueReferenceType(QualType T) {
// If the referencee type isn't canonical, this won't be a canonical type // If the referencee type isn't canonical, this won't be a canonical type
// either, so fill in the canonical type field. // either, so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!T->isCanonical()) { if (!T.isCanonical()) {
Canonical = getLValueReferenceType(getCanonicalType(T)); Canonical = getLValueReferenceType(getCanonicalType(T));
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1281,7 +1281,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) {
// If the referencee type isn't canonical, this won't be a canonical type // If the referencee type isn't canonical, this won't be a canonical type
// either, so fill in the canonical type field. // either, so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!T->isCanonical()) { if (!T.isCanonical()) {
Canonical = getRValueReferenceType(getCanonicalType(T)); Canonical = getRValueReferenceType(getCanonicalType(T));
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1313,7 +1313,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) {
// If the pointee or class type isn't canonical, this won't be a canonical // If the pointee or class type isn't canonical, this won't be a canonical
// type either, so fill in the canonical type field. // type either, so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!T->isCanonical()) { if (!T.isCanonical()) {
Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls)); Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1353,7 +1353,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
// If the element type isn't canonical, this won't be a canonical type either, // If the element type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field. // so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!EltTy->isCanonical()) { if (!EltTy.isCanonical()) {
Canonical = getConstantArrayType(getCanonicalType(EltTy), ArySize, Canonical = getConstantArrayType(getCanonicalType(EltTy), ArySize,
ASM, EltTypeQuals); ASM, EltTypeQuals);
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1448,7 +1448,7 @@ QualType ASTContext::getIncompleteArrayType(QualType EltTy,
// either, so fill in the canonical type field. // either, so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!EltTy->isCanonical()) { if (!EltTy.isCanonical()) {
Canonical = getIncompleteArrayType(getCanonicalType(EltTy), Canonical = getIncompleteArrayType(getCanonicalType(EltTy),
ASM, EltTypeQuals); ASM, EltTypeQuals);
@ -1484,7 +1484,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
// If the element type isn't canonical, this won't be a canonical type either, // If the element type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field. // so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!vecType->isCanonical()) { if (!vecType.isCanonical()) {
Canonical = getVectorType(getCanonicalType(vecType), NumElts); Canonical = getVectorType(getCanonicalType(vecType), NumElts);
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1516,7 +1516,7 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
// If the element type isn't canonical, this won't be a canonical type either, // If the element type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field. // so fill in the canonical type field.
QualType Canonical; QualType Canonical;
if (!vecType->isCanonical()) { if (!vecType.isCanonical()) {
Canonical = getExtVectorType(getCanonicalType(vecType), NumElts); Canonical = getExtVectorType(getCanonicalType(vecType), NumElts);
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1580,7 +1580,7 @@ QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn) {
return QualType(FT, 0); return QualType(FT, 0);
QualType Canonical; QualType Canonical;
if (!ResultTy->isCanonical()) { if (!ResultTy.isCanonical()) {
Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn); Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn);
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
@ -1622,11 +1622,11 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
return QualType(FTP, 0); return QualType(FTP, 0);
// Determine whether the type being created is already canonical or not. // Determine whether the type being created is already canonical or not.
bool isCanonical = ResultTy->isCanonical(); bool isCanonical = ResultTy.isCanonical();
if (hasExceptionSpec) if (hasExceptionSpec)
isCanonical = false; isCanonical = false;
for (unsigned i = 0; i != NumArgs && isCanonical; ++i) for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
if (!ArgArray[i]->isCanonical()) if (!ArgArray[i].isCanonical())
isCanonical = false; isCanonical = false;
// If this type isn't canonical, get the canonical version of it. // If this type isn't canonical, get the canonical version of it.
@ -1711,7 +1711,7 @@ QualType ASTContext::getTypedefType(TypedefDecl *Decl) {
QualType QualType
ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
QualType Replacement) { QualType Replacement) {
assert(Replacement->isCanonical() assert(Replacement.isCanonical()
&& "replacement types must always be canonical"); && "replacement types must always be canonical");
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
@ -2499,7 +2499,7 @@ int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) {
/// routine will assert if passed a built-in type that isn't an integer or enum, /// routine will assert if passed a built-in type that isn't an integer or enum,
/// or if it is not canonicalized. /// or if it is not canonicalized.
unsigned ASTContext::getIntegerRank(Type *T) { unsigned ASTContext::getIntegerRank(Type *T) {
assert(T->isCanonical() && "T should be canonicalized"); assert(T->isCanonicalUnqualified() && "T should be canonicalized");
if (EnumType* ET = dyn_cast<EnumType>(T)) if (EnumType* ET = dyn_cast<EnumType>(T))
T = ET->getDecl()->getIntegerType().getTypePtr(); T = ET->getDecl()->getIntegerType().getTypePtr();
@ -3628,7 +3628,7 @@ Qualifiers::GC ASTContext::getObjCGCAttrKind(const QualType &Ty) const {
/// compatible. /// compatible.
static bool areCompatVectorTypes(const VectorType *LHS, static bool areCompatVectorTypes(const VectorType *LHS,
const VectorType *RHS) { const VectorType *RHS) {
assert(LHS->isCanonical() && RHS->isCanonical()); assert(LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified());
return LHS->getElementType() == RHS->getElementType() && return LHS->getElementType() == RHS->getElementType() &&
LHS->getNumElements() == RHS->getNumElements(); LHS->getNumElements() == RHS->getNumElements();
} }

View File

@ -50,7 +50,7 @@ CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() {
/// different base class subobjects of the same type. BaseType must be /// different base class subobjects of the same type. BaseType must be
/// an unqualified, canonical class type. /// an unqualified, canonical class type.
bool CXXBasePaths::isAmbiguous(QualType BaseType) { bool CXXBasePaths::isAmbiguous(QualType BaseType) {
assert(BaseType->isCanonical() && "Base type must be the canonical type"); assert(BaseType.isCanonical() && "Base type must be the canonical type");
assert(BaseType.hasQualifiers() == 0 && "Base type must be unqualified"); assert(BaseType.hasQualifiers() == 0 && "Base type must be unqualified");
std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType]; std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
return Subobjects.second + (Subobjects.first? 1 : 0) > 1; return Subobjects.second + (Subobjects.first? 1 : 0) > 1;

View File

@ -299,7 +299,7 @@ void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
switch (Arg.getKind()) { switch (Arg.getKind()) {
default: break; default: break;
case TemplateArgument::Type: case TemplateArgument::Type:
assert(Arg.getAsType()->isCanonical() && "Type must be canonical!"); assert(Arg.getAsType().isCanonical() && "Type must be canonical!");
break; break;
} }

View File

@ -365,7 +365,7 @@ public:
/// EmitConversionToBool - Convert the specified expression value to a /// EmitConversionToBool - Convert the specified expression value to a
/// boolean (i1) truth value. This is equivalent to "Val != 0". /// boolean (i1) truth value. This is equivalent to "Val != 0".
Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) { Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
assert(SrcType->isCanonical() && "EmitScalarConversion strips typedefs"); assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs");
if (SrcType->isRealFloatingType()) { if (SrcType->isRealFloatingType()) {
// Compare against 0.0 for fp scalars. // Compare against 0.0 for fp scalars.

View File

@ -221,7 +221,7 @@ DeduceTemplateArguments(ASTContext &Context,
QualType Arg, QualType Arg,
Sema::TemplateDeductionInfo &Info, Sema::TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<TemplateArgument> &Deduced) { llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
assert(Arg->isCanonical() && "Argument type must be canonical"); assert(Arg.isCanonical() && "Argument type must be canonical");
// Check whether the template argument is a dependent template-id. // Check whether the template argument is a dependent template-id.
// FIXME: This is untested code; it can be tested when we implement // FIXME: This is untested code; it can be tested when we implement
@ -313,7 +313,7 @@ DeduceTemplateArguments(ASTContext &Context,
/// that corresponds to T. Otherwise, returns T. /// that corresponds to T. Otherwise, returns T.
static QualType getUnqualifiedArrayType(ASTContext &Context, QualType T, static QualType getUnqualifiedArrayType(ASTContext &Context, QualType T,
Qualifiers &Quals) { Qualifiers &Quals) {
assert(T->isCanonical() && "Only operates on canonical types"); assert(T.isCanonical() && "Only operates on canonical types");
if (!isa<ArrayType>(T)) { if (!isa<ArrayType>(T)) {
Quals = T.getQualifiers(); Quals = T.getQualifiers();
return T.getUnqualifiedType(); return T.getUnqualifiedType();