aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/DeclTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/DeclTemplate.cpp')
-rw-r--r--lib/AST/DeclTemplate.cpp206
1 files changed, 135 insertions, 71 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index f1bd1b67d21e..7836b3f827ce 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -25,7 +25,7 @@ using namespace clang;
TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
- Decl **Params, unsigned NumParams,
+ NamedDecl **Params, unsigned NumParams,
SourceLocation RAngleLoc)
: TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
NumParams(NumParams) {
@@ -35,31 +35,32 @@ TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
TemplateParameterList *
TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc,
- SourceLocation LAngleLoc, Decl **Params,
+ SourceLocation LAngleLoc, NamedDecl **Params,
unsigned NumParams, SourceLocation RAngleLoc) {
- unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams;
+ unsigned Size = sizeof(TemplateParameterList)
+ + sizeof(NamedDecl *) * NumParams;
unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
void *Mem = C.Allocate(Size, Align);
- return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
+ return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
NumParams, RAngleLoc);
}
unsigned TemplateParameterList::getMinRequiredArguments() const {
unsigned NumRequiredArgs = size();
- iterator Param = const_cast<TemplateParameterList *>(this)->end(),
+ iterator Param = const_cast<TemplateParameterList *>(this)->end(),
ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
while (Param != ParamBegin) {
--Param;
-
+
if (!(*Param)->isTemplateParameterPack() &&
- !(isa<TemplateTypeParmDecl>(*Param) &&
+ !(isa<TemplateTypeParmDecl>(*Param) &&
cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
!(isa<NonTypeTemplateParmDecl>(*Param) &&
cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&
!(isa<TemplateTemplateParmDecl>(*Param) &&
cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument()))
break;
-
+
--NumRequiredArgs;
}
@@ -94,16 +95,23 @@ void FunctionTemplateDecl::Destroy(ASTContext &C) {
Spec != SpecEnd; ++Spec)
C.Deallocate(&*Spec);
}
-
+
Decl::Destroy(C);
}
+FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() {
+ FunctionTemplateDecl *FunTmpl = this;
+ while (FunTmpl->getPreviousDeclaration())
+ FunTmpl = FunTmpl->getPreviousDeclaration();
+ return FunTmpl;
+}
+
FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
// Find the first declaration of this function template.
FunctionTemplateDecl *First = this;
while (First->getPreviousDeclaration())
First = First->getPreviousDeclaration();
-
+
if (First->CommonOrPrev.isNull()) {
// FIXME: Allocate with the ASTContext
First->CommonOrPrev = new Common;
@@ -115,6 +123,13 @@ FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
// ClassTemplateDecl Implementation
//===----------------------------------------------------------------------===//
+ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
+ ClassTemplateDecl *Template = this;
+ while (Template->getPreviousDeclaration())
+ Template = Template->getPreviousDeclaration();
+ return Template;
+}
+
ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
@@ -128,7 +143,7 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
else
CommonPtr = new (C) Common;
- return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
+ return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
CommonPtr);
}
@@ -147,6 +162,21 @@ void ClassTemplateDecl::Destroy(ASTContext& C) {
C.Deallocate((void*)this);
}
+ClassTemplatePartialSpecializationDecl *
+ClassTemplateDecl::findPartialSpecialization(QualType T) {
+ ASTContext &Context = getASTContext();
+ typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+ partial_spec_iterator;
+ for (partial_spec_iterator P = getPartialSpecializations().begin(),
+ PEnd = getPartialSpecializations().end();
+ P != PEnd; ++P) {
+ if (Context.hasSameType(Context.getTypeDeclType(&*P), T))
+ return &*P;
+ }
+
+ return 0;
+}
+
QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
if (!CommonPtr->InjectedClassNameType.isNull())
return CommonPtr->InjectedClassNameType;
@@ -157,52 +187,32 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
// better to fix that redundancy.
TemplateParameterList *Params = getTemplateParameters();
-
llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
- llvm::SmallVector<TemplateArgument, 16> CanonTemplateArgs;
TemplateArgs.reserve(Params->size());
- CanonTemplateArgs.reserve(Params->size());
-
- for (TemplateParameterList::iterator
- Param = Params->begin(), ParamEnd = Params->end();
+ for (TemplateParameterList::iterator Param = Params->begin(),
+ ParamEnd = Params->end();
Param != ParamEnd; ++Param) {
if (isa<TemplateTypeParmDecl>(*Param)) {
QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
- TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(),
+ TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(),
ParamType));
- CanonTemplateArgs.push_back(
- TemplateArgument((*Param)->getLocation(),
- Context.getCanonicalType(ParamType)));
- } else if (NonTypeTemplateParmDecl *NTTP =
+ } else if (NonTypeTemplateParmDecl *NTTP =
dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
- // FIXME: Build canonical expression, too!
Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
NTTP->getLocation(),
NTTP->getType()->isDependentType(),
/*Value-dependent=*/true);
TemplateArgs.push_back(TemplateArgument(E));
- CanonTemplateArgs.push_back(TemplateArgument(E));
- } else {
+ } else {
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP));
- CanonTemplateArgs.push_back(TemplateArgument(TTP->getLocation(),
- Context.getCanonicalDecl(TTP)));
}
}
- // FIXME: I should really move the "build-the-canonical-type" logic
- // into ASTContext::getTemplateSpecializationType.
- TemplateName Name = TemplateName(this);
- QualType CanonType = Context.getTemplateSpecializationType(
- Context.getCanonicalTemplateName(Name),
- &CanonTemplateArgs[0],
- CanonTemplateArgs.size());
-
CommonPtr->InjectedClassNameType
- = Context.getTemplateSpecializationType(Name,
+ = Context.getTemplateSpecializationType(TemplateName(this),
&TemplateArgs[0],
- TemplateArgs.size(),
- CanonType);
+ TemplateArgs.size());
return CommonPtr->InjectedClassNameType;
}
@@ -227,14 +237,13 @@ NonTypeTemplateParmDecl *
NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
- SourceLocation TypeSpecStartLoc) {
- return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T,
- TypeSpecStartLoc);
+ DeclaratorInfo *DInfo) {
+ return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, DInfo);
}
SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
- : SourceLocation();
+ : SourceLocation();
}
//===----------------------------------------------------------------------===//
@@ -251,7 +260,7 @@ TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
- : SourceLocation();
+ : SourceLocation();
}
//===----------------------------------------------------------------------===//
@@ -264,10 +273,10 @@ TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
}
/// \brief Construct a template argument pack.
-void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
+void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
bool CopyArgs) {
assert(isNull() && "Must call setArgumentPack on a null argument");
-
+
Kind = Pack;
Args.NumArgs = NumArgs;
Args.CopyArgs = CopyArgs;
@@ -275,7 +284,8 @@ void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
Args.Args = args;
return;
}
-
+
+ // FIXME: Allocate in ASTContext
Args.Args = new TemplateArgument[NumArgs];
for (unsigned I = 0; I != Args.NumArgs; ++I)
Args.Args[I] = args[I];
@@ -292,21 +302,21 @@ void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
assert(Arg.getAsType()->isCanonical() && "Type must be canonical!");
break;
}
-
+
assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
- assert(!StructuredArgs &&
+ assert(!StructuredArgs &&
"Can't append arguments when an argument pack has been added!");
-
+
if (!FlatArgs)
FlatArgs = new TemplateArgument[MaxFlatArgs];
-
+
FlatArgs[NumFlatArgs++] = Arg;
}
void TemplateArgumentListBuilder::BeginPack() {
assert(!AddingToPack && "Already adding to pack!");
assert(!StructuredArgs && "Argument list already contains a pack!");
-
+
AddingToPack = true;
PackBeginIndex = NumFlatArgs;
}
@@ -314,24 +324,24 @@ void TemplateArgumentListBuilder::BeginPack() {
void TemplateArgumentListBuilder::EndPack() {
assert(AddingToPack && "Not adding to pack!");
assert(!StructuredArgs && "Argument list already contains a pack!");
-
+
AddingToPack = false;
StructuredArgs = new TemplateArgument[MaxStructuredArgs];
-
+
// First copy the flat entries over to the list (if any)
for (unsigned I = 0; I != PackBeginIndex; ++I) {
NumStructuredArgs++;
StructuredArgs[I] = FlatArgs[I];
}
-
+
// Next, set the pack.
TemplateArgument *PackArgs = 0;
unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
if (NumPackArgs)
PackArgs = &FlatArgs[PackBeginIndex];
-
- StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
+
+ StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
/*CopyArgs=*/false);
}
@@ -350,19 +360,25 @@ void TemplateArgumentListBuilder::ReleaseArgs() {
TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
TemplateArgumentListBuilder &Builder,
bool TakeArgs)
- : FlatArguments(Builder.getFlatArguments(), TakeArgs),
- NumFlatArguments(Builder.flatSize()),
+ : FlatArguments(Builder.getFlatArguments(), TakeArgs),
+ NumFlatArguments(Builder.flatSize()),
StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
NumStructuredArguments(Builder.structuredSize()) {
-
+
if (!TakeArgs)
return;
-
+
if (Builder.getStructuredArguments() == Builder.getFlatArguments())
StructuredArguments.setInt(0);
Builder.ReleaseArgs();
}
+TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other)
+ : FlatArguments(Other.FlatArguments.getPointer(), 1),
+ NumFlatArguments(Other.flat_size()),
+ StructuredArguments(Other.StructuredArguments.getPointer(), 1),
+ NumStructuredArguments(Other.NumStructuredArguments) { }
+
TemplateArgumentList::~TemplateArgumentList() {
// FIXME: Deallocate template arguments
}
@@ -374,34 +390,66 @@ ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder)
- : CXXRecordDecl(DK,
- SpecializedTemplate->getTemplatedDecl()->getTagKind(),
+ TemplateArgumentListBuilder &Builder,
+ ClassTemplateSpecializationDecl *PrevDecl)
+ : CXXRecordDecl(DK,
+ SpecializedTemplate->getTemplatedDecl()->getTagKind(),
DC, L,
// FIXME: Should we use DeclarationName for the name of
// class template specializations?
- SpecializedTemplate->getIdentifier()),
+ SpecializedTemplate->getIdentifier(),
+ PrevDecl),
SpecializedTemplate(SpecializedTemplate),
TemplateArgs(Context, Builder, /*TakeArgs=*/true),
SpecializationKind(TSK_Undeclared) {
}
-
+
ClassTemplateSpecializationDecl *
-ClassTemplateSpecializationDecl::Create(ASTContext &Context,
+ClassTemplateSpecializationDecl::Create(ASTContext &Context,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
ClassTemplateSpecializationDecl *PrevDecl) {
ClassTemplateSpecializationDecl *Result
- = new (Context)ClassTemplateSpecializationDecl(Context,
+ = new (Context)ClassTemplateSpecializationDecl(Context,
ClassTemplateSpecialization,
- DC, L,
+ DC, L,
SpecializedTemplate,
- Builder);
+ Builder,
+ PrevDecl);
Context.getTypeDeclType(Result, PrevDecl);
return Result;
}
+void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) {
+ if (SpecializedPartialSpecialization *PartialSpec
+ = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+ C.Deallocate(PartialSpec);
+
+ CXXRecordDecl::Destroy(C);
+}
+
+void
+ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
+ const PrintingPolicy &Policy,
+ bool Qualified) const {
+ NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
+
+ const TemplateArgumentList &TemplateArgs = getTemplateArgs();
+ S += TemplateSpecializationType::PrintTemplateArgumentList(
+ TemplateArgs.getFlatArgumentList(),
+ TemplateArgs.flat_size(),
+ Policy);
+}
+
+ClassTemplateDecl *
+ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
+ if (SpecializedPartialSpecialization *PartialSpec
+ = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+ return PartialSpec->PartialSpecialization->getSpecializedTemplate();
+ return SpecializedTemplate.get<ClassTemplateDecl*>();
+}
+
//===----------------------------------------------------------------------===//
// ClassTemplatePartialSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
@@ -413,11 +461,27 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
TemplateArgumentListBuilder &Builder,
ClassTemplatePartialSpecializationDecl *PrevDecl) {
ClassTemplatePartialSpecializationDecl *Result
- = new (Context)ClassTemplatePartialSpecializationDecl(Context,
+ = new (Context)ClassTemplatePartialSpecializationDecl(Context,
DC, L, Params,
SpecializedTemplate,
- Builder);
+ Builder, PrevDecl);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
Context.getTypeDeclType(Result, PrevDecl);
return Result;
}
+
+//===----------------------------------------------------------------------===//
+// FriendTemplateDecl Implementation
+//===----------------------------------------------------------------------===//
+
+FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
+ DeclContext *DC,
+ SourceLocation L,
+ unsigned NParams,
+ TemplateParameterList **Params,
+ FriendUnion Friend,
+ SourceLocation FLoc) {
+ FriendTemplateDecl *Result
+ = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
+ return Result;
+}