[cfe-commits] r39932 - in /cfe/trunk: AST/Type.cpp include/clang/AST/Type.h
Chris Lattner
sabre at nondot.org
Mon Jul 16 15:05:22 PDT 2007
Author: lattner
Date: Mon Jul 16 17:05:22 2007
New Revision: 39932
URL: http://llvm.org/viewvc/llvm-project?rev=39932&view=rev
Log:
In the final step for preserving typedef info better in the AST, upgrade
isPointerType and isVectorType to only look through a single level of typedef
when one is present. For this invalid code:
typedef float float4 __attribute__((vector_size(16)));
typedef int int4 __attribute__((vector_size(16)));
typedef int4* int4p;
void test(float4 a, int4p result, int i) {
result[i] = a;
}
we now get:
t.c:5:15: error: incompatible types assigning 'float4' to 'int4'
result[i] = a;
~~~~~~~~~ ^ ~
instead of:
t.c:5:15: error: incompatible types assigning 'float4' to 'int __attribute__((vector_size(16)))'
result[i] = a;
~~~~~~~~~ ^ ~
The rest of the type predicates should be upgraded to do the same thing.
Modified:
cfe/trunk/AST/Type.cpp
cfe/trunk/include/clang/AST/Type.h
Modified: cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Type.cpp?rev=39932&r1=39931&r2=39932&view=diff
==============================================================================
--- cfe/trunk/AST/Type.cpp (original)
+++ cfe/trunk/AST/Type.cpp Mon Jul 16 17:05:22 2007
@@ -64,9 +64,11 @@
// 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 @@
// 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 @@
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))
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=39932&r1=39931&r2=39932&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Jul 16 17:05:22 2007
@@ -585,6 +585,14 @@
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;
More information about the cfe-commits
mailing list