@@ -2883,14 +2883,21 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
28832883 // / because the type is a RecordType or because it is the injected-class-name
28842884 // / type of a class template or class template partial specialization.
28852885 CXXRecordDecl *getAsCXXRecordDecl () const ;
2886+ CXXRecordDecl *castAsCXXRecordDecl () const ;
28862887
28872888 // / Retrieves the RecordDecl this type refers to.
28882889 RecordDecl *getAsRecordDecl () const ;
2890+ RecordDecl *castAsRecordDecl () const ;
2891+
2892+ // / Retrieves the EnumDecl this type refers to.
2893+ EnumDecl *getAsEnumDecl () const ;
2894+ EnumDecl *castAsEnumDecl () const ;
28892895
28902896 // / Retrieves the TagDecl that this type refers to, either
28912897 // / because the type is a TagType or because it is the injected-class-name
28922898 // / type of a class template or class template partial specialization.
28932899 TagDecl *getAsTagDecl () const ;
2900+ TagDecl *castAsTagDecl () const ;
28942901
28952902 // / If this is a pointer or reference to a RecordType, return the
28962903 // / CXXRecordDecl that the type refers to.
@@ -2922,8 +2929,31 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
29222929 // /
29232930 // / There are some specializations of this member template listed
29242931 // / immediately following this class.
2932+ // /
2933+ // / If you are interested only in the canonical properties of this type,
2934+ // / consider using getAsCanonical instead, as that is much faster.
29252935 template <typename T> const T *getAs () const ;
29262936
2937+ // / If this type is canonically the specified type, return its canonical type
2938+ // / cast to that specified type, otherwise returns null.
2939+ template <typename T> const T *getAsCanonical () const {
2940+ return dyn_cast<T>(CanonicalType);
2941+ }
2942+
2943+ // / Return this type's canonical type cast to the specified type.
2944+ // / If the type is not canonically that specified type, the behaviour is
2945+ // / undefined.
2946+ template <typename T> const T *castAsCanonical () const {
2947+ return cast<T>(CanonicalType);
2948+ }
2949+
2950+ // It is not helpful to use these on types which are never canonical
2951+ #define TYPE (Class, Base )
2952+ #define NEVER_CANONICAL_TYPE (Class ) \
2953+ template <> inline const Class##Type *Type::getAsCanonical () const = delete ; \
2954+ template <> inline const Class##Type *Type::castAsCanonical () const = delete ;
2955+ #include " clang/AST/TypeNodes.inc"
2956+
29272957 // / Look through sugar for an instance of TemplateSpecializationType which
29282958 // / is not a type alias, or null if there is no such type.
29292959 // / This is used when you want as-written template arguments or the template
@@ -3135,16 +3165,16 @@ template <> const BoundsAttributedType *Type::getAs() const;
31353165// / sugar until it reaches an CountAttributedType or a non-sugared type.
31363166template <> const CountAttributedType *Type::getAs () const ;
31373167
3138- // We can do canonical leaf types faster, because we don't have to
3139- // worry about preserving child type decoration.
3168+ // We can do always canonical types faster, because we don't have to
3169+ // worry about preserving decoration.
31403170#define TYPE (Class, Base )
3141- #define LEAF_TYPE (Class ) \
3142- template <> inline const Class##Type *Type::getAs () const { \
3143- return dyn_cast<Class##Type>(CanonicalType); \
3144- } \
3145- template <> inline const Class##Type *Type::castAs () const { \
3146- return cast<Class##Type>(CanonicalType); \
3147- }
3171+ #define ALWAYS_CANONICAL_TYPE (Class ) \
3172+ template <> inline const Class##Type *Type::getAs () const { \
3173+ return dyn_cast<Class##Type>(CanonicalType); \
3174+ } \
3175+ template <> inline const Class##Type *Type::castAs () const { \
3176+ return cast<Class##Type>(CanonicalType); \
3177+ }
31483178#include " clang/AST/TypeNodes.inc"
31493179
31503180// / This class is used for builtin types like 'int'. Builtin
0 commit comments