aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Driver/ASTConsumers.cpp15
-rw-r--r--include/clang/AST/AST.h1
-rw-r--r--include/clang/AST/DeclBase.h4
-rw-r--r--include/clang/AST/DeclCXX.h92
-rw-r--r--include/clang/AST/DeclNodes.def5
-rw-r--r--include/clang/AST/DeclTemplate.h325
-rw-r--r--include/clang/AST/Type.h2
-rw-r--r--include/clang/Parse/Action.h31
-rw-r--r--lib/AST/ASTContext.cpp1
-rw-r--r--lib/AST/CMakeLists.txt1
-rw-r--r--lib/AST/DeclBase.cpp3
-rw-r--r--lib/AST/DeclCXX.cpp30
-rw-r--r--lib/AST/DeclSerialization.cpp48
-rw-r--r--lib/AST/DeclTemplate.cpp108
-rw-r--r--lib/AST/Expr.cpp1
-rw-r--r--lib/AST/Type.cpp1
-rw-r--r--lib/Parse/ParseDecl.cpp2
-rw-r--r--lib/Parse/ParseDeclCXX.cpp12
-rw-r--r--lib/Parse/ParseTemplate.cpp39
-rw-r--r--lib/Parse/Parser.cpp1
-rw-r--r--lib/Sema/Sema.h21
-rw-r--r--lib/Sema/SemaDecl.cpp46
-rw-r--r--lib/Sema/SemaDeclCXX.cpp1
-rw-r--r--lib/Sema/SemaExpr.cpp1
-rw-r--r--lib/Sema/SemaLookup.cpp2
-rw-r--r--lib/Sema/SemaTemplate.cpp70
-rw-r--r--test/Parser/cxx-template-decl.cpp6
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;
+}
+
+//===----------------------------------------------------------------------===//
+/