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.
///
/// FIXME: In the future, this class will be extended to support
@ -589,7 +603,6 @@ class TemplateArgumentList {
/// argument list.
unsigned NumArguments;
public:
TemplateArgumentList(ASTContext &Context,
TemplateArgument *TemplateArgs,

View File

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

View File

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