From 2fa8c2598c2615da4639b4e42e9079647bd3aea4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 17 Mar 2009 22:51:02 +0000 Subject: [PATCH] Fix Type::getDesugaredType() to remove all direct sugar on a type. For example, if we have a typedef of a typeof of int, we strip all the say down to int. This allows us to simplify the getAs* methods, and is the first step towards fixing PR3817 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67126 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Type.h | 7 ++++++ lib/AST/Type.cpp | 53 ++++++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 4e1672d435..94368b707d 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -145,6 +145,13 @@ public: bool isAtLeastAsQualifiedAs(QualType Other) const; QualType getNonReferenceType() const; + /// getDesugaredType - Return the specified type with any "sugar" removed from + /// the type. This takes off typedefs, typeof's etc. If the outer level of + /// the type is already concrete, it returns it unmodified. This is similar + /// to getting the canonical type, but it doesn't remove *all* typedefs. For + /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is + /// concrete. + QualType getDesugaredType() const; /// operator==/!= - Indicate whether the specified types and qualifiers are /// identical. diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 1714e84129..bb3df0882f 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -66,7 +66,18 @@ const Type *Type::getArrayElementTypeNoTypeQual() const { // If this is a typedef for an array type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getArrayElementTypeNoTypeQual(); + return cast(getDesugaredType())->getElementType().getTypePtr(); +} + +/// getDesugaredType - Return the specified type with any "sugar" removed from +/// the type. This takes off typedefs, typeof's etc. If the outer level of +/// the type is already concrete, it returns it unmodified. This is similar +/// to getting the canonical type, but it doesn't remove *all* typedefs. For +/// example, it returns "T*" as "T*", (not as "int*"), because the pointer is +/// concrete. +QualType QualType::getDesugaredType() const { + return getTypePtr()->getDesugaredType() + .getWithAdditionalQualifiers(getCVRQualifiers()); } /// getDesugaredType - Return the specified type with any "sugar" removed from @@ -77,14 +88,14 @@ const Type *Type::getArrayElementTypeNoTypeQual() const { /// concrete. QualType Type::getDesugaredType() const { if (const TypedefType *TDT = dyn_cast(this)) - return TDT->LookThroughTypedefs(); + return TDT->LookThroughTypedefs().getDesugaredType(); if (const TypeOfExprType *TOE = dyn_cast(this)) - return TOE->getUnderlyingExpr()->getType(); + return TOE->getUnderlyingExpr()->getType().getDesugaredType(); if (const TypeOfType *TOT = dyn_cast(this)) - return TOT->getUnderlyingType(); + return TOT->getUnderlyingType().getDesugaredType(); if (const ClassTemplateSpecializationType *Spec = dyn_cast(this)) - return Spec->getCanonicalTypeInternal(); + return Spec->getCanonicalTypeInternal().getDesugaredType(); // FIXME: remove this cast. return QualType(const_cast(this), 0); @@ -177,7 +188,7 @@ const ComplexType *Type::getAsComplexIntegerType() const { // If this is a typedef for a complex type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsComplexIntegerType(); + return cast(getDesugaredType()); } const BuiltinType *Type::getAsBuiltinType() const { @@ -195,7 +206,7 @@ const BuiltinType *Type::getAsBuiltinType() const { // If this is a typedef for a builtin type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsBuiltinType(); + return cast(getDesugaredType()); } const FunctionType *Type::getAsFunctionType() const { @@ -213,7 +224,7 @@ const FunctionType *Type::getAsFunctionType() const { // If this is a typedef for a function type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsFunctionType(); + return cast(getDesugaredType()); } const FunctionNoProtoType *Type::getAsFunctionNoProtoType() const { @@ -240,7 +251,7 @@ const PointerType *Type::getAsPointerType() const { // If this is a typedef for a pointer type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsPointerType(); + return cast(getDesugaredType()); } const BlockPointerType *Type::getAsBlockPointerType() const { @@ -258,7 +269,7 @@ const BlockPointerType *Type::getAsBlockPointerType() const { // If this is a typedef for a block pointer type, strip the typedef off // without losing all typedef information. - return getDesugaredType()->getAsBlockPointerType(); + return cast(getDesugaredType()); } const ReferenceType *Type::getAsReferenceType() const { @@ -276,7 +287,7 @@ const ReferenceType *Type::getAsReferenceType() const { // If this is a typedef for a reference type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsReferenceType(); + return cast(getDesugaredType()); } const LValueReferenceType *Type::getAsLValueReferenceType() const { @@ -294,7 +305,7 @@ const LValueReferenceType *Type::getAsLValueReferenceType() const { // If this is a typedef for an lvalue reference type, strip the typedef off // without losing all typedef information. - return getDesugaredType()->getAsLValueReferenceType(); + return cast(getDesugaredType()); } const RValueReferenceType *Type::getAsRValueReferenceType() const { @@ -312,7 +323,7 @@ const RValueReferenceType *Type::getAsRValueReferenceType() const { // If this is a typedef for an rvalue reference type, strip the typedef off // without losing all typedef information. - return getDesugaredType()->getAsRValueReferenceType(); + return cast(getDesugaredType()); } const MemberPointerType *Type::getAsMemberPointerType() const { @@ -330,7 +341,7 @@ const MemberPointerType *Type::getAsMemberPointerType() const { // If this is a typedef for a member pointer type, strip the typedef off // without losing all typedef information. - return getDesugaredType()->getAsMemberPointerType(); + return cast(getDesugaredType()); } /// isVariablyModifiedType (C99 6.7.5p3) - Return true for variable length @@ -381,7 +392,7 @@ const RecordType *Type::getAsRecordType() const { // If this is a typedef for a record type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsRecordType(); + return cast(getDesugaredType()); } const TagType *Type::getAsTagType() const { @@ -399,7 +410,7 @@ const TagType *Type::getAsTagType() const { // If this is a typedef for a tag type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsTagType(); + return cast(getDesugaredType()); } const RecordType *Type::getAsStructureType() const { @@ -416,7 +427,7 @@ const RecordType *Type::getAsStructureType() const { // If this is a typedef for a structure type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsStructureType(); + return cast(getDesugaredType()); } // Look through type qualifiers if (isa(CanonicalType.getUnqualifiedType())) @@ -438,7 +449,7 @@ const RecordType *Type::getAsUnionType() const { // If this is a typedef for a union type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsUnionType(); + return cast(getDesugaredType()); } // Look through type qualifiers @@ -469,7 +480,7 @@ const ComplexType *Type::getAsComplexType() const { // If this is a typedef for a complex type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsComplexType(); + return cast(getDesugaredType()); } const VectorType *Type::getAsVectorType() const { @@ -487,7 +498,7 @@ const VectorType *Type::getAsVectorType() const { // If this is a typedef for a vector type, strip the typedef off without // losing all typedef information. - return getDesugaredType()->getAsVectorType(); + return cast(getDesugaredType()); } const ExtVectorType *Type::getAsExtVectorType() const { @@ -505,7 +516,7 @@ const ExtVectorType *Type::getAsExtVectorType() const { // If this is a typedef for an extended vector type, strip the typedef off // without losing all typedef information. - return getDesugaredType()->getAsExtVectorType(); + return cast(getDesugaredType()); } const ObjCInterfaceType *Type::getAsObjCInterfaceType() const { -- 2.50.1