diff options
-rw-r--r-- | AST/Type.cpp | 42 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 8 |
2 files changed, 44 insertions, 6 deletions
diff --git a/AST/Type.cpp b/AST/Type.cpp index 0bc058f742..7b999faa66 100644 --- a/AST/Type.cpp +++ b/AST/Type.cpp @@ -64,9 +64,11 @@ const PointerType *Type::isPointerType() const { // If this is directly a pointer type, return it. if (const PointerType *PTy = dyn_cast<PointerType>(this)) return PTy; - // If this is a typedef for a pointer type, strip the typedef off. - if (const PointerType *PTy = dyn_cast<PointerType>(CanonicalType)) - return PTy; + + // If this is a typedef for a pointer type, strip the typedef off without + // losing all typedef information. + if (isa<PointerType>(CanonicalType)) + return cast<PointerType>(cast<TypedefType>(this)->LookThroughTypedefs()); return 0; } @@ -102,9 +104,12 @@ const VectorType *Type::isVectorType() const { // Are we directly a vector type? if (const VectorType *VTy = dyn_cast<VectorType>(this)) return VTy; - // If this is a typedef for a vector type, strip the typedef off. - if (const VectorType *VTy = dyn_cast<VectorType>(CanonicalType)) - return VTy; + + // If this is a typedef for a vector type, strip the typedef off without + // losing all typedef information. + if (isa<VectorType>(CanonicalType)) + return cast<VectorType>(cast<TypedefType>(this)->LookThroughTypedefs()); + return 0; } @@ -423,6 +428,31 @@ void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getResultType(), ArgInfo, NumArgs, isVariadic()); } +/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to +/// potentially looking through *all* consequtive typedefs. This returns the +/// sum of the type qualifiers, so if you have: +/// typedef const int A; +/// typedef volatile A B; +/// looking through the typedefs for B will give you "const volatile A". +/// +QualType TypedefType::LookThroughTypedefs() const { + // Usually, there is only a single level of typedefs, be fast in that case. + QualType FirstType = getDecl()->getUnderlyingType(); + if (!isa<TypedefType>(FirstType)) + return FirstType; + + // Otherwise, do the fully general loop. + unsigned TypeQuals = 0; + const TypedefType *TDT = this; + while (1) { + QualType CurType = TDT->getDecl()->getUnderlyingType(); + TypeQuals |= CurType.getQualifiers(); + + TDT = dyn_cast<TypedefType>(CurType); + if (TDT == 0) + return QualType(CurType.getTypePtr(), TypeQuals); + } +} bool RecordType::classof(const Type *T) { if (const TagType *TT = dyn_cast<TagType>(T)) diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index ecce34c64e..83d79df4a5 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -585,6 +585,14 @@ class TypedefType : public Type { public: TypedefDecl *getDecl() const { return Decl; } + + /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to + /// potentially looking through *all* consequtive typedefs. This returns the + /// sum of the type qualifiers, so if you have: + /// typedef const int A; + /// typedef volatile A B; + /// looking through the typedefs for B will give you "const volatile A". + QualType LookThroughTypedefs() const; virtual void getAsStringInternal(std::string &InnerString) const; |