//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the C++ related Decl classes for templates.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/STLExtras.h"
#include <memory>
using namespace clang;
//===----------------------------------------------------------------------===//
// TemplateParameterList Implementation
//===----------------------------------------------------------------------===//
TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
NamedDecl **Params, unsigned NumParams,
SourceLocation RAngleLoc)
: TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
NumParams(NumParams), ContainsUnexpandedParameterPack(false) {
assert(this->NumParams == NumParams && "Too many template parameters");
for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
NamedDecl *P = Params[Idx];
begin()[Idx] = P;
if (!P->isTemplateParameterPack()) {
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
if (NTTP->getType()->containsUnexpandedParameterPack())
ContainsUnexpandedParameterPack = true;
if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
ContainsUnexpandedParameterPack = true;
// FIXME: If a default argument contains an unexpanded parameter pack, the
// template parameter list does too.
}
}
}
TemplateParameterList *
TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, NamedDecl **Params,
unsigned NumParams, SourceLocation RAngleLoc) {
unsigned Size = sizeof(TemplateParameterList)
+ sizeof(NamedDecl *) * NumParams;
unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
llvm::alignOf<NamedDecl*>());
void *Mem = C.Allocate(Size, Align);
return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
NumParams, RAngleLoc);
}
unsigned TemplateParameterList::getMinRequiredArguments() const {
unsigned NumRequiredArgs = 0;
for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
PEnd = const_cast<TemplateParameterList *>(this)->end();
P != PEnd; ++P) {
if ((*P)->isTemplateParameterPack()) {
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
if (NTTP->isExpandedParameterPack()) {
NumRequiredArgs += NTTP->getNumExpansionTypes();
continue;
}
break;
}
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
if (TTP->hasDefaultArgument())
break;
} else if (NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(*P)) {
if (NTTP->hasDefaultArgument())
break;
} else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
break;
++NumRequiredArgs;
}
return NumRequiredArgs;
}
unsigned TemplateParameterList::getDepth() const {
if (size() == 0)
return 0;
const NamedDecl *FirstParm = getParam(0);
if (const TemplateTypeParmDecl *TTP
= dyn_cast<TemplateTypeParmDecl>(FirstParm))
return TTP->getDepth();
else if (const NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
return NTTP->getDepth();
else
return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
}
static void AdoptTemplateParameterList(TemplateParameterList *Params,
DeclContext *Owner) {
for (TemplateParameterList::iterator P = Params->begin(),
PEnd = Params->end();
P != PEnd; ++P) {
(*P)->setDeclContext(Owner);
if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
}
}
//===----------------------------------------------------------------------===//
// RedeclarableTemplateDecl Implementation
//===----------------------------------------------------------------------===//