[cfe-commits] r103517 - in /cfe/trunk: include/clang/AST/ include/clang/Frontend/ lib/AST/ lib/Checker/ lib/CodeGen/ lib/Frontend/ lib/Sema/ tools/libclang/

Abramo Bagnara abramo.bagnara at gmail.com
Tue May 11 14:36:43 PDT 2010


Author: abramo
Date: Tue May 11 16:36:43 2010
New Revision: 103517

URL: http://llvm.org/viewvc/llvm-project?rev=103517&view=rev
Log:
Merged Elaborated and QualifiedName types.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/TemplateName.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/AST/TypeLoc.h
    cfe/trunk/include/clang/AST/TypeNodes.def
    cfe/trunk/include/clang/Frontend/TypeXML.def
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTDiagnostic.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/NestedNameSpecifier.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/AST/TypePrinter.cpp
    cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Frontend/RewriteObjC.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/tools/libclang/CIndexUSRs.cpp
    cfe/trunk/tools/libclang/CXCursor.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue May 11 16:36:43 2010
@@ -96,11 +96,10 @@
   llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
   llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
   llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
-  llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
+  llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
   llvm::FoldingSet<DependentNameType> DependentNameTypes;
   llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
   llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
-  llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
 
   llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
   llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
@@ -613,8 +612,9 @@
                                     const TemplateArgumentListInfo &Args,
                                     QualType Canon = QualType());
 
-  QualType getQualifiedNameType(NestedNameSpecifier *NNS,
-                                QualType NamedType);
+  QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
+                             NestedNameSpecifier *NNS,
+                             QualType NamedType);
   QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
                                 NestedNameSpecifier *NNS,
                                 const IdentifierInfo *Name,
@@ -623,8 +623,6 @@
                                 NestedNameSpecifier *NNS,
                                 const TemplateSpecializationType *TemplateId,
                                 QualType Canon = QualType());
-  QualType getElaboratedType(QualType UnderlyingType,
-                             ElaboratedType::TagKind Tag);
 
   QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
                                 ObjCProtocolDecl **Protocols = 0,

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Tue May 11 16:36:43 2010
@@ -1648,11 +1648,7 @@
   : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
 public:
   // This is really ugly.
-  typedef ElaboratedType::TagKind TagKind;
-  static const TagKind TK_struct = ElaboratedType::TK_struct;
-  static const TagKind TK_union = ElaboratedType::TK_union;
-  static const TagKind TK_class = ElaboratedType::TK_class;
-  static const TagKind TK_enum = ElaboratedType::TK_enum;
+  typedef TagTypeKind TagKind;
 
 private:
   // FIXME: This can be packed into the bitfields in Decl.
@@ -1703,7 +1699,8 @@
           TagDecl *PrevDecl, SourceLocation TKL = SourceLocation())
     : TypeDecl(DK, DC, L, Id), DeclContext(DK), TagKeywordLoc(TKL),
       TypedefDeclOrQualifier((TypedefDecl*) 0) {
-    assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
+    assert((DK != Enum || TK == TTK_Enum) &&
+           "EnumDecl not matched with TTK_Enum");
     TagDeclKind = TK;
     IsDefinition = false;
     IsEmbeddedInDeclarator = false;
@@ -1776,24 +1773,19 @@
   void setDefinition(bool V) { IsDefinition = V; }
 
   const char *getKindName() const {
-    return ElaboratedType::getNameForTagKind(getTagKind());
+    return TypeWithKeyword::getTagTypeKindName(getTagKind());
   }
 
-  /// getTagKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
-  /// into a tag kind.  It is an error to provide a type specifier
-  /// which *isn't* a tag kind here.
-  static TagKind getTagKindForTypeSpec(unsigned TypeSpec);
-
   TagKind getTagKind() const {
     return TagKind(TagDeclKind);
   }
 
   void setTagKind(TagKind TK) { TagDeclKind = TK; }
 
-  bool isStruct() const { return getTagKind() == TK_struct; }
-  bool isClass()  const { return getTagKind() == TK_class; }
-  bool isUnion()  const { return getTagKind() == TK_union; }
-  bool isEnum()   const { return getTagKind() == TK_enum; }
+  bool isStruct() const { return getTagKind() == TTK_Struct; }
+  bool isClass()  const { return getTagKind() == TTK_Class; }
+  bool isUnion()  const { return getTagKind() == TTK_Union; }
+  bool isEnum()   const { return getTagKind() == TTK_Enum; }
 
   TypedefDecl *getTypedefForAnonDecl() const {
     return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
@@ -1852,7 +1844,7 @@
 
   EnumDecl(DeclContext *DC, SourceLocation L,
            IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
-    : TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
+    : TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
       IntegerType = QualType();
     }
 public:

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue May 11 16:36:43 2010
@@ -567,14 +567,6 @@
   }
 
   template<typename Derived>
-  bool RecursiveASTVisitor<Derived>::VisitElaboratedType(ElaboratedType *T) {
-    if (Visit(T->getUnderlyingType()))
-      return true;
-    
-    return getDerived().VisitType(T);
-  }
-
-  template<typename Derived>
   bool RecursiveASTVisitor<Derived>::VisitTemplateTypeParmType(
                                                       TemplateTypeParmType *T) {
     return getDerived().VisitType(T);
@@ -603,12 +595,13 @@
   }
 
   template<typename Derived>
-  bool RecursiveASTVisitor<Derived>::VisitQualifiedNameType(
-                                                        QualifiedNameType *T) {
-    if (getDerived().VisitNestedNameSpecifier(T->getQualifier()) ||
-        Visit(T->getNamedType()))
+  bool RecursiveASTVisitor<Derived>::VisitElaboratedType(ElaboratedType *T) {
+    if (T->getQualifier() &&
+        getDerived().VisitNestedNameSpecifier(T->getQualifier()))
       return true;
-    
+    if (Visit(T->getNamedType()))
+      return true;
+
     return getDerived().VisitType(T);
   }
 

Modified: cfe/trunk/include/clang/AST/TemplateName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateName.h?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateName.h (original)
+++ cfe/trunk/include/clang/AST/TemplateName.h Tue May 11 16:36:43 2010
@@ -188,7 +188,7 @@
 /// declaration for "vector". The QualifiedTemplateName class is only
 /// used to provide "sugar" for template names that were expressed
 /// with a qualified name, and has no semantic meaning. In this
-/// manner, it is to TemplateName what QualifiedNameType is to Type,
+/// manner, it is to TemplateName what ElaboratedType is to Type,
 /// providing extra syntactic sugar for downstream clients.
 class QualifiedTemplateName : public llvm::FoldingSetNode {
   /// \brief The nested name specifier that qualifies the template name.

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Tue May 11 16:36:43 2010
@@ -92,7 +92,7 @@
   class TemplateArgumentLoc;
   class TemplateArgumentListInfo;
   class Type;
-  class QualifiedNameType;
+  class ElaboratedType;
   struct PrintingPolicy;
 
   template <typename> class CanQual;  
@@ -2264,68 +2264,6 @@
   static bool classof(const EnumType *) { return true; }
 };
 
-/// ElaboratedType - A non-canonical type used to represents uses of
-/// elaborated type specifiers in C++.  For example:
-///
-///   void foo(union MyUnion);
-///            ^^^^^^^^^^^^^
-///
-/// At the moment, for efficiency we do not create elaborated types in
-/// C, since outside of typedefs all references to structs would
-/// necessarily be elaborated.
-class ElaboratedType : public Type, public llvm::FoldingSetNode {
-public:
-  enum TagKind {
-    TK_struct,
-    TK_union,
-    TK_class,
-    TK_enum
-  };
-
-private:
-  /// The tag that was used in this elaborated type specifier.
-  TagKind Tag;
-
-  /// The underlying type.
-  QualType UnderlyingType;
-
-  explicit ElaboratedType(QualType Ty, TagKind Tag, QualType Canon)
-    : Type(Elaborated, Canon, Canon->isDependentType()),
-      Tag(Tag), UnderlyingType(Ty) { }
-  friend class ASTContext;   // ASTContext creates these.
-
-public:
-  TagKind getTagKind() const { return Tag; }
-  QualType getUnderlyingType() const { return UnderlyingType; }
-
-  /// \brief Remove a single level of sugar.
-  QualType desugar() const { return getUnderlyingType(); }
-
-  /// \brief Returns whether this type directly provides sugar.
-  bool isSugared() const { return true; }
-
-  static const char *getNameForTagKind(TagKind Kind) {
-    switch (Kind) {
-    default: assert(0 && "Unknown TagKind!");
-    case TK_struct: return "struct";
-    case TK_union:  return "union";
-    case TK_class:  return "class";
-    case TK_enum:   return "enum";
-    }
-  }
-
-  void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getUnderlyingType(), getTagKind());
-  }
-  static void Profile(llvm::FoldingSetNodeID &ID, QualType T, TagKind Tag) {
-    ID.AddPointer(T.getAsOpaquePtr());
-    ID.AddInteger(Tag);
-  }
-
-  static bool classof(const ElaboratedType*) { return true; }
-  static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
-};
-
 class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
   unsigned Depth : 15;
   unsigned Index : 16;
@@ -2592,46 +2530,116 @@
   static bool classof(const InjectedClassNameType *T) { return true; }
 };
 
+/// \brief The kind of a tag type.
+enum TagTypeKind {
+  /// \brief The "struct" keyword.
+  TTK_Struct,
+  /// \brief The "union" keyword.
+  TTK_Union,
+  /// \brief The "class" keyword.
+  TTK_Class,
+  /// \brief The "enum" keyword.
+  TTK_Enum
+};
+
 /// \brief The elaboration keyword that precedes a qualified type name or
 /// introduces an elaborated-type-specifier.
 enum ElaboratedTypeKeyword {
-  /// \brief No keyword precedes the qualified type name.
-  ETK_None,
-  /// \brief The "typename" keyword precedes the qualified type name, e.g.,
-  /// \c typename T::type.
-  ETK_Typename,
-  /// \brief The "class" keyword introduces the elaborated-type-specifier.
-  ETK_Class,
   /// \brief The "struct" keyword introduces the elaborated-type-specifier.
   ETK_Struct,
   /// \brief The "union" keyword introduces the elaborated-type-specifier.
   ETK_Union,
+  /// \brief The "class" keyword introduces the elaborated-type-specifier.
+  ETK_Class,
   /// \brief The "enum" keyword introduces the elaborated-type-specifier.
-  ETK_Enum
+  ETK_Enum,
+  /// \brief The "typename" keyword precedes the qualified type name, e.g.,
+  /// \c typename T::type.
+  ETK_Typename,
+  /// \brief No keyword precedes the qualified type name.
+  ETK_None
 };
-  
-/// \brief Represents a type that was referred to via a qualified
-/// name, e.g., N::M::type.
+
+/// A helper class for Type nodes having an ElaboratedTypeKeyword.
+/// The keyword in stored in the free bits of the base class.
+/// Also provides a few static helpers for converting and printing
+/// elaborated type keyword and tag type kind enumerations.
+class TypeWithKeyword : public Type {
+  /// Keyword - Encodes an ElaboratedTypeKeyword enumeration constant.
+  unsigned Keyword : 3;
+
+protected:
+  TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
+                  QualType Canonical, bool dependent)
+    : Type(tc, Canonical, dependent), Keyword(Keyword) {}
+
+public:
+  virtual ~TypeWithKeyword(); // pin vtable to Type.cpp
+
+  ElaboratedTypeKeyword getKeyword() const {
+    return static_cast<ElaboratedTypeKeyword>(Keyword);
+  }
+
+  /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST)
+  /// into an elaborated type keyword.
+  static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
+
+  /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
+  /// into a tag type kind.  It is an error to provide a type specifier
+  /// which *isn't* a tag kind here.
+  static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
+
+  /// getKeywordForTagDeclKind - Converts a TagTypeKind into an
+  /// elaborated type keyword.
+  static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
+
+  /// getTagTypeKindForKeyword - Converts an elaborated type keyword into
+  // a TagTypeKind. It is an error to provide an elaborated type keyword
+  /// which *isn't* a tag kind here.
+  static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
+
+  static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
+
+  static const char *getKeywordName(ElaboratedTypeKeyword Keyword);
+
+  static const char *getTagTypeKindName(TagTypeKind Kind) {
+    return getKeywordName(getKeywordForTagTypeKind(Kind));
+  }
+
+  class CannotCastToThisType {};
+  static CannotCastToThisType classof(const Type *);
+};
+
+/// \brief Represents a type that was referred to using an elaborated type
+/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
+/// or both.
 ///
 /// This type is used to keep track of a type name as written in the
-/// source code, including any nested-name-specifiers. The type itself
-/// is always "sugar", used to express what was written in the source
-/// code but containing no additional semantic information.
-class QualifiedNameType : public Type, public llvm::FoldingSetNode {
+/// source code, including tag keywords and any nested-name-specifiers.
+/// The type itself is always "sugar", used to express what was written
+/// in the source code but containing no additional semantic information.
+class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
+
   /// \brief The nested name specifier containing the qualifier.
   NestedNameSpecifier *NNS;
 
   /// \brief The type that this qualified name refers to.
   QualType NamedType;
 
-  QualifiedNameType(NestedNameSpecifier *NNS, QualType NamedType,
-                    QualType CanonType)
-    : Type(QualifiedName, CanonType, NamedType->isDependentType()),
-      NNS(NNS), NamedType(NamedType) { }
+  ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+                 QualType NamedType, QualType CanonType)
+    : TypeWithKeyword(Keyword, Elaborated, CanonType,
+                      NamedType->isDependentType()),
+      NNS(NNS), NamedType(NamedType) {
+    assert(!(Keyword == ETK_None && NNS == 0) &&
+           "ElaboratedType cannot have elaborated type keyword "
+           "and name qualifier both null.");
+  }
 
   friend class ASTContext;  // ASTContext creates these
 
 public:
+
   /// \brief Retrieve the qualification on this type.
   NestedNameSpecifier *getQualifier() const { return NNS; }
 
@@ -2645,19 +2653,20 @@
   bool isSugared() const { return true; }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, NNS, NamedType);
+    Profile(ID, getKeyword(), NNS, NamedType);
   }
 
-  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
-                      QualType NamedType) {
+  static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+                      NestedNameSpecifier *NNS, QualType NamedType) {
+    ID.AddInteger(Keyword);
     ID.AddPointer(NNS);
     NamedType.Profile(ID);
   }
 
   static bool classof(const Type *T) {
-    return T->getTypeClass() == QualifiedName;
+    return T->getTypeClass() == Elaborated;
   }
-  static bool classof(const QualifiedNameType *T) { return true; }
+  static bool classof(const ElaboratedType *T) { return true; }
 };
 
 /// \brief Represents a qualified type name for which the type name is
@@ -2669,10 +2678,8 @@
 /// typename-specifier), "class", "struct", "union", or "enum" (for a 
 /// dependent elaborated-type-specifier), or nothing (in contexts where we
 /// know that we must be referring to a type, e.g., in a base class specifier).
-class DependentNameType : public Type, public llvm::FoldingSetNode {
-  /// \brief The keyword used to elaborate this type.
-  ElaboratedTypeKeyword Keyword;
-  
+class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
+
   /// \brief The nested name specifier containing the qualifier.
   NestedNameSpecifier *NNS;
 
@@ -2684,16 +2691,16 @@
 
   DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 
                     const IdentifierInfo *Name, QualType CanonType)
-    : Type(DependentName, CanonType, true), 
-      Keyword(Keyword), NNS(NNS), Name(Name) {
+    : TypeWithKeyword(Keyword, DependentName, CanonType, true),
+      NNS(NNS), Name(Name) {
     assert(NNS->isDependent() &&
            "DependentNameType requires a dependent nested-name-specifier");
   }
 
   DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
                     const TemplateSpecializationType *Ty, QualType CanonType)
-    : Type(DependentName, CanonType, true), 
-      Keyword(Keyword), NNS(NNS), Name(Ty) {
+    : TypeWithKeyword(Keyword, DependentName, CanonType, true),
+      NNS(NNS), Name(Ty) {
     assert(NNS->isDependent() &&
            "DependentNameType requires a dependent nested-name-specifier");
   }
@@ -2701,9 +2708,7 @@
   friend class ASTContext;  // ASTContext creates these
 
 public:
-  /// \brief Retrieve the keyword used to elaborate this type.
-  ElaboratedTypeKeyword getKeyword() const { return Keyword; }
-  
+
   /// \brief Retrieve the qualification on this type.
   NestedNameSpecifier *getQualifier() const { return NNS; }
 
@@ -2727,7 +2732,7 @@
   QualType desugar() const { return QualType(this, 0); }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, Keyword, NNS, Name);
+    Profile(ID, getKeyword(), NNS, Name);
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Tue May 11 16:36:43 2010
@@ -1231,18 +1231,12 @@
                                                          DecltypeType> {
 };
 
-// FIXME: location of the tag keyword.
-class ElaboratedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
-                                                           ElaboratedTypeLoc,
-                                                           ElaboratedType> {
-};
-
 // FIXME: locations for the nested name specifier;  at the very least,
 // a SourceRange.
-class QualifiedNameTypeLoc :
+class ElaboratedTypeLoc :
     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
-                                     QualifiedNameTypeLoc,
-                                     QualifiedNameType> {
+                                     ElaboratedTypeLoc,
+                                     ElaboratedType> {
 };
 
 // FIXME: locations for the typename keyword and nested name specifier.

Modified: cfe/trunk/include/clang/AST/TypeNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)
+++ cfe/trunk/include/clang/AST/TypeNodes.def Tue May 11 16:36:43 2010
@@ -90,7 +90,6 @@
 DEPENDENT_TYPE(TemplateTypeParm, Type)
 NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
-NON_CANONICAL_TYPE(QualifiedName, Type)
 DEPENDENT_TYPE(InjectedClassName, Type)
 DEPENDENT_TYPE(DependentName, Type)
 TYPE(ObjCInterface, Type)

Modified: cfe/trunk/include/clang/Frontend/TypeXML.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/TypeXML.def?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/TypeXML.def (original)
+++ cfe/trunk/include/clang/Frontend/TypeXML.def Tue May 11 16:36:43 2010
@@ -211,22 +211,13 @@
   ID_ATTRIBUTE_XML
   ATTRIBUTE_XML(getDecl()->getNameAsString(), "name")   // string
   ATTRIBUTE_ENUM_XML(getDecl()->getTagKind(), "kind")
-    ENUM_XML(TagDecl::TK_struct, "struct")
-    ENUM_XML(TagDecl::TK_union, "union")
-    ENUM_XML(TagDecl::TK_class, "class")
+    ENUM_XML(TTK_Struct, "struct")
+    ENUM_XML(TTK_Union, "union")
+    ENUM_XML(TTK_Class, "class")
   END_ENUM_XML
   CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
 END_NODE_XML
 
-NODE_XML(ElaboratedType, "Elaborated")
-  ID_ATTRIBUTE_XML
-  ATTRIBUTE_ENUM_XML(getTagKind(), "kind")
-    ENUM_XML(ElaboratedType::TK_struct, "struct")
-    ENUM_XML(ElaboratedType::TK_union, "union")
-    ENUM_XML(ElaboratedType::TK_class, "class")
-  END_ENUM_XML
-END_NODE_XML
-
 NODE_XML(EnumType, "Enum")
   ID_ATTRIBUTE_XML
   ATTRIBUTE_XML(getDecl()->getNameAsString(), "name")   // string
@@ -241,8 +232,16 @@
   ID_ATTRIBUTE_XML
 END_NODE_XML
 
-NODE_XML(QualifiedNameType, "QualifiedNameType")
+NODE_XML(ElaboratedType, "ElaboratedType")
   ID_ATTRIBUTE_XML
+  ATTRIBUTE_ENUM_XML(getKeyword(), "keyword")
+    ENUM_XML(ETK_None, "none")
+    ENUM_XML(ETK_Typename, "typename")
+    ENUM_XML(ETK_Struct, "struct")
+    ENUM_XML(ETK_Union, "union")
+    ENUM_XML(ETK_Class, "class")
+    ENUM_XML(ETK_Enum, "enum")
+  END_ENUM_XML
   TYPE_ATTRIBUTE_XML(getNamedType())
 END_NODE_XML
 

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue May 11 16:36:43 2010
@@ -626,10 +626,6 @@
     return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->
                        getReplacementType().getTypePtr());
 
-  case Type::Elaborated:
-    return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType()
-                         .getTypePtr());
-
   case Type::Typedef: {
     const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
     if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
@@ -652,8 +648,8 @@
     return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType()
                         .getTypePtr());
 
-  case Type::QualifiedName:
-    return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr());
+  case Type::Elaborated:
+    return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr());
 
   case Type::TemplateSpecialization:
     assert(getCanonicalType(T) != T &&
@@ -1890,29 +1886,28 @@
 }
 
 QualType
-ASTContext::getQualifiedNameType(NestedNameSpecifier *NNS,
-                                 QualType NamedType) {
+ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
+                              NestedNameSpecifier *NNS,
+                              QualType NamedType) {
   llvm::FoldingSetNodeID ID;
-  QualifiedNameType::Profile(ID, NNS, NamedType);
+  ElaboratedType::Profile(ID, Keyword, NNS, NamedType);
 
   void *InsertPos = 0;
-  QualifiedNameType *T
-    = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+  ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
   if (T)
     return QualType(T, 0);
 
   QualType Canon = NamedType;
   if (!Canon.isCanonical()) {
     Canon = getCanonicalType(NamedType);
-    QualifiedNameType *CheckT
-      = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(!CheckT && "Qualified name canonical type broken");
+    ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(!CheckT && "Elaborated canonical type broken");
     (void)CheckT;
   }
 
-  T = new (*this) QualifiedNameType(NNS, NamedType, Canon);
+  T = new (*this) ElaboratedType(Keyword, NNS, NamedType, Canon);
   Types.push_back(T);
-  QualifiedNameTypes.InsertNode(T, InsertPos);
+  ElaboratedTypes.InsertNode(T, InsertPos);
   return QualType(T, 0);
 }
 
@@ -1989,30 +1984,6 @@
   return QualType(T, 0);
 }
 
-QualType
-ASTContext::getElaboratedType(QualType UnderlyingType,
-                              ElaboratedType::TagKind Tag) {
-  llvm::FoldingSetNodeID ID;
-  ElaboratedType::Profile(ID, UnderlyingType, Tag);
-
-  void *InsertPos = 0;
-  ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
-  if (T)
-    return QualType(T, 0);
-
-  QualType Canon = UnderlyingType;
-  if (!Canon.isCanonical()) {
-    Canon = getCanonicalType(Canon);
-    ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(!CheckT && "Elaborated canonical type is broken"); (void)CheckT;
-  }
-
-  T = new (*this) ElaboratedType(UnderlyingType, Tag, Canon);
-  Types.push_back(T);
-  ElaboratedTypes.InsertNode(T, InsertPos);
-  return QualType(T, 0);
-}
-
 /// CmpProtocolNames - Comparison predicate for sorting protocols
 /// alphabetically.
 static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,
@@ -2813,7 +2784,7 @@
 QualType ASTContext::getCFConstantStringType() {
   if (!CFConstantStringTypeDecl) {
     CFConstantStringTypeDecl =
-      CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+      CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get("NSConstantString"));
     CFConstantStringTypeDecl->startDefinition();
 
@@ -2855,7 +2826,7 @@
 QualType ASTContext::getNSConstantStringType() {
   if (!NSConstantStringTypeDecl) {
     NSConstantStringTypeDecl =
-    CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+    CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                      &Idents.get("__builtin_NSString"));
     NSConstantStringTypeDecl->startDefinition();
     
@@ -2894,7 +2865,7 @@
 QualType ASTContext::getObjCFastEnumerationStateType() {
   if (!ObjCFastEnumerationStateTypeDecl) {
     ObjCFastEnumerationStateTypeDecl =
-      CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+      CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get("__objcFastEnumerationState"));
     ObjCFastEnumerationStateTypeDecl->startDefinition();
 
@@ -2929,7 +2900,7 @@
 
   RecordDecl *T;
   // FIXME: Needs the FlagAppleBlock bit.
-  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+  T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get("__block_descriptor"));
   T->startDefinition();
   
@@ -2974,7 +2945,7 @@
 
   RecordDecl *T;
   // FIXME: Needs the FlagAppleBlock bit.
-  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+  T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get("__block_descriptor_withcopydispose"));
   T->startDefinition();
   
@@ -3046,7 +3017,7 @@
   llvm::raw_svector_ostream(Name) << "__Block_byref_" <<
                                   ++UniqueBlockByRefTypeID << '_' << DeclName;
   RecordDecl *T;
-  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+  T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get(Name.str()));
   T->startDefinition();
   QualType Int32Ty = IntTy;
@@ -3097,7 +3068,7 @@
   llvm::raw_svector_ostream(Name) << "__block_literal_"
                                   << ++UniqueBlockParmTypeID;
   RecordDecl *T;
-  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+  T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get(Name.str()));
   T->startDefinition();
   QualType FieldTypes[] = {

Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Tue May 11 16:36:43 2010
@@ -50,12 +50,6 @@
       QT = cast<ElaboratedType>(Ty)->desugar();
       continue;
     }
-    
-    // ...or a qualified name type...
-    if (isa<QualifiedNameType>(Ty)) {
-      QT = cast<QualifiedNameType>(Ty)->desugar();
-      continue;
-    }
 
     // ...or a substituted template type parameter.
     if (isa<SubstTemplateTypeParmType>(Ty)) {

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue May 11 16:36:43 2010
@@ -68,11 +68,10 @@
     // FIXME: DependentDecltypeType
     QualType VisitRecordType(RecordType *T);
     QualType VisitEnumType(EnumType *T);
-    QualType VisitElaboratedType(ElaboratedType *T);
     // FIXME: TemplateTypeParmType
     // FIXME: SubstTemplateTypeParmType
     // FIXME: TemplateSpecializationType
-    QualType VisitQualifiedNameType(QualifiedNameType *T);
+    QualType VisitElaboratedType(ElaboratedType *T);
     // FIXME: DependentNameType
     QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
     QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
@@ -532,19 +531,7 @@
                                   cast<TagType>(T2)->getDecl()))
       return false;
     break;
-      
-  case Type::Elaborated: {
-    const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
-    const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
-    if (Elab1->getTagKind() != Elab2->getTagKind())
-      return false;
-    if (!IsStructurallyEquivalent(Context, 
-                                  Elab1->getUnderlyingType(),
-                                  Elab2->getUnderlyingType()))
-      return false;
-    break;
-  }
-   
+
   case Type::TemplateTypeParm: {
     const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
     const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
@@ -594,16 +581,19 @@
     break;
   }
       
-  case Type::QualifiedName: {
-    const QualifiedNameType *Qual1 = cast<QualifiedNameType>(T1);
-    const QualifiedNameType *Qual2 = cast<QualifiedNameType>(T2);
+  case Type::Elaborated: {
+    const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
+    const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
+    // CHECKME: what if a keyword is ETK_None or ETK_typename ?
+    if (Elab1->getKeyword() != Elab2->getKeyword())
+      return false;
     if (!IsStructurallyEquivalent(Context, 
-                                  Qual1->getQualifier(), 
-                                  Qual2->getQualifier()))
+                                  Elab1->getQualifier(), 
+                                  Elab2->getQualifier()))
       return false;
     if (!IsStructurallyEquivalent(Context,
-                                  Qual1->getNamedType(),
-                                  Qual2->getNamedType()))
+                                  Elab1->getNamedType(),
+                                  Elab2->getNamedType()))
       return false;
     break;
   }
@@ -1293,24 +1283,20 @@
 }
 
 QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
-  QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
-  if (ToUnderlyingType.isNull())
-    return QualType();
-
-  return Importer.getToContext().getElaboratedType(ToUnderlyingType,
-                                                   T->getTagKind());
-}
-
-QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
-  NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
-  if (!ToQualifier)
-    return QualType();
+  NestedNameSpecifier *ToQualifier = 0;
+  // Note: the qualifier in an ElaboratedType is optional.
+  if (T->getQualifier()) {
+    ToQualifier = Importer.Import(T->getQualifier());
+    if (!ToQualifier)
+      return QualType();
+  }
 
   QualType ToNamedType = Importer.Import(T->getNamedType());
   if (ToNamedType.isNull())
     return QualType();
 
-  return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
+  return Importer.getToContext().getElaboratedType(T->getKeyword(),
+                                                   ToQualifier, ToNamedType);
 }
 
 QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue May 11 16:36:43 2010
@@ -23,7 +23,7 @@
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/IdentifierTable.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Basic/Specifiers.h"
 #include "llvm/Support/ErrorHandling.h"
 
 using namespace clang;
@@ -1520,16 +1520,6 @@
   return 0;
 }
 
-TagDecl::TagKind TagDecl::getTagKindForTypeSpec(unsigned TypeSpec) {
-  switch (TypeSpec) {
-  default: llvm_unreachable("unexpected type specifier");
-  case DeclSpec::TST_struct: return TK_struct;
-  case DeclSpec::TST_class: return TK_class;
-  case DeclSpec::TST_union: return TK_union;
-  case DeclSpec::TST_enum: return TK_enum;
-  }
-}
-
 void TagDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
                                SourceRange QualifierRange) {
   if (Qualifier) {

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Tue May 11 16:36:43 2010
@@ -137,7 +137,7 @@
 
     data().VBases[I] =
       CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
-                       VBaseClassDecl->getTagKind() == RecordDecl::TK_class,
+                       VBaseClassDecl->getTagKind() == TTK_Class,
                        VBases[I]->getAccessSpecifier(), VBaseType);
   }
 }

Modified: cfe/trunk/lib/AST/NestedNameSpecifier.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/NestedNameSpecifier.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/AST/NestedNameSpecifier.cpp (original)
+++ cfe/trunk/lib/AST/NestedNameSpecifier.cpp Tue May 11 16:36:43 2010
@@ -145,14 +145,14 @@
     InnerPolicy.SuppressScope = true;
 
     // Nested-name-specifiers are intended to contain minimally-qualified
-    // types. An actual QualifiedNameType will not occur, since we'll store
+    // types. An actual ElaboratedType will not occur, since we'll store
     // just the type that is referred to in the nested-name-specifier (e.g.,
     // a TypedefType, TagType, etc.). However, when we are dealing with
     // dependent template-id types (e.g., Outer<T>::template Inner<U>),
     // the type requires its own nested-name-specifier for uniqueness, so we
     // suppress that nested-name-specifier during printing.
-    assert(!isa<QualifiedNameType>(T) &&
-           "Qualified name type in nested-name-specifier");
+    assert(!isa<ElaboratedType>(T) &&
+           "Elaborated type in nested-name-specifier");
     if (const TemplateSpecializationType *SpecType
           = dyn_cast<TemplateSpecializationType>(T)) {
       // Print the template name without its corresponding

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Tue May 11 16:36:43 2010
@@ -18,6 +18,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/PrettyPrinter.h"
+#include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
@@ -764,36 +765,105 @@
   case TemplateTypeParm:
   case SubstTemplateTypeParm:
   case TemplateSpecialization:
-  case QualifiedName:
+  case Elaborated:
   case DependentName:
   case ObjCInterface:
   case ObjCObjectPointer:
-  case Elaborated:
     return true;
   default:
     return false;
   }
 }
 
-bool Type::isElaboratedTypeSpecifier() const {
-  if (getTypeClass() == Elaborated)
+TypeWithKeyword::~TypeWithKeyword() {
+}
+
+ElaboratedTypeKeyword
+TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
+  switch (TypeSpec) {
+  default: return ETK_None;
+  case TST_typename: return ETK_Typename;
+  case TST_class: return ETK_Class;
+  case TST_struct: return ETK_Struct;
+  case TST_union: return ETK_Union;
+  case TST_enum: return ETK_Enum;
+  }
+}
+
+TagTypeKind
+TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
+  switch(TypeSpec) {
+  case TST_class: return TTK_Class;
+  case TST_struct: return TTK_Struct;
+  case TST_union: return TTK_Union;
+  case TST_enum: return TTK_Enum;
+  default: llvm_unreachable("Type specifier is not a tag type kind.");
+  }
+}
+
+ElaboratedTypeKeyword
+TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
+  switch (Kind) {
+  case TTK_Class: return ETK_Class;
+  case TTK_Struct: return ETK_Struct;
+  case TTK_Union: return ETK_Union;
+  case TTK_Enum: return ETK_Enum;
+  }
+  llvm_unreachable("Unknown tag type kind.");
+}
+
+TagTypeKind
+TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
+  switch (Keyword) {
+  case ETK_Class: return TTK_Class;
+  case ETK_Struct: return TTK_Struct;
+  case ETK_Union: return TTK_Union;
+  case ETK_Enum: return TTK_Enum;
+  case ETK_None: // Fall through.
+  case ETK_Typename:
+    llvm_unreachable("Elaborated type keyword is not a tag type kind.");
+  }
+  llvm_unreachable("Unknown elaborated type keyword.");
+}
+
+bool
+TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
+  switch (Keyword) {
+  case ETK_None:
+  case ETK_Typename:
+    return false;
+  case ETK_Class:
+  case ETK_Struct:
+  case ETK_Union:
+  case ETK_Enum:
     return true;
-  
-  if (const DependentNameType *Dependent = dyn_cast<DependentNameType>(this)) {
-    switch (Dependent->getKeyword()) {
-    case ETK_None:
-    case ETK_Typename:
-      return false;
-        
-    case ETK_Class:
-    case ETK_Struct:
-    case ETK_Union:
-    case ETK_Enum:
-      return true;
-    }
   }
-  
-  return false;
+  llvm_unreachable("Unknown elaborated type keyword.");
+}
+
+const char*
+TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
+  switch (Keyword) {
+  default: llvm_unreachable("Unknown elaborated type keyword.");
+  case ETK_None: return "";
+  case ETK_Typename: return "typename";
+  case ETK_Class:  return "class";
+  case ETK_Struct: return "struct";
+  case ETK_Union:  return "union";
+  case ETK_Enum:   return "enum";
+  }
+}
+
+bool Type::isElaboratedTypeSpecifier() const {
+  ElaboratedTypeKeyword Keyword;
+  if (const ElaboratedType *Elab = dyn_cast<ElaboratedType>(this))
+    Keyword = Elab->getKeyword();
+  else if (const DependentNameType *DepName = dyn_cast<DependentNameType>(this))
+    Keyword = DepName->getKeyword();
+  else
+    return false;
+
+  return TypeWithKeyword::KeywordIsTagTypeKind(Keyword);
 }
 
 const char *Type::getTypeClassName() const {

Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Tue May 11 16:36:43 2010
@@ -497,16 +497,6 @@
   PrintTag(T->getDecl(), S);
 }
 
-void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { 
-  Print(T->getUnderlyingType(), S);
-
-  // We don't actually make these in C, but the language options
-  // sometimes lie to us -- for example, if someone calls
-  // QualType::getAsString().  Just suppress the redundant tag if so.
-  if (Policy.LangOpts.CPlusPlus)
-    S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S;  
-}
-
 void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, 
                                         std::string &S) { 
   if (!S.empty())    // Prefix the basic type, e.g. 'parmname X'.
@@ -549,13 +539,17 @@
   PrintTemplateSpecialization(T->getInjectedTST(), S);
 }
 
-void TypePrinter::PrintQualifiedName(const QualifiedNameType *T, 
-                                     std::string &S) { 
+void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
   std::string MyString;
   
   {
     llvm::raw_string_ostream OS(MyString);
-    T->getQualifier()->print(OS, Policy);
+    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+    if (T->getKeyword() != ETK_None)
+      OS << " ";
+    NestedNameSpecifier* Qualifier = T->getQualifier();
+    if (Qualifier)
+      Qualifier->print(OS, Policy);
   }
   
   std::string TypeStr;
@@ -575,14 +569,9 @@
   
   {
     llvm::raw_string_ostream OS(MyString);
-    switch (T->getKeyword()) {
-    case ETK_None: break;
-    case ETK_Typename: OS << "typename "; break;
-    case ETK_Class: OS << "class "; break;
-    case ETK_Struct: OS << "struct "; break;
-    case ETK_Union: OS << "union "; break;
-    case ETK_Enum: OS << "enum "; break;
-    }
+    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+    if (T->getKeyword() != ETK_None)
+      OS << " ";
     
     T->getQualifier()->print(OS, Policy);
     

Modified: cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp (original)
+++ cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp Tue May 11 16:36:43 2010
@@ -47,7 +47,7 @@
 }
 
 static bool IsStdString(QualType T) {
-  if (const QualifiedNameType *QT = T->getAs<QualifiedNameType>())
+  if (const ElaboratedType *QT = T->getAs<ElaboratedType>())
     T = QT->getNamedType();
 
   const TypedefType *TT = T->getAs<TypedefType>();

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue May 11 16:36:43 2010
@@ -1154,15 +1154,12 @@
     case Type::Decltype:
       T = cast<DecltypeType>(T)->getUnderlyingType();
       break;
-    case Type::QualifiedName:
-      T = cast<QualifiedNameType>(T)->getNamedType();
+    case Type::Elaborated:
+      T = cast<ElaboratedType>(T)->getNamedType();
       break;
     case Type::SubstTemplateTypeParm:
       T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
       break;
-    case Type::Elaborated:
-      T = cast<ElaboratedType>(T)->getUnderlyingType();
-      break;
     }
     
     assert(T != LastT && "Type unwrapping failed to unwrap!");
@@ -1253,7 +1250,6 @@
 
   case Type::TemplateSpecialization:
   case Type::Elaborated:
-  case Type::QualifiedName:
   case Type::SubstTemplateTypeParm:
   case Type::TypeOfExpr:
   case Type::TypeOf:

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue May 11 16:36:43 2010
@@ -3669,7 +3669,7 @@
   //   id self;
   //   Class cls;
   // }
-  RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct,
+  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
                                       Ctx.getTranslationUnitDecl(),
                                       SourceLocation(),
                                       &Ctx.Idents.get("_objc_super"));
@@ -4131,7 +4131,7 @@
   // };
 
   // First the clang type for struct _message_ref_t
-  RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct,
+  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
                                       Ctx.getTranslationUnitDecl(),
                                       SourceLocation(),
                                       &Ctx.Idents.get("_message_ref_t"));

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Tue May 11 16:36:43 2010
@@ -2165,8 +2165,10 @@
       return QualType();
     }
     unsigned Tag = Record[1];
-    return Context->getElaboratedType(GetType(Record[0]),
-                                      (ElaboratedType::TagKind) Tag);
+    // FIXME: Deserialize the qualifier (C++ only)
+    return Context->getElaboratedType((ElaboratedTypeKeyword) Tag,
+                                      /* NNS */ 0,
+                                      GetType(Record[0]));
   }
 
   case pch::TYPE_OBJC_INTERFACE: {
@@ -2334,9 +2336,6 @@
 void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
-void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
-  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-}
 void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
@@ -2354,7 +2353,7 @@
         Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
                                           Record, Idx));
 }
-void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
+void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
 void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Tue May 11 16:36:43 2010
@@ -865,7 +865,7 @@
     D = EnumDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(), 0);
     break;
   case pch::DECL_RECORD:
-    D = RecordDecl::Create(*Context, TagDecl::TK_struct, 0, SourceLocation(),
+    D = RecordDecl::Create(*Context, TTK_Struct, 0, SourceLocation(),
                            0, SourceLocation(), 0);
     break;
   case pch::DECL_ENUM_CONSTANT:
@@ -913,7 +913,7 @@
                                             DeclarationName());
     break;
   case pch::DECL_CXX_RECORD:
-    D = CXXRecordDecl::Create(*Context, TagDecl::TK_struct, 0,
+    D = CXXRecordDecl::Create(*Context, TTK_Struct, 0,
                               SourceLocation(), 0, SourceLocation(), 0);
     break;
   case pch::DECL_CXX_METHOD:

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Tue May 11 16:36:43 2010
@@ -213,12 +213,6 @@
   Code = pch::TYPE_ENUM;
 }
 
-void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
-  Writer.AddTypeRef(T->getUnderlyingType(), Record);
-  Record.push_back(T->getTagKind());
-  Code = pch::TYPE_ELABORATED;
-}
-
 void
 PCHTypeWriter::VisitSubstTemplateTypeParmType(
                                         const SubstTemplateTypeParmType *T) {
@@ -234,9 +228,12 @@
   assert(false && "Cannot serialize template specialization types");
 }
 
-void PCHTypeWriter::VisitQualifiedNameType(const QualifiedNameType *T) {
-  // FIXME: Serialize this type (C++ only)
-  assert(false && "Cannot serialize qualified name types");
+void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
+  Writer.AddTypeRef(T->getNamedType(), Record);
+  Record.push_back(T->getKeyword());
+  // FIXME: Serialize the qualifier (C++ only)
+  assert(T->getQualifier() == 0 && "Cannot serialize qualified name types");
+  Code = pch::TYPE_ELABORATED;
 }
 
 void PCHTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
@@ -383,9 +380,6 @@
 void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) {
   Writer.AddSourceLocation(TL.getNameLoc(), Record);
 }
-void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
-  Writer.AddSourceLocation(TL.getNameLoc(), Record);
-}
 void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
   Writer.AddSourceLocation(TL.getNameLoc(), Record);
 }
@@ -401,7 +395,7 @@
   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
     Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record);
 }
-void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
+void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
   Writer.AddSourceLocation(TL.getNameLoc(), Record);
 }
 void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {

Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Tue May 11 16:36:43 2010
@@ -1349,7 +1349,7 @@
       std::string RecName = clsDeclared->getIdentifier()->getName();
       RecName += "_IMPL";
       IdentifierInfo *II = &Context->Idents.get(RecName);
-      RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                           SourceLocation(), II);
       assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
@@ -1394,7 +1394,7 @@
       std::string RecName = clsDeclared->getIdentifier()->getName();
       RecName += "_IMPL";
       IdentifierInfo *II = &Context->Idents.get(RecName);
-      RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                           SourceLocation(), II);
       assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
@@ -2426,7 +2426,7 @@
 void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
   llvm::SmallVector<QualType, 16> ArgTys;
-  RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                       SourceLocation(),
                                       &Context->Idents.get("objc_super"));
   QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
@@ -2475,7 +2475,7 @@
   IdentifierInfo *msgSendIdent =
     &Context->Idents.get("objc_msgSendSuper_stret");
   llvm::SmallVector<QualType, 16> ArgTys;
-  RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                       SourceLocation(),
                                       &Context->Idents.get("objc_super"));
   QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
@@ -2625,7 +2625,7 @@
 // struct objc_super { struct objc_object *receiver; struct objc_class *super; };
 QualType RewriteObjC::getSuperStructType() {
   if (!SuperStructDecl) {
-    SuperStructDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+    SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                          SourceLocation(),
                                          &Context->Idents.get("objc_super"));
     QualType FieldTypes[2];
@@ -2651,7 +2651,7 @@
 
 QualType RewriteObjC::getConstantStringStructType() {
   if (!ConstantStringDecl) {
-    ConstantStringDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+    ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                             SourceLocation(),
                          &Context->Idents.get("__NSConstantStringImpl"));
     QualType FieldTypes[4];
@@ -4573,7 +4573,7 @@
   const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
   // FTP will be null for closures that don't take arguments.
 
-  RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                       SourceLocation(),
                                       &Context->Idents.get("__block_impl"));
   QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
@@ -5245,7 +5245,7 @@
       RewriteByRefString(RecName, Name, ND);
       IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
                                                 + sizeof("struct"));
-      RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                           SourceLocation(), II);
       assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Tue May 11 16:36:43 2010
@@ -40,11 +40,11 @@
 
 static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name) {
   if (C.getLangOptions().CPlusPlus)
-    return CXXRecordDecl::Create(C, TagDecl::TK_struct,
+    return CXXRecordDecl::Create(C, TTK_Struct,
                                  C.getTranslationUnitDecl(),
                                  SourceLocation(), &C.Idents.get(Name));
 
-  return RecordDecl::Create(C, TagDecl::TK_struct,
+  return RecordDecl::Create(C, TTK_Struct,
                             C.getTranslationUnitDecl(),
                             SourceLocation(), &C.Idents.get(Name));
 }

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue May 11 16:36:43 2010
@@ -768,7 +768,8 @@
   bool RequireCompleteType(SourceLocation Loc, QualType T,
                            unsigned DiagID);
 
-  QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T);
+  QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
+                             const CXXScopeSpec &SS, QualType T);
 
   QualType BuildTypeofExprType(Expr *E);
   QualType BuildDecltypeType(Expr *E);

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue May 11 16:36:43 2010
@@ -672,8 +672,8 @@
     ND = ClassTemplate->getTemplatedDecl();
   
   if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
-    return RD->getTagKind() == TagDecl::TK_class ||
-    RD->getTagKind() == TagDecl::TK_struct;
+    return RD->getTagKind() == TTK_Class ||
+    RD->getTagKind() == TTK_Struct;
   
   return false;
 }
@@ -685,7 +685,7 @@
     ND = ClassTemplate->getTemplatedDecl();
   
   if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
-    return RD->getTagKind() == TagDecl::TK_union;
+    return RD->getTagKind() == TTK_Union;
   
   return false;
 }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May 11 16:36:43 2010
@@ -191,7 +191,7 @@
       T = Context.getTypeDeclType(TD);
     
     if (SS)
-      T = getQualifiedNameType(*SS, T);
+      T = getElaboratedType(ETK_None, *SS, T);
     
   } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
     T = Context.getObjCInterfaceType(IDecl);
@@ -223,10 +223,11 @@
   if (R.getResultKind() == LookupResult::Found)
     if (const TagDecl *TD = R.getAsSingle<TagDecl>()) {
       switch (TD->getTagKind()) {
-      case TagDecl::TK_struct: return DeclSpec::TST_struct;
-      case TagDecl::TK_union:  return DeclSpec::TST_union;
-      case TagDecl::TK_class:  return DeclSpec::TST_class;
-      case TagDecl::TK_enum:   return DeclSpec::TST_enum;
+      default:         return DeclSpec::TST_unspecified;
+      case TTK_Struct: return DeclSpec::TST_struct;
+      case TTK_Union:  return DeclSpec::TST_union;
+      case TTK_Class:  return DeclSpec::TST_class;
+      case TTK_Enum:   return DeclSpec::TST_enum;
       }
     }
 
@@ -4845,38 +4846,38 @@
 ///
 /// \returns true if the new tag kind is acceptable, false otherwise.
 bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous,
-                                        TagDecl::TagKind NewTag,
+                                        TagTypeKind NewTag,
                                         SourceLocation NewTagLoc,
                                         const IdentifierInfo &Name) {
   // C++ [dcl.type.elab]p3:
   //   The class-key or enum keyword present in the
   //   elaborated-type-specifier shall agree in kind with the
-  //   declaration to which the name in theelaborated-type-specifier
+  //   declaration to which the name in the elaborated-type-specifier
   //   refers. This rule also applies to the form of
   //   elaborated-type-specifier that declares a class-name or
   //   friend class since it can be construed as referring to the
   //   definition of the class. Thus, in any
   //   elaborated-type-specifier, the enum keyword shall be used to
-  //   refer to an enumeration (7.2), the union class-keyshall be
+  //   refer to an enumeration (7.2), the union class-key shall be
   //   used to refer to a union (clause 9), and either the class or
   //   struct class-key shall be used to refer to a class (clause 9)
   //   declared using the class or struct class-key.
-  TagDecl::TagKind OldTag = Previous->getTagKind();
+  TagTypeKind OldTag = Previous->getTagKind();
   if (OldTag == NewTag)
     return true;
 
-  if ((OldTag == TagDecl::TK_struct || OldTag == TagDecl::TK_class) &&
-      (NewTag == TagDecl::TK_struct || NewTag == TagDecl::TK_class)) {
+  if ((OldTag == TTK_Struct || OldTag == TTK_Class) &&
+      (NewTag == TTK_Struct || NewTag == TTK_Class)) {
     // Warn about the struct/class tag mismatch.
     bool isTemplate = false;
     if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Previous))
       isTemplate = Record->getDescribedClassTemplate();
 
     Diag(NewTagLoc, diag::warn_struct_class_tag_mismatch)
-      << (NewTag == TagDecl::TK_class)
+      << (NewTag == TTK_Class)
       << isTemplate << &Name
       << FixItHint::CreateReplacement(SourceRange(NewTagLoc),
-                              OldTag == TagDecl::TK_class? "class" : "struct");
+                              OldTag == TTK_Class? "class" : "struct");
     Diag(Previous->getLocation(), diag::note_previous_use);
     return true;
   }
@@ -4898,7 +4899,7 @@
          "Nameless record must be a definition!");
 
   OwnedDecl = false;
-  TagDecl::TagKind Kind = TagDecl::getTagKindForTypeSpec(TagSpec);
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
 
   // FIXME: Check explicit specializations more carefully.
   bool isExplicitSpecialization = false;
@@ -4922,7 +4923,7 @@
       } else {
         // The "template<>" header is extraneous.
         Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
-          << ElaboratedType::getNameForTagKind(Kind) << Name;
+          << TypeWithKeyword::getTagTypeKindName(Kind) << Name;
         isExplicitSpecialization = true;
       }
     }
@@ -5141,8 +5142,8 @@
         // struct or something similar.
         if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind, KWLoc, *Name)) {
           bool SafeToContinue
-            = (PrevTagDecl->getTagKind() != TagDecl::TK_enum &&
-               Kind != TagDecl::TK_enum);
+            = (PrevTagDecl->getTagKind() != TTK_Enum &&
+               Kind != TTK_Enum);
           if (SafeToContinue)
             Diag(KWLoc, diag::err_use_with_wrong_tag)
               << Name
@@ -5296,7 +5297,7 @@
   // PrevDecl.
   TagDecl *New;
 
-  if (Kind == TagDecl::TK_enum) {
+  if (Kind == TTK_Enum) {
     // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
     // enum X { A, B, C } D;    D should chain to X.
     New = EnumDecl::Create(Context, SearchDC, Loc, Name, KWLoc,
@@ -5331,7 +5332,7 @@
     New->setQualifierInfo(NNS, SS.getRange());
   }
 
-  if (Kind != TagDecl::TK_enum) {
+  if (Kind != TTK_Enum) {
     // Handle #pragma pack: if the #pragma pack stack has non-default
     // alignment, make up a packed attribute for this decl. These
     // attributes are checked when the ASTContext lays out the

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue May 11 16:36:43 2010
@@ -150,7 +150,7 @@
     return false;
 
   const RecordDecl *RD = RT->getDecl();
-  if (RD->getTagKind() != TagDecl::TK_struct)
+  if (RD->getTagKind() != TTK_Struct)
     return false;
 
   return RD->getIdentifier() == &Ctx.Idents.get("__CFString");

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue May 11 16:36:43 2010
@@ -461,7 +461,7 @@
 
   if (BaseType->isDependentType())
     return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
-                                Class->getTagKind() == RecordDecl::TK_class,
+                                Class->getTagKind() == TTK_Class,
                                 Access, BaseType);
 
   // Base specifiers must be record types.
@@ -505,7 +505,7 @@
   
   // Create the base specifier.
   return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
-                              Class->getTagKind() == RecordDecl::TK_class,
+                              Class->getTagKind() == TTK_Class,
                               Access, BaseType);
 }
 
@@ -1191,7 +1191,7 @@
           static_cast<NestedNameSpecifier*>(SS.getScopeRep());
 
         // FIXME: preserve source range information
-        BaseType = Context.getQualifiedNameType(Qualifier, BaseType);
+        BaseType = Context.getElaboratedType(ETK_None, Qualifier, BaseType);
       }
     }
   }

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue May 11 16:36:43 2010
@@ -1173,7 +1173,7 @@
   if (!StdBadAlloc) {
     // The "std::bad_alloc" class has not yet been declared, so build it
     // implicitly.
-    StdBadAlloc = CXXRecordDecl::Create(Context, TagDecl::TK_class, 
+    StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class, 
                                         StdNamespace, 
                                         SourceLocation(), 
                                       &PP.getIdentifierTable().get("bad_alloc"), 

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue May 11 16:36:43 2010
@@ -2742,8 +2742,8 @@
       //    without a user-provided constructor, then the object is
       //    zero-initialized and, if T’s implicitly-declared default
       //    constructor is non-trivial, that constructor is called.
-      if ((ClassDecl->getTagKind() == TagDecl::TK_class ||
-           ClassDecl->getTagKind() == TagDecl::TK_struct) &&
+      if ((ClassDecl->getTagKind() == TTK_Class ||
+           ClassDecl->getTagKind() == TTK_Struct) &&
           !ClassDecl->hasTrivialConstructor()) {
         Sequence.AddZeroInitializationStep(Entity.getType());
         return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);        

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue May 11 16:36:43 2010
@@ -739,8 +739,8 @@
   if (CheckTemplateDeclScope(S, TemplateParams))
     return true;
 
-  TagDecl::TagKind Kind = TagDecl::getTagKindForTypeSpec(TagSpec);
-  assert(Kind != TagDecl::TK_enum && "can't build template of enumerated type");
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
+  assert(Kind != TTK_Enum && "can't build template of enumerated type");
 
   // There is no such thing as an unnamed class template.
   if (!Name) {
@@ -1568,7 +1568,7 @@
   QualType Type = GetTypeFromParser(TypeResult.get(), &DI);
 
   // Verify the tag specifier.
-  TagDecl::TagKind TagKind = TagDecl::getTagKindForTypeSpec(TagSpec);
+  TagTypeKind TagKind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
 
   if (const RecordType *RT = Type->getAs<RecordType>()) {
     RecordDecl *D = RT->getDecl();
@@ -1584,7 +1584,9 @@
     }
   }
 
-  QualType ElabType = Context.getElaboratedType(Type, TagKind);
+  ElaboratedTypeKeyword Keyword
+    = TypeWithKeyword::getKeywordForTagTypeKind(TagKind);
+  QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type);
 
   return ElabType.getAsOpaquePtr();
 }
@@ -3664,13 +3666,8 @@
 
   // Check that the specialization uses the same tag kind as the
   // original template.
-  TagDecl::TagKind Kind;
-  switch (TagSpec) {
-  default: assert(0 && "Unknown tag type!");
-  case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
-  case DeclSpec::TST_union:  Kind = TagDecl::TK_union; break;
-  case DeclSpec::TST_class:  Kind = TagDecl::TK_class; break;
-  }
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
+  assert(Kind != TTK_Enum && "Invalid enum tag in class template spec!");
   if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
                                     Kind, KWLoc,
                                     *ClassTemplate->getIdentifier())) {
@@ -4621,13 +4618,9 @@
 
   // Check that the specialization uses the same tag kind as the
   // original template.
-  TagDecl::TagKind Kind;
-  switch (TagSpec) {
-  default: assert(0 && "Unknown tag type!");
-  case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
-  case DeclSpec::TST_union:  Kind = TagDecl::TK_union; break;
-  case DeclSpec::TST_class:  Kind = TagDecl::TK_class; break;
-  }
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
+  assert(Kind != TTK_Enum &&
+         "Invalid enum tag in class template explicit instantiation!");
   if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
                                     Kind, KWLoc,
                                     *ClassTemplate->getIdentifier())) {
@@ -5173,23 +5166,16 @@
   if (!NNS)
     return true;
 
-  ElaboratedTypeKeyword Keyword = ETK_None;
-  switch (TagDecl::getTagKindForTypeSpec(TagSpec)) {
-  case TagDecl::TK_struct: Keyword = ETK_Struct; break;
-  case TagDecl::TK_class: Keyword = ETK_Class; break;
-  case TagDecl::TK_union: Keyword = ETK_Union; break;
-  case TagDecl::TK_enum: Keyword = ETK_Enum; break;
-  }
-  assert(Keyword != ETK_None && "Invalid tag kind!");
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
 
   if (TUK == TUK_Declaration || TUK == TUK_Definition) {
     Diag(NameLoc, diag::err_dependent_tag_decl)
-      << (TUK == TUK_Definition) << TagDecl::getTagKindForTypeSpec(TagSpec)
-      << SS.getRange();
+      << (TUK == TUK_Definition) << Kind << SS.getRange();
     return true;
   }
-  
-  return Context.getDependentNameType(Keyword, NNS, Name).getAsOpaquePtr();
+
+  ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind);
+  return Context.getDependentNameType(Kwd, NNS, Name).getAsOpaquePtr();
 }
 
 static void FillTypeLoc(DependentNameTypeLoc TL,
@@ -5199,7 +5185,7 @@
   TL.setNameLoc(TypenameLoc);
 }
 
-static void FillTypeLoc(QualifiedNameTypeLoc TL,
+static void FillTypeLoc(ElaboratedTypeLoc TL,
                         SourceLocation TypenameLoc,
                         SourceRange QualifierRange) {
   // FIXME: typename, qualifier range
@@ -5225,7 +5211,7 @@
     // FIXME: fill inner type loc
     FillTypeLoc(TL, TypenameLoc, SS.getRange());
   } else {
-    QualifiedNameTypeLoc TL = cast<QualifiedNameTypeLoc>(TSI->getTypeLoc());
+    ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
     // FIXME: fill inner type loc
     FillTypeLoc(TL, TypenameLoc, SS.getRange());
   }
@@ -5245,14 +5231,11 @@
 
   if (computeDeclContext(SS, false)) {
     // If we can compute a declaration context, then the "typename"
-    // keyword was superfluous. Just build a QualifiedNameType to keep
+    // keyword was superfluous. Just build an ElaboratedType to keep
     // track of the nested-name-specifier.
-
-    // FIXME: Note that the QualifiedNameType had the "typename" keyword!
-    
-    T = Context.getQualifiedNameType(NNS, T);
+    T = Context.getElaboratedType(ETK_Typename, NNS, T);
     TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
-    QualifiedNameTypeLoc TL = cast<QualifiedNameTypeLoc>(TSI->getTypeLoc());
+    ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
     // FIXME: fill inner type loc
     FillTypeLoc(TL, TypenameLoc, SS.getRange());
     return CreateLocInfoType(T, TSI).getAsOpaquePtr();
@@ -5309,10 +5292,10 @@
 
   case LookupResult::Found:
     if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
-      // We found a type. Build a QualifiedNameType, since the
-      // typename-specifier was just sugar. FIXME: Tell
-      // QualifiedNameType that it has a "typename" prefix.
-      return Context.getQualifiedNameType(NNS, Context.getTypeDeclType(Type));
+      // We found a type. Build an ElaboratedType, since the
+      // typename-specifier was just sugar.
+      return Context.getElaboratedType(ETK_Typename, NNS,
+                                       Context.getTypeDeclType(Type));
     }
 
     DiagID = diag::err_typename_nested_not_type;
@@ -5391,9 +5374,10 @@
 
     /// \brief Transforms a typename type by determining whether the type now
     /// refers to a member of the current instantiation, and then
-    /// type-checking and building a QualifiedNameType (when possible).
-    QualType TransformDependentNameType(TypeLocBuilder &TLB, DependentNameTypeLoc TL, 
-                                   QualType ObjectType);
+    /// type-checking and building an ElaboratedType (when possible).
+    QualType TransformDependentNameType(TypeLocBuilder &TLB,
+                                        DependentNameTypeLoc TL,
+                                        QualType ObjectType);
   };
 }
 
@@ -5422,7 +5406,7 @@
     Result = QualType(T, 0);
 
   // Rebuild the typename type, which will probably turn into a
-  // QualifiedNameType.
+  // ElaboratedType.
   else if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
     QualType NewTemplateId
       = TransformType(QualType(TemplateId, 0));
@@ -5471,7 +5455,7 @@
 /// Here, the type "typename X<T>::pointer" will be created as a DependentNameType,
 /// since we do not know that we can look into X<T> when we parsed the type.
 /// This function will rebuild the type, performing the lookup of "pointer"
-/// in X<T> and returning a QualifiedNameType whose canonical type is the same
+/// in X<T> and returning an ElaboratedType whose canonical type is the same
 /// as the canonical type of T*, allowing the return types of the out-of-line
 /// definition and the declaration to match.
 TypeSourceInfo *Sema::RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Tue May 11 16:36:43 2010
@@ -601,7 +601,8 @@
       
     /// \brief Check for tag mismatches when instantiating an
     /// elaborated type.
-    QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag);
+    QualType RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
+                                   NestedNameSpecifier *NNS, QualType T);
 
     Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E);
     Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E);
@@ -719,8 +720,9 @@
 }
 
 QualType
-TemplateInstantiator::RebuildElaboratedType(QualType T,
-                                            ElaboratedType::TagKind Tag) {
+TemplateInstantiator::RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
+                                            NestedNameSpecifier *NNS,
+                                            QualType T) {
   if (const TagType *TT = T->getAs<TagType>()) {
     TagDecl* TD = TT->getDecl();
 
@@ -732,16 +734,20 @@
 
     // TODO: should we even warn on struct/class mismatches for this?  Seems
     // like it's likely to produce a lot of spurious errors.
-    if (!SemaRef.isAcceptableTagRedeclaration(TD, Tag, TagLocation, *Id)) {
-      SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag)
-        << Id
-        << FixItHint::CreateReplacement(SourceRange(TagLocation),
-                                        TD->getKindName());
-      SemaRef.Diag(TD->getLocation(), diag::note_previous_use);
+    if (Keyword != ETK_None && Keyword != ETK_Typename) {
+      TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
+      if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, TagLocation, *Id)) {
+        SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag)
+          << Id
+          << FixItHint::CreateReplacement(SourceRange(TagLocation),
+                                          TD->getKindName());
+        SemaRef.Diag(TD->getLocation(), diag::note_previous_use);
+      }
     }
   }
 
-  return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(T, Tag);
+  return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(Keyword,
+                                                                    NNS, T);
 }
 
 Sema::OwningExprResult 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue May 11 16:36:43 2010
@@ -283,12 +283,11 @@
 
     // In C++, make an ElaboratedType.
     if (TheSema.getLangOptions().CPlusPlus) {
-      TagDecl::TagKind Tag
-        = TagDecl::getTagKindForTypeSpec(DS.getTypeSpecType());
-      Result = TheSema.getQualifiedNameType(DS.getTypeSpecScope(), Result);
-      Result = Context.getElaboratedType(Result, Tag);
+      ElaboratedTypeKeyword Keyword
+        = ElaboratedType::getKeywordForTypeSpec(DS.getTypeSpecType());
+      Result = TheSema.getElaboratedType(Keyword, DS.getTypeSpecScope(),
+                                         Result);
     }
-
     if (D->isInvalidDecl())
       TheDeclarator.setInvalidType(true);
     break;
@@ -995,10 +994,10 @@
       break;
     case Declarator::MemberContext:
       switch (cast<TagDecl>(CurContext)->getTagKind()) {
-      case TagDecl::TK_enum: assert(0 && "unhandled tag kind"); break;
-      case TagDecl::TK_struct: Error = 1; /* Struct member */ break;
-      case TagDecl::TK_union:  Error = 2; /* Union member */ break;
-      case TagDecl::TK_class:  Error = 3; /* Class member */ break;
+      case TTK_Enum: assert(0 && "unhandled tag kind"); break;
+      case TTK_Struct: Error = 1; /* Struct member */ break;
+      case TTK_Union:  Error = 2; /* Union member */ break;
+      case TTK_Class:  Error = 3; /* Class member */ break;
       }
       break;
     case Declarator::CXXCatchContext:
@@ -1301,7 +1300,7 @@
         case NestedNameSpecifier::TypeSpecWithTemplate:
           ClsType = QualType(NNS->getAsType(), 0);
           if (NNSPrefix)
-            ClsType = Context.getQualifiedNameType(NNSPrefix, ClsType);
+            ClsType = Context.getElaboratedType(ETK_None, NNSPrefix, ClsType);
           break;
         }
       } else {
@@ -2082,15 +2081,21 @@
                              std::make_pair(SourceLocation(), PDiag(0)));
 }
 
-/// \brief Retrieve a version of the type 'T' that is qualified by the
-/// nested-name-specifier contained in SS.
-QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) {
-  if (!SS.isSet() || SS.isInvalid() || T.isNull())
+/// \brief Retrieve a version of the type 'T' that is elaborated by Keyword
+/// and qualified by the nested-name-specifier contained in SS.
+QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword,
+                                 const CXXScopeSpec &SS, QualType T) {
+  if (T.isNull())
     return T;
-
-  NestedNameSpecifier *NNS
-    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
-  return Context.getQualifiedNameType(NNS, T);
+  NestedNameSpecifier *NNS;
+  if (SS.isSet() && !SS.isInvalid())
+    NNS = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  else {
+    if (Keyword == ETK_None)
+      return T;
+    NNS = 0;
+  }
+  return Context.getElaboratedType(Keyword, NNS, T);
 }
 
 QualType Sema::BuildTypeofExprType(Expr *E) {

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue May 11 16:36:43 2010
@@ -492,11 +492,6 @@
     return SemaRef.Context.getTypeDeclType(Enum);
   }
 
-  /// \brief Build a new elaborated type.
-  QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
-    return SemaRef.Context.getElaboratedType(T, Tag);
-  }
-
   /// \brief Build a new typeof(expr) type.
   ///
   /// By default, performs semantic analysis when building the typeof type.
@@ -525,11 +520,12 @@
 
   /// \brief Build a new qualified name type.
   ///
-  /// By default, builds a new QualifiedNameType type from the
-  /// nested-name-specifier and the named type. Subclasses may override
-  /// this routine to provide different behavior.
-  QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
-    return SemaRef.Context.getQualifiedNameType(NNS, Named);
+  /// By default, builds a new ElaboratedType type from the keyword,
+  /// the nested-name-specifier and the named type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
+                                 NestedNameSpecifier *NNS, QualType Named) {
+    return SemaRef.Context.getElaboratedType(Keyword, NNS, Named);
   }
 
   /// \brief Build a new typename type that refers to a template-id.
@@ -548,9 +544,8 @@
         return SemaRef.Context.getDependentNameType(Keyword, NNS,
                                           cast<TemplateSpecializationType>(T));
     }
-    
-    // FIXME: Handle elaborated-type-specifiers separately.
-    return SemaRef.Context.getQualifiedNameType(NNS, T);
+
+    return SemaRef.Context.getElaboratedType(Keyword, NNS, T);
   }
 
   /// \brief Build a new typename type that refers to an identifier.
@@ -571,19 +566,11 @@
         return SemaRef.Context.getDependentNameType(Keyword, NNS, Id);
     }
 
-    TagDecl::TagKind Kind = TagDecl::TK_enum;
-    switch (Keyword) {
-      case ETK_None:
-        // Fall through.
-      case ETK_Typename:
-        return SemaRef.CheckTypenameType(Keyword, NNS, *Id, SR);
-        
-      case ETK_Class: Kind = TagDecl::TK_class; break;
-      case ETK_Struct: Kind = TagDecl::TK_struct; break;
-      case ETK_Union: Kind = TagDecl::TK_union; break;
-      case ETK_Enum: Kind = TagDecl::TK_enum; break;
-    }
-    
+    if (Keyword == ETK_None || Keyword == ETK_Typename)
+      return SemaRef.CheckTypenameType(Keyword, NNS, *Id, SR);
+
+    TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
+
     // We had a dependent elaborated-type-specifier that as been transformed
     // into a non-dependent elaborated-type-specifier. Find the tag we're
     // referring to.
@@ -619,7 +606,7 @@
         << Kind << Id << DC;
       return QualType();
     }
-    
+
     // FIXME: Terrible location information
     if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, SR.getEnd(), *Id)) {
       SemaRef.Diag(SR.getBegin(), diag::err_use_with_wrong_tag) << Id;
@@ -629,8 +616,7 @@
 
     // Build the elaborated-type-specifier type.
     QualType T = SemaRef.Context.getTypeDeclType(Tag);
-    T = SemaRef.Context.getQualifiedNameType(NNS, T);
-    return SemaRef.Context.getElaboratedType(T, Kind);
+    return SemaRef.Context.getElaboratedType(Keyword, NNS, T);
   }
 
   /// \brief Build a new nested-name-specifier given the prefix and an
@@ -3146,31 +3132,6 @@
   return Result;
 }
 
-template <typename Derived>
-QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
-                                                         ElaboratedTypeLoc TL,
-                                                       QualType ObjectType) {
-  ElaboratedType *T = TL.getTypePtr();
-
-  // FIXME: this should be a nested type.
-  QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
-  if (Underlying.isNull())
-    return QualType();
-
-  QualType Result = TL.getType();
-  if (getDerived().AlwaysRebuild() ||
-      Underlying != T->getUnderlyingType()) {
-    Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
-    if (Result.isNull())
-      return QualType();
-  }
-
-  ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
-  NewTL.setNameLoc(TL.getNameLoc());
-
-  return Result;
-}
-
 template<typename Derived>
 QualType TreeTransform<Derived>::TransformInjectedClassNameType(
                                          TypeLocBuilder &TLB,
@@ -3275,16 +3236,20 @@
 
 template<typename Derived>
 QualType
-TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
-                                                   QualifiedNameTypeLoc TL,
-                                                   QualType ObjectType) {
-  QualifiedNameType *T = TL.getTypePtr();
-  NestedNameSpecifier *NNS
-    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
-                                                SourceRange(),
-                                                ObjectType);
-  if (!NNS)
-    return QualType();
+TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
+                                                ElaboratedTypeLoc TL,
+                                                QualType ObjectType) {
+  ElaboratedType *T = TL.getTypePtr();
+
+  NestedNameSpecifier *NNS = 0;
+  // NOTE: the qualifier in an ElaboratedType is optional.
+  if (T->getQualifier() != 0) {
+    NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
+                                                    SourceRange(),
+                                                    ObjectType);
+    if (!NNS)
+      return QualType();
+  }
 
   QualType Named = getDerived().TransformType(T->getNamedType());
   if (Named.isNull())
@@ -3294,12 +3259,12 @@
   if (getDerived().AlwaysRebuild() ||
       NNS != T->getQualifier() ||
       Named != T->getNamedType()) {
-    Result = getDerived().RebuildQualifiedNameType(NNS, Named);
+    Result = getDerived().RebuildElaboratedType(T->getKeyword(), NNS, Named);
     if (Result.isNull())
       return QualType();
   }
 
-  QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
+  ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());
 
   return Result;

Modified: cfe/trunk/tools/libclang/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexUSRs.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexUSRs.cpp Tue May 11 16:36:43 2010
@@ -314,10 +314,10 @@
   VisitDeclContext(D->getDeclContext());
 
   switch (D->getTagKind()) {
-    case TagDecl::TK_struct: Out << "@S"; break;
-    case TagDecl::TK_class:  Out << "@C"; break;
-    case TagDecl::TK_union:  Out << "@U"; break;
-    case TagDecl::TK_enum:   Out << "@E"; break;
+    case TTK_Struct: Out << "@S"; break;
+    case TTK_Class:  Out << "@C"; break;
+    case TTK_Union:  Out << "@U"; break;
+    case TTK_Enum:   Out << "@E"; break;
   }
 
   Out << '@';

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=103517&r1=103516&r2=103517&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Tue May 11 16:36:43 2010
@@ -60,10 +60,10 @@
     default:
       if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
         switch (TD->getTagKind()) {
-          case TagDecl::TK_struct: return CXCursor_StructDecl;
-          case TagDecl::TK_class:  return CXCursor_ClassDecl;
-          case TagDecl::TK_union:  return CXCursor_UnionDecl;
-          case TagDecl::TK_enum:   return CXCursor_EnumDecl;
+          case TTK_Struct: return CXCursor_StructDecl;
+          case TTK_Class:  return CXCursor_ClassDecl;
+          case TTK_Union:  return CXCursor_UnionDecl;
+          case TTK_Enum:   return CXCursor_EnumDecl;
         }
       }
 





More information about the cfe-commits mailing list