[cfe-commits] r129567 - in /cfe/trunk: include/clang-c/ include/clang/AST/ include/clang/Basic/ include/clang/Sema/ include/clang/Serialization/ lib/AST/ lib/CodeGen/ lib/Frontend/ lib/Index/ lib/Parse/ lib/Rewrite/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Checkers/ test/CXX/basic/basic.scope/basic.scope.pdecl/ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/ test/CXX/dcl.dcl/dcl.spec/dcl.typedef/ test/FixIt/ tools/libclang/

Richard Smith richard-llvm at metafoo.co.uk
Fri Apr 15 07:24:38 PDT 2011


Author: rsmith
Date: Fri Apr 15 09:24:37 2011
New Revision: 129567

URL: http://llvm.org/viewvc/llvm-project?rev=129567&view=rev
Log:
Support for C++11 (non-template) alias declarations.


Added:
    cfe/trunk/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
Modified:
    cfe/trunk/include/clang-c/Index.h
    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/Type.h
    cfe/trunk/include/clang/AST/TypeLoc.h
    cfe/trunk/include/clang/Basic/DeclNodes.td
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Sema/Template.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTDiagnostic.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/CXXInheritance.cpp
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/AST/DumpXML.cpp
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/lib/AST/StmtDumper.cpp
    cfe/trunk/lib/AST/StmtIterator.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/AST/TypePrinter.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/Frontend/ASTConsumers.cpp
    cfe/trunk/lib/Index/DeclReferenceMap.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Rewrite/RewriteObjC.cpp
    cfe/trunk/lib/Sema/JumpDiagnostics.cpp
    cfe/trunk/lib/Sema/SemaAccess.cpp
    cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    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/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Sema/TargetAttributesSema.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
    cfe/trunk/test/FixIt/fixit-cxx0x.cpp
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CIndexUSRs.cpp

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Fri Apr 15 09:24:37 2011
@@ -1101,10 +1101,12 @@
   CXCursor_NamespaceAlias                = 33,
   /** \brief A C++ using directive. */
   CXCursor_UsingDirective                = 34,
-  /** \brief A using declaration. */
+  /** \brief A C++ using declaration. */
   CXCursor_UsingDeclaration              = 35,
+  /** \brief A C++ alias declaration */
+  CXCursor_TypeAliasDecl                 = 36,
   CXCursor_FirstDecl                     = CXCursor_UnexposedDecl,
-  CXCursor_LastDecl                      = CXCursor_UsingDeclaration,
+  CXCursor_LastDecl                      = CXCursor_TypeAliasDecl,
 
   /* References */
   CXCursor_FirstRef                      = 40, /* Decl references */

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Apr 15 09:24:37 2011
@@ -71,7 +71,7 @@
   class TemplateTypeParmDecl;
   class TranslationUnitDecl;
   class TypeDecl;
-  class TypedefDecl;
+  class TypedefNameDecl;
   class UsingDecl;
   class UsingShadowDecl;
   class UnresolvedSetIterator;
@@ -664,9 +664,9 @@
   }
 
   /// getTypedefType - Return the unique reference to the type for the
-  /// specified typename decl.
-  QualType getTypedefType(const TypedefDecl *Decl, QualType Canon = QualType())
-    const;
+  /// specified typedef-name decl.
+  QualType getTypedefType(const TypedefNameDecl *Decl,
+                          QualType Canon = QualType()) const;
 
   QualType getRecordType(const RecordDecl *Decl) const;
 

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Apr 15 09:24:37 2011
@@ -1995,17 +1995,21 @@
 };
 
 
-class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
+/// Base class for declarations which introduce a typedef-name.
+class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
   /// UnderlyingType - This is the type the typedef is set to.
   TypeSourceInfo *TInfo;
 
-  TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
-              IdentifierInfo *Id, TypeSourceInfo *TInfo)
-    : TypeDecl(Typedef, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {}
-
 protected:
-  typedef Redeclarable<TypedefDecl> redeclarable_base;
-  virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+  TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+                  SourceLocation IdLoc, IdentifierInfo *Id,
+                  TypeSourceInfo *TInfo)
+    : TypeDecl(DK, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {}
+
+  typedef Redeclarable<TypedefNameDecl> redeclarable_base;
+  virtual TypedefNameDecl *getNextRedeclaration() {
+    return RedeclLink.getNext();
+  }
 
 public:
   typedef redeclarable_base::redecl_iterator redecl_iterator;
@@ -2016,19 +2020,15 @@
     return redeclarable_base::redecls_end();
   }
 
-  static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
-                             SourceLocation StartLoc, SourceLocation IdLoc,
-                             IdentifierInfo *Id, TypeSourceInfo *TInfo);
-
   TypeSourceInfo *getTypeSourceInfo() const {
     return TInfo;
   }
 
-  /// Retrieves the canonical declaration of this typedef.
-  TypedefDecl *getCanonicalDecl() {
+  /// Retrieves the canonical declaration of this typedef-name.
+  TypedefNameDecl *getCanonicalDecl() {
     return getFirstDeclaration();
   }
-  const TypedefDecl *getCanonicalDecl() const {
+  const TypedefNameDecl *getCanonicalDecl() const {
     return getFirstDeclaration();
   }
 
@@ -2039,6 +2039,26 @@
     TInfo = newType;
   }
 
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const TypedefNameDecl *D) { return true; }
+  static bool classofKind(Kind K) {
+    return K >= firstTypedefName && K <= lastTypedefName;
+  }
+};
+
+/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
+/// type specifier.
+class TypedefDecl : public TypedefNameDecl {
+  TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
+              IdentifierInfo *Id, TypeSourceInfo *TInfo)
+    : TypedefNameDecl(Typedef, DC, StartLoc, IdLoc, Id, TInfo) {}
+
+public:
+  static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
+                             SourceLocation StartLoc, SourceLocation IdLoc,
+                             IdentifierInfo *Id, TypeSourceInfo *TInfo);
+
   SourceRange getSourceRange() const;
 
   // Implement isa/cast/dyncast/etc.
@@ -2047,6 +2067,26 @@
   static bool classofKind(Kind K) { return K == Typedef; }
 };
 
+/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
+/// alias-declaration.
+class TypeAliasDecl : public TypedefNameDecl {
+  TypeAliasDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
+                IdentifierInfo *Id, TypeSourceInfo *TInfo)
+    : TypedefNameDecl(TypeAlias, DC, StartLoc, IdLoc, Id, TInfo) {}
+
+public:
+  static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
+                               SourceLocation StartLoc, SourceLocation IdLoc,
+                               IdentifierInfo *Id, TypeSourceInfo *TInfo);
+
+  SourceRange getSourceRange() const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const TypeAliasDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == TypeAlias; }
+};
+
 /// TagDecl - Represents the declaration of a struct/union/class/enum.
 class TagDecl
   : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
@@ -2096,17 +2136,17 @@
   // to be used for the (uncommon) case of out-of-line declarations.
   typedef QualifierInfo ExtInfo;
 
-  /// TypedefDeclOrQualifier - If the (out-of-line) tag declaration name
+  /// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name
   /// is qualified, it points to the qualifier info (nns and range);
   /// otherwise, if the tag declaration is anonymous and it is part of
-  /// a typedef, it points to the TypedefDecl (used for mangling);
-  /// otherwise, it is a null (TypedefDecl) pointer.
-  llvm::PointerUnion<TypedefDecl*, ExtInfo*> TypedefDeclOrQualifier;
+  /// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
+  /// otherwise, it is a null (TypedefNameDecl) pointer.
+  llvm::PointerUnion<TypedefNameDecl*, ExtInfo*> TypedefNameDeclOrQualifier;
 
-  bool hasExtInfo() const { return TypedefDeclOrQualifier.is<ExtInfo*>(); }
-  ExtInfo *getExtInfo() { return TypedefDeclOrQualifier.get<ExtInfo*>(); }
+  bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo*>(); }
+  ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo*>(); }
   const ExtInfo *getExtInfo() const {
-    return TypedefDeclOrQualifier.get<ExtInfo*>();
+    return TypedefNameDeclOrQualifier.get<ExtInfo*>();
   }
 
 protected:
@@ -2114,7 +2154,7 @@
           SourceLocation L, IdentifierInfo *Id,
           TagDecl *PrevDecl, SourceLocation StartL)
     : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK),
-      TypedefDeclOrQualifier((TypedefDecl*) 0) {
+      TypedefNameDeclOrQualifier((TypedefNameDecl*) 0) {
     assert((DK != Enum || TK == TTK_Enum) &&
            "EnumDecl not matched with TTK_Enum");
     TagDeclKind = TK;
@@ -2219,11 +2259,11 @@
   bool isUnion()  const { return getTagKind() == TTK_Union; }
   bool isEnum()   const { return getTagKind() == TTK_Enum; }
 
-  TypedefDecl *getTypedefForAnonDecl() const {
-    return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
+  TypedefNameDecl *getTypedefNameForAnonDecl() const {
+    return hasExtInfo() ? 0 : TypedefNameDeclOrQualifier.get<TypedefNameDecl*>();
   }
 
-  void setTypedefForAnonDecl(TypedefDecl *TDD);
+  void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
 
   /// \brief Retrieve the nested-name-specifier that qualifies the name of this
   /// declaration, if it was present in the source.

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Apr 15 09:24:37 2011
@@ -1357,6 +1357,13 @@
     // source.
   })
 
+DEF_TRAVERSE_DECL(TypeAliasDecl, {
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+    // We shouldn't traverse D->getTypeForDecl(); it's a result of
+    // declaring the type alias, not something that was written in the
+    // source.
+  })
+
 DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
     // A dependent using declaration which was marked with 'typename'.
     //   template<class T> class A : public B<T> { using typename B<T>::foo; };

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Apr 15 09:24:37 2011
@@ -73,7 +73,7 @@
 
 namespace clang {
   class ASTContext;
-  class TypedefDecl;
+  class TypedefNameDecl;
   class TemplateDecl;
   class TemplateTypeParmDecl;
   class NonTypeTemplateParmDecl;
@@ -2625,18 +2625,18 @@
 
 
 class TypedefType : public Type {
-  TypedefDecl *Decl;
+  TypedefNameDecl *Decl;
 protected:
-  TypedefType(TypeClass tc, const TypedefDecl *D, QualType can)
+  TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
     : Type(tc, can, can->isDependentType(), can->isVariablyModifiedType(), 
            /*ContainsUnexpandedParameterPack=*/false),
-      Decl(const_cast<TypedefDecl*>(D)) {
+      Decl(const_cast<TypedefNameDecl*>(D)) {
     assert(!isa<TypedefType>(can) && "Invalid canonical type");
   }
   friend class ASTContext;  // ASTContext creates these.
 public:
 
-  TypedefDecl *getDecl() const { return Decl; }
+  TypedefNameDecl *getDecl() const { return Decl; }
 
   bool isSugared() const { return true; }
   QualType desugar() const;

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Fri Apr 15 09:24:37 2011
@@ -527,7 +527,7 @@
                                                         TypedefTypeLoc,
                                                         TypedefType> {
 public:
-  TypedefDecl *getTypedefDecl() const {
+  TypedefNameDecl *getTypedefNameDecl() const {
     return getTypePtr()->getDecl();
   }
 };

Modified: cfe/trunk/include/clang/Basic/DeclNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DeclNodes.td (original)
+++ cfe/trunk/include/clang/Basic/DeclNodes.td Fri Apr 15 09:24:37 2011
@@ -17,7 +17,9 @@
   def NamespaceAlias : DDecl<Named>;
   def Label : DDecl<Named>;
   def Type : DDecl<Named, 1>;
-    def Typedef : DDecl<Type>;
+    def TypedefName : DDecl<Type, 1>;
+      def Typedef : DDecl<TypedefName>;
+      def TypeAlias : DDecl<TypedefName>;
     def UnresolvedUsingTypename : DDecl<Type>;
     def Tag : DDecl<Type, 1>, DeclContext;
       def Enum : DDecl<Tag>;

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Fri Apr 15 09:24:37 2011
@@ -430,6 +430,12 @@
 def warn_deleted_function_accepted_as_extension: ExtWarn<
   "deleted function definition accepted as a C++0x extension">, InGroup<CXX0x>;
 
+// C++0x alias-declaration
+def ext_alias_declaration : ExtWarn<
+  "alias declarations accepted as a C++0x extension">, InGroup<CXX0x>;
+def err_alias_declaration_not_identifier : Error<
+  "name defined in alias declaration must be an identifier">;
+    
 // C++0x override control
 def ext_override_control_keyword : Extension<
   "'%0' keyword accepted as a C++0x extension">, InGroup<CXX0x>;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Apr 15 09:24:37 2011
@@ -545,7 +545,7 @@
   
 // C++ exception specifications
 def err_exception_spec_in_typedef : Error<
-  "exception specifications are not allowed in typedefs">;
+  "exception specifications are not allowed in %select{typedefs|type aliases}0">;
 def err_distant_exception_spec : Error<
   "exception specifications are not allowed beyond a single level "
   "of indirection">;
@@ -795,7 +795,7 @@
 def err_destructor_with_params : Error<"destructor cannot have any parameters">;
 def err_destructor_variadic : Error<"destructor cannot be variadic">;
 def err_destructor_typedef_name : Error<
-  "destructor cannot be declared using a typedef %0 of the class name">;
+  "destructor cannot be declared using a %select{typedef|type alias}1 %0 of the class name">;
 def err_destructor_name : Error<
   "expected the class name after '~' to name the enclosing class">;
 def err_destructor_class_name : Error<
@@ -932,7 +932,7 @@
   "'auto' not allowed %select{in function prototype|in struct member"
   "|in union member|in class member|in exception declaration"
   "|in template parameter|in block literal|in template argument"
-  "|in typedef|in function return type|here}0">;
+  "|in typedef|in type alias|in function return type|here}0">;
 def err_auto_var_requires_init : Error<
   "declaration of variable %0 with type %1 requires an initializer">;
 def err_auto_new_requires_ctor_arg : Error<
@@ -1321,7 +1321,7 @@
 def ext_param_not_declared : Extension<
   "parameter %0 was not declared, defaulting to type 'int'">;
 def err_param_typedef_of_void : Error<
-  "empty parameter list defined with a typedef of 'void' not allowed in C++">;
+  "empty parameter list defined with a %select{typedef|type alias}0 of 'void' not allowed%select{ in C++|}0">;
 def err_param_default_argument : Error<
   "C does not support default arguments">;
 def err_param_default_argument_redefinition : Error<
@@ -2133,17 +2133,17 @@
 def err_redefinition_different_kind : Error<
   "redefinition of %0 as different kind of symbol">;
 def err_redefinition_different_typedef : Error<
-  "typedef redefinition with different types (%0 vs %1)">;
+  "%select{typedef|type alias}0 redefinition with different types (%1 vs %2)">;
 def err_tag_reference_non_tag : Error<
-  "elaborated type refers to %select{a non-tag type|a typedef|a template}0">;
+  "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template}0">;
 def err_tag_reference_conflict : Error<
   "implicit declaration introduced by elaborated type conflicts with "
-  "%select{a declaration|a typedef|a template}0 of the same name">;
+  "%select{a declaration|a typedef|a type alias|a template}0 of the same name">;
 def err_dependent_tag_decl : Error<
   "%select{declaration|definition}0 of %select{struct|union|class|enum}1 "
   "in a dependent scope">;
 def err_tag_definition_of_typedef : Error<
-  "definition of type %0 conflicts with typedef of the same name">;
+  "definition of type %0 conflicts with %select{typedef|type alias}1 of the same name">;
 def err_conflicting_types : Error<"conflicting types for %0">;
 def err_nested_redefinition : Error<"nested redefinition of %0">;
 def err_use_with_wrong_tag : Error<
@@ -2295,6 +2295,8 @@
   "jump bypasses initialization of variable with __attribute__((cleanup))">;
 def note_protected_by_vla_typedef : Note<
   "jump bypasses initialization of VLA typedef">;
+def note_protected_by_vla_type_alias : Note<
+  "jump bypasses initialization of VLA type alias">;
 def note_protected_by_vla : Note<
   "jump bypasses initialization of variable length array">;
 def note_protected_by_objc_try : Note<

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Fri Apr 15 09:24:37 2011
@@ -1325,7 +1325,8 @@
     TemplateParamContext,// Within a template parameter list.
     CXXCatchContext,     // C++ catch exception-declaration
     BlockLiteralContext,  // Block literal declarator.
-    TemplateTypeArgContext // Template type argument.
+    TemplateTypeArgContext, // Template type argument.
+    AliasDeclContext     // C++0x alias-declaration.
   };
 
 private:
@@ -1466,6 +1467,7 @@
       return false;
 
     case TypeNameContext:
+    case AliasDeclContext:
     case PrototypeContext:
     case ObjCPrototypeContext:
     case TemplateParamContext:
@@ -1494,6 +1496,7 @@
       return true;
 
     case TypeNameContext:
+    case AliasDeclContext:
     case ObjCPrototypeContext:
     case BlockLiteralContext:
     case TemplateTypeArgContext:
@@ -1521,6 +1524,7 @@
     case TemplateParamContext:
     case CXXCatchContext:
     case TypeNameContext:
+    case AliasDeclContext:
     case BlockLiteralContext:
     case TemplateTypeArgContext:
       return false;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Apr 15 09:24:37 2011
@@ -128,7 +128,9 @@
   class TemplatePartialOrderingContext;
   class TemplateTemplateParmDecl;
   class Token;
+  class TypeAliasDecl;
   class TypedefDecl;
+  class TypedefNameDecl;
   class TypeLoc;
   class UnqualifiedId;
   class UnresolvedLookupExpr;
@@ -255,7 +257,7 @@
   /// ExtVectorDecls - This is a list all the extended vector types. This allows
   /// us to associate a raw vector type with one of the ext_vector type names.
   /// This is only necessary for issuing pretty diagnostics.
-  llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
+  llvm::SmallVector<TypedefNameDecl*, 24> ExtVectorDecls;
 
   /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
   llvm::OwningPtr<CXXFieldCollector> FieldCollector;
@@ -814,6 +816,7 @@
   void RegisterLocallyScopedExternCDecl(NamedDecl *ND,
                                         const LookupResult &Previous,
                                         Scope *S);
+  bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   void DiagnoseFunctionSpecifiers(Declarator& D);
   void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
   void CheckShadow(Scope *S, VarDecl *D);
@@ -821,6 +824,8 @@
   NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                                     QualType R, TypeSourceInfo *TInfo,
                                     LookupResult &Previous, bool &Redeclaration);
+  NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D,
+                                  LookupResult &Previous, bool &Redeclaration);
   NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                                      QualType R, TypeSourceInfo *TInfo,
                                      LookupResult &Previous,
@@ -1076,7 +1081,7 @@
   /// Subroutines of ActOnDeclarator().
   TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
                                 TypeSourceInfo *TInfo);
-  void MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls);
+  void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls);
   bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
   bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
   void mergeObjCMethodDecls(ObjCMethodDecl *New, const ObjCMethodDecl *Old);
@@ -2309,6 +2314,11 @@
                               AttributeList *AttrList,
                               bool IsTypeName,
                               SourceLocation TypenameLoc);
+  Decl *ActOnAliasDeclaration(Scope *CurScope,
+                              AccessSpecifier AS,
+                              SourceLocation UsingLoc,
+                              UnqualifiedId &Name,
+                              TypeResult Type);
 
   /// AddCXXDirectInitializerToDecl - This action is called immediately after
   /// ActOnDeclarator, when a C++ direct initializer is present.

Modified: cfe/trunk/include/clang/Sema/Template.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Template.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Template.h (original)
+++ cfe/trunk/include/clang/Sema/Template.h Fri Apr 15 09:24:37 2011
@@ -335,7 +335,9 @@
     Decl *VisitLabelDecl(LabelDecl *D);
     Decl *VisitNamespaceDecl(NamespaceDecl *D);
     Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
+    Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
     Decl *VisitTypedefDecl(TypedefDecl *D);
+    Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
     Decl *VisitVarDecl(VarDecl *D);
     Decl *VisitAccessSpecDecl(AccessSpecDecl *D);
     Decl *VisitFieldDecl(FieldDecl *D);

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Apr 15 09:24:37 2011
@@ -642,6 +642,8 @@
       DECL_TRANSLATION_UNIT = 50,
       /// \brief A TypedefDecl record.
       DECL_TYPEDEF,
+      /// \brief A TypeAliasDecl record.
+      DECL_TYPEALIAS,
       /// \brief An EnumDecl record.
       DECL_ENUM,
       /// \brief A RecordDecl record.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Apr 15 09:24:37 2011
@@ -907,7 +907,7 @@
     return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr());
 
   case Type::Typedef: {
-    const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
+    const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl();
     std::pair<uint64_t, unsigned> Info
       = getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
     // If the typedef has an aligned attribute on it, it overrides any computed
@@ -2032,7 +2032,7 @@
   assert(Decl && "Passed null for Decl param");
   assert(!Decl->TypeForDecl && "TypeForDecl present in slow case");
 
-  if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
+  if (const TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Decl))
     return getTypedefType(Typedef);
 
   assert(!isa<TemplateTypeParmDecl>(Decl) &&
@@ -2059,9 +2059,10 @@
 }
 
 /// getTypedefType - Return the unique reference to the type for the
-/// specified typename decl.
+/// specified typedef name decl.
 QualType
-ASTContext::getTypedefType(const TypedefDecl *Decl, QualType Canonical) const {
+ASTContext::getTypedefType(const TypedefNameDecl *Decl,
+                           QualType Canonical) const {
   if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
 
   if (Canonical.isNull())
@@ -4577,7 +4578,7 @@
 ///
 bool ASTContext::isObjCNSObjectType(QualType Ty) const {
   if (const TypedefType *TDT = dyn_cast<TypedefType>(Ty)) {
-    if (TypedefDecl *TD = TDT->getDecl())
+    if (TypedefNameDecl *TD = TDT->getDecl())
       if (TD->getAttr<ObjCNSObjectAttr>())
         return true;
   }

Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Fri Apr 15 09:24:37 2011
@@ -100,7 +100,7 @@
     // Don't desugar through the primary typedef of an anonymous type.
     if (const TagType *UTT = Underlying->getAs<TagType>())
       if (const TypedefType *QTT = dyn_cast<TypedefType>(QT))
-        if (UTT->getDecl()->getTypedefForAnonDecl() == QTT->getDecl())
+        if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl())
           break;
 
     // Record that we actually looked through an opaque type here.

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Fri Apr 15 09:24:37 2011
@@ -97,7 +97,9 @@
     bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
     Decl *VisitDecl(Decl *D);
     Decl *VisitNamespaceDecl(NamespaceDecl *D);
+    Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
     Decl *VisitTypedefDecl(TypedefDecl *D);
+    Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
     Decl *VisitEnumDecl(EnumDecl *D);
     Decl *VisitRecordDecl(RecordDecl *D);
     Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
@@ -1194,11 +1196,11 @@
       if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
         // Check for equivalent structure names.
         IdentifierInfo *Name1 = Record1->getIdentifier();
-        if (!Name1 && Record1->getTypedefForAnonDecl())
-          Name1 = Record1->getTypedefForAnonDecl()->getIdentifier();
+        if (!Name1 && Record1->getTypedefNameForAnonDecl())
+          Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
         IdentifierInfo *Name2 = Record2->getIdentifier();
-        if (!Name2 && Record2->getTypedefForAnonDecl())
-          Name2 = Record2->getTypedefForAnonDecl()->getIdentifier();
+        if (!Name2 && Record2->getTypedefNameForAnonDecl())
+          Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
         if (!::IsStructurallyEquivalent(Name1, Name2) ||
             !::IsStructurallyEquivalent(*this, Record1, Record2))
           Equivalent = false;
@@ -1210,11 +1212,11 @@
       if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
         // Check for equivalent enum names.
         IdentifierInfo *Name1 = Enum1->getIdentifier();
-        if (!Name1 && Enum1->getTypedefForAnonDecl())
-          Name1 = Enum1->getTypedefForAnonDecl()->getIdentifier();
+        if (!Name1 && Enum1->getTypedefNameForAnonDecl())
+          Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
         IdentifierInfo *Name2 = Enum2->getIdentifier();
-        if (!Name2 && Enum2->getTypedefForAnonDecl())
-          Name2 = Enum2->getTypedefForAnonDecl()->getIdentifier();
+        if (!Name2 && Enum2->getTypedefNameForAnonDecl())
+          Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
         if (!::IsStructurallyEquivalent(Name1, Name2) ||
             !::IsStructurallyEquivalent(*this, Enum1, Enum2))
           Equivalent = false;
@@ -1222,8 +1224,8 @@
         // Enum/non-enum mismatch
         Equivalent = false;
       }
-    } else if (TypedefDecl *Typedef1 = dyn_cast<TypedefDecl>(D1)) {
-      if (TypedefDecl *Typedef2 = dyn_cast<TypedefDecl>(D2)) {
+    } else if (TypedefNameDecl *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
+      if (TypedefNameDecl *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
         if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
                                         Typedef2->getIdentifier()) ||
             !::IsStructurallyEquivalent(*this,
@@ -1536,8 +1538,8 @@
 }
 
 QualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
-  TypedefDecl *ToDecl
-                 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
+  TypedefNameDecl *ToDecl
+             = dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl()));
   if (!ToDecl)
     return QualType();
   
@@ -1995,7 +1997,7 @@
   return ToNamespace;
 }
 
-Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
+Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
   // Import the major distinguishing characteristics of this typedef.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
@@ -2014,7 +2016,8 @@
          ++Lookup.first) {
       if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
         continue;
-      if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
+      if (TypedefNameDecl *FoundTypedef =
+            dyn_cast<TypedefNameDecl>(*Lookup.first)) {
         if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
                                             FoundTypedef->getUnderlyingType()))
           return Importer.Imported(D, FoundTypedef);
@@ -2040,10 +2043,17 @@
   // Create the new typedef node.
   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   SourceLocation StartL = Importer.Import(D->getLocStart());
-  TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
-                                               StartL, Loc,
-                                               Name.getAsIdentifierInfo(),
-                                               TInfo);
+  TypedefNameDecl *ToTypedef;
+  if (IsAlias)
+    ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
+                                    StartL, Loc,
+                                    Name.getAsIdentifierInfo(),
+                                    TInfo);
+  else
+    ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC,
+                                  StartL, Loc,
+                                  Name.getAsIdentifierInfo(),
+                                  TInfo);
   ToTypedef->setAccess(D->getAccess());
   ToTypedef->setLexicalDeclContext(LexicalDC);
   Importer.Imported(D, ToTypedef);
@@ -2052,6 +2062,14 @@
   return ToTypedef;
 }
 
+Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
+  return VisitTypedefNameDecl(D, /*IsAlias=*/false);
+}
+
+Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
+  return VisitTypedefNameDecl(D, /*IsAlias=*/true);
+}
+
 Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
   // Import the major distinguishing characteristics of this enum.
   DeclContext *DC, *LexicalDC;
@@ -2063,8 +2081,8 @@
   // Figure out what enum name we're looking for.
   unsigned IDNS = Decl::IDNS_Tag;
   DeclarationName SearchName = Name;
-  if (!SearchName && D->getTypedefForAnonDecl()) {
-    SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
+  if (!SearchName && D->getTypedefNameForAnonDecl()) {
+    SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
     IDNS = Decl::IDNS_Ordinary;
   } else if (Importer.getToContext().getLangOptions().CPlusPlus)
     IDNS |= Decl::IDNS_Ordinary;
@@ -2079,7 +2097,7 @@
         continue;
       
       Decl *Found = *Lookup.first;
-      if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
+      if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
         if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
           Found = Tag->getDecl();
       }
@@ -2164,8 +2182,8 @@
   // Figure out what structure name we're looking for.
   unsigned IDNS = Decl::IDNS_Tag;
   DeclarationName SearchName = Name;
-  if (!SearchName && D->getTypedefForAnonDecl()) {
-    SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
+  if (!SearchName && D->getTypedefNameForAnonDecl()) {
+    SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
     IDNS = Decl::IDNS_Ordinary;
   } else if (Importer.getToContext().getLangOptions().CPlusPlus)
     IDNS |= Decl::IDNS_Ordinary;
@@ -2181,7 +2199,7 @@
         continue;
       
       Decl *Found = *Lookup.first;
-      if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
+      if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
         if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
           Found = Tag->getDecl();
       }
@@ -3997,19 +4015,19 @@
   
   if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
     // Keep track of anonymous tags that have an associated typedef.
-    if (FromTag->getTypedefForAnonDecl())
+    if (FromTag->getTypedefNameForAnonDecl())
       AnonTagsWithPendingTypedefs.push_back(FromTag);
-  } else if (TypedefDecl *FromTypedef = dyn_cast<TypedefDecl>(FromD)) {
+  } else if (TypedefNameDecl *FromTypedef = dyn_cast<TypedefNameDecl>(FromD)) {
     // When we've finished transforming a typedef, see whether it was the
     // typedef for an anonymous tag.
     for (llvm::SmallVector<TagDecl *, 4>::iterator
                FromTag = AnonTagsWithPendingTypedefs.begin(), 
             FromTagEnd = AnonTagsWithPendingTypedefs.end();
          FromTag != FromTagEnd; ++FromTag) {
-      if ((*FromTag)->getTypedefForAnonDecl() == FromTypedef) {
+      if ((*FromTag)->getTypedefNameForAnonDecl() == FromTypedef) {
         if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
           // We found the typedef for an anonymous tag; link them.
-          ToTag->setTypedefForAnonDecl(cast<TypedefDecl>(ToD));
+          ToTag->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToD));
           AnonTagsWithPendingTypedefs.erase(FromTag);
           break;
         }

Modified: cfe/trunk/lib/AST/CXXInheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXInheritance.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CXXInheritance.cpp (original)
+++ cfe/trunk/lib/AST/CXXInheritance.cpp Fri Apr 15 09:24:37 2011
@@ -415,7 +415,7 @@
        Path.Decls.first != Path.Decls.second;
        ++Path.Decls.first) {
     // FIXME: Refactor the "is it a nested-name-specifier?" check
-    if (isa<TypedefDecl>(*Path.Decls.first) ||
+    if (isa<TypedefNameDecl>(*Path.Decls.first) ||
         (*Path.Decls.first)->isInIdentifierNamespace(IDNS_Tag))
       return true;
   }

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Apr 15 09:24:37 2011
@@ -405,7 +405,7 @@
   //       has the typedef name for linkage purposes (7.1.3); or
   } else if (const TagDecl *Tag = dyn_cast<TagDecl>(D)) {
     // Unnamed tags have no linkage.
-    if (!Tag->getDeclName() && !Tag->getTypedefForAnonDecl())
+    if (!Tag->getDeclName() && !Tag->getTypedefNameForAnonDecl())
       return LinkageInfo::none();
 
     // If this is a class template specialization, consider the
@@ -477,7 +477,7 @@
         isa<VarDecl>(D) ||
         isa<FieldDecl>(D) ||
         (isa<TagDecl>(D) &&
-         (D->getDeclName() || cast<TagDecl>(D)->getTypedefForAnonDecl()))))
+         (D->getDeclName() || cast<TagDecl>(D)->getTypedefNameForAnonDecl()))))
     return LinkageInfo::none();
 
   LinkageInfo LV;
@@ -2082,8 +2082,8 @@
   return getFirstDeclaration();
 }
 
-void TagDecl::setTypedefForAnonDecl(TypedefDecl *TDD) { 
-  TypedefDeclOrQualifier = TDD; 
+void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { 
+  TypedefNameDeclOrQualifier = TDD; 
   if (TypeForDecl)
     const_cast<Type*>(TypeForDecl)->ClearLinkageCache();
   ClearLinkageCache();
@@ -2131,7 +2131,7 @@
   if (QualifierLoc) {
     // Make sure the extended qualifier info is allocated.
     if (!hasExtInfo())
-      TypedefDeclOrQualifier = new (getASTContext()) ExtInfo;
+      TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo;
     // Set qualifier info.
     getExtInfo()->QualifierLoc = QualifierLoc;
   }
@@ -2140,7 +2140,7 @@
     if (hasExtInfo()) {
       if (getExtInfo()->NumTemplParamLists == 0) {
         getASTContext().Deallocate(getExtInfo());
-        TypedefDeclOrQualifier = (TypedefDecl*) 0;
+        TypedefNameDeclOrQualifier = (TypedefNameDecl*) 0;
       }
       else
         getExtInfo()->QualifierLoc = QualifierLoc;
@@ -2155,7 +2155,7 @@
   // Make sure the extended decl info is allocated.
   if (!hasExtInfo())
     // Allocate external info struct.
-    TypedefDeclOrQualifier = new (getASTContext()) ExtInfo;
+    TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo;
   // Set the template parameter lists info.
   getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
 }
@@ -2393,6 +2393,13 @@
   return new (C) TypedefDecl(DC, StartLoc, IdLoc, Id, TInfo);
 }
 
+TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC,
+                                     SourceLocation StartLoc,
+                                     SourceLocation IdLoc, IdentifierInfo *Id,
+                                     TypeSourceInfo *TInfo) {
+  return new (C) TypeAliasDecl(DC, StartLoc, IdLoc, Id, TInfo);
+}
+
 SourceRange TypedefDecl::getSourceRange() const {
   SourceLocation RangeEnd = getLocation();
   if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
@@ -2402,6 +2409,13 @@
   return SourceRange(getLocStart(), RangeEnd);
 }
 
+SourceRange TypeAliasDecl::getSourceRange() const {
+  SourceLocation RangeEnd = getLocStart();
+  if (TypeSourceInfo *TInfo = getTypeSourceInfo())
+    RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd();
+  return SourceRange(getLocStart(), RangeEnd);
+}
+
 FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
                                            StringLiteral *Str,
                                            SourceLocation AsmLoc,

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Apr 15 09:24:37 2011
@@ -427,6 +427,7 @@
       return IDNS_Ordinary | IDNS_Type;
 
     case Typedef:
+    case TypeAlias:
     case UnresolvedUsingTypename:
     case TemplateTypeParm:
       return IDNS_Ordinary | IDNS_Type;

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Fri Apr 15 09:24:37 2011
@@ -45,6 +45,7 @@
 
     void VisitTranslationUnitDecl(TranslationUnitDecl *D);
     void VisitTypedefDecl(TypedefDecl *D);
+    void VisitTypeAliasDecl(TypeAliasDecl *D);
     void VisitEnumDecl(EnumDecl *D);
     void VisitRecordDecl(RecordDecl *D);
     void VisitEnumConstantDecl(EnumConstantDecl *D);
@@ -110,7 +111,7 @@
 }
 
 static QualType getDeclType(Decl* D) {
-  if (TypedefDecl* TDD = dyn_cast<TypedefDecl>(D))
+  if (TypedefNameDecl* TDD = dyn_cast<TypedefNameDecl>(D))
     return TDD->getUnderlyingType();
   if (ValueDecl* VD = dyn_cast<ValueDecl>(D))
     return VD->getType();
@@ -308,6 +309,11 @@
   Out << S;
 }
 
+void DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) {
+  Out << "using " << D->getNameAsString() << " = "
+      << D->getUnderlyingType().getAsString(Policy);
+}
+
 void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
   Out << "enum ";
   if (D->isScoped()) {

Modified: cfe/trunk/lib/AST/DumpXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DumpXML.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DumpXML.cpp (original)
+++ cfe/trunk/lib/AST/DumpXML.cpp Fri Apr 15 09:24:37 2011
@@ -543,12 +543,20 @@
 
   // TypedefDecl
   void visitTypedefDeclAttrs(TypedefDecl *D) {
-    visitRedeclarableAttrs(D);
+    visitRedeclarableAttrs<TypedefNameDecl>(D);
   }
   void visitTypedefDeclChildren(TypedefDecl *D) {
     dispatch(D->getTypeSourceInfo()->getTypeLoc());
   }
 
+  // TypeAliasDecl
+  void visitTypeAliasDeclAttrs(TypeAliasDecl *D) {
+    visitRedeclarableAttrs<TypedefNameDecl>(D);
+  }
+  void visitTypeAliasDeclChildren(TypeAliasDecl *D) {
+    dispatch(D->getTypeSourceInfo()->getTypeLoc());
+  }
+
   // TagDecl
   void visitTagDeclAttrs(TagDecl *D) {
     visitRedeclarableAttrs(D);

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Fri Apr 15 09:24:37 2011
@@ -748,7 +748,7 @@
     
     // We must have an anonymous struct.
     const TagDecl *TD = cast<TagDecl>(ND);
-    if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) {
+    if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
       assert(TD->getDeclContext() == D->getDeclContext() &&
              "Typedef should not be in another decl context!");
       assert(D->getDeclName().getAsIdentifierInfo() &&

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Fri Apr 15 09:24:37 2011
@@ -314,7 +314,7 @@
       
       // We must have an anonymous struct.
       const TagDecl *TD = cast<TagDecl>(ND);
-      if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) {
+      if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
         assert(TD->getDeclContext() == D->getDeclContext() &&
                "Typedef should not be in another decl context!");
         assert(D->getDeclName().getAsIdentifierInfo() &&

Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Fri Apr 15 09:24:37 2011
@@ -236,6 +236,9 @@
   if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
     OS << "\"typedef " << localType->getUnderlyingType().getAsString()
        << ' ' << localType << '"';
+  } else if (TypeAliasDecl *localType = dyn_cast<TypeAliasDecl>(D)) {
+    OS << "\"using " << localType << " = "
+       << localType->getUnderlyingType().getAsString() << '"';
   } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
     OS << "\"";
     // Emit storage class for vardecls.

Modified: cfe/trunk/lib/AST/StmtIterator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtIterator.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtIterator.cpp (original)
+++ cfe/trunk/lib/AST/StmtIterator.cpp Fri Apr 15 09:24:37 2011
@@ -98,7 +98,7 @@
     if (VD->getInit())
       return true;
   }
-  else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(D)) {
+  else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) {
     if (const VariableArrayType* VAPtr =
         FindVA(TD->getUnderlyingType().getTypePtr())) {
       setVAPtr(VAPtr);

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri Apr 15 09:24:37 2011
@@ -1578,7 +1578,7 @@
     NamedDecl::LinkageInfo LV = Tag->getLinkageAndVisibility();
     bool IsLocalOrUnnamed =
       Tag->getDeclContext()->isFunctionOrMethod() ||
-      (!Tag->getIdentifier() && !Tag->getTypedefForAnonDecl());
+      (!Tag->getIdentifier() && !Tag->getTypedefNameForAnonDecl());
     return CachedProperties(LV.linkage(), LV.visibility(), IsLocalOrUnnamed);
   }
 

Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Fri Apr 15 09:24:37 2011
@@ -546,7 +546,7 @@
     Buffer += Spec->getIdentifier()->getName();
     Buffer += TemplateArgsStr;
   } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
-    if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
+    if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
       Buffer += Typedef->getIdentifier()->getName();
     else if (Tag->getIdentifier())
       Buffer += Tag->getIdentifier()->getName();
@@ -569,7 +569,7 @@
   // We don't print tags unless this is an elaborated type.
   // In C, we just assume every RecordType is an elaborated type.
   if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword ||
-        D->getTypedefForAnonDecl())) {
+        D->getTypedefNameForAnonDecl())) {
     HasKindDecoration = true;
     Buffer += D->getKindName();
     Buffer += ' ';
@@ -583,7 +583,7 @@
 
   if (const IdentifierInfo *II = D->getIdentifier())
     Buffer += II->getNameStart();
-  else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) {
+  else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
     assert(Typedef->getIdentifier() && "Typedef without identifier?");
     Buffer += Typedef->getIdentifier()->getNameStart();
   } else {

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Apr 15 09:24:37 2011
@@ -91,8 +91,9 @@
     return EmitVarDecl(VD);
   }
 
-  case Decl::Typedef: {   // typedef int X;
-    const TypedefDecl &TD = cast<TypedefDecl>(D);
+  case Decl::Typedef:      // typedef int X;
+  case Decl::TypeAlias: {  // using X = int; [C++0x]
+    const TypedefNameDecl &TD = cast<TypedefNameDecl>(D);
     QualType Ty = TD.getUnderlyingType();
 
     if (Ty->isVariablyModifiedType())

Modified: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp Fri Apr 15 09:24:37 2011
@@ -155,7 +155,7 @@
     // theoretically implement this by combining information about all the
     // members into a single identifying MDNode.
     if (!Features.CPlusPlus &&
-        ETy->getDecl()->getTypedefForAnonDecl())
+        ETy->getDecl()->getTypedefNameForAnonDecl())
       return MetadataCache[Ty] = getChar();
 
     // In C++ mode, types have linkage, so we can rely on the ODR and

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Fri Apr 15 09:24:37 2011
@@ -387,7 +387,7 @@
         OS << TD->getQualifiedNameAsString();
       else
         TD->printName(OS);
-    } else if (const TypedefDecl *TDD = TD->getTypedefForAnonDecl()) {
+    } else if (const TypedefNameDecl *TDD = TD->getTypedefNameForAnonDecl()) {
       // FIXME: We should not have to check for a null decl context here.
       // Right now we do it because the implicit Obj-C decls don't have one.
       if (TDD->getDeclContext())

Modified: cfe/trunk/lib/Frontend/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTConsumers.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTConsumers.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTConsumers.cpp Fri Apr 15 09:24:37 2011
@@ -335,8 +335,9 @@
       Out << "<field> " << FD << '\n';
       break;
     }
-    case Decl::Typedef: {
-      TypedefDecl* TD = cast<TypedefDecl>(*I);
+    case Decl::Typedef:
+    case Decl::TypeAlias: {
+      TypedefNameDecl* TD = cast<TypedefNameDecl>(*I);
       Out << "<typedef> " << TD << '\n';
       break;
     }

Modified: cfe/trunk/lib/Index/DeclReferenceMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/DeclReferenceMap.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Index/DeclReferenceMap.cpp (original)
+++ cfe/trunk/lib/Index/DeclReferenceMap.cpp Fri Apr 15 09:24:37 2011
@@ -55,7 +55,7 @@
 }
 
 void RefMapper::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-  NamedDecl *ND = TL.getTypedefDecl();
+  NamedDecl *ND = TL.getTypedefNameDecl();
   Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc())));
 }
 

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Apr 15 09:24:37 2011
@@ -253,7 +253,7 @@
     return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
   }
 
-  // Otherwise, it must be a using-declaration.
+  // Otherwise, it must be a using-declaration or an alias-declaration.
 
   // Using declarations can't have attributes.
   ProhibitAttributes(attrs);
@@ -323,14 +323,17 @@
                                      IdentLoc, NamespcName, attrs.getList());
 }
 
-/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
-/// 'using' was already seen.
+/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
+/// Assumes that 'using' was already seen.
 ///
 ///     using-declaration: [C++ 7.3.p3: namespace.udecl]
 ///       'using' 'typename'[opt] ::[opt] nested-name-specifier
 ///               unqualified-id
 ///       'using' :: unqualified-id
 ///
+///     alias-declaration: C++0x [decl.typedef]p2
+///       'using' identifier = type-id ;
+///
 Decl *Parser::ParseUsingDeclaration(unsigned Context,
                                     const ParsedTemplateInfo &TemplateInfo,
                                     SourceLocation UsingLoc,
@@ -340,10 +343,6 @@
   SourceLocation TypenameLoc;
   bool IsTypeName;
 
-  // TODO: in C++0x, if we have template parameters this must be a
-  // template alias:
-  //   template <...> using id = type;
-
   // Ignore optional 'typename'.
   // FIXME: This is wrong; we should parse this as a typename-specifier.
   if (Tok.is(tok::kw_typename)) {
@@ -377,17 +376,48 @@
     return 0;
   }
 
-  // Parse (optional) attributes (most likely GNU strong-using extension).
   ParsedAttributes attrs(AttrFactory);
-  MaybeParseGNUAttributes(attrs);
+
+  // Maybe this is an alias-declaration.
+  bool IsAliasDecl = Tok.is(tok::equal);
+  TypeResult TypeAlias;
+  if (IsAliasDecl) {
+    // TODO: Do we want to support attributes somewhere in an alias declaration?
+    // Can't follow GCC since it doesn't support them yet!
+    ConsumeToken();
+
+    if (!getLang().CPlusPlus0x)
+      Diag(Tok.getLocation(), diag::ext_alias_declaration);
+
+    // Name must be an identifier.
+    if (Name.getKind() != UnqualifiedId::IK_Identifier) {
+      Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier);
+      // No removal fixit: can't recover from this.
+      SkipUntil(tok::semi);
+      return 0;
+    } else if (IsTypeName)
+      Diag(TypenameLoc, diag::err_alias_declaration_not_identifier)
+        << FixItHint::CreateRemoval(SourceRange(TypenameLoc,
+                             SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc));
+    else if (SS.isNotEmpty())
+      Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
+        << FixItHint::CreateRemoval(SS.getRange());
+
+    TypeAlias = ParseTypeName(0, Declarator::AliasDeclContext);
+  } else
+    // Parse (optional) attributes (most likely GNU strong-using extension).
+    MaybeParseGNUAttributes(attrs);
 
   // Eat ';'.
   DeclEnd = Tok.getLocation();
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
-                   !attrs.empty() ? "attributes list" : "using declaration",
+                   !attrs.empty() ? "attributes list" :
+                   IsAliasDecl ? "alias declaration" : "using declaration",
                    tok::semi);
 
   // Diagnose an attempt to declare a templated using-declaration.
+  // TODO: in C++0x, alias-declarations can be templates:
+  //   template <...> using id = type;
   if (TemplateInfo.Kind) {
     SourceRange R = TemplateInfo.getSourceRange();
     Diag(UsingLoc, diag::err_templated_using_declaration)
@@ -399,6 +429,10 @@
     return 0;
   }
 
+  if (IsAliasDecl)
+    return Actions.ActOnAliasDeclaration(getCurScope(), AS, UsingLoc, Name,
+                                         TypeAlias);
+
   return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
                                        Name, attrs.getList(),
                                        IsTypeName, TypenameLoc);

Modified: cfe/trunk/lib/Rewrite/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteObjC.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteObjC.cpp Fri Apr 15 09:24:37 2011
@@ -4953,7 +4953,7 @@
   QualType DeclT;
   if (VarDecl *VD = dyn_cast<VarDecl>(ND))
     DeclT = VD->getType();
-  else if (TypedefDecl *TDD = dyn_cast<TypedefDecl>(ND))
+  else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND))
     DeclT = TDD->getUnderlyingType();
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
     DeclT = FD->getType();
@@ -5736,7 +5736,7 @@
             RewriteTypeOfDecl(VD);
         }
       }
-      if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
         if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
           RewriteBlockPointerDecl(TD);
         else if (TD->getUnderlyingType()->isFunctionPointerType())
@@ -5906,7 +5906,7 @@
     }
     return;
   }
-  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
     if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
       RewriteBlockPointerDecl(TD);
     else if (TD->getUnderlyingType()->isFunctionPointerType())

Modified: cfe/trunk/lib/Sema/JumpDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/JumpDiagnostics.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/JumpDiagnostics.cpp (original)
+++ cfe/trunk/lib/Sema/JumpDiagnostics.cpp Fri Apr 15 09:24:37 2011
@@ -149,6 +149,11 @@
       return std::make_pair((unsigned) diag::note_protected_by_vla_typedef, 0);
   }
 
+  if (const TypeAliasDecl *TD = dyn_cast<TypeAliasDecl>(D)) {
+    if (TD->getUnderlyingType()->isVariablyModifiedType())
+      return std::make_pair((unsigned) diag::note_protected_by_vla_type_alias, 0);
+  }
+
   return std::make_pair(0U, 0U);
 }
 

Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAccess.cpp Fri Apr 15 09:24:37 2011
@@ -1011,16 +1011,16 @@
       // Find an original declaration.
       while (D->isOutOfLine()) {
         NamedDecl *PrevDecl = 0;
-        if (isa<VarDecl>(D))
-          PrevDecl = cast<VarDecl>(D)->getPreviousDeclaration();
-        else if (isa<FunctionDecl>(D))
-          PrevDecl = cast<FunctionDecl>(D)->getPreviousDeclaration();
-        else if (isa<TypedefDecl>(D))
-          PrevDecl = cast<TypedefDecl>(D)->getPreviousDeclaration();
-        else if (isa<TagDecl>(D)) {
+        if (VarDecl *VD = dyn_cast<VarDecl>(D))
+          PrevDecl = VD->getPreviousDeclaration();
+        else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+          PrevDecl = FD->getPreviousDeclaration();
+        else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
+          PrevDecl = TND->getPreviousDeclaration();
+        else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
           if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
             break;
-          PrevDecl = cast<TagDecl>(D)->getPreviousDeclaration();
+          PrevDecl = TD->getPreviousDeclaration();
         }
         if (!PrevDecl) break;
         D = PrevDecl;

Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Fri Apr 15 09:24:37 2011
@@ -255,7 +255,7 @@
   QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD));
   if (T->isDependentType())
     return true;
-  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
+  else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
     if (TD->getUnderlyingType()->isRecordType() ||
         (Context.getLangOptions().CPlusPlus0x &&
          TD->getUnderlyingType()->isEnumeralType()))
@@ -549,7 +549,7 @@
     } else if (isa<RecordDecl>(SD)) {
       RecordTypeLoc RecordTL = TLB.push<RecordTypeLoc>(T);
       RecordTL.setNameLoc(IdentifierLoc);
-    } else if (isa<TypedefDecl>(SD)) {
+    } else if (isa<TypedefNameDecl>(SD)) {
       TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(T);
       TypedefTL.setNameLoc(IdentifierLoc);
     } else if (isa<EnumDecl>(SD)) {

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Apr 15 09:24:37 2011
@@ -2964,9 +2964,9 @@
   if (const EnumType *SourceEnum = Source->getAs<EnumType>())
     if (const EnumType *TargetEnum = Target->getAs<EnumType>())
       if ((SourceEnum->getDecl()->getIdentifier() || 
-           SourceEnum->getDecl()->getTypedefForAnonDecl()) &&
+           SourceEnum->getDecl()->getTypedefNameForAnonDecl()) &&
           (TargetEnum->getDecl()->getIdentifier() ||
-           TargetEnum->getDecl()->getTypedefForAnonDecl()) &&
+           TargetEnum->getDecl()->getTypedefNameForAnonDecl()) &&
           SourceEnum != TargetEnum) {
         if (isFromSystemMacro(S, CC))
           return;

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Fri Apr 15 09:24:37 2011
@@ -1837,7 +1837,7 @@
     // Anonymous tag types are constant strings.
     if (const TagType *TagT = dyn_cast<TagType>(T))
       if (TagDecl *Tag = TagT->getDecl())
-        if (!Tag->getIdentifier() && !Tag->getTypedefForAnonDecl()) {
+        if (!Tag->getIdentifier() && !Tag->getTypedefNameForAnonDecl()) {
           switch (Tag->getTagKind()) {
           case TTK_Struct: return "struct <anonymous>";
           case TTK_Class:  return "class <anonymous>";            
@@ -1940,7 +1940,7 @@
       // Look through typedefs.
       if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
         if (TypeSourceInfo *InnerTSInfo
-            = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
+            = TypedefTL->getTypedefNameDecl()->getTypeSourceInfo()) {
           TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
           continue;
         }
@@ -2640,6 +2640,7 @@
     case Decl::ObjCProtocol:       return CXCursor_ObjCProtocolDecl;
     case Decl::ParmVar:            return CXCursor_ParmDecl;
     case Decl::Typedef:            return CXCursor_TypedefDecl;
+    case Decl::TypeAlias:          return CXCursor_TypeAliasDecl;
     case Decl::Var:                return CXCursor_VarDecl;
     case Decl::Namespace:          return CXCursor_Namespace;
     case Decl::NamespaceAlias:     return CXCursor_NamespaceAlias;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Apr 15 09:24:37 2011
@@ -946,12 +946,12 @@
   return New;
 }
 
-/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the
+/// MergeTypedefNameDecl - We just parsed a typedef 'New' which has the
 /// same name and scope as a previous declaration 'Old'.  Figure out
 /// how to resolve this situation, merging decls or emitting
 /// diagnostics as appropriate. If there was an error, set New to be invalid.
 ///
-void Sema::MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls) {
+void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) {
   // If the new decl is known invalid already, don't bother doing any
   // merging checks.
   if (New->isInvalidDecl()) return;
@@ -1011,7 +1011,7 @@
 
   // Determine the "old" type we'll use for checking and diagnostics.
   QualType OldType;
-  if (TypedefDecl *OldTypedef = dyn_cast<TypedefDecl>(Old))
+  if (TypedefNameDecl *OldTypedef = dyn_cast<TypedefNameDecl>(Old))
     OldType = OldTypedef->getUnderlyingType();
   else
     OldType = Context.getTypeDeclType(Old);
@@ -1022,8 +1022,11 @@
   if (OldType != New->getUnderlyingType() &&
       Context.getCanonicalType(OldType) !=
       Context.getCanonicalType(New->getUnderlyingType())) {
+    int Kind = 0;
+    if (isa<TypeAliasDecl>(Old))
+      Kind = 1;
     Diag(New->getLocation(), diag::err_redefinition_different_typedef)
-      << New->getUnderlyingType() << OldType;
+      << Kind << New->getUnderlyingType() << OldType;
     if (Old->getLocation().isValid())
       Diag(Old->getLocation(), diag::note_previous_definition);
     return New->setInvalidDecl();
@@ -1033,8 +1036,8 @@
   // declaration was a typedef.
   // FIXME: this is a potential source of wierdness if the type
   // spellings don't match exactly.
-  if (isa<TypedefDecl>(Old))
-    New->setPreviousDeclaration(cast<TypedefDecl>(Old));
+  if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Old))
+    New->setPreviousDeclaration(Typedef);
 
   if (getLangOptions().Microsoft)
     return;
@@ -1068,7 +1071,7 @@
     //   };
     //
     // since that was the intent of DR56.
-    if (!isa<TypedefDecl >(Old))
+    if (!isa<TypedefNameDecl>(Old))
       return;
 
     Diag(New->getLocation(), diag::err_redefinition)
@@ -2553,6 +2556,26 @@
   return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
 }
 
+/// DiagnoseClassNameShadow - Implement C++ [class.mem]p13:
+///   If T is the name of a class, then each of the following shall have a 
+///   name different from T:
+///     - every static data member of class T;
+///     - every member function of class T
+///     - every member of class T that is itself a type;
+/// \returns true if the declaration name violates these rules.
+bool Sema::DiagnoseClassNameShadow(DeclContext *DC,
+                                   DeclarationNameInfo NameInfo) {
+  DeclarationName Name = NameInfo.getName();
+
+  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC)) 
+    if (Record->getIdentifier() && Record->getDeclName() == Name) {
+      Diag(NameInfo.getLoc(), diag::err_member_name_of_class) << Name;
+      return true;
+    }
+
+  return false;
+}
+  
 Decl *Sema::HandleDeclarator(Scope *S, Declarator &D,
                              MultiTemplateParamsArg TemplateParamLists,
                              bool IsFunctionDefinition) {
@@ -2640,23 +2663,12 @@
         D.setInvalidType();
     }
   }
-  
-  // C++ [class.mem]p13:
-  //   If T is the name of a class, then each of the following shall have a 
-  //   name different from T:
-  //     - every static data member of class T;
-  //     - every member function of class T
-  //     - every member of class T that is itself a type;
-  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC)) 
-    if (Record->getIdentifier() && Record->getDeclName() == Name) {
-      Diag(D.getIdentifierLoc(), diag::err_member_name_of_class)
-        << Name;
-      
-      // If this is a typedef, we'll end up spewing multiple diagnostics.
-      // Just return early; it's safer.
-      if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
-        return 0;
-    }
+
+  if (DiagnoseClassNameShadow(DC, NameInfo))
+    // If this is a typedef, we'll end up spewing multiple diagnostics.
+    // Just return early; it's safer.
+    if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
+      return 0;
   
   NamedDecl *New;
 
@@ -2951,6 +2963,15 @@
   // Handle attributes prior to checking for duplicates in MergeVarDecl
   ProcessDeclAttributes(S, NewTD, D);
 
+  return ActOnTypedefNameDecl(S, DC, NewTD, Previous, Redeclaration);
+}
+
+/// ActOnTypedefNameDecl - Perform semantic checking for a declaration which
+/// declares a typedef-name, either using the 'typedef' type specifier or via
+/// a C++0x [dcl.typedef]p2 alias-declaration: 'using T = A;'.
+NamedDecl*
+Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD,
+                           LookupResult &Previous, bool &Redeclaration) {
   // C99 6.7.7p2: If a typedef name specifies a variably modified type
   // then it shall have block scope.
   // Note that variably modified types must be fixed before merging the decl so
@@ -2966,18 +2987,17 @@
           TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
                                               Oversized);
       if (!FixedTy.isNull()) {
-        Diag(D.getIdentifierLoc(), diag::warn_illegal_constant_array_size);
+        Diag(NewTD->getLocation(), diag::warn_illegal_constant_array_size);
         NewTD->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(FixedTy));
       } else {
         if (SizeIsNegative)
-          Diag(D.getIdentifierLoc(), diag::err_typecheck_negative_array_size);
+          Diag(NewTD->getLocation(), diag::err_typecheck_negative_array_size);
         else if (T->isVariableArrayType())
-          Diag(D.getIdentifierLoc(), diag::err_vla_decl_in_file_scope);
+          Diag(NewTD->getLocation(), diag::err_vla_decl_in_file_scope);
         else if (Oversized.getBoolValue())
-          Diag(D.getIdentifierLoc(), diag::err_array_too_large)
-            << Oversized.toString(10);
+          Diag(NewTD->getLocation(), diag::err_array_too_large) << Oversized.toString(10);
         else
-          Diag(D.getIdentifierLoc(), diag::err_vm_decl_in_file_scope);
+          Diag(NewTD->getLocation(), diag::err_vm_decl_in_file_scope);
         NewTD->setInvalidDecl();
       }
     }
@@ -2989,7 +3009,7 @@
                        /*ExplicitInstantiationOrSpecialization=*/false);
   if (!Previous.empty()) {
     Redeclaration = true;
-    MergeTypeDefDecl(NewTD, Previous);
+    MergeTypedefNameDecl(NewTD, Previous);
   }
 
   // If this is the C FILE type, notify the AST context.
@@ -4061,8 +4081,13 @@
       // In C++, the empty parameter-type-list must be spelled "void"; a
       // typedef of void is not permitted.
       if (getLangOptions().CPlusPlus &&
-          Param->getType().getUnqualifiedType() != Context.VoidTy)
-        Diag(Param->getLocation(), diag::err_param_typedef_of_void);
+          Param->getType().getUnqualifiedType() != Context.VoidTy) {
+        bool IsTypeAlias = false;
+        if (const TypedefType *TT = Param->getType()->getAs<TypedefType>())
+          IsTypeAlias = isa<TypeAliasDecl>(TT->getDecl());
+        Diag(Param->getLocation(), diag::err_param_typedef_of_void)
+          << IsTypeAlias;
+      }
     } else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
       for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
         ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
@@ -6117,7 +6142,7 @@
     // Do nothing if the tag is not anonymous or already has an
     // associated typedef (from an earlier typedef in this decl group).
     if (tagFromDeclSpec->getIdentifier()) break;
-    if (tagFromDeclSpec->getTypedefForAnonDecl()) break;
+    if (tagFromDeclSpec->getTypedefNameForAnonDecl()) break;
 
     // A well-formed anonymous tag must always be a TUK_Definition.
     assert(tagFromDeclSpec->isThisDeclarationADefinition());
@@ -6127,7 +6152,7 @@
       break;
 
     // Otherwise, set this is the anon-decl typedef for the tag.
-    tagFromDeclSpec->setTypedefForAnonDecl(NewTD);
+    tagFromDeclSpec->setTypedefNameForAnonDecl(NewTD);
     break;
   }
     
@@ -6468,7 +6493,7 @@
     // okay according to the likely resolution of an open issue;
     // see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#407
     if (getLangOptions().CPlusPlus) {
-      if (TypedefDecl *TD = dyn_cast<TypedefDecl>(PrevDecl)) {
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(PrevDecl)) {
         if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
           TagDecl *Tag = TT->getDecl();
           if (Tag->getDeclName() == Name &&
@@ -6626,7 +6651,8 @@
           !Previous.isForRedeclaration()) {
         unsigned Kind = 0;
         if (isa<TypedefDecl>(PrevDecl)) Kind = 1;
-        else if (isa<ClassTemplateDecl>(PrevDecl)) Kind = 2;
+        else if (isa<TypeAliasDecl>(PrevDecl)) Kind = 2;
+        else if (isa<ClassTemplateDecl>(PrevDecl)) Kind = 3;
         Diag(NameLoc, diag::err_tag_reference_non_tag) << Kind;
         Diag(PrevDecl->getLocation(), diag::note_declared_at);
         Invalid = true;
@@ -6640,17 +6666,19 @@
       } else if (TUK == TUK_Reference || TUK == TUK_Friend) {
         unsigned Kind = 0;
         if (isa<TypedefDecl>(PrevDecl)) Kind = 1;
-        else if (isa<ClassTemplateDecl>(PrevDecl)) Kind = 2;
+        else if (isa<TypeAliasDecl>(PrevDecl)) Kind = 2;
+        else if (isa<ClassTemplateDecl>(PrevDecl)) Kind = 3;
         Diag(NameLoc, diag::err_tag_reference_conflict) << Kind;
         Diag(PrevDecl->getLocation(), diag::note_previous_decl) << PrevDecl;
         Invalid = true;
 
       // Otherwise it's a declaration.  Call out a particularly common
       // case here.
-      } else if (isa<TypedefDecl>(PrevDecl)) {
+      } else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(PrevDecl)) {
+        unsigned Kind = 0;
+        if (isa<TypeAliasDecl>(PrevDecl)) Kind = 1;
         Diag(NameLoc, diag::err_tag_definition_of_typedef)
-          << Name
-          << cast<TypedefDecl>(PrevDecl)->getUnderlyingType();
+          << Name << Kind << TND->getUnderlyingType();
         Diag(PrevDecl->getLocation(), diag::note_previous_decl) << PrevDecl;
         Invalid = true;
 

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Apr 15 09:24:37 2011
@@ -55,7 +55,7 @@
     Ty = decl->getType();
   else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
     Ty = decl->getType();
-  else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
+  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(d))
     Ty = decl->getUnderlyingType();
   else
     return 0;
@@ -101,8 +101,8 @@
 /// Return true if the given decl has a declarator that should have
 /// been processed by Sema::GetTypeForDeclarator.
 static bool hasDeclarator(const Decl *d) {
-  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
-  return isa<DeclaratorDecl>(d) || isa<BlockDecl>(d) || isa<TypedefDecl>(d);
+  // In some sense, TypedefNameDecl really *ought* to be a DeclaratorDecl.
+  return isa<DeclaratorDecl>(d) || isa<BlockDecl>(d) || isa<TypedefNameDecl>(d);
 }
 
 /// hasFunctionProto - Return true if the given decl has a argument
@@ -202,7 +202,7 @@
 
 static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
                                     const AttributeList &Attr, Sema &S) {
-  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
+  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(d);
   if (tDecl == 0) {
     S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
     return;
@@ -1229,7 +1229,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
     return;
   }
-  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
     QualType T = TD->getUnderlyingType();
     if (!T->isPointerType() ||
         !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
@@ -1912,7 +1912,7 @@
 
   // Try to find the underlying union declaration.
   RecordDecl *RD = 0;
-  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
+  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(d);
   if (TD && TD->getUnderlyingType()->isUnionType())
     RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
   else
@@ -2103,7 +2103,7 @@
   }
 
   QualType OldTy;
-  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
+  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
     OldTy = TD->getUnderlyingType();
   else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
     OldTy = VD->getType();
@@ -2202,7 +2202,7 @@
   }
 
   // Install the new type.
-  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
     // FIXME: preserve existing source info.
     TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
   } else

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Apr 15 09:24:37 2011
@@ -3416,9 +3416,9 @@
   //   be used as the identifier in the declarator for a destructor
   //   declaration.
   QualType DeclaratorType = GetTypeFromParser(D.getName().DestructorName);
-  if (isa<TypedefType>(DeclaratorType))
+  if (const TypedefType *TT = DeclaratorType->getAs<TypedefType>())
     Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name)
-      << DeclaratorType;
+      << DeclaratorType << isa<TypeAliasDecl>(TT->getDecl());
 
   // C++ [class.dtor]p2:
   //   A destructor is used to destroy objects of its class type. A
@@ -4051,8 +4051,8 @@
     return true;
   }
 
-  if (TypedefDecl *TD1 = dyn_cast<TypedefDecl>(D1))
-    if (TypedefDecl *TD2 = dyn_cast<TypedefDecl>(D2)) {
+  if (TypedefNameDecl *TD1 = dyn_cast<TypedefNameDecl>(D1))
+    if (TypedefNameDecl *TD2 = dyn_cast<TypedefNameDecl>(D2)) {
       SuppressRedeclaration = true;
       return Context.hasSameType(TD1->getUnderlyingType(),
                                  TD2->getUnderlyingType());
@@ -4651,6 +4651,61 @@
   return true;
 }
 
+Decl *Sema::ActOnAliasDeclaration(Scope *S,
+                                  AccessSpecifier AS,
+                                  SourceLocation UsingLoc,
+                                  UnqualifiedId &Name,
+                                  TypeResult Type) {
+  assert((S->getFlags() & Scope::DeclScope) &&
+         "got alias-declaration outside of declaration scope");
+
+  if (Type.isInvalid())
+    return 0;
+
+  bool Invalid = false;
+  DeclarationNameInfo NameInfo = GetNameFromUnqualifiedId(Name);
+  TypeSourceInfo *TInfo = 0;
+  QualType T = GetTypeFromParser(Type.get(), &TInfo);
+
+  if (DiagnoseClassNameShadow(CurContext, NameInfo))
+    return 0;
+
+  if (DiagnoseUnexpandedParameterPack(Name.StartLocation, TInfo,
+                                      UPPC_DeclarationType))
+    Invalid = true;
+
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName, ForRedeclaration);
+  LookupName(Previous, S);
+
+  // Warn about shadowing the name of a template parameter.
+  if (Previous.isSingleResult() &&
+      Previous.getFoundDecl()->isTemplateParameter()) {
+    if (DiagnoseTemplateParameterShadow(Name.StartLocation,
+                                        Previous.getFoundDecl()))
+      Invalid = true;
+    Previous.clear();
+  }
+
+  assert(Name.Kind == UnqualifiedId::IK_Identifier &&
+         "name in alias declaration must be an identifier");
+  TypeAliasDecl *NewTD = TypeAliasDecl::Create(Context, CurContext, UsingLoc,
+                                               Name.StartLocation,
+                                               Name.Identifier, TInfo);
+
+  NewTD->setAccess(AS);
+
+  if (Invalid)
+    NewTD->setInvalidDecl();
+
+  bool Redeclaration = false;
+  ActOnTypedefNameDecl(S, CurContext, NewTD, Previous, Redeclaration);
+
+  if (!Redeclaration)
+    PushOnScopeChains(NewTD, S);
+
+  return NewTD;
+}
+
 Decl *Sema::ActOnNamespaceAliasDef(Scope *S,
                                              SourceLocation NamespaceLoc,
                                              SourceLocation AliasLoc,

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri Apr 15 09:24:37 2011
@@ -174,7 +174,8 @@
       if (PrevDecl && SuperClassDecl == 0) {
         // The previous declaration was not a class decl. Check if we have a
         // typedef. If we do, get the underlying class type.
-        if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
+        if (const TypedefNameDecl *TDecl =
+              dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
           QualType T = TDecl->getUnderlyingType();
           if (T->isObjCObjectType()) {
             if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface())
@@ -193,7 +194,7 @@
         }
       }
 
-      if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
+      if (!dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
         if (!SuperClassDecl)
           Diag(SuperLoc, diag::err_undef_superclass)
             << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
@@ -242,7 +243,8 @@
   // Check for class declaration
   NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
                                        LookupOrdinaryName, ForRedeclaration);
-  if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
+  if (const TypedefNameDecl *TDecl =
+        dyn_cast_or_null<TypedefNameDecl>(CDeclU)) {
     QualType T = TDecl->getUnderlyingType();
     if (T->isObjCObjectType()) {
       if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
@@ -1242,7 +1244,7 @@
       // @class XCElementToggler;
       //
       // FIXME: Make an extension?
-      TypedefDecl *TDD = dyn_cast<TypedefDecl>(PrevDecl);
+      TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(PrevDecl);
       if (!TDD || !TDD->getUnderlyingType()->isObjCObjectType()) {
         Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
         Diag(PrevDecl->getLocation(), diag::note_previous_definition);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Apr 15 09:24:37 2011
@@ -2469,7 +2469,7 @@
 /// were not overloaded, and it doesn't promise that the declaration
 /// will in fact be used.
 static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {
-  if (isa<TypedefDecl>(D)) {
+  if (isa<TypedefNameDecl>(D)) {
     S.Diag(Loc, diag::err_unexpected_typedef) << D->getDeclName();
     return true;
   }

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Apr 15 09:24:37 2011
@@ -2978,7 +2978,7 @@
     return true;
   }
 
-  if (!Tag->getDeclName() && !Tag->getTypedefForAnonDecl()) {
+  if (!Tag->getDeclName() && !Tag->getTypedefNameForAnonDecl()) {
     S.Diag(SR.getBegin(), diag::ext_template_arg_unnamed_type) << SR;
     S.Diag(Tag->getLocation(), diag::note_template_unnamed_type_here);
     return true;
@@ -4374,7 +4374,7 @@
     return FD->getPreviousDeclaration();
   if (TagDecl *TD = dyn_cast<TagDecl>(ND))
     return TD->getPreviousDeclaration();
-  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(ND))
+  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(ND))
     return TD->getPreviousDeclaration();
   if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
     return FTD->getPreviousDeclaration();

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Apr 15 09:24:37 2011
@@ -128,7 +128,8 @@
   return Inst;
 }
 
-Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
+Decl *TemplateDeclInstantiator::VisitTypedefNameDecl(TypedefNameDecl *D,
+                                                     bool IsTypeAlias) {
   bool Invalid = false;
   TypeSourceInfo *DI = D->getTypeSourceInfo();
   if (DI->getType()->isDependentType() ||
@@ -144,9 +145,13 @@
   }
 
   // Create the new typedef
-  TypedefDecl *Typedef
-    = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocStart(),
-                          D->getLocation(), D->getIdentifier(), DI);
+  TypedefNameDecl *Typedef;
+  if (IsTypeAlias)
+    Typedef = TypeAliasDecl::Create(SemaRef.Context, Owner, D->getLocStart(),
+                                    D->getLocation(), D->getIdentifier(), DI);
+  else
+    Typedef = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocStart(),
+                                  D->getLocation(), D->getIdentifier(), DI);
   if (Invalid)
     Typedef->setInvalidDecl();
 
@@ -154,20 +159,20 @@
   // tag decl, re-establish that relationship for the new typedef.
   if (const TagType *oldTagType = D->getUnderlyingType()->getAs<TagType>()) {
     TagDecl *oldTag = oldTagType->getDecl();
-    if (oldTag->getTypedefForAnonDecl() == D) {
+    if (oldTag->getTypedefNameForAnonDecl() == D) {
       TagDecl *newTag = DI->getType()->castAs<TagType>()->getDecl();
-      assert(!newTag->getIdentifier() && !newTag->getTypedefForAnonDecl());
-      newTag->setTypedefForAnonDecl(Typedef);
+      assert(!newTag->getIdentifier() && !newTag->getTypedefNameForAnonDecl());
+      newTag->setTypedefNameForAnonDecl(Typedef);
     }
   }
   
-  if (TypedefDecl *Prev = D->getPreviousDeclaration()) {
+  if (TypedefNameDecl *Prev = D->getPreviousDeclaration()) {
     NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev,
                                                        TemplateArgs);
     if (!InstPrev)
       return 0;
     
-    Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
+    Typedef->setPreviousDeclaration(cast<TypedefNameDecl>(InstPrev));
   }
 
   SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef);
@@ -178,6 +183,14 @@
   return Typedef;
 }
 
+Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
+  return VisitTypedefNameDecl(D, /*IsTypeAlias=*/false);
+}
+
+Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) {
+  return VisitTypedefNameDecl(D, /*IsTypeAlias=*/true);
+}
+
 /// \brief Instantiate an initializer, breaking it into separate
 /// initialization arguments.
 ///

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Apr 15 09:24:37 2011
@@ -1600,9 +1600,12 @@
     case Declarator::TemplateTypeArgContext:
       Error = 7; // Template type argument
       break;
+    case Declarator::AliasDeclContext:
+      Error = 9; // Type alias
+      break;
     case Declarator::TypeNameContext:
       if (!AutoAllowedInTypeName)
-        Error = 10; // Generic
+        Error = 11; // Generic
       break;
     case Declarator::FileContext:
     case Declarator::BlockContext:
@@ -1616,7 +1619,7 @@
 
     // In Objective-C it is an error to use 'auto' on a function declarator.
     if (D.isFunctionDeclarator())
-      Error = 9;
+      Error = 10;
 
     // C++0x [dcl.spec.auto]p2: 'auto' is always fine if the declarator
     // contains a trailing return type. That is only legal at the outermost
@@ -1653,6 +1656,11 @@
   if (D.getIdentifier())
     Name = D.getIdentifier();
 
+  // Does this declaration declare a typedef-name?
+  bool IsTypedefName =
+    D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef ||
+    D.getContext() == Declarator::AliasDeclContext;
+
   // Walk the DeclTypeInfo, building the recursive type as we go.
   // DeclTypeInfos are ordered from the identifier out, which is
   // opposite of what we want :).
@@ -1829,9 +1837,9 @@
 
       // Exception specs are not allowed in typedefs. Complain, but add it
       // anyway.
-      if (FTI.getExceptionSpecType() != EST_None &&
-          D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
-        Diag(FTI.getExceptionSpecLoc(), diag::err_exception_spec_in_typedef);
+      if (IsTypedefName && FTI.getExceptionSpecType())
+        Diag(FTI.getExceptionSpecLoc(), diag::err_exception_spec_in_typedef)
+          << (D.getContext() == Declarator::AliasDeclContext);
 
       if (!FTI.NumArgs && !FTI.isVariadic && !getLangOptions().CPlusPlus) {
         // Simple void foo(), where the incoming T is the result type.
@@ -2057,8 +2065,7 @@
     //   declaration.
     if ((FnTy->getTypeQuals() != 0 || FnTy->getRefQualifier()) &&
         !(D.getContext() == Declarator::TemplateTypeArgContext &&
-          !D.isFunctionDeclarator()) &&
-        D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
+          !D.isFunctionDeclarator()) && !IsTypedefName &&
         (FreeFunction ||
          D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)) {
       if (D.getContext() == Declarator::TemplateTypeArgContext) {
@@ -2196,6 +2203,7 @@
     case Declarator::KNRTypeListContext:
     case Declarator::ObjCPrototypeContext: // FIXME: special diagnostic here?
     case Declarator::TypeNameContext:
+    case Declarator::AliasDeclContext:
     case Declarator::MemberContext:
     case Declarator::BlockContext:
     case Declarator::ForContext:
@@ -2635,7 +2643,8 @@
     //   A type-specifier-seq shall not define a class or enumeration
     //   unless it appears in the type-id of an alias-declaration
     //   (7.1.3).
-    if (OwnedTag && OwnedTag->isDefinition())
+    if (OwnedTag && OwnedTag->isDefinition() &&
+        D.getContext() != Declarator::AliasDeclContext)
       Diag(OwnedTag->getLocation(), diag::err_type_defined_in_type_specifier)
         << Context.getTypeDeclType(OwnedTag);
   }

Modified: cfe/trunk/lib/Sema/TargetAttributesSema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TargetAttributesSema.cpp (original)
+++ cfe/trunk/lib/Sema/TargetAttributesSema.cpp Fri Apr 15 09:24:37 2011
@@ -136,7 +136,7 @@
   if (VD && VD->getType()->isFunctionPointerType())
     return;
   // Also don't warn on function pointer typedefs.
-  TypedefDecl *TD = dyn_cast<TypedefDecl>(D);
+  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
   if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
              TD->getUnderlyingType()->isFunctionType()))
     return;

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Apr 15 09:24:37 2011
@@ -669,7 +669,7 @@
   QualType RebuildUnresolvedUsingType(Decl *D);
 
   /// \brief Build a new typedef type.
-  QualType RebuildTypedefType(TypedefDecl *Typedef) {
+  QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
     return SemaRef.Context.getTypeDeclType(Typedef);
   }
 
@@ -851,7 +851,8 @@
 	  NamedDecl *SomeDecl = Result.getRepresentativeDecl();
           unsigned Kind = 0;
           if (isa<TypedefDecl>(SomeDecl)) Kind = 1;
-          else if (isa<ClassTemplateDecl>(SomeDecl)) Kind = 2;
+          else if (isa<TypeAliasDecl>(SomeDecl)) Kind = 2;
+          else if (isa<ClassTemplateDecl>(SomeDecl)) Kind = 3;
           SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) << Kind;
           SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
           break;
@@ -3981,9 +3982,9 @@
 QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
                                                       TypedefTypeLoc TL) {
   const TypedefType *T = TL.getTypePtr();
-  TypedefDecl *Typedef
-    = cast_or_null<TypedefDecl>(getDerived().TransformDecl(TL.getNameLoc(),
-                                                           T->getDecl()));
+  TypedefNameDecl *Typedef
+    = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
+                                                               T->getDecl()));
   if (!Typedef)
     return QualType();
 

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Apr 15 09:24:37 2011
@@ -3151,7 +3151,7 @@
       Error("incorrect encoding of typedef type");
       return QualType();
     }
-    TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
+    TypedefNameDecl *Decl = cast<TypedefNameDecl>(GetDecl(Record[0]));
     QualType Canonical = GetType(Record[1]);
     if (!Canonical.isNull())
       Canonical = Context->getCanonicalType(Canonical);
@@ -4083,7 +4083,7 @@
   // and add them to Sema's vector of such declarations.
   for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
     SemaObj->ExtVectorDecls.push_back(
-                               cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
+                             cast<TypedefNameDecl>(GetDecl(ExtVectorDecls[I])));
 
   // FIXME: Do VTable uses and dynamic classes deserialize too much ?
   // Can we cut them down before writing them ?

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Apr 15 09:24:37 2011
@@ -93,6 +93,7 @@
     void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
     void VisitTypeDecl(TypeDecl *TD);
     void VisitTypedefDecl(TypedefDecl *TD);
+    void VisitTypeAliasDecl(TypeAliasDecl *TD);
     void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
     void VisitTagDecl(TagDecl *TD);
     void VisitEnumDecl(EnumDecl *ED);
@@ -240,6 +241,11 @@
   TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
 }
 
+void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) {
+  VisitTypeDecl(TD);
+  TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
+}
+
 void ASTDeclReader::VisitTagDecl(TagDecl *TD) {
   VisitTypeDecl(TD);
   VisitRedeclarable(TD);
@@ -251,10 +257,10 @@
   if (Record[Idx++]) { // hasExtInfo
     TagDecl::ExtInfo *Info = new (*Reader.getContext()) TagDecl::ExtInfo();
     ReadQualifierInfo(*Info, Record, Idx);
-    TD->TypedefDeclOrQualifier = Info;
+    TD->TypedefNameDeclOrQualifier = Info;
   } else
-    TD->setTypedefForAnonDecl(
-                      cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++])));
+    TD->setTypedefNameForAnonDecl(
+                  cast_or_null<TypedefNameDecl>(Reader.GetDecl(Record[Idx++])));
 }
 
 void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
@@ -1429,6 +1435,10 @@
     D = TypedefDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
                             0, 0);
     break;
+  case DECL_TYPEALIAS:
+    D = TypeAliasDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
+                              0, 0);
+    break;
   case DECL_ENUM:
     D = EnumDecl::Create(*Context, Decl::EmptyShell());
     break;

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Apr 15 09:24:37 2011
@@ -53,6 +53,7 @@
     void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
     void VisitTypeDecl(TypeDecl *D);
     void VisitTypedefDecl(TypedefDecl *D);
+    void VisitTypeAliasDecl(TypeAliasDecl *D);
     void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
     void VisitTagDecl(TagDecl *D);
     void VisitEnumDecl(EnumDecl *D);
@@ -167,6 +168,12 @@
   Code = serialization::DECL_TYPEDEF;
 }
 
+void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
+  VisitTypeDecl(D);
+  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
+  Code = serialization::DECL_TYPEALIAS;
+}
+
 void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
   VisitTypeDecl(D);
   VisitRedeclarable(D);
@@ -179,7 +186,7 @@
   if (D->hasExtInfo())
     Writer.AddQualifierInfo(*D->getExtInfo(), Record);
   else
-    Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);
+    Writer.AddDeclRef(D->getTypedefNameForAnonDecl(), Record);
 }
 
 void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp Fri Apr 15 09:24:37 2011
@@ -176,7 +176,7 @@
 }
 
 static RefKind getTemplateKind(const TypedefType *tdt) {
-  const TypedefDecl *td = tdt->getDecl();
+  const TypedefNameDecl *td = tdt->getDecl();
   RefKind parentKind = getTemplateKind(td->getDeclContext());
   if (parentKind == VectorKind) {
     return llvm::StringSwitch<RefKind>(td->getName())

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp Fri Apr 15 09:24:37 2011
@@ -56,7 +56,7 @@
   if (!TT)
     return false;
 
-  const TypedefDecl *TD = TT->getDecl();
+  const TypedefNameDecl *TD = TT->getDecl();
 
   if (!InNamespace(TD, "std"))
     return false;

Added: cfe/trunk/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp?rev=129567&view=auto
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp (added)
+++ cfe/trunk/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp Fri Apr 15 09:24:37 2011
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// Classes.
+namespace Class {
+  namespace NS {
+    class C {}; // expected-note {{candidate}}
+  }
+  using namespace NS;
+  class C : C {}; // expected-error {{reference to 'C' is ambiguous}} \
+                     expected-note {{candidate}}
+}
+
+// Enumerations.
+enum E {
+  EPtrSize = sizeof((E*)0) // ok, E is already declared
+};
+
+// Alias declarations. clang implements the proposed resolution to N1044.
+namespace Alias {
+  namespace NS {
+    class C;
+  }
+  using namespace NS;
+  using C = C; // ok, C = B::C
+  using C = NS::C; // ok, same type
+}

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp Fri Apr 15 09:24:37 2011
@@ -63,7 +63,7 @@
 struct F : auto {}; // expected-error{{expected class name}}
 template<typename T = auto> struct G { }; // expected-error{{'auto' not allowed here}}
 
-using A = auto; // expected-error{{expected ';'}} expected-error{{requires a qualified name}}
+using A = auto; // expected-error{{'auto' not allowed in type alias}}
 
 // FIXME: don't issue the second diagnostic for this error.
 auto k() -> auto; // expected-error{{'auto' not allowed here}} unexpected-error{{without trailing return type}}

Added: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp?rev=129567&view=auto
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp (added)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp Fri Apr 15 09:24:37 2011
@@ -0,0 +1,161 @@
+// RUN: %clang_cc1 -verify -std=c++0x %s
+
+namespace RedeclAliasTypedef {
+  typedef int T;
+  using T = int;
+  using T = int;
+  typedef T T;
+  using T = T;
+  typedef int T;
+}
+
+namespace IllegalTypeIds {
+  using A = void(int n = 0); // expected-error {{default arguments can only be specified for parameters in a function declaration}}
+  using B = inline void(int n); // expected-error {{type name does not allow function specifier}}
+  using C = virtual void(int n); // expected-error {{type name does not allow function specifier}}
+  using D = explicit void(int n); // expected-error {{type name does not allow function specifier}}
+  using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}}
+  // FIXME: this is illegal; we incorrectly accept it for typedefs too.
+  using F = void(*)(int n) &&; // expected-err
+  using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}}
+
+  using H = void(int n); // ok
+  using I = void(int n) &&; // ok
+}
+
+namespace IllegalSyntax {
+  using ::T = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+  using operator int = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+  using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}}
+  using typename ::V = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+  using typename ::operator bool = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+}
+
+namespace VariableLengthArrays {
+  using T = int[42]; // ok
+
+  int n = 32;
+  using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}}
+
+  const int m = 42;
+  using U = int[m]; // expected-note {{previous definition}}
+  using U = int[42]; // ok
+  using U = int; // expected-error {{type alias redefinition with different types ('int' vs 'int [42]')}}
+
+  void f() {
+    int n = 42;
+    goto foo; // expected-error {{goto into protected scope}}
+    using T = int[n]; // expected-note {{bypasses initialization of VLA type alias}}
+  foo: ;
+  }
+}
+
+namespace RedeclFunc {
+  int f(int, char**);
+  using T = int;
+  T f(int, char **); // ok
+}
+
+namespace LookupFilter {
+  namespace N { struct S; }
+  using namespace N;
+  using S = S*; // ok
+}
+
+namespace InFunctions {
+  template<typename...T> void f0() {
+    using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
+    U u;
+  }
+  template void f0<int, char>();
+
+  void f1() {
+    using T = int;
+  }
+  void f2() {
+    using T = int[-1]; // expected-error {{array size is negative}}
+  }
+
+  template<typename...T> void f3() { // expected-note {{template parameter is declared here}}
+    using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
+  }
+}
+
+namespace ClassNameRedecl {
+  class C0 {
+    // FIXME: this diagnostic is pretty poor
+    using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}}
+  };
+  class C1 {
+    // FIXME: this diagnostic is pretty poor
+    using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}}
+  };
+  class C2 {
+    using C0 = C1; // ok
+  };
+  template<typename...T> class C3 {
+    using f = T; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
+  };
+  template<typename T> class C4 { // expected-note {{template parameter is declared here}}
+    using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
+  };
+  class C5 {
+    class c; // expected-note {{previous definition}}
+    using c = int; // expected-error {{typedef redefinition with different types}}
+    class d;
+    using d = d; // ok
+  };
+  class C6 {
+    class c { using C6 = int; }; // ok
+  };
+}
+
+class CtorDtorName {
+  using X = CtorDtorName;
+  X(); // expected-error {{expected member name}}
+  ~X(); // expected-error {{destructor cannot be declared using a type alias}}
+};
+
+namespace TagName {
+  using S = struct { int n; };
+  using T = class { int n; };
+  using U = enum { a, b, c };
+  using V = struct V { int n; };
+}
+
+namespace CWG1044 {
+  // FIXME: this is terrible. one error is plenty.
+  using T = T; // expected-error {{type name requires a specifier}} \
+                  expected-error {{C++ requires a type specifier}} \
+                  expected-error {{expected ';' after alias declaration}}
+}
+
+namespace StdExample {
+  template<typename T, typename U> struct pair;
+
+  using handler_t = void (*)(int);
+  extern handler_t ignore;
+  extern void (*ignore)(int);
+  // FIXME: we know we're parsing a type here; don't recover as if we were
+  // using operator*.
+  using cell = pair<void*, cell*>; // expected-error {{use of undeclared identifier 'cell'}} \
+                                      expected-error {{expected expression}}
+}
+
+namespace Access {
+  class C0 {
+    using U = int; // expected-note {{declared private here}}
+  };
+  C0::U v; // expected-error {{'U' is a private member}}
+  class C1 {
+  public:
+    using U = int;
+  };
+  C1::U w; // ok
+}
+
+namespace VoidArg {
+  using V = void;
+  V f(int); // ok
+  V g(V); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}}
+}

Modified: cfe/trunk/test/FixIt/fixit-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-cxx0x.cpp Fri Apr 15 09:24:37 2011
@@ -14,3 +14,6 @@
   }
 }
 
+using ::T = void; // expected-error {{name defined in alias declaration must be an identifier}}
+using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}}
+using typename ::V = void; // expected-error {{name defined in alias declaration must be an identifier}}

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Apr 15 09:24:37 2011
@@ -272,6 +272,7 @@
   bool VisitChildren(CXCursor Parent);
 
   // Declaration visitors
+  bool VisitTypeAliasDecl(TypeAliasDecl *D);
   bool VisitAttributes(Decl *D);
   bool VisitBlockDecl(BlockDecl *B);
   bool VisitCXXRecordDecl(CXXRecordDecl *D);
@@ -642,6 +643,13 @@
   return false;
 }
 
+bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
+  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
+    return Visit(TSInfo->getTypeLoc());
+
+  return false;
+}
+
 bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
   if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
     return Visit(TSInfo->getTypeLoc());
@@ -1430,7 +1438,7 @@
 }
 
 bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-  return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
+  return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
 }
 
 bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
@@ -3337,6 +3345,8 @@
     return createCXString("UsingDirective");
   case CXCursor_UsingDeclaration:
     return createCXString("UsingDeclaration");
+  case CXCursor_TypeAliasDecl:
+      return createCXString("TypeAliasDecl");
   }
 
   llvm_unreachable("Unhandled CXCursorKind");
@@ -3877,6 +3887,7 @@
   // declaration and definition.
   case Decl::Namespace:
   case Decl::Typedef:
+  case Decl::TypeAlias:
   case Decl::TemplateTypeParm:
   case Decl::EnumConstant:
   case Decl::Field:

Modified: cfe/trunk/tools/libclang/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexUSRs.cpp?rev=129567&r1=129566&r2=129567&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexUSRs.cpp Fri Apr 15 09:24:37 2011
@@ -431,7 +431,7 @@
   const unsigned off = Buf.size() - 1;
 
   if (EmitDeclName(D)) {
-    if (const TypedefDecl *TD = D->getTypedefForAnonDecl()) {
+    if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
       Buf[off] = 'A';
       Out << '@' << TD;
     }





More information about the cfe-commits mailing list