[cfe-commits] r88969 - in /cfe/trunk: include/clang/AST/ include/clang/Frontend/ lib/AST/ lib/Analysis/ lib/CodeGen/ lib/Frontend/ lib/Sema/

Douglas Gregor dgregor at apple.com
Mon Nov 16 13:35:15 PST 2009


Author: dgregor
Date: Mon Nov 16 15:35:15 2009
New Revision: 88969

URL: http://llvm.org/viewvc/llvm-project?rev=88969&view=rev
Log:
First part of changes to eliminate problems with cv-qualifiers and
sugared types. The basic problem is that our qualifier accessors
(getQualifiers, getCVRQualifiers, isConstQualified, etc.) only look at
the current QualType and not at any qualifiers that come from sugared
types, meaning that we won't see these qualifiers through, e.g.,
typedefs:

  typedef const int CInt;
  typedef CInt Self;

Self.isConstQualified() currently returns false!

Various bugs (e.g., PR5383) have cropped up all over the front end due
to such problems. I'm addressing this problem by splitting each
qualifier accessor into two versions: 

  - the "local" version only returns qualifiers on this particular
    QualType instance
  - the "normal" version that will eventually combine qualifiers from this
    QualType instance with the qualifiers on the canonical type to
    produce the full set of qualifiers.

This commit adds the local versions and switches a few callers from
the "normal" version (e.g., isConstQualified) over to the "local"
version (e.g., isLocalConstQualified) when that is the right thing to
do, e.g., because we're printing or serializing the qualifiers. Also,
switch a bunch of
  
  Context.getCanonicalType(T1).getUnqualifiedType() == Context.getCanonicalType(T2).getQualifiedType()

expressions over to 

  Context.hasSameUnqualifiedType(T1, T2)



Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/CanonicalType.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/AST/TypeLoc.h
    cfe/trunk/include/clang/Frontend/PCHWriter.h
    cfe/trunk/include/clang/Frontend/TypeXML.def
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/CXXInheritance.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/TypePrinter.cpp
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/lib/Analysis/SValuator.cpp
    cfe/trunk/lib/Analysis/Store.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/Frontend/DocumentXML.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/TreeTransform.h

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Nov 16 15:35:15 2009
@@ -872,9 +872,9 @@
   /// \brief Determine whether the given types are equivalent after
   /// cvr-qualifiers have been removed.
   bool hasSameUnqualifiedType(QualType T1, QualType T2) {
-    T1 = getCanonicalType(T1);
-    T2 = getCanonicalType(T2);
-    return T1.getUnqualifiedType() == T2.getUnqualifiedType();
+    CanQualType CT1 = getCanonicalType(T1);
+    CanQualType CT2 = getCanonicalType(T2);
+    return CT1.getUnqualifiedType() == CT2.getUnqualifiedType();
   }
 
   /// \brief Retrieves the "canonical" declaration of

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

==============================================================================
--- cfe/trunk/include/clang/AST/CanonicalType.h (original)
+++ cfe/trunk/include/clang/AST/CanonicalType.h Mon Nov 16 15:35:15 2009
@@ -102,22 +102,22 @@
   CanProxy<T> operator->() const;
 
   /// \brief Retrieve all qualifiers.
-  Qualifiers getQualifiers() const { return Stored.getQualifiers(); }
+  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
 
   /// \brief Retrieve the const/volatile/restrict qualifiers.
-  unsigned getCVRQualifiers() const { return Stored.getCVRQualifiers(); }
+  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
 
   /// \brief Determines whether this type has any qualifiers
-  bool hasQualifiers() const { return Stored.hasQualifiers(); }
+  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
 
   bool isConstQualified() const {
-    return Stored.isConstQualified();
+    return Stored.isLocalConstQualified();
   }
   bool isVolatileQualified() const {
-    return Stored.isVolatileQualified();
+    return Stored.isLocalVolatileQualified();
   }
   bool isRestrictQualified() const {
-    return Stored.isRestrictQualified();
+    return Stored.isLocalRestrictQualified();
   }
 
   /// \brief Retrieve the unqualified form of this type.
@@ -638,7 +638,7 @@
 //----------------------------------------------------------------------------//
 template<typename T>
 inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
-  return CanQual<T>::CreateUnsafe(Stored.getUnqualifiedType());
+  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
 }
 
 template<typename T>

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

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Nov 16 15:35:15 2009
@@ -396,10 +396,6 @@
   llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
                        Qualifiers::FastWidth> Value;
 
-  bool hasExtQuals() const {
-    return Value.getPointer().is<const ExtQuals*>();
-  }
-
   const ExtQuals *getExtQualsUnsafe() const {
     return Value.getPointer().get<const ExtQuals*>();
   }
@@ -417,14 +413,14 @@
   QualType(const ExtQuals *Ptr, unsigned Quals)
     : Value(Ptr, Quals) {}
 
-  unsigned getFastQualifiers() const { return Value.getInt(); }
-  void setFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
+  unsigned getLocalFastQualifiers() const { return Value.getInt(); }
+  void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
 
   /// Retrieves a pointer to the underlying (unqualified) type.
   /// This should really return a const Type, but it's not worth
   /// changing all the users right now.
   Type *getTypePtr() const {
-    if (hasNonFastQualifiers())
+    if (hasLocalNonFastQualifiers())
       return const_cast<Type*>(getExtQualsUnsafe()->getBaseType());
     return const_cast<Type*>(getTypePtrUnsafe());
   }
@@ -452,41 +448,99 @@
     return Value.getPointer().isNull();
   }
 
+  /// \brief Determine whether this particular QualType instance has the 
+  /// "const" qualifier set, without looking through typedefs that may have
+  /// added "const" at a different level.
+  bool isLocalConstQualified() const {
+    return (getLocalFastQualifiers() & Qualifiers::Const);
+  }
+  
+  /// \brief Determine whether this type is const-qualified.
   bool isConstQualified() const {
-    return (getFastQualifiers() & Qualifiers::Const);
+    // FIXME: Look through sugar types.
+    return isLocalConstQualified();
+  }
+  
+  /// \brief Determine whether this particular QualType instance has the 
+  /// "restrict" qualifier set, without looking through typedefs that may have
+  /// added "restrict" at a different level.
+  bool isLocalRestrictQualified() const {
+    return (getLocalFastQualifiers() & Qualifiers::Restrict);
   }
+  
+  /// \brief Determine whether this type is restrict-qualified.
   bool isRestrictQualified() const {
-    return (getFastQualifiers() & Qualifiers::Restrict);
+    // FIXME: Look through sugar types.
+    return isLocalRestrictQualified();
+  }
+  
+  /// \brief Determine whether this particular QualType instance has the 
+  /// "volatile" qualifier set, without looking through typedefs that may have
+  /// added "volatile" at a different level.
+  bool isLocalVolatileQualified() const {
+    return (hasLocalNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
   }
+
+  /// \brief Determine whether this type is volatile-qualified.
   bool isVolatileQualified() const {
-    return (hasNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
+    // FIXME: Look through sugar types.
+    return isLocalVolatileQualified();
+  }
+  
+  /// \brief Determine whether this particular QualType instance has any
+  /// qualifiers, without looking through any typedefs that might add 
+  /// qualifiers at a different level.
+  bool hasLocalQualifiers() const {
+    return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
   }
 
-  // Determines whether this type has any direct qualifiers.
+  /// \brief Determine whether this type has any qualifiers.
   bool hasQualifiers() const {
-    return getFastQualifiers() || hasNonFastQualifiers();
+    // FIXME: Look for qualifiers at any level.
+    return hasLocalQualifiers();
   }
-
-  bool hasNonFastQualifiers() const {
-    return hasExtQuals();
+  
+  /// \brief Determine whether this particular QualType instance has any
+  /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
+  /// instance.
+  bool hasLocalNonFastQualifiers() const {
+    return Value.getPointer().is<const ExtQuals*>();
   }
 
-  // Retrieves the set of qualifiers belonging to this type.
-  Qualifiers getQualifiers() const {
+  /// \brief Retrieve the set of qualifiers local to this particular QualType
+  /// instance, not including any qualifiers acquired through typedefs or
+  /// other sugar.
+  Qualifiers getLocalQualifiers() const {
     Qualifiers Quals;
-    if (hasNonFastQualifiers())
+    if (hasLocalNonFastQualifiers())
       Quals = getExtQualsUnsafe()->getQualifiers();
-    Quals.addFastQualifiers(getFastQualifiers());
+    Quals.addFastQualifiers(getLocalFastQualifiers());
     return Quals;
   }
 
-  // Retrieves the CVR qualifiers of this type.
-  unsigned getCVRQualifiers() const {
-    unsigned CVR = getFastQualifiers();
-    if (isVolatileQualified()) CVR |= Qualifiers::Volatile;
+  /// \brief Retrieve the set of qualifiers applied to this type.
+  Qualifiers getQualifiers() const {
+    // FIXME: Collect qualifiers from all levels.
+    return getLocalQualifiers();
+  }
+  
+  /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers 
+  /// local to this particular QualType instance, not including any qualifiers
+  /// acquired through typedefs or other sugar.
+  unsigned getLocalCVRQualifiers() const {
+    unsigned CVR = getLocalFastQualifiers();
+    if (isLocalVolatileQualified())
+      CVR |= Qualifiers::Volatile;
     return CVR;
   }
 
+  /// \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();
+  }
+  
   bool isConstant(ASTContext& Ctx) const {
     return QualType::isConstant(*this, Ctx);
   }
@@ -508,6 +562,9 @@
     Value.setInt(Value.getInt() | TQs);
   }
 
+  // FIXME: The remove* functions are semantically broken, because they might
+  // not remove a qualifier stored on a typedef. Most of the with* functions
+  // have the same problem.
   void removeConst();
   void removeVolatile();
   void removeRestrict();
@@ -540,8 +597,18 @@
     return T;
   }
 
-  QualType getUnqualifiedType() const { return QualType(getTypePtr(), 0); }
-
+  /// \brief Return this type with all of the instance-specific qualifiers
+  /// removed, but without removing any qualifiers that may have been applied
+  /// through typedefs.
+  QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
+
+  /// \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();
+  }
+  
   bool isMoreQualifiedThan(QualType Other) const;
   bool isAtLeastAsQualifiedAs(QualType Other) const;
   QualType getNonReferenceType() const;
@@ -2529,8 +2596,8 @@
   /// Collect any qualifiers on the given type and return an
   /// unqualified type.
   const Type *strip(QualType QT) {
-    addFastQualifiers(QT.getFastQualifiers());
-    if (QT.hasNonFastQualifiers()) {
+    addFastQualifiers(QT.getLocalFastQualifiers());
+    if (QT.hasLocalNonFastQualifiers()) {
       const ExtQuals *EQ = QT.getExtQualsUnsafe();
       Context = &EQ->getContext();
       addQualifiers(EQ->getQualifiers());
@@ -2552,13 +2619,13 @@
 
 inline bool QualType::isCanonical() const {
   const Type *T = getTypePtr();
-  if (hasQualifiers())
+  if (hasLocalQualifiers())
     return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
   return T->isCanonicalUnqualified();
 }
 
 inline bool QualType::isCanonicalAsParam() const {
-  if (hasQualifiers()) return false;
+  if (hasLocalQualifiers()) return false;
   const Type *T = getTypePtr();
   return T->isCanonicalUnqualified() &&
            !isa<FunctionType>(T) && !isa<ArrayType>(T);
@@ -2598,14 +2665,14 @@
 
 /// getAddressSpace - Return the address space of this type.
 inline unsigned QualType::getAddressSpace() const {
-  if (hasNonFastQualifiers()) {
+  if (hasLocalNonFastQualifiers()) {
     const ExtQuals *EQ = getExtQualsUnsafe();
     if (EQ->hasAddressSpace())
       return EQ->getAddressSpace();
   }
 
   QualType CT = getTypePtr()->getCanonicalTypeInternal();
-  if (CT.hasNonFastQualifiers()) {
+  if (CT.hasLocalNonFastQualifiers()) {
     const ExtQuals *EQ = CT.getExtQualsUnsafe();
     if (EQ->hasAddressSpace())
       return EQ->getAddressSpace();
@@ -2620,14 +2687,14 @@
 
 /// getObjCGCAttr - Return the gc attribute of this type.
 inline Qualifiers::GC QualType::getObjCGCAttr() const {
-  if (hasNonFastQualifiers()) {
+  if (hasLocalNonFastQualifiers()) {
     const ExtQuals *EQ = getExtQualsUnsafe();
     if (EQ->hasObjCGCAttr())
       return EQ->getObjCGCAttr();
   }
 
   QualType CT = getTypePtr()->getCanonicalTypeInternal();
-  if (CT.hasNonFastQualifiers()) {
+  if (CT.hasLocalNonFastQualifiers()) {
     const ExtQuals *EQ = CT.getExtQualsUnsafe();
     if (EQ->hasObjCGCAttr())
       return EQ->getObjCGCAttr();
@@ -2705,28 +2772,26 @@
   return 0;
 }
 
-// NOTE: All of these methods use "getUnqualifiedType" to strip off address
-// space qualifiers if present.
 inline bool Type::isFunctionType() const {
-  return isa<FunctionType>(CanonicalType.getUnqualifiedType());
+  return isa<FunctionType>(CanonicalType);
 }
 inline bool Type::isPointerType() const {
-  return isa<PointerType>(CanonicalType.getUnqualifiedType());
+  return isa<PointerType>(CanonicalType);
 }
 inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
 inline bool Type::isBlockPointerType() const {
-  return isa<BlockPointerType>(CanonicalType.getUnqualifiedType());
+  return isa<BlockPointerType>(CanonicalType);
 }
 inline bool Type::isReferenceType() const {
-  return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
+  return isa<ReferenceType>(CanonicalType);
 }
 inline bool Type::isLValueReferenceType() const {
-  return isa<LValueReferenceType>(CanonicalType.getUnqualifiedType());
+  return isa<LValueReferenceType>(CanonicalType);
 }
 inline bool Type::isRValueReferenceType() const {
-  return isa<RValueReferenceType>(CanonicalType.getUnqualifiedType());
+  return isa<RValueReferenceType>(CanonicalType);
 }
 inline bool Type::isFunctionPointerType() const {
   if (const PointerType* T = getAs<PointerType>())
@@ -2735,7 +2800,7 @@
     return false;
 }
 inline bool Type::isMemberPointerType() const {
-  return isa<MemberPointerType>(CanonicalType.getUnqualifiedType());
+  return isa<MemberPointerType>(CanonicalType);
 }
 inline bool Type::isMemberFunctionPointerType() const {
   if (const MemberPointerType* T = getAs<MemberPointerType>())
@@ -2744,37 +2809,37 @@
     return false;
 }
 inline bool Type::isArrayType() const {
-  return isa<ArrayType>(CanonicalType.getUnqualifiedType());
+  return isa<ArrayType>(CanonicalType);
 }
 inline bool Type::isConstantArrayType() const {
-  return isa<ConstantArrayType>(CanonicalType.getUnqualifiedType());
+  return isa<ConstantArrayType>(CanonicalType);
 }
 inline bool Type::isIncompleteArrayType() const {
-  return isa<IncompleteArrayType>(CanonicalType.getUnqualifiedType());
+  return isa<IncompleteArrayType>(CanonicalType);
 }
 inline bool Type::isVariableArrayType() const {
-  return isa<VariableArrayType>(CanonicalType.getUnqualifiedType());
+  return isa<VariableArrayType>(CanonicalType);
 }
 inline bool Type::isDependentSizedArrayType() const {
-  return isa<DependentSizedArrayType>(CanonicalType.getUnqualifiedType());
+  return isa<DependentSizedArrayType>(CanonicalType);
 }
 inline bool Type::isRecordType() const {
-  return isa<RecordType>(CanonicalType.getUnqualifiedType());
+  return isa<RecordType>(CanonicalType);
 }
 inline bool Type::isAnyComplexType() const {
-  return isa<ComplexType>(CanonicalType.getUnqualifiedType());
+  return isa<ComplexType>(CanonicalType);
 }
 inline bool Type::isVectorType() const {
-  return isa<VectorType>(CanonicalType.getUnqualifiedType());
+  return isa<VectorType>(CanonicalType);
 }
 inline bool Type::isExtVectorType() const {
-  return isa<ExtVectorType>(CanonicalType.getUnqualifiedType());
+  return isa<ExtVectorType>(CanonicalType);
 }
 inline bool Type::isObjCObjectPointerType() const {
-  return isa<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
+  return isa<ObjCObjectPointerType>(CanonicalType);
 }
 inline bool Type::isObjCInterfaceType() const {
-  return isa<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
+  return isa<ObjCInterfaceType>(CanonicalType);
 }
 inline bool Type::isObjCQualifiedIdType() const {
   if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
@@ -2800,7 +2865,7 @@
   return isObjCIdType() || isObjCClassType();
 }
 inline bool Type::isTemplateTypeParmType() const {
-  return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
+  return isa<TemplateTypeParmType>(CanonicalType);
 }
 
 inline bool Type::isSpecificBuiltinType(unsigned K) const {

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

==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Nov 16 15:35:15 2009
@@ -58,7 +58,7 @@
     : Ty(ty), Data(opaqueData) { }
 
   TypeLocClass getTypeLocClass() const {
-    if (getType().hasQualifiers()) return Qualified;
+    if (getType().hasLocalQualifiers()) return Qualified;
     return (TypeLocClass) getType()->getTypeClass();
   }
 
@@ -155,7 +155,7 @@
   }
 
   static bool classof(const TypeLoc *TL) {
-    return !TL->getType().hasQualifiers();
+    return !TL->getType().hasLocalQualifiers();
   }
   static bool classof(const UnqualTypeLoc *TL) { return true; }
 };
@@ -200,7 +200,7 @@
   }
 
   static bool classof(const TypeLoc *TL) {
-    return TL->getType().hasQualifiers();
+    return TL->getType().hasLocalQualifiers();
   }
   static bool classof(const QualifiedTypeLoc *TL) { return true; }
 };

Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Mon Nov 16 15:35:15 2009
@@ -52,7 +52,8 @@
     return QualType::getFromOpaquePtr((void*) 2);
   }
   static inline unsigned getHashValue(QualType T) {
-    assert(!T.getFastQualifiers() && "hash invalid for types with fast quals");
+    assert(!T.getLocalFastQualifiers() && 
+           "hash invalid for types with fast quals");
     uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
     return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
   }

Modified: cfe/trunk/include/clang/Frontend/TypeXML.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/TypeXML.def?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/TypeXML.def (original)
+++ cfe/trunk/include/clang/Frontend/TypeXML.def Mon Nov 16 15:35:15 2009
@@ -65,9 +65,9 @@
 NODE_XML(QualType, "CvQualifiedType")
   ID_ATTRIBUTE_XML
   TYPE_ATTRIBUTE_XML(getTypePtr())                      // the qualified type, e.g. for 'T* const' it's 'T*'
-  ATTRIBUTE_OPT_XML(isConstQualified(), "const")        // boolean
-  ATTRIBUTE_OPT_XML(isVolatileQualified(), "volatile")  // boolean
-  ATTRIBUTE_OPT_XML(isRestrictQualified(), "restrict")  // boolean
+  ATTRIBUTE_OPT_XML(isLocalConstQualified(), "const")        // boolean
+  ATTRIBUTE_OPT_XML(isLocalVolatileQualified(), "volatile")  // boolean
+  ATTRIBUTE_OPT_XML(isLocalRestrictQualified(), "restrict")  // boolean
   ATTRIBUTE_OPT_XML(getObjCGCAttr(), "objc_gc")         // Qualifiers::GC
   ATTRIBUTE_OPT_XML(getAddressSpace(), "address_space") // unsigned
 END_NODE_XML

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

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Nov 16 15:35:15 2009
@@ -1186,7 +1186,7 @@
     }
   }
 
-  return getQualifiedType(ResultType, T.getQualifiers());
+  return getQualifiedType(ResultType, T.getLocalQualifiers());
 }
 
 /// getComplexType - Return the uniqued reference to the type for a complex
@@ -2435,7 +2435,7 @@
 
 const ArrayType *ASTContext::getAsArrayType(QualType T) {
   // Handle the non-qualified case efficiently.
-  if (!T.hasQualifiers()) {
+  if (!T.hasLocalQualifiers()) {
     // Handle the common positive case fast.
     if (const ArrayType *AT = dyn_cast<ArrayType>(T))
       return AT;
@@ -4204,8 +4204,8 @@
     return LHS;
 
   // If the qualifiers are different, the types aren't compatible... mostly.
-  Qualifiers LQuals = LHSCan.getQualifiers();
-  Qualifiers RQuals = RHSCan.getQualifiers();
+  Qualifiers LQuals = LHSCan.getLocalQualifiers();
+  Qualifiers RQuals = RHSCan.getLocalQualifiers();
   if (LQuals != RQuals) {
     // If any of these qualifiers are different, we have a type
     // mismatch.

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

==============================================================================
--- cfe/trunk/lib/AST/CXXInheritance.cpp (original)
+++ cfe/trunk/lib/AST/CXXInheritance.cpp Mon Nov 16 15:35:15 2009
@@ -99,8 +99,8 @@
   for (base_class_const_iterator BaseSpec = bases_begin(),
          BaseSpecEnd = bases_end(); BaseSpec != BaseSpecEnd; ++BaseSpec) {
     // Find the record of the base class subobjects for this type.
-    QualType BaseType = Context.getCanonicalType(BaseSpec->getType());
-    BaseType = BaseType.getUnqualifiedType();
+    QualType BaseType = Context.getCanonicalType(BaseSpec->getType())
+                                                          .getUnqualifiedType();
     
     // C++ [temp.dep]p3:
     //   In the definition of a class template or a member of a class template,

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

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Nov 16 15:35:15 2009
@@ -211,7 +211,7 @@
       if (!ArgType.isConstQualified())
         AcceptsConst = false;
     }
-    if (Context.getCanonicalType(ArgType).getUnqualifiedType() != ClassType)
+    if (!Context.hasSameUnqualifiedType(ArgType, ClassType))
       continue;
     MD = Method;
     // We have a single argument of type cv X or cv X&, i.e. we've found the
@@ -276,7 +276,7 @@
   QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
     const_cast<CXXRecordDecl*>(this)));
 
-  if (ClassType != Context.getCanonicalType(ArgType))
+  if (!Context.hasSameUnqualifiedType(ClassType, ArgType))
     return;
 
   // This is a copy assignment operator.

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

==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Mon Nov 16 15:35:15 2009
@@ -63,7 +63,7 @@
     return;
   
   // Print qualifiers as appropriate.
-  Qualifiers Quals = T.getQualifiers();
+  Qualifiers Quals = T.getLocalQualifiers();
   if (!Quals.empty()) {
     std::string TQS;
     Quals.getAsStringInternal(TQS, Policy);
@@ -550,7 +550,8 @@
     ObjCQIString += '>';
   }
   
-  T->getPointeeType().getQualifiers().getAsStringInternal(ObjCQIString, Policy);
+  T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString, 
+                                                               Policy);
   
   if (!T->isObjCIdType() && !T->isObjCQualifiedIdType())
     ObjCQIString += " *"; // Don't forget the implicit pointer.

Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Mon Nov 16 15:35:15 2009
@@ -1537,7 +1537,7 @@
          E = MD->param_end(); I != E; ++I, ++i)
       if (ParmVarDecl *PD = *I) {
         QualType Ty = Ctx.getCanonicalType(PD->getType());
-        if (Ty.getUnqualifiedType() == Ctx.VoidPtrTy)
+        if (Ty.getLocalUnqualifiedType() == Ctx.VoidPtrTy)
           ScratchArgs = AF.Add(ScratchArgs, i, StopTracking);
       }
   }

Modified: cfe/trunk/lib/Analysis/SValuator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SValuator.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/SValuator.cpp (original)
+++ cfe/trunk/lib/Analysis/SValuator.cpp Mon Nov 16 15:35:15 2009
@@ -62,8 +62,7 @@
   ASTContext &C = ValMgr.getContext();
 
   // For const casts, just propagate the value.
-  if (C.getCanonicalType(castTy).getUnqualifiedType() ==
-      C.getCanonicalType(originalTy).getUnqualifiedType())
+  if (C.hasSameUnqualifiedType(castTy, originalTy))
     return CastResult(state, val);
 
   // Check for casts from pointers to integers.

Modified: cfe/trunk/lib/Analysis/Store.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Store.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/Store.cpp (original)
+++ cfe/trunk/lib/Analysis/Store.cpp Mon Nov 16 15:35:15 2009
@@ -64,7 +64,7 @@
   QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
 
   // Handle casts to void*.  We just pass the region through.
-  if (CanonPointeeTy.getUnqualifiedType() == Ctx.VoidTy)
+  if (CanonPointeeTy.getLocalUnqualifiedType() == Ctx.VoidTy)
     return R;
 
   // Handle casts from compatible types.
@@ -199,9 +199,7 @@
   if (castTy.isNull())
     return V;
   
-  assert(Ctx.getCanonicalType(castTy).getUnqualifiedType() == 
-         Ctx.getCanonicalType(R->getValueType(Ctx)).getUnqualifiedType());
-
+  assert(Ctx.hasSameUnqualifiedType(castTy, R->getValueType(Ctx)));
   return V;
 }
 

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Nov 16 15:35:15 2009
@@ -851,7 +851,7 @@
 llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,
                                          llvm::DICompileUnit Unit) {
   // Handle qualifiers, which recursively handles what they refer to.
-  if (Ty.hasQualifiers())
+  if (Ty.hasLocalQualifiers())
     return CreateQualifiedType(Ty, Unit);
 
   // Work out details of type.

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Mon Nov 16 15:35:15 2009
@@ -744,15 +744,15 @@
   // Only operate on the canonical type!
   T = Context.getASTContext().getCanonicalType(T);
 
-  bool IsSubstitutable = T.hasQualifiers() || !isa<BuiltinType>(T);
+  bool IsSubstitutable = T.hasLocalQualifiers() || !isa<BuiltinType>(T);
   if (IsSubstitutable && mangleSubstitution(T))
     return;
 
-  if (Qualifiers Quals = T.getQualifiers()) {
+  if (Qualifiers Quals = T.getLocalQualifiers()) {
     mangleQualifiers(Quals);
     // Recurse:  even if the qualified type isn't yet substitutable,
     // the unqualified type might be.
-    mangleType(T.getUnqualifiedType());
+    mangleType(T.getLocalUnqualifiedType());
   } else {
     switch (T->getTypeClass()) {
 #define ABSTRACT_TYPE(CLASS, PARENT)

Modified: cfe/trunk/lib/Frontend/DocumentXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DocumentXML.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/DocumentXML.cpp (original)
+++ cfe/trunk/lib/Frontend/DocumentXML.cpp Mon Nov 16 15:35:15 2009
@@ -135,7 +135,7 @@
 
   for (XML::IdMap<QualType>::iterator i = Types.begin(), e = Types.end();
        i != e; ++i) {
-    if (i->first.hasQualifiers()) {
+    if (i->first.hasLocalQualifiers()) {
       writeTypeToXML(i->first);
       addAttribute("id", getPrefixedId(i->second, ID_NORMAL));
       toParent();
@@ -205,7 +205,7 @@
   {
     addTypeRecursively(pType.getTypePtr());
     // beautifier: a non-qualified type shall be transparent
-    if (!pType.hasQualifiers())
+    if (!pType.hasLocalQualifiers())
     {
       Types[pType] = BasicTypes[pType.getTypePtr()];
     }

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Mon Nov 16 15:35:15 2009
@@ -1248,9 +1248,9 @@
   // Emit the type's representation.
   PCHTypeWriter W(*this, Record);
 
-  if (T.hasNonFastQualifiers()) {
-    Qualifiers Qs = T.getQualifiers();
-    AddTypeRef(T.getUnqualifiedType(), Record);
+  if (T.hasLocalNonFastQualifiers()) {
+    Qualifiers Qs = T.getLocalQualifiers();
+    AddTypeRef(T.getLocalUnqualifiedType(), Record);
     Record.push_back(Qs.getAsOpaqueValue());
     W.Code = pch::TYPE_EXT_QUAL;
   } else {
@@ -2154,10 +2154,10 @@
     return;
   }
 
-  unsigned FastQuals = T.getFastQualifiers();
+  unsigned FastQuals = T.getLocalFastQualifiers();
   T.removeFastQualifiers();
 
-  if (T.hasNonFastQualifiers()) {
+  if (T.hasLocalNonFastQualifiers()) {
     pch::TypeID &ID = TypeIDs[T];
     if (ID == 0) {
       // We haven't seen these qualifiers applied to this type before.
@@ -2172,7 +2172,7 @@
     return;
   }
 
-  assert(!T.hasQualifiers());
+  assert(!T.hasLocalQualifiers());
   
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
     pch::TypeID ID = 0;

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Mon Nov 16 15:35:15 2009
@@ -737,10 +737,8 @@
   }
 
   // T == T, modulo cv
-  if (Self.Context.getCanonicalType(
-        SrcMemPtr->getPointeeType().getUnqualifiedType()) !=
-      Self.Context.getCanonicalType(DestMemPtr->getPointeeType().
-                                    getUnqualifiedType()))
+  if (!Self.Context.hasSameUnqualifiedType(SrcMemPtr->getPointeeType(),
+                                           DestMemPtr->getPointeeType()))
     return TC_NotApplicable;
 
   // B base of D

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Nov 16 15:35:15 2009
@@ -628,8 +628,7 @@
       return ExprError();
     }
 
-    if (Context.getCanonicalType(FAType).getUnqualifiedType() !=
-        Context.getCanonicalType(SAType).getUnqualifiedType()) {
+    if (!Context.hasSameUnqualifiedType(FAType, SAType)) {
       Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector)
         << SourceRange(TheCall->getArg(0)->getLocStart(),
                        TheCall->getArg(1)->getLocEnd());

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Nov 16 15:35:15 2009
@@ -1698,9 +1698,8 @@
     QualType DeclParamTy = Declaration->getParamDecl(Idx)->getType();
     QualType DefParamTy = Definition->getParamDecl(Idx)->getType();
 
-    DeclParamTy = Context.getCanonicalType(DeclParamTy.getNonReferenceType());
-    DefParamTy = Context.getCanonicalType(DefParamTy.getNonReferenceType());
-    if (DeclParamTy.getUnqualifiedType() != DefParamTy.getUnqualifiedType())
+    if (!Context.hasSameUnqualifiedType(DeclParamTy.getNonReferenceType(),
+                                        DefParamTy.getNonReferenceType()))
       return false;
   }
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Nov 16 15:35:15 2009
@@ -587,7 +587,7 @@
   for (unsigned idx = 0; idx < NumBases; ++idx) {
     QualType NewBaseType
       = Context.getCanonicalType(Bases[idx]->getType());
-    NewBaseType = NewBaseType.getUnqualifiedType();
+    NewBaseType = NewBaseType.getLocalUnqualifiedType();
 
     if (KnownBaseTypes[NewBaseType]) {
       // C++ [class.mi]p3:
@@ -1140,8 +1140,7 @@
     const CXXBaseSpecifier *DirectBaseSpec = 0;
     for (CXXRecordDecl::base_class_const_iterator Base =
          ClassDecl->bases_begin(); Base != ClassDecl->bases_end(); ++Base) {
-      if (Context.getCanonicalType(BaseType).getUnqualifiedType() ==
-          Context.getCanonicalType(Base->getType()).getUnqualifiedType()) {
+      if (Context.hasSameUnqualifiedType(BaseType, Base->getType())) {
         // We found a direct base of this type. That's what we're
         // initializing.
         DirectBaseSpec = &*Base;
@@ -3649,8 +3648,8 @@
 
   QualType T1 = Context.getCanonicalType(OrigT1);
   QualType T2 = Context.getCanonicalType(OrigT2);
-  QualType UnqualT1 = T1.getUnqualifiedType();
-  QualType UnqualT2 = T2.getUnqualifiedType();
+  QualType UnqualT1 = T1.getLocalUnqualifiedType();
+  QualType UnqualT2 = T2.getLocalUnqualifiedType();
 
   // C++ [dcl.init.ref]p4:
   //   Given types "cv1 T1" and "cv2 T2," "cv1 T1" is
@@ -4756,7 +4755,7 @@
   QualType COldTy = Context.getCanonicalType(OldTy);
 
   if (CNewTy == COldTy &&
-      CNewTy.getCVRQualifiers() == COldTy.getCVRQualifiers())
+      CNewTy.getLocalCVRQualifiers() == COldTy.getLocalCVRQualifiers())
     return false;
 
   // Check if the return types are covariant
@@ -4785,7 +4784,7 @@
     return true;
   }
 
-  if (NewClassTy.getUnqualifiedType() != OldClassTy.getUnqualifiedType()) {
+  if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
     // Check if the new class derives from the old class.
     if (!IsDerivedFrom(NewClassTy, OldClassTy)) {
       Diag(New->getLocation(),
@@ -4807,7 +4806,7 @@
   }
 
   // The qualifiers of the return types must be the same.
-  if (CNewTy.getCVRQualifiers() != COldTy.getCVRQualifiers()) {
+  if (CNewTy.getLocalCVRQualifiers() != COldTy.getLocalCVRQualifiers()) {
     Diag(New->getLocation(),
          diag::err_covariant_return_type_different_qualifications)
     << New->getDeclName() << NewTy << OldTy;

Modified: cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExceptionSpec.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExceptionSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExceptionSpec.cpp Mon Nov 16 15:35:15 2009
@@ -183,7 +183,7 @@
       SubIsPointer = true;
     }
     bool SubIsClass = CanonicalSubT->isRecordType();
-    CanonicalSubT = CanonicalSubT.getUnqualifiedType();
+    CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType();
 
     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
                        /*DetectVirtual=*/false);
@@ -205,7 +205,7 @@
           continue;
         }
       }
-      CanonicalSuperT = CanonicalSuperT.getUnqualifiedType();
+      CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType();
       // If the types are the same, move on to the next type in the subset.
       if (CanonicalSubT == CanonicalSuperT) {
         Contained = true;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Nov 16 15:35:15 2009
@@ -3070,8 +3070,7 @@
 
 static CastExpr::CastKind getScalarCastKind(ASTContext &Context,
                                             QualType SrcTy, QualType DestTy) {
-  if (Context.getCanonicalType(SrcTy).getUnqualifiedType() ==
-      Context.getCanonicalType(DestTy).getUnqualifiedType())
+  if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
     return CastExpr::CK_NoOp;
 
   if (SrcTy->hasPointerRepresentation()) {
@@ -3122,8 +3121,7 @@
   }
   
   if (!castType->isScalarType() && !castType->isVectorType()) {
-    if (Context.getCanonicalType(castType).getUnqualifiedType() ==
-        Context.getCanonicalType(castExpr->getType().getUnqualifiedType()) &&
+    if (Context.hasSameUnqualifiedType(castType, castExpr->getType()) &&
         (castType->isStructureType() || castType->isUnionType())) {
       // GCC struct/union extension: allow cast to self.
       // FIXME: Check that the cast destination type is complete.
@@ -3139,8 +3137,8 @@
       RecordDecl::field_iterator Field, FieldEnd;
       for (Field = RD->field_begin(), FieldEnd = RD->field_end();
            Field != FieldEnd; ++Field) {
-        if (Context.getCanonicalType(Field->getType()).getUnqualifiedType() ==
-            Context.getCanonicalType(castExpr->getType()).getUnqualifiedType()) {
+        if (Context.hasSameUnqualifiedType(Field->getType(), 
+                                           castExpr->getType())) {
           Diag(TyR.getBegin(), diag::ext_typecheck_cast_to_union)
             << castExpr->getSourceRange();
           break;
@@ -3761,7 +3759,7 @@
         rhptee = Context.getCanonicalType(rhptee);
       } while (lhptee->isPointerType() && rhptee->isPointerType());
       
-      if (lhptee.getUnqualifiedType() == rhptee.getUnqualifiedType())
+      if (Context.hasSameUnqualifiedType(lhptee, rhptee))
         return IncompatibleNestedPointerQualifiers;
     }
     
@@ -3791,7 +3789,7 @@
   AssignConvertType ConvTy = Compatible;
 
   // For blocks we enforce that qualifiers are identical.
-  if (lhptee.getCVRQualifiers() != rhptee.getCVRQualifiers())
+  if (lhptee.getLocalCVRQualifiers() != rhptee.getLocalCVRQualifiers())
     ConvTy = CompatiblePointerDiscardsQualifiers;
 
   if (!Context.typesAreCompatible(lhptee, rhptee))

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Nov 16 15:35:15 2009
@@ -1431,8 +1431,7 @@
     }
   }
 
-  if (Context.getCanonicalType(Class).getUnqualifiedType() !=
-      Context.getCanonicalType(LType).getUnqualifiedType()) {
+  if (!Context.hasSameUnqualifiedType(Class, LType)) {
     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false,
                        /*DetectVirtual=*/false);
     // FIXME: Would it be useful to print full ambiguity paths, or is that

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Nov 16 15:35:15 2009
@@ -174,7 +174,8 @@
       //      copy-initialization where the cv-unqualified version of the
       //      source type is the same class as, or a derived class of, the
       //      class of the destination, constructors are considered.
-      if ((DeclTypeC.getUnqualifiedType() == InitTypeC.getUnqualifiedType()) ||
+      if ((DeclTypeC.getLocalUnqualifiedType() 
+                                     == InitTypeC.getLocalUnqualifiedType()) ||
           IsDerivedFrom(InitTypeC, DeclTypeC)) {
         const CXXRecordDecl *RD =
           cast<CXXRecordDecl>(DeclType->getAs<RecordType>()->getDecl());

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Nov 16 15:35:15 2009
@@ -1576,8 +1576,7 @@
 
   if (T1->isEnumeralType()) {
     QualType ArgType = Proto->getArgType(0).getNonReferenceType();
-    if (Context.getCanonicalType(T1).getUnqualifiedType()
-          == Context.getCanonicalType(ArgType).getUnqualifiedType())
+    if (Context.hasSameUnqualifiedType(T1, ArgType))
       return true;
   }
 
@@ -1586,8 +1585,7 @@
 
   if (!T2.isNull() && T2->isEnumeralType()) {
     QualType ArgType = Proto->getArgType(1).getNonReferenceType();
-    if (Context.getCanonicalType(T2).getUnqualifiedType()
-          == Context.getCanonicalType(ArgType).getUnqualifiedType())
+    if (Context.hasSameUnqualifiedType(T2, ArgType))
       return true;
   }
 

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Nov 16 15:35:15 2009
@@ -519,8 +519,6 @@
     // cv-unqualified version of T. Otherwise, the type of the rvalue
     // is T (C++ 4.1p1). C++ can't get here with class types; in C, we
     // just strip the qualifiers because they don't matter.
-
-    // FIXME: Doesn't see through to qualifiers behind a typedef!
     FromType = FromType.getUnqualifiedType();
   } else if (FromType->isArrayType()) {
     // Array-to-pointer conversion (C++ 4.2)
@@ -678,8 +676,9 @@
     //   a conversion. [...]
     CanonFrom = Context.getCanonicalType(FromType);
     CanonTo = Context.getCanonicalType(ToType);
-    if (CanonFrom.getUnqualifiedType() == CanonTo.getUnqualifiedType() &&
-        CanonFrom.getCVRQualifiers() != CanonTo.getCVRQualifiers()) {
+    if (CanonFrom.getLocalUnqualifiedType() 
+                                       == CanonTo.getLocalUnqualifiedType() &&
+        CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()) {
       FromType = ToType;
       CanonFrom = CanonTo;
     }
@@ -756,8 +755,7 @@
         // We found the type that we can promote to. If this is the
         // type we wanted, we have a promotion. Otherwise, no
         // promotion.
-        return Context.getCanonicalType(ToType).getUnqualifiedType()
-          == Context.getCanonicalType(PromoteTypes[Idx]).getUnqualifiedType();
+        return Context.hasSameUnqualifiedType(ToType, PromoteTypes[Idx]);
       }
     }
   }
@@ -864,7 +862,7 @@
   Qualifiers Quals = CanonFromPointee.getQualifiers();
 
   // Exact qualifier match -> return the pointer type we're converting to.
-  if (CanonToPointee.getQualifiers() == Quals) {
+  if (CanonToPointee.getLocalQualifiers() == Quals) {
     // ToType is exactly what we need. Return it.
     if (!ToType.isNull())
       return ToType;
@@ -876,7 +874,8 @@
 
   // Just build a canonical type that has the right qualifiers.
   return Context.getPointerType(
-         Context.getQualifiedType(CanonToPointee.getUnqualifiedType(), Quals));
+         Context.getQualifiedType(CanonToPointee.getLocalUnqualifiedType(), 
+                                  Quals));
 }
 
 static bool isNullPointerConstantForConversion(Expr *Expr,
@@ -1348,8 +1347,7 @@
   // of types. If we unwrapped any pointers, and if FromType and
   // ToType have the same unqualified type (since we checked
   // qualifiers above), then this is a qualification conversion.
-  return UnwrappedAnyPointer &&
-    FromType.getUnqualifiedType() == ToType.getUnqualifiedType();
+  return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType);
 }
 
 /// \brief Given a function template or function, extract the function template
@@ -1742,7 +1740,7 @@
     QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr);
     T1 = Context.getCanonicalType(T1);
     T2 = Context.getCanonicalType(T2);
-    if (T1.getUnqualifiedType() == T2.getUnqualifiedType()) {
+    if (Context.hasSameUnqualifiedType(T1, T2)) {
       if (T2.isMoreQualifiedThan(T1))
         return ImplicitConversionSequence::Better;
       else if (T1.isMoreQualifiedThan(T2))
@@ -1778,7 +1776,7 @@
 
   // If the types are the same, we won't learn anything by unwrapped
   // them.
-  if (T1.getUnqualifiedType() == T2.getUnqualifiedType())
+  if (Context.hasSameUnqualifiedType(T1, T2))
     return ImplicitConversionSequence::Indistinguishable;
 
   ImplicitConversionSequence::CompareKind Result
@@ -1818,7 +1816,7 @@
     }
 
     // If the types after this point are equivalent, we're done.
-    if (T1.getUnqualifiedType() == T2.getUnqualifiedType())
+    if (Context.hasSameUnqualifiedType(T1, T2))
       break;
   }
 
@@ -1933,8 +1931,8 @@
     //   -- binding of an expression of type C to a reference of type
     //      B& is better than binding an expression of type C to a
     //      reference of type A&,
-    if (FromType1.getUnqualifiedType() == FromType2.getUnqualifiedType() &&
-        ToType1.getUnqualifiedType() != ToType2.getUnqualifiedType()) {
+    if (Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        !Context.hasSameUnqualifiedType(ToType1, ToType2)) {
       if (IsDerivedFrom(ToType1, ToType2))
         return ImplicitConversionSequence::Better;
       else if (IsDerivedFrom(ToType2, ToType1))
@@ -1944,8 +1942,8 @@
     //   -- binding of an expression of type B to a reference of type
     //      A& is better than binding an expression of type C to a
     //      reference of type A&,
-    if (FromType1.getUnqualifiedType() != FromType2.getUnqualifiedType() &&
-        ToType1.getUnqualifiedType() == ToType2.getUnqualifiedType()) {
+    if (!Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        Context.hasSameUnqualifiedType(ToType1, ToType2)) {
       if (IsDerivedFrom(FromType2, FromType1))
         return ImplicitConversionSequence::Better;
       else if (IsDerivedFrom(FromType1, FromType2))
@@ -1992,8 +1990,8 @@
   if (SCS1.CopyConstructor && SCS2.CopyConstructor &&
       SCS1.Second == ICK_Derived_To_Base) {
     //   -- conversion of C to B is better than conversion of C to A,
-    if (FromType1.getUnqualifiedType() == FromType2.getUnqualifiedType() &&
-        ToType1.getUnqualifiedType() != ToType2.getUnqualifiedType()) {
+    if (Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        !Context.hasSameUnqualifiedType(ToType1, ToType2)) {
       if (IsDerivedFrom(ToType1, ToType2))
         return ImplicitConversionSequence::Better;
       else if (IsDerivedFrom(ToType2, ToType1))
@@ -2001,8 +1999,8 @@
     }
 
     //   -- conversion of B to A is better than conversion of C to A.
-    if (FromType1.getUnqualifiedType() != FromType2.getUnqualifiedType() &&
-        ToType1.getUnqualifiedType() == ToType2.getUnqualifiedType()) {
+    if (!Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        Context.hasSameUnqualifiedType(ToType1, ToType2)) {
       if (IsDerivedFrom(FromType2, FromType1))
         return ImplicitConversionSequence::Better;
       else if (IsDerivedFrom(FromType1, FromType2))
@@ -2114,14 +2112,15 @@
   // First check the qualifiers. We don't care about lvalue-vs-rvalue
   // with the implicit object parameter (C++ [over.match.funcs]p5).
   QualType FromTypeCanon = Context.getCanonicalType(FromType);
-  if (ImplicitParamType.getCVRQualifiers() != FromTypeCanon.getCVRQualifiers() &&
+  if (ImplicitParamType.getCVRQualifiers() 
+                                    != FromTypeCanon.getLocalCVRQualifiers() &&
       !ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon))
     return ICS;
 
   // Check that we have either the same type or a derived type. It
   // affects the conversion rank.
   QualType ClassTypeCanon = Context.getCanonicalType(ClassType);
-  if (ClassTypeCanon == FromTypeCanon.getUnqualifiedType())
+  if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType())
     ICS.Standard.Second = ICK_Identity;
   else if (IsDerivedFrom(FromType, ClassType))
     ICS.Standard.Second = ICK_Derived_To_Base;
@@ -3079,7 +3078,7 @@
     Ty = RefTy->getPointeeType();
 
   // We don't care about qualifiers on the type.
-  Ty = Ty.getUnqualifiedType();
+  Ty = Ty.getLocalUnqualifiedType();
 
   // If we're dealing with an array type, decay to the pointer.
   if (Ty->isArrayType())

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Mon Nov 16 15:35:15 2009
@@ -873,8 +873,7 @@
   if (!RetType->isRecordType())
     return false;
   // ... the same cv-unqualified type as the function return type ...
-  if (Ctx.getCanonicalType(RetType).getUnqualifiedType() !=
-      Ctx.getCanonicalType(ExprType).getUnqualifiedType())
+  if (!Ctx.hasSameUnqualifiedType(RetType, ExprType))
     return false;
   // ... the expression is the name of a non-volatile automatic object ...
   // We ignore parentheses here.

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Nov 16 15:35:15 2009
@@ -354,8 +354,8 @@
                                         Qualifiers &Quals) {
   assert(T.isCanonical() && "Only operates on canonical types");
   if (!isa<ArrayType>(T)) {
-    Quals = T.getQualifiers();
-    return T.getUnqualifiedType();
+    Quals = T.getLocalQualifiers();
+    return T.getLocalUnqualifiedType();
   }
 
   assert(!T.hasQualifiers() && "canonical array type has qualifiers!");
@@ -1440,16 +1440,16 @@
         // - If A is a cv-qualified type, the top level cv-qualifiers of A’s
         //   type are ignored for type deduction.
         QualType CanonArgType = Context.getCanonicalType(ArgType);
-        if (CanonArgType.getCVRQualifiers())
-          ArgType = CanonArgType.getUnqualifiedType();
+        if (CanonArgType.getLocalCVRQualifiers())
+          ArgType = CanonArgType.getLocalUnqualifiedType();
       }
     }
 
     // C++0x [temp.deduct.call]p3:
     //   If P is a cv-qualified type, the top level cv-qualifiers of P’s type
     //   are ignored for type deduction.
-    if (CanonParamType.getCVRQualifiers())
-      ParamType = CanonParamType.getUnqualifiedType();
+    if (CanonParamType.getLocalCVRQualifiers())
+      ParamType = CanonParamType.getLocalUnqualifiedType();
     if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
       //   [...] If P is a reference type, the type referred to by P is used
       //   for type deduction.

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=88969&r1=88968&r2=88969&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Nov 16 15:35:15 2009
@@ -2146,7 +2146,7 @@
 QualType
 TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
                                                QualifiedTypeLoc T) {
-  Qualifiers Quals = T.getType().getQualifiers();
+  Qualifiers Quals = T.getType().getLocalQualifiers();
 
   QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
   if (Result.isNull())
@@ -5306,7 +5306,7 @@
                                                    QualType T) {
   if (T->isDependentType() || T->isRecordType() ||
       (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
-    assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
+    assert(!T.hasLocalQualifiers() && "Can't get cv-qualifiers here");
     return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
                                        T.getTypePtr());
   }





More information about the cfe-commits mailing list