diff options
-rw-r--r-- | Driver/ASTConsumers.cpp | 15 | ||||
-rw-r--r-- | include/clang/AST/AST.h | 1 | ||||
-rw-r--r-- | include/clang/AST/DeclBase.h | 4 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 92 | ||||
-rw-r--r-- | include/clang/AST/DeclNodes.def | 5 | ||||
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 325 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 2 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 31 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 1 | ||||
-rw-r--r-- | lib/AST/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 3 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 30 | ||||
-rw-r--r-- | lib/AST/DeclSerialization.cpp | 48 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 108 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 1 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 12 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 39 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 21 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 46 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 70 | ||||
-rw-r--r-- | test/Parser/cxx-template-decl.cpp | 6 |
27 files changed, 690 insertions, 179 deletions
diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index 6fec595e51..78b199680a 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -52,6 +52,8 @@ namespace { void PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID); void PrintObjCPropertyDecl(ObjCPropertyDecl *PD); void PrintObjCPropertyImplDecl(ObjCPropertyImplDecl *PID); + + void PrintTemplateDecl(TemplateDecl *TD); }; } // end anonymous namespace @@ -116,6 +118,8 @@ void DeclPrinter:: PrintDecl(Decl *D) { Out << "};\n"; } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { Out << "Read top-level tag decl: '" << TD->getNameAsString() << "'\n"; + } else if (TemplateDecl *TempD = dyn_cast<TemplateDecl>(D)) { + PrintTemplateDecl(TempD); } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) { PrintLinkageSpec(LSD); } else if (FileScopeAsmDecl *AD = dyn_cast<FileScopeAsmDecl>(D)) { @@ -437,6 +441,17 @@ void DeclPrinter::PrintObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) { Out << "=" << PID->getPropertyIvarDecl()->getNameAsString(); Out << ";\n"; } + +/// PrintTemplateParams - Print a template parameter list and recursively print +/// it's underlying top-level definition. +void DeclPrinter::PrintTemplateDecl(TemplateDecl *TD) { + // TODO: Write template parameters. + Out << "template <...> "; + PrintDecl(TD->getTemplatedDecl()); +} + + + //===----------------------------------------------------------------------===// /// ASTPrinter - Pretty-printer of ASTs diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h index 96e887cfc0..164c5fbbb6 100644 --- a/include/clang/AST/AST.h +++ b/include/clang/AST/AST.h @@ -19,6 +19,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/Type.h" diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 3aaadedb15..eaecb1e5c8 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -237,6 +237,10 @@ public: return IDNS_Tag; case Namespace: + case Template: + case FunctionTemplate: + case ClassTemplate: + case TemplateTemplateParm: return IdentifierNamespace(IDNS_Tag | IDNS_Ordinary); } } diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 7c248fd9e3..e41dc1802d 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -24,70 +24,6 @@ class CXXDestructorDecl; class CXXConversionDecl; class CXXMethodDecl; -/// TemplateTypeParmDecl - Declaration of a template type parameter, -/// e.g., "T" in -/// @code -/// template<typename T> class vector; -/// @endcode -class TemplateTypeParmDecl : public TypeDecl { - /// Typename - Whether this template type parameter was declaration - /// with the 'typename' keyword. If false, it was declared with the - /// 'class' keyword. - bool Typename : 1; - - TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, bool Typename) - : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename) { } - -public: - static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - bool Typename); - - /// wasDeclarationWithTypename - Whether this template type - /// parameter was declared with the 'typename' keyword. If not, it - /// was declared with the 'class' keyword. - bool wasDeclaredWithTypename() const { return Typename; } - - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *D) { - return D->getKind() == TemplateTypeParm; - } - static bool classof(const TemplateTypeParmDecl *D) { return true; } - -protected: - /// EmitImpl - Serialize this TemplateTypeParmDecl. Called by Decl::Emit. - virtual void EmitImpl(llvm::Serializer& S) const; - - /// CreateImpl - Deserialize a TemplateTypeParmDecl. Called by Decl::Create. - static TemplateTypeParmDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C); - - friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C); -}; - -/// NonTypeTemplateParmDecl - Declares a non-type template parameter, -/// e.g., "Size" in -/// @code -/// template<int Size> class array { }; -/// @endcode -class NonTypeTemplateParmDecl : public VarDecl { - NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, - SourceLocation TSSL = SourceLocation()) - : VarDecl(NonTypeTemplateParm, DC, L, Id, T, VarDecl::None, TSSL) { } - -public: - static NonTypeTemplateParmDecl * - Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - QualType T, SourceLocation TypeSpecStartLoc = SourceLocation()); - - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *D) { - return D->getKind() == NonTypeTemplateParm; - } - static bool classof(const NonTypeTemplateParmDecl *D) { return true; } -}; - /// OverloadedFunctionDecl - An instance of this class represents a /// set of overloaded functions. All of the functions have the same /// name and occur within the same scope. @@ -1024,34 +960,6 @@ public: friend class DeclContext; }; -/// TemplateParameterList - Stores a list of template parameters. -class TemplateParameterList { - /// NumParams - The number of template parameters in this template - /// parameter list. - unsigned NumParams; - - TemplateParameterList(Decl **Params, unsigned NumParams); - -public: - static TemplateParameterList *Create(ASTContext &C, Decl **Params, - unsigned NumParams); - - /// iterator - Iterates through the template parameters in this list. - typedef Decl** iterator; - - /// const_iterator - Iterates through the template parameters in this list. - typedef Decl* const* const_iterator; - - iterator begin() { return reinterpret_cast<Decl **>(this + 1); } - const_iterator begin() const { - return reinterpret_cast<Decl * const *>(this + 1); - } - iterator end() { return begin() + NumParams; } - const_iterator end() const { return begin() + NumParams; } - - unsigned size() const { return NumParams; } -}; - } // end namespace clang #endif diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def index 17a8bc3835..195553ccef 100644 --- a/include/clang/AST/DeclNodes.def +++ b/include/clang/AST/DeclNodes.def @@ -97,6 +97,10 @@ ABSTRACT_DECL(Named, Decl) DECL(ParmVar, VarDecl) DECL(OriginalParmVar, ParmVarDecl) DECL(NonTypeTemplateParm, VarDecl) + DECL(Template, NamedDecl) + DECL(FunctionTemplate, TemplateDecl) + DECL(ClassTemplate, TemplateDecl) + DECL(TemplateTemplateParm, TemplateDecl) DECL(ObjCMethod, NamedDecl) DECL(ObjCContainer, NamedDecl) DECL(ObjCCategory, ObjCContainerDecl) @@ -139,6 +143,7 @@ DECL_RANGE(Tag, Enum, CXXRecord) DECL_RANGE(Record, Record, CXXRecord) DECL_RANGE(Value, EnumConstant, NonTypeTemplateParm) DECL_RANGE(Function, Function, CXXConversion) +DECL_RANGE(Template, Template, TemplateTemplateParm) LAST_DECL_RANGE(Var, Var, NonTypeTemplateParm) #undef LAST_DECL_RANGE diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h new file mode 100644 index 0000000000..98fd42df43 --- /dev/null +++ b/include/clang/AST/DeclTemplate.h @@ -0,0 +1,325 @@ +//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the C++ template declaration subclasses. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H +#define LLVM_CLANG_AST_DECLTEMPLATE_H + +namespace clang { + +class TemplateParameterList; +class TemplateDecl; +class FunctionTemplateDecl; +class ClassTemplateDecl; +class TemplateTypeParmDecl; +class NonTypeTemplateParmDecl; +class TemplateTemplateParmDecl; + +/// TemplateParameterList - Stores a list of template parameters for a +/// TemplateDecl and its derived classes. +class TemplateParameterList { + /// NumParams - The number of template parameters in this template + /// parameter list. + unsigned NumParams; + + TemplateParameterList(Decl **Params, unsigned NumParams); + +public: + static TemplateParameterList *Create(ASTContext &C, Decl **Params, + unsigned NumParams); + + /// iterator - Iterates through the template parameters in this list. + typedef Decl** iterator; + + /// const_iterator - Iterates through the template parameters in this list. + typedef Decl* const* const_iterator; + + iterator begin() { return reinterpret_cast<Decl **>(this + 1); } + const_iterator begin() const { + return reinterpret_cast<Decl * const *>(this + 1); + } + iterator end() { return begin() + NumParams; } + const_iterator end() const { return begin() + NumParams; } + + unsigned size() const { return NumParams; } +}; + +//===----------------------------------------------------------------------===// +// Kinds of Templates +//===----------------------------------------------------------------------===// + +/// TemplateDecl - The base class of all kinds of template declarations (e.g., +/// class, function, etc.). The TemplateDecl class stores the list of template +/// parameters and a reference to the templated scoped declaration: the +/// underlying AST node. +class TemplateDecl : public NamedDecl { +protected: + // This is probably never used. + TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName Name) + : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) + { } + + // Construct a template decl with the given name and parameters. + // Used when there is not templated element (tt-params, alias?). + TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName Name, TemplateParameterList *Params) + : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) + { } + + // Construct a template decl with name, parameters, and templated element. + TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName Name, TemplateParameterList *Params, + NamedDecl *Decl) + : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), + TemplateParams(Params) { } +public: + ~TemplateDecl(); + + /// Get the list of template parameters + TemplateParameterList *GetTemplateParameters() const { + return TemplateParams; + } + + /// Get the underlying, templated declaration. + NamedDecl *getTemplatedDecl() const { return TemplatedDecl; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { + return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast; + } + static bool classof(const TemplateDecl *D) { return true; } + static bool classof(const FunctionTemplateDecl *D) { return true; } + static bool classof(const ClassTemplateDecl *D) { return true; } + static bool classof(const TemplateTemplateParmDecl *D) { return true; } + +protected: + NamedDecl *TemplatedDecl; + TemplateParameterList* TemplateParams; +}; + +/// Declaration of a template function. +class FunctionTemplateDecl : public TemplateDecl { +protected: + FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl) + : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { } +public: + /// Get the underling function declaration of the template. + FunctionDecl *getTemplatedDecl() const { + return static_cast<FunctionDecl*>(TemplatedDecl); + } + + /// Create a template function node. + static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + DeclarationName Name, + TemplateParameterList *Params, + NamedDecl *Decl); + + // Implement isa/cast/dyncast support + static bool classof(const Decl *D) + { return D->getKind() == FunctionTemplate; } + static bool classof(const FunctionTemplateDecl *D) + { return true; } +}; + +/// Declaration of a template class. +class ClassTemplateDecl : public TemplateDecl { +protected: + ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl) + : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { } +public: + /// Get the underlying class declarations of the template. + CXXRecordDecl *getTemplatedDecl() const { + return static_cast<CXXRecordDecl*>(TemplatedDecl); + } + + /// Create a class teplate node. + static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + DeclarationName Name, + TemplateParameterList *Params, + NamedDecl *Decl); + + // Implement isa/cast/dyncast support + static bool classof(const Decl *D) + { return D->getKind() == ClassTemplate; } + static bool classof(const ClassTemplateDecl *D) + { return true; } +}; + +//===----------------------------------------------------------------------===// +// Kinds of Template Parameters +//===----------------------------------------------------------------------===// + + +/// The TemplateParmPosition class defines the position of a template parameter +/// within a template parameter list. Because template parameter can be listed +/// sequentially for out-of-line template members, each template parameter is +/// given a Depth - the nesting of template parameter scopes - and a Position - +/// the occurrence within the parameter list. +/// This class is inheritedly privately by different kinds of template +/// parameters and is not part of the Decl hierarchy. Just a facility. +class TemplateParmPosition +{ +protected: + // FIXME: This should probably never be called, but it's here as + TemplateParmPosition() + : Depth(0), Position(0) + { /* assert(0 && "Cannot create positionless template parameter"); */ } + + TemplateParmPosition(unsigned D, unsigned P) + : Depth(D), Position(P) + { } + + // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for + // position? Maybe? + unsigned Depth; + unsigned Position; + +public: + /// Get the nesting depth of the template parameter. + unsigned getDepth() const { return Depth; } + + /// Get the position of the template parameter within its parameter list. + unsigned getPosition() const { return Position; } +}; + +/// TemplateTypeParmDecl - Declaration of a template type parameter, +/// e.g., "T" in +/// @code +/// template<typename T> class vector; +/// @endcode +class TemplateTypeParmDecl + : public TypeDecl, protected TemplateParmPosition { + /// Typename - Whether this template type parameter was declaration + /// with the 'typename' keyword. If false, it was declared with the + /// 'class' keyword. + bool Typename : 1; + + TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, bool Typename) + : TypeDecl(TemplateTypeParm, DC, L, Id), TemplateParmPosition(D, P), + Typename(Typename) { } +public: + static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, unsigned D, unsigned P, + IdentifierInfo *Id, bool Typename); + + /// wasDeclarationWithTypename - Whether this template type + /// parameter was declared with the 'typename' keyword. If not, it + /// was declared with the 'class' keyword. + bool wasDeclaredWithTypename() const { return Typename; } + + using TemplateParmPosition::getDepth; + using TemplateParmPosition::getPosition; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { + return D->getKind() == TemplateTypeParm; + } + static bool classof(const TemplateTypeParmDecl *D) { return true; } + +protected: + /// EmitImpl - Serialize this TemplateTypeParmDecl. Called by Decl::Emit. + virtual void EmitImpl(llvm::Serializer& S) const; + + /// CreateImpl - Deserialize a TemplateTypeParmDecl. Called by Decl::Create. + static TemplateTypeParmDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C); + + friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C); +}; + +/// NonTypeTemplateParmDecl - Declares a non-type template parameter, +/// e.g., "Size" in +/// @code +/// template<int Size> class array { }; +/// @endcode +class NonTypeTemplateParmDecl + : public VarDecl, protected TemplateParmPosition { + NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, QualType T, + SourceLocation TSSL = SourceLocation()) + : VarDecl(NonTypeTemplateParm, DC, L, Id, T, VarDecl::None, TSSL), + TemplateParmPosition(D, P) { } +public: + static NonTypeTemplateParmDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, QualType T, + SourceLocation TypeSpecStartLoc = SourceLocation()); + + using TemplateParmPosition::getDepth; + using TemplateParmPosition::getPosition; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { + return D->getKind() == NonTypeTemplateParm; + } + static bool classof(const NonTypeTemplateParmDecl *D) { return true; } + +protected: + /// EmitImpl - Serialize this TemplateTypeParmDecl. Called by Decl::Emit. + virtual void EmitImpl(llvm::Serializer& S) const; + + /// CreateImpl - Deserialize a TemplateTypeParmDecl. Called by Decl::Create. + static NonTypeTemplateParmDecl* CreateImpl(llvm::Deserializer& D, + ASTContext& C); + + friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C); +}; + +/// TemplateTemplateParmDecl - Declares a template template parameter, +/// e.g., "T" in +/// @code +/// template <template <typename> class T> class container { }; +/// @endcode +/// A template template parameter is a TemplateDecl because it defines the +/// name of a template and the template parameters allowable for substitution. +class TemplateTemplateParmDecl + : public TemplateDecl, protected TemplateParmPosition { + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, + unsigned D, unsigned P, + IdentifierInfo *Id, TemplateParameterList *Params) + : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), + TemplateParmPosition(D, P) + { } +public: + static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, + TemplateParameterList *Params); + + using TemplateParmPosition::getDepth; + using TemplateParmPosition::getPosition; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { + return D->getKind() == TemplateTemplateParm; + } + static bool classof(const TemplateTemplateParmDecl *D) { return true; } + +protected: + /// EmitImpl - Serialize this TemplateTypeParmDecl. Called by Decl::Emit. + virtual void EmitImpl(llvm::Serializer& S) const; + + /// CreateImpl - Deserialize a TemplateTypeParmDecl. Called by Decl::Create. + static TemplateTemplateParmDecl* CreateImpl(llvm::Deserializer& D, + ASTContext& C); + + friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C); +}; + +} /* end of namespace clang */ + +#endif diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 7697f4a01d..6b2797307f 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -31,6 +31,8 @@ namespace clang { class Type; class TypedefDecl; class TemplateTypeParmDecl; + class NonTypeTemplateParmDecl; + class TemplateTemplateParamDecl; class TagDecl; class RecordDecl; class CXXRecordDecl; diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 7d5bf4579e..bf67b7873f 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -1019,16 +1019,16 @@ public: /// (otherwise, "class" was used), and KeyLoc is the location of the /// "class" or "typename" keyword. ParamName is the name of the /// parameter (NULL indicates an unnamed template parameter) and - /// ParamName is the location of the parameter name (if any). + /// ParamNameLoc is the location of the parameter name (if any). /// If the type parameter has a default argument, it will be added /// later via ActOnTypeParameterDefault. Depth and Position provide /// the number of enclosing templates (see /// ActOnTemplateParameterList) and the number of previous /// parameters within this template parameter list. - virtual DeclTy *ActOnTypeParameter(Scope *S, bool Typename, - SourceLocation KeyLoc, - IdentifierInfo *ParamName, - SourceLocation ParamNameLoc, + virtual DeclTy *ActOnTypeParameter(Scope *S, bool Typename, + SourceLocation KeyLoc, + IdentifierInfo *ParamName, + SourceLocation ParamNameLoc, unsigned Depth, unsigned Position) { return 0; } @@ -1041,8 +1041,8 @@ public: /// ActOnNonTypeTemplateParameter - Called when a C++ non-type /// template parameter (e.g., "int Size" in "template<int Size> /// class Array") has been parsed. S is the current scope and D is - /// the parsed declarator. Depth and Position provide - /// the number of enclosing templates (see + /// the parsed declarator. Depth and Position provide the number of + /// enclosing templates (see /// ActOnTemplateParameterList) and the number of previous /// parameters within this template parameter list. virtual DeclTy *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, @@ -1051,6 +1051,22 @@ public: return 0; } + /// ActOnTemplateTemplateParameter - Called when a C++ template template + /// parameter (e.g., "int T" in "template<template <typename> class T> class + /// Array") has been parsed. TmpLoc is the location of the "template" keyword, + /// TemplateParams is the sequence of parameters required by the template, + /// ParamName is the name of the parameter (null if unnamed), and ParamNameLoc + /// is the source location of the identifier (if given). + virtual DeclTy *ActOnTemplateTemplateParameter(Scope *S, + SourceLocation TmpLoc, + TemplateParamsTy *Params, + IdentifierInfo *ParamName, + SourceLocation ParamNameLoc, + unsigned Depth, + unsigned Position) { + return 0; + } + /// ActOnTemplateParameterList - Called when a complete template /// parameter list has been parsed, e.g., /// @@ -1090,6 +1106,7 @@ public: return 0; } + //===----------------------- Obj-C Declarations -------------------------===// // ActOnStartClassInterface - this action is called immediately after parsing diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 7892c84f92..7784aed764 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -14,6 +14,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" #include "clang/Basic/TargetInfo.h" diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index c49a0eeee5..9687f34be8 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -13,6 +13,7 @@ add_clang_library(clangAST DeclGroup.cpp DeclObjC.cpp DeclSerialization.cpp + DeclTemplate.cpp ExprConstant.cpp Expr.cpp ExprCXX.cpp diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 21e1e0ce10..1e3683c857 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -13,8 +13,9 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/Decl.h" -#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Type.h" #include "llvm/ADT/DenseMap.h" diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 5e1875ab65..6de575411b 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -21,36 +21,6 @@ using namespace clang; // Decl Allocation/Deallocation Method Implementations //===----------------------------------------------------------------------===// -TemplateTypeParmDecl * -TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - bool Typename) { - return new (C) TemplateTypeParmDecl(DC, L, Id, Typename); -} - -NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - QualType T, SourceLocation TypeSpecStartLoc) { - return new (C) NonTypeTemplateParmDecl(DC, L, Id, T, TypeSpecStartLoc); -} - -TemplateParameterList::TemplateParameterList(Decl **Params, unsigned NumParams) - : NumParams(NumParams) { - for (unsigned Idx = 0; Idx < NumParams; ++Idx) - begin()[Idx] = Params[Idx]; -} - -TemplateParameterList * -TemplateParameterList::Create(ASTContext &C, Decl **Params, - unsigned NumParams) { - // FIXME: how do I pass in Size to ASTContext::new? - unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams; - unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment; - void *Mem = C.Allocate(Size, Align); - return new (Mem) TemplateParameterList(Params, NumParams); -} - CXXRecordDecl::CXXRecordDecl(TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id) : RecordDecl(CXXRecord, TK, DC, L, Id), diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp index a10b229fcd..dcb8cda33b 100644 --- a/lib/AST/DeclSerialization.cpp +++ b/lib/AST/DeclSerialization.cpp @@ -14,6 +14,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "llvm/Bitcode/Serialize.h" #include "llvm/Bitcode/Deserialize.h" @@ -597,15 +598,60 @@ TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D, ASTContext& C) { //===----------------------------------------------------------------------===// void TemplateTypeParmDecl::EmitImpl(Serializer& S) const { + S.EmitInt(Depth); + S.EmitInt(Position); S.EmitBool(Typename); NamedDecl::EmitInRec(S); } TemplateTypeParmDecl * TemplateTypeParmDecl::CreateImpl(Deserializer& D, ASTContext& C) { + unsigned Depth = D.ReadInt(); + unsigned Position = D.ReadInt(); bool Typename = D.ReadBool(); TemplateTypeParmDecl *decl - = new (C) TemplateTypeParmDecl(0, SourceLocation(), NULL, Typename); + = new (C) TemplateTypeParmDecl(0, SourceLocation(), Depth, Position, + 0, Typename); + decl->NamedDecl::ReadInRec(D, C); + return decl; +} + +//===----------------------------------------------------------------------===// +// NonTypeTemplateParmDecl Serialization. +//===----------------------------------------------------------------------===// +void NonTypeTemplateParmDecl::EmitImpl(Serializer& S) const { + S.EmitInt(Depth); + S.EmitInt(Position); + NamedDecl::Emit(S); +} + +NonTypeTemplateParmDecl* +NonTypeTemplateParmDecl::CreateImpl(Deserializer& D, ASTContext& C) { + unsigned Depth = D.ReadInt(); + unsigned Position = D.ReadInt(); + NonTypeTemplateParmDecl *decl + = new (C) NonTypeTemplateParmDecl(0, SourceLocation(), Depth, Position, + 0, QualType(), SourceLocation()); + decl->NamedDecl::ReadInRec(D, C); + return decl; +} + +//===----------------------------------------------------------------------===// +/ |