[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