Add a helper class for building template argument lists.

llvm-svn: 72915
This commit is contained in:
Anders Carlsson 2009-06-05 03:43:12 +00:00
parent 3c1291d384
commit 8aa89d4049
3 changed files with 59 additions and 40 deletions

View File

@ -573,6 +573,20 @@ public:
} }
}; };
/// \brief A helper class for making template argument lists.
class TemplateArgumentListBuilder {
llvm::SmallVector<TemplateArgument, 16> Args;
public:
// FIXME: Should use index array size.
size_t size() const { return Args.size(); }
size_t flatSize() const { return Args.size(); }
TemplateArgument *getFlatArgumentList() { return Args.data(); }
void push_back(const TemplateArgument& Arg) { Args.push_back(Arg); }
};
/// \brief A template argument list. /// \brief A template argument list.
/// ///
/// FIXME: In the future, this class will be extended to support /// FIXME: In the future, this class will be extended to support
@ -589,7 +603,6 @@ class TemplateArgumentList {
/// argument list. /// argument list.
unsigned NumArguments; unsigned NumArguments;
public: public:
TemplateArgumentList(ASTContext &Context, TemplateArgumentList(ASTContext &Context,
TemplateArgument *TemplateArgs, TemplateArgument *TemplateArgs,

View File

@ -20,6 +20,7 @@
#include "SemaOverload.h" #include "SemaOverload.h"
#include "clang/AST/DeclBase.h" #include "clang/AST/DeclBase.h"
#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Parse/Action.h" #include "clang/Parse/Action.h"
#include "clang/Sema/SemaDiagnostic.h" #include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
@ -1971,7 +1972,7 @@ public:
const TemplateArgument *TemplateArgs, const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs, unsigned NumTemplateArgs,
SourceLocation RAngleLoc, SourceLocation RAngleLoc,
llvm::SmallVectorImpl<TemplateArgument> &Converted); TemplateArgumentListBuilder &Converted);
bool CheckTemplateArgument(TemplateTypeParmDecl *Param, QualType Arg, bool CheckTemplateArgument(TemplateTypeParmDecl *Param, QualType Arg,
SourceLocation ArgLoc); SourceLocation ArgLoc);
@ -1980,7 +1981,7 @@ public:
bool CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member); bool CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member);
bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param, bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
QualType InstantiatedParamType, Expr *&Arg, QualType InstantiatedParamType, Expr *&Arg,
llvm::SmallVectorImpl<TemplateArgument> *Converted = 0); TemplateArgumentListBuilder *Converted = 0);
bool CheckTemplateArgument(TemplateTemplateParmDecl *Param, DeclRefExpr *Arg); bool CheckTemplateArgument(TemplateTemplateParmDecl *Param, DeclRefExpr *Arg);
bool TemplateParameterListsAreEqual(TemplateParameterList *New, bool TemplateParameterListsAreEqual(TemplateParameterList *New,
TemplateParameterList *Old, TemplateParameterList *Old,

View File

@ -811,7 +811,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// Check that the template argument list is well-formed for this // Check that the template argument list is well-formed for this
// template. // template.
llvm::SmallVector<TemplateArgument, 16> ConvertedTemplateArgs; TemplateArgumentListBuilder ConvertedTemplateArgs;
if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc, if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
TemplateArgs, NumTemplateArgs, RAngleLoc, TemplateArgs, NumTemplateArgs, RAngleLoc,
ConvertedTemplateArgs)) ConvertedTemplateArgs))
@ -835,15 +835,16 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// template<typename T, typename U = T> struct A; // template<typename T, typename U = T> struct A;
TemplateName CanonName = Context.getCanonicalTemplateName(Name); TemplateName CanonName = Context.getCanonicalTemplateName(Name);
CanonType = Context.getTemplateSpecializationType(CanonName, CanonType = Context.getTemplateSpecializationType(CanonName,
&ConvertedTemplateArgs[0], ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.size()); ConvertedTemplateArgs.flatSize());
} else if (ClassTemplateDecl *ClassTemplate } else if (ClassTemplateDecl *ClassTemplate
= dyn_cast<ClassTemplateDecl>(Template)) { = dyn_cast<ClassTemplateDecl>(Template)) {
// Find the class template specialization declaration that // Find the class template specialization declaration that
// corresponds to these arguments. // corresponds to these arguments.
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
ClassTemplateSpecializationDecl::Profile(ID, &ConvertedTemplateArgs[0], ClassTemplateSpecializationDecl::Profile(ID,
ConvertedTemplateArgs.size()); ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.flatSize());
void *InsertPos = 0; void *InsertPos = 0;
ClassTemplateSpecializationDecl *Decl ClassTemplateSpecializationDecl *Decl
= ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos); = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
@ -852,12 +853,11 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// specialization. Create the canonical declaration and add it to // specialization. Create the canonical declaration and add it to
// the set of specializations. // the set of specializations.
Decl = ClassTemplateSpecializationDecl::Create(Context, Decl = ClassTemplateSpecializationDecl::Create(Context,
ClassTemplate->getDeclContext(), ClassTemplate->getDeclContext(),
TemplateLoc, TemplateLoc,
ClassTemplate, ClassTemplate,
&ConvertedTemplateArgs[0], ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.size(), ConvertedTemplateArgs.flatSize(), 0);
0);
ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos); ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos);
Decl->setLexicalDeclContext(CurContext); Decl->setLexicalDeclContext(CurContext);
} }
@ -955,7 +955,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
const TemplateArgument *TemplateArgs, const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs, unsigned NumTemplateArgs,
SourceLocation RAngleLoc, SourceLocation RAngleLoc,
llvm::SmallVectorImpl<TemplateArgument> &Converted) { TemplateArgumentListBuilder &Converted) {
TemplateParameterList *Params = Template->getTemplateParameters(); TemplateParameterList *Params = Template->getTemplateParameters();
unsigned NumParams = Params->size(); unsigned NumParams = Params->size();
unsigned NumArgs = NumTemplateArgs; unsigned NumArgs = NumTemplateArgs;
@ -1004,12 +1004,13 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
// on the previously-computed template arguments. // on the previously-computed template arguments.
if (ArgType->isDependentType()) { if (ArgType->isDependentType()) {
InstantiatingTemplate Inst(*this, TemplateLoc, InstantiatingTemplate Inst(*this, TemplateLoc,
Template, &Converted[0], Template, Converted.getFlatArgumentList(),
Converted.size(), Converted.flatSize(),
SourceRange(TemplateLoc, RAngleLoc)); SourceRange(TemplateLoc, RAngleLoc));
TemplateArgumentList TemplateArgs(Context, &Converted[0], TemplateArgumentList TemplateArgs(Context,
Converted.size(), Converted.getFlatArgumentList(),
Converted.flatSize(),
/*CopyArgs=*/false); /*CopyArgs=*/false);
ArgType = InstantiateType(ArgType, TemplateArgs, ArgType = InstantiateType(ArgType, TemplateArgs,
TTP->getDefaultArgumentLoc(), TTP->getDefaultArgumentLoc(),
@ -1075,12 +1076,13 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
if (NTTPType->isDependentType()) { if (NTTPType->isDependentType()) {
// Instantiate the type of the non-type template parameter. // Instantiate the type of the non-type template parameter.
InstantiatingTemplate Inst(*this, TemplateLoc, InstantiatingTemplate Inst(*this, TemplateLoc,
Template, &Converted[0], Template, Converted.getFlatArgumentList(),
Converted.size(), Converted.flatSize(),
SourceRange(TemplateLoc, RAngleLoc)); SourceRange(TemplateLoc, RAngleLoc));
TemplateArgumentList TemplateArgs(Context, &Converted[0], TemplateArgumentList TemplateArgs(Context,
Converted.size(), Converted.getFlatArgumentList(),
Converted.flatSize(),
/*CopyArgs=*/false); /*CopyArgs=*/false);
NTTPType = InstantiateType(NTTPType, TemplateArgs, NTTPType = InstantiateType(NTTPType, TemplateArgs,
NTTP->getLocation(), NTTP->getLocation(),
@ -1393,7 +1395,7 @@ Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member) {
/// of this argument will be added to the end of the Converted vector. /// of this argument will be added to the end of the Converted vector.
bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
QualType InstantiatedParamType, Expr *&Arg, QualType InstantiatedParamType, Expr *&Arg,
llvm::SmallVectorImpl<TemplateArgument> *Converted) { TemplateArgumentListBuilder *Converted) {
SourceLocation StartLoc = Arg->getSourceRange().getBegin(); SourceLocation StartLoc = Arg->getSourceRange().getBegin();
// If either the parameter has a dependent type or the argument is // If either the parameter has a dependent type or the argument is
@ -2065,7 +2067,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
// Check that the template argument list is well-formed for this // Check that the template argument list is well-formed for this
// template. // template.
llvm::SmallVector<TemplateArgument, 16> ConvertedTemplateArgs; TemplateArgumentListBuilder ConvertedTemplateArgs;
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc, if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
&TemplateArgs[0], TemplateArgs.size(), &TemplateArgs[0], TemplateArgs.size(),
RAngleLoc, ConvertedTemplateArgs)) RAngleLoc, ConvertedTemplateArgs))
@ -2080,11 +2082,13 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
if (isPartialSpecialization) if (isPartialSpecialization)
// FIXME: Template parameter list matters, too // FIXME: Template parameter list matters, too
ClassTemplatePartialSpecializationDecl::Profile(ID, &ConvertedTemplateArgs[0], ClassTemplatePartialSpecializationDecl::Profile(ID,
ConvertedTemplateArgs.size()); ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.flatSize());
else else
ClassTemplateSpecializationDecl::Profile(ID, &ConvertedTemplateArgs[0], ClassTemplateSpecializationDecl::Profile(ID,
ConvertedTemplateArgs.size()); ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.flatSize());
void *InsertPos = 0; void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl = 0; ClassTemplateSpecializationDecl *PrevDecl = 0;
@ -2128,8 +2132,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
TemplateNameLoc, TemplateNameLoc,
TemplateParams, TemplateParams,
ClassTemplate, ClassTemplate,
&ConvertedTemplateArgs[0], ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.size(), ConvertedTemplateArgs.flatSize(),
PrevPartial); PrevPartial);
if (PrevPartial) { if (PrevPartial) {
@ -2147,8 +2151,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
ClassTemplate->getDeclContext(), ClassTemplate->getDeclContext(),
TemplateNameLoc, TemplateNameLoc,
ClassTemplate, ClassTemplate,
&ConvertedTemplateArgs[0], ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.size(), ConvertedTemplateArgs.flatSize(),
PrevDecl); PrevDecl);
if (PrevDecl) { if (PrevDecl) {
@ -2269,7 +2273,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
// Check that the template argument list is well-formed for this // Check that the template argument list is well-formed for this
// template. // template.
llvm::SmallVector<TemplateArgument, 16> ConvertedTemplateArgs; TemplateArgumentListBuilder ConvertedTemplateArgs;
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc, if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
TemplateArgs.data(), TemplateArgs.size(), TemplateArgs.data(), TemplateArgs.size(),
RAngleLoc, ConvertedTemplateArgs)) RAngleLoc, ConvertedTemplateArgs))
@ -2282,8 +2286,9 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
// Find the class template specialization declaration that // Find the class template specialization declaration that
// corresponds to these arguments. // corresponds to these arguments.
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
ClassTemplateSpecializationDecl::Profile(ID, &ConvertedTemplateArgs[0], ClassTemplateSpecializationDecl::Profile(ID,
ConvertedTemplateArgs.size()); ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.flatSize());
void *InsertPos = 0; void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl ClassTemplateSpecializationDecl *PrevDecl
= ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos); = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
@ -2326,8 +2331,8 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
ClassTemplate->getDeclContext(), ClassTemplate->getDeclContext(),
TemplateNameLoc, TemplateNameLoc,
ClassTemplate, ClassTemplate,
&ConvertedTemplateArgs[0], ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.size(), ConvertedTemplateArgs.flatSize(),
0); 0);
Specialization->setLexicalDeclContext(CurContext); Specialization->setLexicalDeclContext(CurContext);
CurContext->addDecl(Context, Specialization); CurContext->addDecl(Context, Specialization);
@ -2354,8 +2359,8 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
ClassTemplate->getDeclContext(), ClassTemplate->getDeclContext(),
TemplateNameLoc, TemplateNameLoc,
ClassTemplate, ClassTemplate,
&ConvertedTemplateArgs[0], ConvertedTemplateArgs.getFlatArgumentList(),
ConvertedTemplateArgs.size(), ConvertedTemplateArgs.flatSize(),
0); 0);
ClassTemplate->getSpecializations().InsertNode(Specialization, ClassTemplate->getSpecializations().InsertNode(Specialization,