diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-04-15 14:24:37 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-04-15 14:24:37 +0000 |
commit | 162e1c1b487352434552147967c3dd296ebee2f7 (patch) | |
tree | 997de42e97482fd054626d9433d6bf766f93b738 | |
parent | 98a57868d696cb5faf6195a609ad084a711c6bbe (diff) |
Support for C++11 (non-template) alias declarations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129567 91177308-0d34-0410-b5e6-96231b3b80d8
60 files changed, 724 insertions, 228 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 4d93afd105..715a360c4b 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -1101,10 +1101,12 @@ enum CXCursorKind { 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 */ diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 7a62af7eea..63d6d0096b 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -71,7 +71,7 @@ namespace clang { class TemplateTypeParmDecl; class TranslationUnitDecl; class TypeDecl; - class TypedefDecl; + class TypedefNameDecl; class UsingDecl; class UsingShadowDecl; class UnresolvedSetIterator; @@ -664,9 +664,9 @@ public: } /// 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; diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 44b04dfa1f..9255b280d6 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1995,17 +1995,21 @@ public: }; -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 @@ public: 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 @@ public: 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 @@ public: 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 @@ private: // 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 @@ protected: 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 @@ public: 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. diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index d4a90fbefd..0b3993d88e 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1357,6 +1357,13 @@ DEF_TRAVERSE_DECL(TypedefDecl, { // 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; }; diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index e74a9c9dd6..5d1588726b 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -73,7 +73,7 @@ namespace llvm { namespace clang { class ASTContext; - class TypedefDecl; + class TypedefNameDecl; class TemplateDecl; class TemplateTypeParmDecl; class NonTypeTemplateParmDecl; @@ -2625,18 +2625,18 @@ public: 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; diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 8c97a4225b..d1ce52b3dd 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -527,7 +527,7 @@ class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, TypedefTypeLoc, TypedefType> { public: - TypedefDecl *getTypedefDecl() const { + TypedefNameDecl *getTypedefNameDecl() const { return getTypePtr()->getDecl(); } }; diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index 2ec7427cf7..9e69492e13 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -17,7 +17,9 @@ def Named : Decl<1>; 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>; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 26cb8e14d6..09ac5fe02f 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -430,6 +430,12 @@ def err_missing_whitespace_digraph : Error< 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>; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index bddfff2f6e..747a657a4b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -545,7 +545,7 @@ def ext_using_undefined_std : ExtWarn< // 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_redeclared : Error<"destructor cannot be redeclared">; 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 @@ def err_auto_not_allowed : Error< "'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 err_ident_list_in_fn_declaration : Error< 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_type : Error< 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 @@ def note_protected_by_cleanup : Note< "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< diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 08d0d00cbf..1f67292f15 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -1325,7 +1325,8 @@ public: 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 @@ public: return false; case TypeNameContext: + case AliasDeclContext: case PrototypeContext: case ObjCPrototypeContext: case TemplateParamContext: @@ -1494,6 +1496,7 @@ public: return true; case TypeNameContext: + case AliasDeclContext: case ObjCPrototypeContext: case BlockLiteralContext: case TemplateTypeArgContext: @@ -1521,6 +1524,7 @@ public: case TemplateParamContext: case CXXCatchContext: case TypeNameContext: + case AliasDeclContext: case BlockLiteralContext: case TemplateTypeArgContext: return false; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index f9d7d9aecd..df3c6643e3 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -128,7 +128,9 @@ namespace clang { class TemplatePartialOrderingContext; class TemplateTemplateParmDecl; class Token; + class TypeAliasDecl; class TypedefDecl; + class TypedefNameDecl; class TypeLoc; class UnqualifiedId; class UnresolvedLookupExpr; @@ -255,7 +257,7 @@ public: /// 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 @@ public: 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 @@ public: 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 @@ public: /// Subroutines of ActOnDeclarator(). TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T, TypeSour |