[cfe-commits] r89018 - in /cfe/trunk: include/clang/AST/Type.h include/clang/AST/TypeLoc.h lib/AST/Type.cpp

Douglas Gregor dgregor at apple.com
Mon Nov 16 16:55:51 PST 2009


Author: dgregor
Date: Mon Nov 16 18:55:50 2009
New Revision: 89018

URL: http://llvm.org/viewvc/llvm-project?rev=89018&view=rev
Log:
When querying type qualifiers on QualType via one of the "non-local"
interfaces (which are used throughout the front end), combine the
qualifiers on the QualType instance with the qualifiers on the
canonical type to produce the set of qualifiers that, semantically,
apply to that type. This should design away a large category of
"qualifier-hidden-behind-a-typedef" buts like we saw in PR5383.

Performance-wise, this caused a regression of ~0.5% on Cocoa.h, but
it's totally worth it. We may actually be able to get a little more
performance back by using CanQualType more often.


Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/AST/TypeLoc.h
    cfe/trunk/lib/AST/Type.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=89018&r1=89017&r2=89018&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Nov 16 18:55:50 2009
@@ -404,6 +404,8 @@
     return Value.getPointer().get<const Type*>();
   }
 
+  QualType getUnqualifiedTypeSlow() const;
+  
   friend class QualifierCollector;
 public:
   QualType() {}
@@ -456,10 +458,7 @@
   }
   
   /// \brief Determine whether this type is const-qualified.
-  bool isConstQualified() const {
-    // FIXME: Look through sugar types.
-    return isLocalConstQualified();
-  }
+  bool isConstQualified() const;
   
   /// \brief Determine whether this particular QualType instance has the 
   /// "restrict" qualifier set, without looking through typedefs that may have
@@ -469,10 +468,7 @@
   }
   
   /// \brief Determine whether this type is restrict-qualified.
-  bool isRestrictQualified() const {
-    // FIXME: Look through sugar types.
-    return isLocalRestrictQualified();
-  }
+  bool isRestrictQualified() const;
   
   /// \brief Determine whether this particular QualType instance has the 
   /// "volatile" qualifier set, without looking through typedefs that may have
@@ -482,10 +478,7 @@
   }
 
   /// \brief Determine whether this type is volatile-qualified.
-  bool isVolatileQualified() const {
-    // FIXME: Look through sugar types.
-    return isLocalVolatileQualified();
-  }
+  bool isVolatileQualified() const;
   
   /// \brief Determine whether this particular QualType instance has any
   /// qualifiers, without looking through any typedefs that might add 
@@ -495,10 +488,7 @@
   }
 
   /// \brief Determine whether this type has any qualifiers.
-  bool hasQualifiers() const {
-    // FIXME: Look for qualifiers at any level.
-    return hasLocalQualifiers();
-  }
+  bool hasQualifiers() const;
   
   /// \brief Determine whether this particular QualType instance has any
   /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
@@ -519,10 +509,7 @@
   }
 
   /// \brief Retrieve the set of qualifiers applied to this type.
-  Qualifiers getQualifiers() const {
-    // FIXME: Collect qualifiers from all levels.
-    return getLocalQualifiers();
-  }
+  Qualifiers getQualifiers() const;
   
   /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers 
   /// local to this particular QualType instance, not including any qualifiers
@@ -536,10 +523,7 @@
 
   /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers 
   /// applied to this type.
-  unsigned getCVRQualifiers() const {
-    // FIXME: Collect qualifiers from all levels.
-    return getLocalCVRQualifiers();
-  }
+  unsigned getCVRQualifiers() const;
   
   bool isConstant(ASTContext& Ctx) const {
     return QualType::isConstant(*this, Ctx);
@@ -604,9 +588,12 @@
 
   /// \brief Return the unqualified form of the given type, which might be
   /// desugared to eliminate qualifiers introduced via typedefs.
-  QualType getUnqualifiedType() const { 
-    // FIXME: We may have to desugar the type to remove qualifiers.
-    return getLocalUnqualifiedType();
+  QualType getUnqualifiedType() const {
+    QualType T = getLocalUnqualifiedType();
+    if (!T.hasQualifiers())
+      return T;
+    
+    return getUnqualifiedTypeSlow();
   }
   
   bool isMoreQualifiedThan(QualType Other) const;
@@ -2631,6 +2618,39 @@
            !isa<FunctionType>(T) && !isa<ArrayType>(T);
 }
 
+inline bool QualType::isConstQualified() const {
+  return isLocalConstQualified() || 
+              getTypePtr()->getCanonicalTypeInternal().isLocalConstQualified();
+}
+
+inline bool QualType::isRestrictQualified() const {
+  return isLocalRestrictQualified() || 
+            getTypePtr()->getCanonicalTypeInternal().isLocalRestrictQualified();
+}
+
+
+inline bool QualType::isVolatileQualified() const {
+  return isLocalVolatileQualified() || 
+  getTypePtr()->getCanonicalTypeInternal().isLocalVolatileQualified();
+}
+  
+inline bool QualType::hasQualifiers() const {
+  return hasLocalQualifiers() ||
+                  getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers();
+}
+  
+inline Qualifiers QualType::getQualifiers() const {
+  Qualifiers Quals = getLocalQualifiers();
+  Quals.addQualifiers(
+                 getTypePtr()->getCanonicalTypeInternal().getLocalQualifiers());
+  return Quals;
+}
+  
+inline unsigned QualType::getCVRQualifiers() const {
+  return getLocalCVRQualifiers() | 
+              getTypePtr()->getCanonicalTypeInternal().getLocalCVRQualifiers();
+}
+  
 inline void QualType::removeConst() {
   removeFastQualifiers(Qualifiers::Const);
 }

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=89018&r1=89017&r2=89018&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Nov 16 18:55:50 2009
@@ -196,7 +196,7 @@
   /// \brief Returns the size of the type source info data block.
   unsigned getFullDataSize() const {
     return getLocalDataSize() + 
-      getFullDataSizeForType(getType().getUnqualifiedType());
+      getFullDataSizeForType(getType().getLocalUnqualifiedType());
   }
 
   static bool classof(const TypeLoc *TL) {

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=89018&r1=89017&r2=89018&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Mon Nov 16 18:55:50 2009
@@ -98,6 +98,44 @@
     ->getElementType().getTypePtr();
 }
 
+/// \brief Retrieve the unqualified variant of the given type, removing as
+/// little sugar as possible.
+///
+/// This routine looks through various kinds of sugar to find the 
+/// least-desuraged type that is unqualified. For example, given:
+///
+/// \code
+/// typedef int Integer;
+/// typedef const Integer CInteger;
+/// typedef CInteger DifferenceType;
+/// \endcode
+///
+/// Executing \c getUnqualifiedTypeSlow() on the type \c DifferenceType will
+/// desugar until we hit the type \c Integer, which has no qualifiers on it.
+QualType QualType::getUnqualifiedTypeSlow() const {
+  QualType Cur = *this;
+  while (true) {
+    if (!Cur.hasQualifiers())
+      return Cur;
+    
+    const Type *CurTy = Cur.getTypePtr();
+    switch (CurTy->getTypeClass()) {
+#define ABSTRACT_TYPE(Class, Parent)
+#define TYPE(Class, Parent)                                  \
+    case Type::Class: {                                      \
+      const Class##Type *Ty = cast<Class##Type>(CurTy);      \
+      if (!Ty->isSugared())                                  \
+        return Cur.getLocalUnqualifiedType();                \
+      Cur = Ty->desugar();                                   \
+      break;                                                 \
+    }
+#include "clang/AST/TypeNodes.def"
+    }
+  }
+  
+  return Cur.getUnqualifiedType();
+}
+
 /// getDesugaredType - Return the specified type with any "sugar" removed from
 /// the type.  This takes off typedefs, typeof's etc.  If the outer level of
 /// the type is already concrete, it returns it unmodified.  This is similar





More information about the cfe-commits mailing list