From: John McCall Date: Thu, 27 Jan 2011 08:17:49 +0000 (+0000) Subject: Provide Type::castAs<>, which is to getAs<> what cast<> is to dyn_cast<>. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d0370f59e79702ac908c81bf556519f91e9ca297;p=clang Provide Type::castAs<>, which is to getAs<> what cast<> is to dyn_cast<>. Also provide a method to grab the base element type of a type without stressing out over qualifiers (but give it a nice scary name). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124367 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index cc365a2f87..7d7c8b02ec 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1315,18 +1315,35 @@ public: /// type of a class template or class template partial specialization. CXXRecordDecl *getAsCXXRecordDecl() const; - // Member-template getAs'. Look through sugar for - // an instance of . This scheme will eventually - // replace the specific getAsXXXX methods above. - // - // There are some specializations of this member template listed - // immediately following this class. + /// Member-template getAs'. Look through sugar for + /// an instance of . This scheme will eventually + /// replace the specific getAsXXXX methods above. + /// + /// There are some specializations of this member template listed + /// immediately following this class. template const T *getAs() const; /// A variant of getAs<> for array types which silently discards /// qualifiers from the outermost type. const ArrayType *getAsArrayTypeUnsafe() const; + /// Member-template castAs. Look through sugar for + /// the underlying instance of . + /// + /// This method has the same relationship to getAs as cast has + /// to dyn_cast; which is to say, the underlying type *must* + /// have the intended type, and this method will never return null. + template const T *castAs() const; + + /// A variant of castAs<> for array type which silently discards + /// qualifiers from the outermost type. + const ArrayType *castAsArrayTypeUnsafe() const; + + /// getBaseElementTypeUnsafe - Get the base element type of this + /// type, potentially discarding type qualifiers. This method + /// should never be used when type qualifiers are meaningful. + const Type *getBaseElementTypeUnsafe() const; + /// getArrayElementTypeNoTypeQual - If this is an array type, return the /// element type of the array, potentially with type qualifiers missing. /// This method should never be used when type qualifiers are meaningful. @@ -1400,6 +1417,9 @@ template <> inline const TypedefType *Type::getAs() const { #define LEAF_TYPE(Class) \ template <> inline const Class##Type *Type::getAs() const { \ return dyn_cast(CanonicalType); \ +} \ +template <> inline const Class##Type *Type::castAs() const { \ + return cast(CanonicalType); \ } #include "clang/AST/TypeNodes.def" @@ -1655,7 +1675,7 @@ public: // FIXME: this might strip inner qualifiers; okay? const ReferenceType *T = this; while (T->isInnerRef()) - T = T->PointeeType->getAs(); + T = T->PointeeType->castAs(); return T->PointeeType; } @@ -3737,7 +3757,7 @@ public: /// would return 'A1P' (and we'd have to make iterating over /// qualifiers more complicated). const ObjCObjectType *getObjectType() const { - return PointeeType->getAs(); + return PointeeType->castAs(); } /// getInterfaceType - If this pointer points to an Objective C @@ -4050,7 +4070,7 @@ inline bool Type::isRValueReferenceType() const { return isa(CanonicalType); } inline bool Type::isFunctionPointerType() const { - if (const PointerType* T = getAs()) + if (const PointerType *T = getAs()) return T->getPointeeType()->isFunctionType(); else return false; @@ -4174,6 +4194,13 @@ inline bool Type::hasObjCPointerRepresentation() const { return isObjCObjectPointerType(); } +inline const Type *Type::getBaseElementTypeUnsafe() const { + const Type *type = this; + while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe()) + type = arrayType->getElementType().getTypePtr(); + return type; +} + /// Insertion operator for diagnostics. This allows sending QualType's into a /// diagnostic with <<. inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, @@ -4234,6 +4261,21 @@ inline const ArrayType *Type::getAsArrayTypeUnsafe() const { return cast(getUnqualifiedDesugaredType()); } +template const T *Type::castAs() const { + ArrayType_cannot_be_used_with_getAs at; + (void) at; + + assert(isa(CanonicalType)); + if (const T *ty = dyn_cast(this)) return ty; + return cast(getUnqualifiedDesugaredType()); +} + +inline const ArrayType *Type::castAsArrayTypeUnsafe() const { + assert(isa(CanonicalType)); + if (const ArrayType *arr = dyn_cast(this)) return arr; + return cast(getUnqualifiedDesugaredType()); +} + } // end namespace clang #endif