DeclTemplate.cpp revision 193326
1193326Sed//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the C++ related Decl classes for templates. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/AST/DeclCXX.h" 15193326Sed#include "clang/AST/DeclTemplate.h" 16193326Sed#include "clang/AST/Expr.h" 17193326Sed#include "clang/AST/ASTContext.h" 18193326Sed#include "clang/Basic/IdentifierTable.h" 19193326Sed#include "llvm/ADT/STLExtras.h" 20193326Sedusing namespace clang; 21193326Sed 22193326Sed//===----------------------------------------------------------------------===// 23193326Sed// TemplateParameterList Implementation 24193326Sed//===----------------------------------------------------------------------===// 25193326Sed 26193326SedTemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, 27193326Sed SourceLocation LAngleLoc, 28193326Sed Decl **Params, unsigned NumParams, 29193326Sed SourceLocation RAngleLoc) 30193326Sed : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), 31193326Sed NumParams(NumParams) { 32193326Sed for (unsigned Idx = 0; Idx < NumParams; ++Idx) 33193326Sed begin()[Idx] = Params[Idx]; 34193326Sed} 35193326Sed 36193326SedTemplateParameterList * 37193326SedTemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc, 38193326Sed SourceLocation LAngleLoc, Decl **Params, 39193326Sed unsigned NumParams, SourceLocation RAngleLoc) { 40193326Sed unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams; 41193326Sed unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment; 42193326Sed void *Mem = C.Allocate(Size, Align); 43193326Sed return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, 44193326Sed NumParams, RAngleLoc); 45193326Sed} 46193326Sed 47193326Sedunsigned TemplateParameterList::getMinRequiredArguments() const { 48193326Sed unsigned NumRequiredArgs = size(); 49193326Sed iterator Param = const_cast<TemplateParameterList *>(this)->end(), 50193326Sed ParamBegin = const_cast<TemplateParameterList *>(this)->begin(); 51193326Sed while (Param != ParamBegin) { 52193326Sed --Param; 53193326Sed if (!(isa<TemplateTypeParmDecl>(*Param) && 54193326Sed cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) && 55193326Sed !(isa<NonTypeTemplateParmDecl>(*Param) && 56193326Sed cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) && 57193326Sed !(isa<TemplateTemplateParmDecl>(*Param) && 58193326Sed cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument())) 59193326Sed break; 60193326Sed 61193326Sed --NumRequiredArgs; 62193326Sed } 63193326Sed 64193326Sed return NumRequiredArgs; 65193326Sed} 66193326Sed 67193326Sed//===----------------------------------------------------------------------===// 68193326Sed// TemplateDecl Implementation 69193326Sed//===----------------------------------------------------------------------===// 70193326Sed 71193326SedTemplateDecl::~TemplateDecl() { 72193326Sed} 73193326Sed 74193326Sed//===----------------------------------------------------------------------===// 75193326Sed// FunctionTemplateDecl Implementation 76193326Sed//===----------------------------------------------------------------------===// 77193326Sed 78193326SedFunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 79193326Sed DeclContext *DC, 80193326Sed SourceLocation L, 81193326Sed DeclarationName Name, 82193326Sed TemplateParameterList *Params, 83193326Sed NamedDecl *Decl) { 84193326Sed return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl); 85193326Sed} 86193326Sed 87193326Sed//===----------------------------------------------------------------------===// 88193326Sed// ClassTemplateDecl Implementation 89193326Sed//===----------------------------------------------------------------------===// 90193326Sed 91193326SedClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 92193326Sed DeclContext *DC, 93193326Sed SourceLocation L, 94193326Sed DeclarationName Name, 95193326Sed TemplateParameterList *Params, 96193326Sed NamedDecl *Decl, 97193326Sed ClassTemplateDecl *PrevDecl) { 98193326Sed Common *CommonPtr; 99193326Sed if (PrevDecl) 100193326Sed CommonPtr = PrevDecl->CommonPtr; 101193326Sed else 102193326Sed CommonPtr = new (C) Common; 103193326Sed 104193326Sed return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl, 105193326Sed CommonPtr); 106193326Sed} 107193326Sed 108193326SedClassTemplateDecl::~ClassTemplateDecl() { 109193326Sed assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed"); 110193326Sed} 111193326Sed 112193326Sedvoid ClassTemplateDecl::Destroy(ASTContext& C) { 113193326Sed if (!PreviousDeclaration) { 114193326Sed CommonPtr->~Common(); 115193326Sed C.Deallocate((void*)CommonPtr); 116193326Sed } 117193326Sed CommonPtr = 0; 118193326Sed 119193326Sed this->~ClassTemplateDecl(); 120193326Sed C.Deallocate((void*)this); 121193326Sed} 122193326Sed 123193326SedQualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) { 124193326Sed if (!CommonPtr->InjectedClassNameType.isNull()) 125193326Sed return CommonPtr->InjectedClassNameType; 126193326Sed 127193326Sed // FIXME: n2800 14.6.1p1 should say how the template arguments 128193326Sed // corresponding to template parameter packs should be pack 129193326Sed // expansions. We already say that in 14.6.2.1p2, so it would be 130193326Sed // better to fix that redundancy. 131193326Sed 132193326Sed TemplateParameterList *Params = getTemplateParameters(); 133193326Sed 134193326Sed llvm::SmallVector<TemplateArgument, 16> TemplateArgs; 135193326Sed llvm::SmallVector<TemplateArgument, 16> CanonTemplateArgs; 136193326Sed TemplateArgs.reserve(Params->size()); 137193326Sed CanonTemplateArgs.reserve(Params->size()); 138193326Sed 139193326Sed for (TemplateParameterList::iterator 140193326Sed Param = Params->begin(), ParamEnd = Params->end(); 141193326Sed Param != ParamEnd; ++Param) { 142193326Sed if (isa<TemplateTypeParmDecl>(*Param)) { 143193326Sed QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param)); 144193326Sed TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(), 145193326Sed ParamType)); 146193326Sed CanonTemplateArgs.push_back( 147193326Sed TemplateArgument((*Param)->getLocation(), 148193326Sed Context.getCanonicalType(ParamType))); 149193326Sed } else if (NonTypeTemplateParmDecl *NTTP = 150193326Sed dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 151193326Sed // FIXME: Build canonical expression, too! 152193326Sed Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(), 153193326Sed NTTP->getLocation(), 154193326Sed NTTP->getType()->isDependentType(), 155193326Sed /*Value-dependent=*/true); 156193326Sed TemplateArgs.push_back(TemplateArgument(E)); 157193326Sed CanonTemplateArgs.push_back(TemplateArgument(E)); 158193326Sed } else { 159193326Sed TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 160193326Sed TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP)); 161193326Sed CanonTemplateArgs.push_back(TemplateArgument(TTP->getLocation(), 162193326Sed Context.getCanonicalDecl(TTP))); 163193326Sed } 164193326Sed } 165193326Sed 166193326Sed // FIXME: I should really move the "build-the-canonical-type" logic 167193326Sed // into ASTContext::getTemplateSpecializationType. 168193326Sed TemplateName Name = TemplateName(this); 169193326Sed QualType CanonType = Context.getTemplateSpecializationType( 170193326Sed Context.getCanonicalTemplateName(Name), 171193326Sed &CanonTemplateArgs[0], 172193326Sed CanonTemplateArgs.size()); 173193326Sed 174193326Sed CommonPtr->InjectedClassNameType 175193326Sed = Context.getTemplateSpecializationType(Name, 176193326Sed &TemplateArgs[0], 177193326Sed TemplateArgs.size(), 178193326Sed CanonType); 179193326Sed return CommonPtr->InjectedClassNameType; 180193326Sed} 181193326Sed 182193326Sed//===----------------------------------------------------------------------===// 183193326Sed// TemplateTypeParm Allocation/Deallocation Method Implementations 184193326Sed//===----------------------------------------------------------------------===// 185193326Sed 186193326SedTemplateTypeParmDecl * 187193326SedTemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, 188193326Sed SourceLocation L, unsigned D, unsigned P, 189193326Sed IdentifierInfo *Id, bool Typename) { 190193326Sed QualType Type = C.getTemplateTypeParmType(D, P, Id); 191193326Sed return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type); 192193326Sed} 193193326Sed 194193326Sed//===----------------------------------------------------------------------===// 195193326Sed// NonTypeTemplateParmDecl Method Implementations 196193326Sed//===----------------------------------------------------------------------===// 197193326Sed 198193326SedNonTypeTemplateParmDecl * 199193326SedNonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, 200193326Sed SourceLocation L, unsigned D, unsigned P, 201193326Sed IdentifierInfo *Id, QualType T, 202193326Sed SourceLocation TypeSpecStartLoc) { 203193326Sed return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, 204193326Sed TypeSpecStartLoc); 205193326Sed} 206193326Sed 207193326SedSourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 208193326Sed return DefaultArgument? DefaultArgument->getSourceRange().getBegin() 209193326Sed : SourceLocation(); 210193326Sed} 211193326Sed 212193326Sed//===----------------------------------------------------------------------===// 213193326Sed// TemplateTemplateParmDecl Method Implementations 214193326Sed//===----------------------------------------------------------------------===// 215193326Sed 216193326SedTemplateTemplateParmDecl * 217193326SedTemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, 218193326Sed SourceLocation L, unsigned D, unsigned P, 219193326Sed IdentifierInfo *Id, 220193326Sed TemplateParameterList *Params) { 221193326Sed return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params); 222193326Sed} 223193326Sed 224193326SedSourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 225193326Sed return DefaultArgument? DefaultArgument->getSourceRange().getBegin() 226193326Sed : SourceLocation(); 227193326Sed} 228193326Sed 229193326Sed//===----------------------------------------------------------------------===// 230193326Sed// TemplateArgument Implementation 231193326Sed//===----------------------------------------------------------------------===// 232193326Sed 233193326SedTemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) { 234193326Sed TypeOrValue = reinterpret_cast<uintptr_t>(E); 235193326Sed StartLoc = E->getSourceRange().getBegin(); 236193326Sed} 237193326Sed 238193326Sed//===----------------------------------------------------------------------===// 239193326Sed// TemplateArgumentList Implementation 240193326Sed//===----------------------------------------------------------------------===// 241193326SedTemplateArgumentList::TemplateArgumentList(ASTContext &Context, 242193326Sed TemplateArgument *TemplateArgs, 243193326Sed unsigned NumTemplateArgs, 244193326Sed bool CopyArgs) 245193326Sed : NumArguments(NumTemplateArgs) { 246193326Sed if (!CopyArgs) { 247193326Sed Arguments.setPointer(TemplateArgs); 248193326Sed Arguments.setInt(1); 249193326Sed return; 250193326Sed } 251193326Sed 252193326Sed unsigned Size = sizeof(TemplateArgument) * NumTemplateArgs; 253193326Sed unsigned Align = llvm::AlignOf<TemplateArgument>::Alignment; 254193326Sed void *Mem = Context.Allocate(Size, Align); 255193326Sed Arguments.setPointer((TemplateArgument *)Mem); 256193326Sed Arguments.setInt(0); 257193326Sed 258193326Sed TemplateArgument *Args = (TemplateArgument *)Mem; 259193326Sed for (unsigned I = 0; I != NumTemplateArgs; ++I) 260193326Sed new (Args + I) TemplateArgument(TemplateArgs[I]); 261193326Sed} 262193326Sed 263193326SedTemplateArgumentList::~TemplateArgumentList() { 264193326Sed // FIXME: Deallocate template arguments 265193326Sed} 266193326Sed 267193326Sed//===----------------------------------------------------------------------===// 268193326Sed// ClassTemplateSpecializationDecl Implementation 269193326Sed//===----------------------------------------------------------------------===// 270193326SedClassTemplateSpecializationDecl:: 271193326SedClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, 272193326Sed DeclContext *DC, SourceLocation L, 273193326Sed ClassTemplateDecl *SpecializedTemplate, 274193326Sed TemplateArgument *TemplateArgs, 275193326Sed unsigned NumTemplateArgs) 276193326Sed : CXXRecordDecl(DK, 277193326Sed SpecializedTemplate->getTemplatedDecl()->getTagKind(), 278193326Sed DC, L, 279193326Sed // FIXME: Should we use DeclarationName for the name of 280193326Sed // class template specializations? 281193326Sed SpecializedTemplate->getIdentifier()), 282193326Sed SpecializedTemplate(SpecializedTemplate), 283193326Sed TemplateArgs(Context, TemplateArgs, NumTemplateArgs, /*CopyArgs=*/true), 284193326Sed SpecializationKind(TSK_Undeclared) { 285193326Sed} 286193326Sed 287193326SedClassTemplateSpecializationDecl * 288193326SedClassTemplateSpecializationDecl::Create(ASTContext &Context, 289193326Sed DeclContext *DC, SourceLocation L, 290193326Sed ClassTemplateDecl *SpecializedTemplate, 291193326Sed TemplateArgument *TemplateArgs, 292193326Sed unsigned NumTemplateArgs, 293193326Sed ClassTemplateSpecializationDecl *PrevDecl) { 294193326Sed ClassTemplateSpecializationDecl *Result 295193326Sed = new (Context)ClassTemplateSpecializationDecl(Context, 296193326Sed ClassTemplateSpecialization, 297193326Sed DC, L, 298193326Sed SpecializedTemplate, 299193326Sed TemplateArgs, 300193326Sed NumTemplateArgs); 301193326Sed Context.getTypeDeclType(Result, PrevDecl); 302193326Sed return Result; 303193326Sed} 304193326Sed 305193326Sed//===----------------------------------------------------------------------===// 306193326Sed// ClassTemplatePartialSpecializationDecl Implementation 307193326Sed//===----------------------------------------------------------------------===// 308193326SedClassTemplatePartialSpecializationDecl * 309193326SedClassTemplatePartialSpecializationDecl:: 310193326SedCreate(ASTContext &Context, DeclContext *DC, SourceLocation L, 311193326Sed TemplateParameterList *Params, 312193326Sed ClassTemplateDecl *SpecializedTemplate, 313193326Sed TemplateArgument *TemplateArgs, unsigned NumTemplateArgs, 314193326Sed ClassTemplatePartialSpecializationDecl *PrevDecl) { 315193326Sed ClassTemplatePartialSpecializationDecl *Result 316193326Sed = new (Context)ClassTemplatePartialSpecializationDecl(Context, 317193326Sed DC, L, Params, 318193326Sed SpecializedTemplate, 319193326Sed TemplateArgs, 320193326Sed NumTemplateArgs); 321193326Sed Result->setSpecializationKind(TSK_ExplicitSpecialization); 322193326Sed Context.getTypeDeclType(Result, PrevDecl); 323193326Sed return Result; 324193326Sed} 325