[cfe-commits] r78164 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/CanonicalType.h include/clang/AST/DeclarationName.h include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/DeclCXX.cpp lib/AST/DeclarationName.cpp lib/Frontend/PCHReader.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp

Douglas Gregor dgregor at apple.com
Tue Aug 4 22:36:45 PDT 2009


Author: dgregor
Date: Wed Aug  5 00:36:45 2009
New Revision: 78164

URL: http://llvm.org/viewvc/llvm-project?rev=78164&view=rev
Log:
Introduce the canonical type smart pointers, and use them in a few places to
tighten up the static type system.

Added:
    cfe/trunk/include/clang/AST/CanonicalType.h   (with props)
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclarationName.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclarationName.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Aug  5 00:36:45 2009
@@ -22,6 +22,7 @@
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/OwningPtr.h"
@@ -700,7 +701,7 @@
   /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed
   /// to be free of any of these, allowing two canonical types to be compared
   /// for exact equality with a simple pointer comparison.
-  QualType getCanonicalType(QualType T);
+  CanQualType getCanonicalType(QualType T);
   const Type *getCanonicalType(const Type *T) {
     return T->getCanonicalTypeInternal().getTypePtr();
   }

Added: cfe/trunk/include/clang/AST/CanonicalType.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CanonicalType.h?rev=78164&view=auto

==============================================================================
--- cfe/trunk/include/clang/AST/CanonicalType.h (added)
+++ cfe/trunk/include/clang/AST/CanonicalType.h Wed Aug  5 00:36:45 2009
@@ -0,0 +1,746 @@
+//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CanQual class template, which provides access to
+//  canonical types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H
+#define LLVM_CLANG_AST_CANONICAL_TYPE_H
+
+#include "clang/AST/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/type_traits.h"
+#include <iterator>
+
+namespace clang {
+  
+template<typename T> class CanProxy;
+template<typename T> struct CanProxyAdaptor;
+
+//----------------------------------------------------------------------------//
+// Canonical, qualified type template
+//----------------------------------------------------------------------------//
+  
+/// \brief Represents a canonical, potentially-qualified type.
+///
+/// The CanQual template is a lightweight smart pointer that provides access
+/// to the canonical representation of a type, where all typedefs and other
+/// syntactic sugar has been eliminated. A CanQualType may also have various 
+/// qualifiers (const, volatile, restrict) attached to it.
+///
+/// The template type parameter @p T is one of the Type classes (PointerType, 
+/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
+/// type (or some subclass of that type). The typedef @c CanQualType is just
+/// a shorthand for @c CanQual<Type>.
+///
+/// An instance of @c CanQual<T> can be implicitly converted to a 
+/// @c CanQual<U> when T is derived from U, which essentially provides an
+/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be 
+/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can 
+/// be implicitly converted to a QualType, but the reverse operation requires
+/// a call to ASTContext::getCanonicalType().
+/// 
+/// 
+template<typename T = Type>
+class CanQual {
+  /// \brief The actual, canonical type. 
+  QualType Stored;
+  
+public:
+  /// \brief Constructs a NULL canonical type.
+  CanQual() : Stored() { }
+  
+  /// \brief Converting constructor that permits implicit upcasting of
+  /// canonical type pointers.
+  template<typename U>
+  CanQual(const CanQual<U>& Other, 
+          typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
+  
+  /// \brief Implicit conversion to the underlying pointer.
+  ///
+  /// Also provides the ability to use canonical types in a boolean context,
+  /// e.g., 
+  /// @code
+  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
+  /// @endcode
+  operator const T*() const { return getTypePtr(); }
+  
+  /// \brief Retrieve the underlying type pointer, which refers to a 
+  /// canonical type.
+  T *getTypePtr() const { return cast_or_null<T>(Stored.getTypePtr()); }
+  
+  /// \brief Implicit conversion to a qualified type.
+  operator QualType() const { return Stored; }
+  
+  /// \brief Retrieve a canonical type pointer with a different static type,
+  /// upcasting or downcasting as needed.
+  ///
+  /// The getAs() function is typically used to try to downcast to a 
+  /// more specific (canonical) type in the type system. For example:
+  ///
+  /// @code
+  /// void f(CanQual<Type> T) {
+  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
+  ///     // look at Ptr's pointee type
+  ///   }
+  /// }
+  /// @endcode
+  ///
+  /// \returns A proxy pointer to the same type, but with the specified
+  /// static type (@p U). If the dynamic type is not the specified static type
+  /// or a derived class thereof, a NULL canonical type.
+  template<typename U> CanProxy<U> getAs() const;
+  
+  /// \brief Overloaded arrow operator that produces a canonical type
+  /// proxy.
+  CanProxy<T> operator->() const;
+  
+  /// \brief Retrieve the const/volatile/restrict qualifiers.
+  unsigned getCVRQualifiers() const { return Stored.getCVRQualifiers(); }
+  
+  /// \brief Set the const/volatile/restrict qualifiers
+  void setCVRQualifiers(unsigned Quals) { Stored.setCVRQualifiers(Quals); }
+  
+  bool isConstQualified() const {
+    return (getCVRQualifiers() & QualType::Const) ? true : false;
+  }
+  bool isVolatileQualified() const {
+    return (getCVRQualifiers() & QualType::Volatile) ? true : false;
+  }
+  bool isRestrictQualified() const {
+    return (getCVRQualifiers() & QualType::Restrict) ? true : false;
+  }  
+  
+  /// \brief Retrieve the unqualified form of this type.
+  CanQual<T> getUnqualifiedType() const;
+  
+  CanQual<T> getQualifiedType(unsigned TQs) const {
+    return CanQual<T>::CreateUnsafe(QualType(getTypePtr(), TQs));
+  }
+  
+  /// \brief Determines whether this canonical type is more qualified than 
+  /// the @p Other canonical type.
+  bool isMoreQualifiedThan(CanQual<T> Other) const {
+    return Stored.isMoreQualifiedThan(Other.Stored);
+  }
+  
+  /// \brief Determines whether this canonical type is at least as qualified as
+  /// the @p Other canonical type.
+  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
+    return Stored.isAtLeastAsQualifiedAs(Other.Stored);
+  }
+  
+  /// \brief If the canonical type is a reference type, returns the type that
+  /// it refers to; otherwise, 
+  CanQual<Type> getNonReferenceType() const;
+  
+  /// \brief Retrieve the internal representation of this canonical type.
+  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
+  
+  /// \brief Construct a canonical type from its internal representation.
+  static CanQual<T> getFromOpaquePtr(void *Ptr);
+  
+  /// \brief Builds a canonical type from a QualType.
+  ///
+  /// This routine is inherently unsafe, because it requires the user to 
+  /// ensure that the given type is a canonical type with the correct 
+  // (dynamic) type. 
+  static CanQual<T> CreateUnsafe(QualType Other);
+};
+
+template<typename T, typename U>
+inline bool operator==(CanQual<T> x, CanQual<U> y) {
+  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
+}
+
+template<typename T, typename U>
+inline bool operator!=(CanQual<T> x, CanQual<U> y) {
+  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
+}
+
+/// \brief Represents a canonical, potentially-qualified type.
+typedef CanQual<Type> CanQualType;
+
+//----------------------------------------------------------------------------//
+// Internal proxy classes used by canonical types
+//----------------------------------------------------------------------------//
+  
+#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
+CanQualType Accessor() const {                                           \
+return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
+}
+
+#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
+Type Accessor() const { return this->getTypePtr()->Accessor(); }
+
+/// \brief Base class of all canonical proxy types, which is responsible for
+/// storing the underlying canonical type and providing basic conversions.
+template<typename T> 
+class CanProxyBase {
+protected:
+  CanQual<T> Stored;
+  
+public:
+  /// \brief Retrieve the pointer to the underlying Type
+  T* getTypePtr() const { return Stored.getTypePtr(); }
+  
+  /// \brief Implicit conversion to the underlying pointer.
+  ///
+  /// Also provides the ability to use canonical type proxies in a Boolean
+  // context,e.g., 
+  /// @code
+  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
+  /// @endcode
+  operator const T*() const { return this->Stored.getTypePtr(); }
+  
+  /// \brief Try to convert the given canonical type to a specific structural
+  /// type.
+  template<typename U> CanProxy<U> getAs() const { 
+    return this->Stored.template getAs<U>(); 
+  }
+  
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
+  
+  // Type predicates
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPODType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
+
+  /// \brief Retrieve the proxy-adaptor type.
+  ///
+  /// This arrow operator is used when CanProxyAdaptor has been specialized
+  /// for the given type T. In that case, we reference members of the
+  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
+  /// by the arrow operator in the primary CanProxyAdaptor template.
+  const CanProxyAdaptor<T> *operator->() const {
+    return static_cast<const CanProxyAdaptor<T> *>(this);
+  }
+};
+
+/// \brief Replacable canonical proxy adaptor class that provides the link
+/// between a canonical type and the accessors of the type.
+///
+/// The CanProxyAdaptor is a replaceable class template that is instantiated
+/// as part of each canonical proxy type. The primary template merely provides
+/// redirection to the underlying type (T), e.g., @c PointerType. One can
+/// provide specializations of this class template for each underlying type
+/// that provide accessors returning canonical types (@c CanQualType) rather
+/// than the more typical @c QualType, to propagate the notion of "canonical"
+/// through the system.
+template<typename T> 
+struct CanProxyAdaptor : CanProxyBase<T> { };
+
+/// \brief Canonical proxy type returned when retrieving the members of a
+/// canonical type or as the result of the @c CanQual<T>::getAs member 
+/// function.
+///
+/// The CanProxy type mainly exists as a proxy through which operator-> will
+/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy 
+/// type that provides canonical-type access to the fields of the type.
+template<typename T>
+class CanProxy : public CanProxyAdaptor<T> {
+public:
+  /// \brief Build a NULL proxy.
+  CanProxy() { }
+  
+  /// \brief Build a proxy to the given canonical type.
+  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
+  
+  /// \brief Implicit conversion to the stored canonical type.
+  operator CanQual<T>() const { return this->Stored; }
+};
+  
+} // end namespace clang
+
+namespace llvm {
+  
+/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from 
+/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
+/// to return smart pointer (proxies?).
+template<typename T> 
+struct simplify_type<const ::clang::CanQual<T> > {
+  typedef T* SimpleType;
+  static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
+    return Val.getTypePtr();
+  }
+};
+template<typename T> 
+struct simplify_type< ::clang::CanQual<T> >
+: public simplify_type<const ::clang::CanQual<T> > {};
+
+// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
+template<typename T>
+class PointerLikeTypeTraits<clang::CanQual<T> > {
+public:
+  static inline void *getAsVoidPointer(clang::CanQual<T> P) {
+    return P.getAsOpaquePtr();
+  }
+  static inline clang::CanQual<T> getFromVoidPointer(void *P) {
+    return clang::CanQual<T>::getFromOpaquePtr(P);
+  }
+  // CVR qualifiers go in low bits.
+  enum { NumLowBitsAvailable = 0 };
+};
+  
+} // end namespace llvm
+
+namespace clang {
+  
+//----------------------------------------------------------------------------//
+// Canonical proxy adaptors for canonical type nodes.
+//----------------------------------------------------------------------------//
+  
+/// \brief Iterator adaptor that turns an iterator over canonical QualTypes 
+/// into an iterator over CanQualTypes.
+template<typename InputIterator>
+class CanTypeIterator {
+  InputIterator Iter;
+  
+public:
+  typedef CanQualType    value_type;
+  typedef value_type     reference;
+  typedef CanProxy<Type> pointer;
+  typedef typename std::iterator_traits<InputIterator>::difference_type
+    difference_type;
+  typedef typename std::iterator_traits<InputIterator>::iterator_category
+    iterator_category;
+  
+  CanTypeIterator() : Iter() { }
+  explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
+  
+  // Input iterator
+  reference operator*() const {
+    return CanQualType::CreateUnsafe(*Iter);
+  }
+  
+  pointer operator->() const;
+  
+  CanTypeIterator &operator++() {
+    ++Iter;
+    return *this;
+  }
+  
+  CanTypeIterator operator++(int) {
+    CanTypeIterator Tmp(*this);
+    ++Iter;
+    return Tmp;
+  }
+ 
+  friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
+    return X.Iter == Y.Iter;
+  }
+  friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
+    return X.Iter != Y.Iter;
+  }
+  
+  // Bidirectional iterator
+  CanTypeIterator &operator--() {
+    --Iter;
+    return *this;
+  }
+  
+  CanTypeIterator operator--(int) {
+    CanTypeIterator Tmp(*this);
+    --Iter;
+    return Tmp;
+  }
+  
+  // Random access iterator
+  reference operator[](difference_type n) const {
+    return CanQualType::CreateUnsafe(Iter[n]);
+  }
+  
+  CanTypeIterator &operator+=(difference_type n) {
+    Iter += n;
+    return *this;
+  }
+  
+  CanTypeIterator &operator-=(difference_type n) {
+    Iter -= n;
+    return *this;
+  }
+  
+  friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
+    X += n;
+    return X;
+  }
+
+  friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
+    X += n;
+    return X;
+  }
+  
+  friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
+    X -= n;
+    return X;
+  }
+  
+  friend difference_type operator-(const CanTypeIterator &X, 
+                                   const CanTypeIterator &Y) {
+    return X - Y; 
+  }
+};
+
+template<>
+struct CanProxyAdaptor<ExtQualType> : public CanProxyBase<ExtQualType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type*, getBaseType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(QualType::GCAttrTypes, getObjCGCAttr)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getAddressSpace)
+};
+  
+template<>
+struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+};
+
+template<>
+struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+  
+template<>
+struct CanProxyAdaptor<BlockPointerType> 
+  : public CanProxyBase<BlockPointerType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+  
+template<>
+struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<LValueReferenceType> 
+  : public CanProxyBase<LValueReferenceType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<RValueReferenceType> 
+  : public CanProxyBase<RValueReferenceType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<MemberPointerType> 
+  : public CanProxyBase<MemberPointerType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
+};
+  
+template<>
+struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier)
+};
+
+template<>
+struct CanProxyAdaptor<ConstantArrayType> 
+  : public CanProxyBase<ConstantArrayType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
+};
+
+template<>
+struct CanProxyAdaptor<ConstantArrayWithExprType> 
+  : public CanProxyBase<ConstantArrayWithExprType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
+};
+  
+template<>
+struct CanProxyAdaptor<ConstantArrayWithoutExprType> 
+  : public CanProxyBase<ConstantArrayWithoutExprType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
+};
+
+template<>
+struct CanProxyAdaptor<IncompleteArrayType> 
+  : public CanProxyBase<IncompleteArrayType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier)
+};
+  
+template<>
+struct CanProxyAdaptor<VariableArrayType> 
+  : public CanProxyBase<VariableArrayType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 
+                                      getSizeModifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
+};
+
+template<>
+struct CanProxyAdaptor<DependentSizedArrayType> 
+  : public CanProxyBase<DependentSizedArrayType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
+};
+
+template<>
+struct CanProxyAdaptor<DependentSizedExtVectorType> 
+  : public CanProxyBase<DependentSizedExtVectorType>
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)  
+};
+  
+template<>
+struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
+};
+
+template<>
+struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionNoProtoType> 
+  : public CanProxyBase<FunctionNoProtoType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+};
+  
+template<>
+struct CanProxyAdaptor<FunctionProtoType> 
+  : public CanProxyBase<FunctionProtoType>
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs);  
+  CanQualType getArgType(unsigned i) const {
+    return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
+  }
+  
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
+  
+  typedef CanTypeIterator<FunctionProtoType::arg_type_iterator> 
+    arg_type_iterator;
+  
+  arg_type_iterator arg_type_begin() const {
+    return arg_type_iterator(this->getTypePtr()->arg_type_begin());
+  }
+
+  arg_type_iterator arg_type_end() const {
+    return arg_type_iterator(this->getTypePtr()->arg_type_end());
+  }
+  
+  // Note: canonical function types never have exception specifications
+};
+  
+template<>
+struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
+};
+
+template<>
+struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
+};
+
+template<>
+struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+};
+
+template<>
+struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getAddressSpace)  
+};
+  
+template<>
+struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+};
+  
+template<>
+struct CanProxyAdaptor<TemplateTypeParmType> 
+  : public CanProxyBase<TemplateTypeParmType>
+{
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName)    
+};
+  
+template<>
+struct CanProxyAdaptor<ObjCObjectPointerType> 
+  : public CanProxyBase<ObjCObjectPointerType> 
+{
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *, 
+                                      getInterfaceType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
+  
+  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
+};
+  
+//----------------------------------------------------------------------------//
+// Method and function definitions
+//----------------------------------------------------------------------------//
+template<typename T>
+inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
+  if (CanQual<ExtQualType> EQ = getAs<ExtQualType>())
+    return CanQual<T>::CreateUnsafe(QualType(EQ->getBaseType(), 0));
+  return CanQual<T>::CreateUnsafe(QualType(Stored.getTypePtr(), 0));
+}
+
+template<typename T>
+inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
+  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
+    return RefType->getPointeeType();
+  else
+    return *this;
+}
+
+template<typename T>
+CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
+  CanQual<T> Result;
+  Result.Stored.setFromOpaqueValue(Ptr);
+  assert((!Result || Result.Stored.isCanonical()) 
+         && "Type is not canonical!");
+  return Result;
+}
+
+template<typename T> 
+CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
+  assert((Other.isNull() || Other->isCanonical()) && "Type is not canonical!");
+  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
+         "Dynamic type does not meet the static type's requires");
+  CanQual<T> Result;
+  Result.Stored = Other;
+  return Result;
+}
+
+template<typename T> 
+template<typename U> 
+CanProxy<U> CanQual<T>::getAs() const {
+  if (Stored.isNull())
+    return CanProxy<U>();
+  
+  if (isa<U>(Stored.getTypePtr()))
+    return CanQual<U>::CreateUnsafe(Stored);
+    
+  if (const ExtQualType *EQ = Stored->getAs<ExtQualType>())
+    return CanQual<T>::CreateUnsafe(QualType(EQ->getBaseType(), 0))
+             .template getAs<U>();
+  
+  return CanProxy<U>();
+}
+
+template<typename T>
+CanProxy<T> CanQual<T>::operator->() const {
+  return CanProxy<T>(*this);
+}
+  
+template<typename InputIterator>
+typename CanTypeIterator<InputIterator>::pointer 
+CanTypeIterator<InputIterator>::operator->() const {
+  return CanProxy<Type>(*this);
+}
+  
+}
+
+
+#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H

Propchange: cfe/trunk/include/clang/AST/CanonicalType.h

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/include/clang/AST/CanonicalType.h

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/include/clang/AST/CanonicalType.h

------------------------------------------------------------------------------
    svn:mime-type = text/plain

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclarationName.h (original)
+++ cfe/trunk/include/clang/AST/DeclarationName.h Wed Aug  5 00:36:45 2009
@@ -15,6 +15,7 @@
 
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
 
 namespace llvm {
   template <typename T> struct DenseMapInfo;
@@ -290,19 +291,19 @@
 
   /// getCXXConstructorName - Returns the name of a C++ constructor
   /// for the given Type.
-  DeclarationName getCXXConstructorName(QualType Ty) {
+  DeclarationName getCXXConstructorName(CanQualType Ty) {
     return getCXXSpecialName(DeclarationName::CXXConstructorName, Ty);
   }
 
   /// getCXXDestructorName - Returns the name of a C++ destructor
   /// for the given Type.
-  DeclarationName getCXXDestructorName(QualType Ty) {
+  DeclarationName getCXXDestructorName(CanQualType Ty) {
     return getCXXSpecialName(DeclarationName::CXXDestructorName, Ty);
   }
 
   /// getCXXConversionFunctionName - Returns the name of a C++
   /// conversion function for the given Type.
-  DeclarationName getCXXConversionFunctionName(QualType Ty) {
+  DeclarationName getCXXConversionFunctionName(CanQualType Ty) {
     return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
   }
 
@@ -310,7 +311,7 @@
   /// of C++ name, e.g., for a constructor, destructor, or conversion
   /// function.
   DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind, 
-                                    QualType Ty);
+                                    CanQualType Ty);
 
   /// getCXXOperatorName - Get the name of the overloadable C++
   /// operator corresponding to Op.

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

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Aug  5 00:36:45 2009
@@ -19,6 +19,7 @@
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/TemplateName.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/type_traits.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerIntPair.h"
@@ -178,11 +179,11 @@
 
   /// operator==/!= - Indicate whether the specified types and qualifiers are
   /// identical.
-  bool operator==(const QualType &RHS) const {
-    return Value == RHS.Value;
+  friend bool operator==(const QualType &LHS, const QualType &RHS) {
+    return LHS.Value == RHS.Value;
   }
-  bool operator!=(const QualType &RHS) const {
-    return Value != RHS.Value;
+  friend bool operator!=(const QualType &LHS, const QualType &RHS) {
+    return LHS.Value != RHS.Value;
   }
   std::string getAsString() const;
 
@@ -251,6 +252,7 @@
   // CVR qualifiers go in low bits.
   enum { NumLowBitsAvailable = 0 };
 };
+    
 } // end namespace llvm
 
 namespace clang {

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

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Aug  5 00:36:45 2009
@@ -2070,18 +2070,19 @@
 /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed
 /// to be free of any of these, allowing two canonical types to be compared
 /// for exact equality with a simple pointer comparison.
-QualType ASTContext::getCanonicalType(QualType T) {
+CanQualType ASTContext::getCanonicalType(QualType T) {
   QualType CanType = T.getTypePtr()->getCanonicalTypeInternal();
   
   // If the result has type qualifiers, make sure to canonicalize them as well.
   unsigned TypeQuals = T.getCVRQualifiers() | CanType.getCVRQualifiers();
-  if (TypeQuals == 0) return CanType;
+  if (TypeQuals == 0) 
+    return CanQualType::CreateUnsafe(CanType);
 
   // If the type qualifiers are on an array type, get the canonical type of the
   // array with the qualifiers applied to the element type.
   ArrayType *AT = dyn_cast<ArrayType>(CanType);
   if (!AT)
-    return CanType.getQualifiedType(TypeQuals);
+    return CanQualType::CreateUnsafe(CanType.getQualifiedType(TypeQuals));
   
   // Get the canonical version of the element with the extra qualifiers on it.
   // This can recursively sink qualifiers through multiple levels of arrays.
@@ -2089,25 +2090,29 @@
   NewEltTy = getCanonicalType(NewEltTy);
   
   if (ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
-    return getConstantArrayType(NewEltTy, CAT->getSize(),CAT->getSizeModifier(),
-                                CAT->getIndexTypeQualifier());
+    return CanQualType::CreateUnsafe(
+             getConstantArrayType(NewEltTy, CAT->getSize(),
+                                  CAT->getSizeModifier(),
+                                  CAT->getIndexTypeQualifier()));
   if (IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT))
-    return getIncompleteArrayType(NewEltTy, IAT->getSizeModifier(),
-                                  IAT->getIndexTypeQualifier());
+    return CanQualType::CreateUnsafe(
+             getIncompleteArrayType(NewEltTy, IAT->getSizeModifier(),
+                                    IAT->getIndexTypeQualifier()));
   
   if (DependentSizedArrayType *DSAT = dyn_cast<DependentSizedArrayType>(AT))
-    return getDependentSizedArrayType(NewEltTy,
-                                      DSAT->getSizeExpr(),
-                                      DSAT->getSizeModifier(),
-                                      DSAT->getIndexTypeQualifier(),
-                                      DSAT->getBracketsRange());
+    return CanQualType::CreateUnsafe(
+             getDependentSizedArrayType(NewEltTy,
+                                        DSAT->getSizeExpr(),
+                                        DSAT->getSizeModifier(),
+                                        DSAT->getIndexTypeQualifier(),
+                                        DSAT->getBracketsRange()));
 
   VariableArrayType *VAT = cast<VariableArrayType>(AT);
-  return getVariableArrayType(NewEltTy,
-                              VAT->getSizeExpr(),
-                              VAT->getSizeModifier(),
-                              VAT->getIndexTypeQualifier(),
-                              VAT->getBracketsRange());
+  return CanQualType::CreateUnsafe(getVariableArrayType(NewEltTy,
+                                                        VAT->getSizeExpr(),
+                                                        VAT->getSizeModifier(),
+                                                  VAT->getIndexTypeQualifier(),
+                                                     VAT->getBracketsRange()));
 }
 
 TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) {
@@ -2250,7 +2255,7 @@
   
   // If we get here, we either have type qualifiers on the type, or we have
   // sugar such as a typedef in the way.  If we have type qualifiers on the type
-  // we must propagate them down into the elemeng type.
+  // we must propagate them down into the element type.
   unsigned CVRQuals = T.getCVRQualifiers();
   unsigned AddrSpace = 0;
   Type *Ty = T.getTypePtr();

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

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Aug  5 00:36:45 2009
@@ -304,7 +304,8 @@
   QualType ClassType = Context.getTypeDeclType(this);
   
   DeclarationName Name 
-    = Context.DeclarationNames.getCXXDestructorName(ClassType);
+    = Context.DeclarationNames.getCXXDestructorName(
+                                          Context.getCanonicalType(ClassType));
 
   DeclContext::lookup_iterator I, E;
   llvm::tie(I, E) = lookup(Name); 

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

==============================================================================
--- cfe/trunk/lib/AST/DeclarationName.cpp (original)
+++ cfe/trunk/lib/AST/DeclarationName.cpp Wed Aug  5 00:36:45 2009
@@ -298,12 +298,10 @@
 
 DeclarationName 
 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 
-                                        QualType Ty) {
+                                        CanQualType Ty) {
   assert(Kind >= DeclarationName::CXXConstructorName &&
          Kind <= DeclarationName::CXXConversionFunctionName &&
          "Kind must be a C++ special name kind");
-  assert(Ty->isCanonical() && 
-         "Can only build C++ special names from canonical types");
   llvm::FoldingSet<CXXSpecialName> *SpecialNames 
     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
 

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

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Wed Aug  5 00:36:45 2009
@@ -2380,15 +2380,15 @@
 
   case DeclarationName::CXXConstructorName:
     return Context->DeclarationNames.getCXXConstructorName(
-                                                      GetType(Record[Idx++]));
+                          Context->getCanonicalType(GetType(Record[Idx++])));
 
   case DeclarationName::CXXDestructorName:
     return Context->DeclarationNames.getCXXDestructorName(
-                                                      GetType(Record[Idx++]));
+                          Context->getCanonicalType(GetType(Record[Idx++])));
 
   case DeclarationName::CXXConversionFunctionName:
     return Context->DeclarationNames.getCXXConversionFunctionName(
-                                                      GetType(Record[Idx++]));
+                          Context->getCanonicalType(GetType(Record[Idx++])));
 
   case DeclarationName::CXXOperatorName:
     return Context->DeclarationNames.getCXXOperatorName(

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Aug  5 00:36:45 2009
@@ -1553,21 +1553,21 @@
 
   case Declarator::DK_Constructor: {
     QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
-    Ty = Context.getCanonicalType(Ty);
-    return Context.DeclarationNames.getCXXConstructorName(Ty);
+    return Context.DeclarationNames.getCXXConstructorName(
+                                                Context.getCanonicalType(Ty));
   }
 
   case Declarator::DK_Destructor: {
     QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
-    Ty = Context.getCanonicalType(Ty);
-    return Context.DeclarationNames.getCXXDestructorName(Ty);
+    return Context.DeclarationNames.getCXXDestructorName(
+                                                Context.getCanonicalType(Ty));
   }
 
   case Declarator::DK_Conversion: {
     // FIXME: We'd like to keep the non-canonical type for diagnostics!
     QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
-    Ty = Context.getCanonicalType(Ty);
-    return Context.DeclarationNames.getCXXConversionFunctionName(Ty);
+    return Context.DeclarationNames.getCXXConversionFunctionName(
+                                                Context.getCanonicalType(Ty));
   }
 
   case Declarator::DK_Operator:
@@ -2736,9 +2736,9 @@
       CXXRecordDecl *Record = cast<CXXRecordDecl>(NewFD->getParent());
       QualType ClassType = Context.getTypeDeclType(Record);
       if (!ClassType->isDependentType()) {
-        ClassType = Context.getCanonicalType(ClassType);
         DeclarationName Name 
-          = Context.DeclarationNames.getCXXDestructorName(ClassType);
+          = Context.DeclarationNames.getCXXDestructorName(
+                                        Context.getCanonicalType(ClassType));
         if (NewFD->getDeclName() != Name) {
           Diag(NewFD->getLocation(), diag::err_destructor_name);
           return NewFD->setInvalidDecl();  

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Aug  5 00:36:45 2009
@@ -1259,8 +1259,8 @@
 /// [special]p1).  This routine can only be executed just before the
 /// definition of the class is complete.
 void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
-  QualType ClassType = Context.getTypeDeclType(ClassDecl);
-  ClassType = Context.getCanonicalType(ClassType);
+  CanQualType ClassType 
+    = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
 
   // FIXME: Implicit declarations have exception specifications, which are
   // the union of the specifications of the implicitly called functions.

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Aug  5 00:36:45 2009
@@ -32,7 +32,7 @@
                                      const CXXScopeSpec &SS,
                                      bool isAddressOfOperand) {
   QualType ConvType = QualType::getFromOpaquePtr(Ty);
-  QualType ConvTypeCanon = Context.getCanonicalType(ConvType);
+  CanQualType ConvTypeCanon = Context.getCanonicalType(ConvType);
   DeclarationName ConvName 
     = Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon);
   return ActOnDeclarationNameExpr(S, OperatorLoc, ConvName, HasTrailingLParen,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Aug  5 00:36:45 2009
@@ -484,7 +484,7 @@
 
   // Build the instantiated destructor declaration.
   CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
-  QualType ClassTy = 
+  CanQualType ClassTy = 
     SemaRef.Context.getCanonicalType(SemaRef.Context.getTypeDeclType(Record));
   CXXDestructorDecl *Destructor
     = CXXDestructorDecl::Create(SemaRef.Context, Record,
@@ -517,7 +517,7 @@
   // Build the instantiated conversion declaration.
   CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
   QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
-  QualType ConvTy 
+  CanQualType ConvTy 
     = SemaRef.Context.getCanonicalType(T->getAsFunctionType()->getResultType());
   CXXConversionDecl *Conversion
     = CXXConversionDecl::Create(SemaRef.Context, Record,





More information about the cfe-commits mailing list