123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- //===--- DeclCXX.cpp - C++ 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/DeclCXX.h"
- #include "clang/AST/DeclTemplate.h"
- #include "clang/AST/Expr.h"
- #include "clang/AST/ASTContext.h"
- #include "clang/Basic/IdentifierTable.h"
- #include "llvm/ADT/STLExtras.h"
- using namespace clang;
- //===----------------------------------------------------------------------===//
- // TemplateParameterList Implementation
- //===----------------------------------------------------------------------===//
- TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- Decl **Params, unsigned NumParams,
- SourceLocation RAngleLoc)
- : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
- NumParams(NumParams) {
- for (unsigned Idx = 0; Idx < NumParams; ++Idx)
- begin()[Idx] = Params[Idx];
- }
- TemplateParameterList *
- TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc,
- SourceLocation LAngleLoc, Decl **Params,
- unsigned NumParams, SourceLocation RAngleLoc) {
- unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams;
- unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
- void *Mem = C.Allocate(Size, Align);
- return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
- NumParams, RAngleLoc);
- }
- unsigned TemplateParameterList::getMinRequiredArguments() const {
- unsigned NumRequiredArgs = size();
- iterator Param = const_cast<TemplateParameterList *>(this)->end(),
- ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
- while (Param != ParamBegin) {
- --Param;
-
- if (!(*Param)->isTemplateParameterPack() &&
- !(isa<TemplateTypeParmDecl>(*Param) &&
- cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
- !(isa<NonTypeTemplateParmDecl>(*Param) &&
- cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&
- !(isa<TemplateTemplateParmDecl>(*Param) &&
- cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument()))
- break;
-
- --NumRequiredArgs;
- }
- return NumRequiredArgs;
- }
- //===----------------------------------------------------------------------===//
- // TemplateDecl Implementation
- //===----------------------------------------------------------------------===//
- TemplateDecl::~TemplateDecl() {
- }
- //===----------------------------------------------------------------------===//
- // FunctionTemplateDecl Implementation
- //===----------------------------------------------------------------------===//
- FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
- DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl) {
- return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
- }
- //===----------------------------------------------------------------------===//
- // ClassTemplateDecl Implementation
- //===----------------------------------------------------------------------===//
- ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
- DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl,
- ClassTemplateDecl *PrevDecl) {
- Common *CommonPtr;
- if (PrevDecl)
- CommonPtr = PrevDecl->CommonPtr;
- else
- CommonPtr = new (C) Common;
- return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
- CommonPtr);
- }
- ClassTemplateDecl::~ClassTemplateDecl() {
- assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed");
- }
- void ClassTemplateDecl::Destroy(ASTContext& C) {
- if (!PreviousDeclaration) {
- CommonPtr->~Common();
- C.Deallocate((void*)CommonPtr);
- }
- CommonPtr = 0;
- this->~ClassTemplateDecl();
- C.Deallocate((void*)this);
- }
- QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
- if (!CommonPtr->InjectedClassNameType.isNull())
- return CommonPtr->InjectedClassNameType;
- // FIXME: n2800 14.6.1p1 should say how the template arguments
- // corresponding to template parameter packs should be pack
- // expansions. We already say that in 14.6.2.1p2, so it would be
- // 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();
- Param != ParamEnd; ++Param) {
- if (isa<TemplateTypeParmDecl>(*Param)) {
- QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
- TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(),
- ParamType));
- CanonTemplateArgs.push_back(
- TemplateArgument((*Param)->getLocation(),
- Context.getCanonicalType(ParamType)));
- } 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 {
- 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,
- &TemplateArgs[0],
- TemplateArgs.size(),
- CanonType);
- return CommonPtr->InjectedClassNameType;
- }
- //===----------------------------------------------------------------------===//
- // TemplateTypeParm Allocation/Deallocation Method Implementations
- //===----------------------------------------------------------------------===//
- TemplateTypeParmDecl *
- TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, unsigned D, unsigned P,
- IdentifierInfo *Id, bool Typename,
- bool ParameterPack) {
- QualType Type = C.getTemplateTypeParmType(D, P, Id);
- return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
- }
- //===----------------------------------------------------------------------===//
- // NonTypeTemplateParmDecl Method Implementations
- //===----------------------------------------------------------------------===//
- 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);
- }
- SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
- return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
- : SourceLocation();
- }
- //===----------------------------------------------------------------------===//
- // TemplateTemplateParmDecl Method Implementations
- //===----------------------------------------------------------------------===//
- TemplateTemplateParmDecl *
- TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, unsigned D, unsigned P,
- IdentifierInfo *Id,
- TemplateParameterList *Params) {
- return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
- }
- SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
- return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
- : SourceLocation();
- }
- //===----------------------------------------------------------------------===//
- // TemplateArgument Implementation
- //===----------------------------------------------------------------------===//
- TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
- TypeOrValue = reinterpret_cast<uintptr_t>(E);
- StartLoc = E->getSourceRange().getBegin();
- }
- //===----------------------------------------------------------------------===//
- // TemplateArgumentListBuilder Implementation
- //===----------------------------------------------------------------------===//
- void TemplateArgumentListBuilder::push_back(const TemplateArgument& Arg) {
- switch (Arg.getKind()) {
- default: break;
- case TemplateArgument::Type:
- assert(Arg.getAsType()->isCanonical() && "Type must be canonical!");
- break;
- }
-
- if (!isAddingFromParameterPack()) {
- // Add begin and end indicies.
- Indices.push_back(Args.size());
- Indices.push_back(Args.size());
- }
- Args.push_back(Arg);
- }
- void TemplateArgumentListBuilder::BeginParameterPack() {
- assert(!isAddingFromParameterPack() && "Already adding to parameter pack!");
-
- Indices.push_back(Args.size());
- }
- void TemplateArgumentListBuilder::EndParameterPack() {
- assert(isAddingFromParameterPack() && "Not adding to parameter pack!");
-
- Indices.push_back(Args.size());
- }
- //===----------------------------------------------------------------------===//
- // TemplateArgumentList Implementation
- //===----------------------------------------------------------------------===//
- TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
- TemplateArgumentListBuilder &Builder,
- bool CopyArgs, bool FlattenArgs)
- : NumArguments(Builder.flatSize()) {
- if (!CopyArgs) {
- Arguments.setPointer(Builder.getFlatArgumentList());
- Arguments.setInt(1);
- return;
- }
-
- unsigned Size = sizeof(TemplateArgument) * Builder.flatSize();
- unsigned Align = llvm::AlignOf<TemplateArgument>::Alignment;
- void *Mem = Context.Allocate(Size, Align);
- Arguments.setPointer((TemplateArgument *)Mem);
- Arguments.setInt(0);
- TemplateArgument *Args = (TemplateArgument *)Mem;
- for (unsigned I = 0; I != NumArguments; ++I)
- new (Args + I) TemplateArgument(Builder.getFlatArgumentList()[I]);
- }
- TemplateArgumentList::~TemplateArgumentList() {
- // FIXME: Deallocate template arguments
- }
- //===----------------------------------------------------------------------===//
- // ClassTemplateSpecializationDecl Implementation
- //===----------------------------------------------------------------------===//
- ClassTemplateSpecializationDecl::
- ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
- DeclContext *DC, SourceLocation L,
- ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder)
- : CXXRecordDecl(DK,
- SpecializedTemplate->getTemplatedDecl()->getTagKind(),
- DC, L,
- // FIXME: Should we use DeclarationName for the name of
- // class template specializations?
- SpecializedTemplate->getIdentifier()),
- SpecializedTemplate(SpecializedTemplate),
- TemplateArgs(Context, Builder, /*CopyArgs=*/true, /*FlattenArgs=*/true),
- SpecializationKind(TSK_Undeclared) {
- }
-
- ClassTemplateSpecializationDecl *
- ClassTemplateSpecializationDecl::Create(ASTContext &Context,
- DeclContext *DC, SourceLocation L,
- ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
- ClassTemplateSpecializationDecl *PrevDecl) {
- ClassTemplateSpecializationDecl *Result
- = new (Context)ClassTemplateSpecializationDecl(Context,
- ClassTemplateSpecialization,
- DC, L,
- SpecializedTemplate,
- Builder);
- Context.getTypeDeclType(Result, PrevDecl);
- return Result;
- }
- //===----------------------------------------------------------------------===//
- // ClassTemplatePartialSpecializationDecl Implementation
- //===----------------------------------------------------------------------===//
- ClassTemplatePartialSpecializationDecl *
- ClassTemplatePartialSpecializationDecl::
- Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
- TemplateParameterList *Params,
- ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
- ClassTemplatePartialSpecializationDecl *PrevDecl) {
- ClassTemplatePartialSpecializationDecl *Result
- = new (Context)ClassTemplatePartialSpecializationDecl(Context,
- DC, L, Params,
- SpecializedTemplate,
- Builder);
- Result->setSpecializationKind(TSK_ExplicitSpecialization);
- Context.getTypeDeclType(Result, PrevDecl);
- return Result;
- }
|