]> granicus.if.org Git - clang/commitdiff
First part of changes to eliminate problems with cv-qualifiers and
authorDouglas Gregor <dgregor@apple.com>
Mon, 16 Nov 2009 21:35:15 +0000 (21:35 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 16 Nov 2009 21:35:15 +0000 (21:35 +0000)
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)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88969 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 260aca6c893909c3cea453e4a6a83fd25b9179b9..3cf6788b750a37d7b31e9bd7c4917c38d3727f7a 100644 (file)
@@ -872,9 +872,9 @@ public:
   /// \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
index a53f2f48fd21bd1b731f4decc72a3ebf533fe835..9b1187770f6ac78a102f9a38232e423152956e8c 100644 (file)
@@ -102,22 +102,22 @@ public:
   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 @@ struct CanProxyAdaptor<ObjCObjectPointerType>
 //----------------------------------------------------------------------------//
 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>
index e13792bc3aa2d249f98fcafd3a50c0be5a36f4bb..66853b8c9ad7aa2b098ddb3ff324c90a9b9eb153 100644 (file)
@@ -396,10 +396,6 @@ class QualType {
   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 @@ public:
   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 @@ public:
     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 @@ public:
     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 @@ public:
     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 @@ public:
   /// 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 @@ public:
 
 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 @@ inline void QualType::removeCVRQualifiers(unsigned Mask) {
 
 /// 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 @@ inline unsigned QualType::getAddressSpace() const {
 
 /// 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 @@ inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
   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 @@ inline bool Type::isFunctionPointerType() const {
     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 @@ inline bool Type::isMemberFunctionPointerType() const {
     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 @@ inline bool Type::isObjCBuiltinType() const {
   return isObjCIdType() || isObjCClassType();
 }
 inline bool Type::isTemplateTypeParmType() const {
-  return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
+  return isa<TemplateTypeParmType>(CanonicalType);
 }
 
 inline bool Type::isSpecificBuiltinType(unsigned K) const {
index a06b9b82d0dede02bce585aeeb4b5bcf4d065220..8ac8c22a8eeef4248b0838a2bfc0c7527591ebb0 100644 (file)
@@ -58,7 +58,7 @@ public:
     : 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 @@ public:
   }
 
   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 @@ public:
   }
 
   static bool classof(const TypeLoc *TL) {
-    return TL->getType().hasQualifiers();
+    return TL->getType().hasLocalQualifiers();
   }
   static bool classof(const QualifiedTypeLoc *TL) { return true; }
 };
index 22427eb67103611a2443fd1981e08903638f17ca..b520f4be1d31567a8059aafa1d3be4204382a94f 100644 (file)
@@ -52,7 +52,8 @@ struct UnsafeQualTypeDenseMapInfo {
     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);
   }
index 6aca15a75427cc02c33fcfa5ddbdba62b1eb5083..35f5debe5cf043c9af0353cb0c590da7d2da5177 100644 (file)
@@ -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
index 9850ad6f53a67ba20a17f47339febd0f30a4369b..1b3e09291dd389e2336f66651581572ce4999a40 100644 (file)
@@ -1186,7 +1186,7 @@ QualType ASTContext::getNoReturnType(QualType T) {
     }
   }
 
-  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 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) {
 
 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 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
     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.
index d4f6e8717319d04426d193733aab1922ad0ae80e..023bca436339c6074c7152468665d2cc3effad92 100644 (file)
@@ -99,8 +99,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
   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,
index 9867e5a880909bd3d7c9848496426e2c5299feed..bfa338b365926ccfa553517fdbd5a780476dad53 100644 (file)
@@ -211,7 +211,7 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context,
       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 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
   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.
index 234d38a59ffb0075445dc707644ac498efba18ab..a482333782862f09cdfb0d8e66ed305be0a69e1b 100644 (file)
@@ -63,7 +63,7 @@ void TypePrinter::Print(QualType T, std::string &S) {
     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 @@ void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T,
     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.
index a0846b1abf5cde55d3d526f46bcb64253d1ace1f..55e5f174cb9f40c5702d321a522c9fb67ae80bfe 100644 (file)
@@ -1537,7 +1537,7 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl* MD,
          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);
       }
   }
index 573cac315b3a5b95534b62e73f88e71996b714ea..ac727b0ac696ca446a00282a94cf2e7d60599754 100644 (file)
@@ -62,8 +62,7 @@ SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
   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.
index afe2b4e7bd663392e8e8b0f2cd9e2b8f209559cb..2fd72ac0a148c522fd190416c80f4da624faeb04 100644 (file)
@@ -64,7 +64,7 @@ const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy)
   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 @@ SVal  StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
   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;
 }
 
index 41ffddd23aa438363067778c1d7d231b72515521..055166721085478c9e3e1d5ac5b4b2bc96f9043c 100644 (file)
@@ -851,7 +851,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
 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.
index 91e89fb711a267fe8a3d9e65f6d9963c5ce46f8c..0a7124de3621b57d5da9c9a527165641f479d69c 100644 (file)
@@ -744,15 +744,15 @@ void CXXNameMangler::mangleType(QualType T) {
   // 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)
index d92d4cb7b8deeab9cd96553066ac557fe9d12118..0263c30bfd57a1bd86c56e88e9f96449edd7bd35 100644 (file)
@@ -135,7 +135,7 @@ void DocumentXML::finalize() {
 
   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 @@ void DocumentXML::addTypeRecursively(const QualType& pType)
   {
     addTypeRecursively(pType.getTypePtr());
     // beautifier: a non-qualified type shall be transparent
-    if (!pType.hasQualifiers())
+    if (!pType.hasLocalQualifiers())
     {
       Types[pType] = BasicTypes[pType.getTypePtr()];
     }
index 2dcb8b0ceecee6c3f31c3eb9f876c88766b6a746..8a45ebce1b9dd81e4f4c0648ea33e861c06f098a 100644 (file)
@@ -1248,9 +1248,9 @@ void PCHWriter::WriteType(QualType T) {
   // 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 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
     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 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
     return;
   }
 
-  assert(!T.hasQualifiers());
+  assert(!T.hasLocalQualifiers());
   
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
     pch::TypeID ID = 0;
index 3d68e6a10930c35a3e764c74298715d338997255..e5ad338502df1736ef8a5b3cb01acc63d8d8f1df 100644 (file)
@@ -737,10 +737,8 @@ TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType,
   }
 
   // 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
index 38b6ebeefab957a02cdb3626618d2272735e5110..92f1ba5d6ad0fa25903cd957bf244be90eead310 100644 (file)
@@ -628,8 +628,7 @@ Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
       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());
index c6bbb9a438f3aaecccf11fdbdf755734aa2332ff..502a0f1ab2c2db40d75b83d2814b7783cd0807ec 100644 (file)
@@ -1698,9 +1698,8 @@ static bool isNearlyMatchingFunction(ASTContext &Context,
     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;
   }
 
index b0e18d865cffd7ef5fdf0c8a55ba8b78f633df96..56381e76f87e9b4cb64a45ed89b6a82181586a82 100644 (file)
@@ -587,7 +587,7 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
   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 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
     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 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
 
   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 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
   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 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
     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 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
   }
 
   // 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;
index bdd00b84049d3e476d091847e92a25fd3061aba4..25af0528d8b5fd8215cdd09079c0b65f687ad22f 100644 (file)
@@ -183,7 +183,7 @@ bool Sema::CheckExceptionSpecSubset(
       SubIsPointer = true;
     }
     bool SubIsClass = CanonicalSubT->isRecordType();
-    CanonicalSubT = CanonicalSubT.getUnqualifiedType();
+    CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType();
 
     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
                        /*DetectVirtual=*/false);
@@ -205,7 +205,7 @@ bool Sema::CheckExceptionSpecSubset(
           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;
index 0d4ce609136f31c0f7e5857772e454ac7454c726..b089ffe92f35d21a78cd4dbce509315e5930c1ef 100644 (file)
@@ -3070,8 +3070,7 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
 
 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 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
   }
   
   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 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
       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 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
         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 @@ Sema::CheckBlockPointerTypesForAssignment(QualType lhsType,
   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))
index bdd47cc2bb3f4943fe96bfc2a092c52b8fd08f4a..3fcacfc9f325f0a115013b695ac814da50f7d0f5 100644 (file)
@@ -1431,8 +1431,7 @@ QualType Sema::CheckPointerToMemberOperands(
     }
   }
 
-  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
index 4746a2597e552953de9bfc25f3c068dceb7501ed..0f973d6d9ba3bf6eb6edcd1f5b859689d3893545 100644 (file)
@@ -174,7 +174,8 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
       //      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());
index 4f261383adeddac202314926c8bea34e95abd492..d45a1a8b92d84d874bb75dd3250a283a0d71c0f3 100644 (file)
@@ -1576,8 +1576,7 @@ IsAcceptableNonMemberOperatorCandidate(FunctionDecl *Fn,
 
   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 @@ IsAcceptableNonMemberOperatorCandidate(FunctionDecl *Fn,
 
   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;
   }
 
index 56a878b694b8ee32f40dcac56d9b5ecdbf5bd51e..0ec0189ebf8a915ffcb7bbf0027b5b80619ca525 100644 (file)
@@ -519,8 +519,6 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
     // 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 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
     //   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 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
         // 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 @@ BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
   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 @@ BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
 
   // 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 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) {
   // 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 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
     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 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
 
   // 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 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
     }
 
     // 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 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
     //   -- 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 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
     //   -- 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 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
   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 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
     }
 
     //   -- 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 @@ Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
   // 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 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
     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())
index e9061b8ac2a4b5f1b3c2f77e3edac38c9dc4bbc5..d0f214fbd83dd4e824fc01bfac84e9584e0061ae 100644 (file)
@@ -873,8 +873,7 @@ static bool IsReturnCopyElidable(ASTContext &Ctx, QualType RetType,
   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.
index 244bb37c37e19eace4f072c796e70f310b924e40..10594c728fbefc2be827b626aa8eae867c8bf031 100644 (file)
@@ -354,8 +354,8 @@ static QualType getUnqualifiedArrayType(ASTContext &Context, QualType T,
                                         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 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
         // - 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.
index d3dab4b8e132558bf68cc1683e4ea5adef20a9a7..2bee32aa0fc8f3a4ae8ff90bc07f4f06781d1be3 100644 (file)
@@ -2146,7 +2146,7 @@ template<typename Derived>
 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 @@ TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
                                                    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());
   }