DeclTemplate.cpp revision 199482
1//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the C++ related Decl classes for templates. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/DeclCXX.h" 15#include "clang/AST/DeclTemplate.h" 16#include "clang/AST/Expr.h" 17#include "clang/AST/ASTContext.h" 18#include "clang/AST/TypeLoc.h" 19#include "clang/Basic/IdentifierTable.h" 20#include "llvm/ADT/STLExtras.h" 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// TemplateParameterList Implementation 25//===----------------------------------------------------------------------===// 26 27TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, 28 SourceLocation LAngleLoc, 29 NamedDecl **Params, unsigned NumParams, 30 SourceLocation RAngleLoc) 31 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), 32 NumParams(NumParams) { 33 for (unsigned Idx = 0; Idx < NumParams; ++Idx) 34 begin()[Idx] = Params[Idx]; 35} 36 37TemplateParameterList * 38TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc, 39 SourceLocation LAngleLoc, NamedDecl **Params, 40 unsigned NumParams, SourceLocation RAngleLoc) { 41 unsigned Size = sizeof(TemplateParameterList) 42 + sizeof(NamedDecl *) * NumParams; 43 unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment; 44 void *Mem = C.Allocate(Size, Align); 45 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, 46 NumParams, RAngleLoc); 47} 48 49unsigned TemplateParameterList::getMinRequiredArguments() const { 50 unsigned NumRequiredArgs = size(); 51 iterator Param = const_cast<TemplateParameterList *>(this)->end(), 52 ParamBegin = const_cast<TemplateParameterList *>(this)->begin(); 53 while (Param != ParamBegin) { 54 --Param; 55 56 if (!(*Param)->isTemplateParameterPack() && 57 !(isa<TemplateTypeParmDecl>(*Param) && 58 cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) && 59 !(isa<NonTypeTemplateParmDecl>(*Param) && 60 cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) && 61 !(isa<TemplateTemplateParmDecl>(*Param) && 62 cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument())) 63 break; 64 65 --NumRequiredArgs; 66 } 67 68 return NumRequiredArgs; 69} 70 71unsigned TemplateParameterList::getDepth() const { 72 if (size() == 0) 73 return 0; 74 75 const NamedDecl *FirstParm = getParam(0); 76 if (const TemplateTypeParmDecl *TTP 77 = dyn_cast<TemplateTypeParmDecl>(FirstParm)) 78 return TTP->getDepth(); 79 else if (const NonTypeTemplateParmDecl *NTTP 80 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm)) 81 return NTTP->getDepth(); 82 else 83 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth(); 84} 85 86//===----------------------------------------------------------------------===// 87// TemplateDecl Implementation 88//===----------------------------------------------------------------------===// 89 90TemplateDecl::~TemplateDecl() { 91} 92 93//===----------------------------------------------------------------------===// 94// FunctionTemplateDecl Implementation 95//===----------------------------------------------------------------------===// 96 97FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 98 DeclContext *DC, 99 SourceLocation L, 100 DeclarationName Name, 101 TemplateParameterList *Params, 102 NamedDecl *Decl) { 103 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl); 104} 105 106void FunctionTemplateDecl::Destroy(ASTContext &C) { 107 if (Common *CommonPtr = CommonOrPrev.dyn_cast<Common*>()) { 108 for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator 109 Spec = CommonPtr->Specializations.begin(), 110 SpecEnd = CommonPtr->Specializations.end(); 111 Spec != SpecEnd; ++Spec) 112 C.Deallocate(&*Spec); 113 } 114 115 Decl::Destroy(C); 116} 117 118FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() { 119 FunctionTemplateDecl *FunTmpl = this; 120 while (FunTmpl->getPreviousDeclaration()) 121 FunTmpl = FunTmpl->getPreviousDeclaration(); 122 return FunTmpl; 123} 124 125FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() { 126 // Find the first declaration of this function template. 127 FunctionTemplateDecl *First = this; 128 while (First->getPreviousDeclaration()) 129 First = First->getPreviousDeclaration(); 130 131 if (First->CommonOrPrev.isNull()) { 132 // FIXME: Allocate with the ASTContext 133 First->CommonOrPrev = new Common; 134 } 135 return First->CommonOrPrev.get<Common*>(); 136} 137 138//===----------------------------------------------------------------------===// 139// ClassTemplateDecl Implementation 140//===----------------------------------------------------------------------===// 141 142ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() { 143 ClassTemplateDecl *Template = this; 144 while (Template->getPreviousDeclaration()) 145 Template = Template->getPreviousDeclaration(); 146 return Template; 147} 148 149ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 150 DeclContext *DC, 151 SourceLocation L, 152 DeclarationName Name, 153 TemplateParameterList *Params, 154 NamedDecl *Decl, 155 ClassTemplateDecl *PrevDecl) { 156 Common *CommonPtr; 157 if (PrevDecl) 158 CommonPtr = PrevDecl->CommonPtr; 159 else 160 CommonPtr = new (C) Common; 161 162 return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl, 163 CommonPtr); 164} 165 166ClassTemplateDecl::~ClassTemplateDecl() { 167 assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed"); 168} 169 170void ClassTemplateDecl::Destroy(ASTContext& C) { 171 if (!PreviousDeclaration) { 172 CommonPtr->~Common(); 173 C.Deallocate((void*)CommonPtr); 174 } 175 CommonPtr = 0; 176 177 this->~ClassTemplateDecl(); 178 C.Deallocate((void*)this); 179} 180 181ClassTemplatePartialSpecializationDecl * 182ClassTemplateDecl::findPartialSpecialization(QualType T) { 183 ASTContext &Context = getASTContext(); 184 typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator 185 partial_spec_iterator; 186 for (partial_spec_iterator P = getPartialSpecializations().begin(), 187 PEnd = getPartialSpecializations().end(); 188 P != PEnd; ++P) { 189 if (Context.hasSameType(Context.getTypeDeclType(&*P), T)) 190 return &*P; 191 } 192 193 return 0; 194} 195 196QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) { 197 if (!CommonPtr->InjectedClassNameType.isNull()) 198 return CommonPtr->InjectedClassNameType; 199 200 // FIXME: n2800 14.6.1p1 should say how the template arguments 201 // corresponding to template parameter packs should be pack 202 // expansions. We already say that in 14.6.2.1p2, so it would be 203 // better to fix that redundancy. 204 205 TemplateParameterList *Params = getTemplateParameters(); 206 llvm::SmallVector<TemplateArgument, 16> TemplateArgs; 207 TemplateArgs.reserve(Params->size()); 208 for (TemplateParameterList::iterator Param = Params->begin(), 209 ParamEnd = Params->end(); 210 Param != ParamEnd; ++Param) { 211 if (isa<TemplateTypeParmDecl>(*Param)) { 212 QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param)); 213 TemplateArgs.push_back(TemplateArgument(ParamType)); 214 } else if (NonTypeTemplateParmDecl *NTTP = 215 dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 216 Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(), 217 NTTP->getLocation(), 218 NTTP->getType()->isDependentType(), 219 /*Value-dependent=*/true); 220 TemplateArgs.push_back(TemplateArgument(E)); 221 } else { 222 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 223 TemplateArgs.push_back(TemplateArgument(TemplateName(TTP))); 224 } 225 } 226 227 CommonPtr->InjectedClassNameType 228 = Context.getTemplateSpecializationType(TemplateName(this), 229 &TemplateArgs[0], 230 TemplateArgs.size()); 231 return CommonPtr->InjectedClassNameType; 232} 233 234//===----------------------------------------------------------------------===// 235// TemplateTypeParm Allocation/Deallocation Method Implementations 236//===----------------------------------------------------------------------===// 237 238TemplateTypeParmDecl * 239TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, 240 SourceLocation L, unsigned D, unsigned P, 241 IdentifierInfo *Id, bool Typename, 242 bool ParameterPack) { 243 QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id); 244 return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack); 245} 246 247SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 248 return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin(); 249} 250 251unsigned TemplateTypeParmDecl::getDepth() const { 252 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth(); 253} 254 255unsigned TemplateTypeParmDecl::getIndex() const { 256 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex(); 257} 258 259//===----------------------------------------------------------------------===// 260// NonTypeTemplateParmDecl Method Implementations 261//===----------------------------------------------------------------------===// 262 263NonTypeTemplateParmDecl * 264NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, 265 SourceLocation L, unsigned D, unsigned P, 266 IdentifierInfo *Id, QualType T, 267 DeclaratorInfo *DInfo) { 268 return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, DInfo); 269} 270 271SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 272 return DefaultArgument? DefaultArgument->getSourceRange().getBegin() 273 : SourceLocation(); 274} 275 276//===----------------------------------------------------------------------===// 277// TemplateTemplateParmDecl Method Implementations 278//===----------------------------------------------------------------------===// 279 280TemplateTemplateParmDecl * 281TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, 282 SourceLocation L, unsigned D, unsigned P, 283 IdentifierInfo *Id, 284 TemplateParameterList *Params) { 285 return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params); 286} 287 288//===----------------------------------------------------------------------===// 289// TemplateArgumentListBuilder Implementation 290//===----------------------------------------------------------------------===// 291 292void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) { 293 switch (Arg.getKind()) { 294 default: break; 295 case TemplateArgument::Type: 296 assert(Arg.getAsType().isCanonical() && "Type must be canonical!"); 297 break; 298 } 299 300 assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!"); 301 assert(!StructuredArgs && 302 "Can't append arguments when an argument pack has been added!"); 303 304 if (!FlatArgs) 305 FlatArgs = new TemplateArgument[MaxFlatArgs]; 306 307 FlatArgs[NumFlatArgs++] = Arg; 308} 309 310void TemplateArgumentListBuilder::BeginPack() { 311 assert(!AddingToPack && "Already adding to pack!"); 312 assert(!StructuredArgs && "Argument list already contains a pack!"); 313 314 AddingToPack = true; 315 PackBeginIndex = NumFlatArgs; 316} 317 318void TemplateArgumentListBuilder::EndPack() { 319 assert(AddingToPack && "Not adding to pack!"); 320 assert(!StructuredArgs && "Argument list already contains a pack!"); 321 322 AddingToPack = false; 323 324 StructuredArgs = new TemplateArgument[MaxStructuredArgs]; 325 326 // First copy the flat entries over to the list (if any) 327 for (unsigned I = 0; I != PackBeginIndex; ++I) { 328 NumStructuredArgs++; 329 StructuredArgs[I] = FlatArgs[I]; 330 } 331 332 // Next, set the pack. 333 TemplateArgument *PackArgs = 0; 334 unsigned NumPackArgs = NumFlatArgs - PackBeginIndex; 335 if (NumPackArgs) 336 PackArgs = &FlatArgs[PackBeginIndex]; 337 338 StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs, 339 /*CopyArgs=*/false); 340} 341 342void TemplateArgumentListBuilder::ReleaseArgs() { 343 FlatArgs = 0; 344 NumFlatArgs = 0; 345 MaxFlatArgs = 0; 346 StructuredArgs = 0; 347 NumStructuredArgs = 0; 348 MaxStructuredArgs = 0; 349} 350 351//===----------------------------------------------------------------------===// 352// TemplateArgumentList Implementation 353//===----------------------------------------------------------------------===// 354TemplateArgumentList::TemplateArgumentList(ASTContext &Context, 355 TemplateArgumentListBuilder &Builder, 356 bool TakeArgs) 357 : FlatArguments(Builder.getFlatArguments(), TakeArgs), 358 NumFlatArguments(Builder.flatSize()), 359 StructuredArguments(Builder.getStructuredArguments(), TakeArgs), 360 NumStructuredArguments(Builder.structuredSize()) { 361 362 if (!TakeArgs) 363 return; 364 365 if (Builder.getStructuredArguments() == Builder.getFlatArguments()) 366 StructuredArguments.setInt(0); 367 Builder.ReleaseArgs(); 368} 369 370TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other) 371 : FlatArguments(Other.FlatArguments.getPointer(), 1), 372 NumFlatArguments(Other.flat_size()), 373 StructuredArguments(Other.StructuredArguments.getPointer(), 1), 374 NumStructuredArguments(Other.NumStructuredArguments) { } 375 376TemplateArgumentList::~TemplateArgumentList() { 377 // FIXME: Deallocate template arguments 378} 379 380//===----------------------------------------------------------------------===// 381// ClassTemplateSpecializationDecl Implementation 382//===----------------------------------------------------------------------===// 383ClassTemplateSpecializationDecl:: 384ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, 385 DeclContext *DC, SourceLocation L, 386 ClassTemplateDecl *SpecializedTemplate, 387 TemplateArgumentListBuilder &Builder, 388 ClassTemplateSpecializationDecl *PrevDecl) 389 : CXXRecordDecl(DK, 390 SpecializedTemplate->getTemplatedDecl()->getTagKind(), 391 DC, L, 392 // FIXME: Should we use DeclarationName for the name of 393 // class template specializations? 394 SpecializedTemplate->getIdentifier(), 395 PrevDecl), 396 SpecializedTemplate(SpecializedTemplate), 397 TemplateArgs(Context, Builder, /*TakeArgs=*/true), 398 SpecializationKind(TSK_Undeclared) { 399} 400 401ClassTemplateSpecializationDecl * 402ClassTemplateSpecializationDecl::Create(ASTContext &Context, 403 DeclContext *DC, SourceLocation L, 404 ClassTemplateDecl *SpecializedTemplate, 405 TemplateArgumentListBuilder &Builder, 406 ClassTemplateSpecializationDecl *PrevDecl) { 407 ClassTemplateSpecializationDecl *Result 408 = new (Context)ClassTemplateSpecializationDecl(Context, 409 ClassTemplateSpecialization, 410 DC, L, 411 SpecializedTemplate, 412 Builder, 413 PrevDecl); 414 Context.getTypeDeclType(Result, PrevDecl); 415 return Result; 416} 417 418void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) { 419 if (SpecializedPartialSpecialization *PartialSpec 420 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 421 C.Deallocate(PartialSpec); 422 423 CXXRecordDecl::Destroy(C); 424} 425 426void 427ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S, 428 const PrintingPolicy &Policy, 429 bool Qualified) const { 430 NamedDecl::getNameForDiagnostic(S, Policy, Qualified); 431 432 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 433 S += TemplateSpecializationType::PrintTemplateArgumentList( 434 TemplateArgs.getFlatArgumentList(), 435 TemplateArgs.flat_size(), 436 Policy); 437} 438 439ClassTemplateDecl * 440ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 441 if (SpecializedPartialSpecialization *PartialSpec 442 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 443 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 444 return SpecializedTemplate.get<ClassTemplateDecl*>(); 445} 446 447//===----------------------------------------------------------------------===// 448// ClassTemplatePartialSpecializationDecl Implementation 449//===----------------------------------------------------------------------===// 450ClassTemplatePartialSpecializationDecl * 451ClassTemplatePartialSpecializationDecl:: 452Create(ASTContext &Context, DeclContext *DC, SourceLocation L, 453 TemplateParameterList *Params, 454 ClassTemplateDecl *SpecializedTemplate, 455 TemplateArgumentListBuilder &Builder, 456 TemplateArgumentLoc *ArgInfos, unsigned N, 457 ClassTemplatePartialSpecializationDecl *PrevDecl) { 458 TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N]; 459 for (unsigned I = 0; I != N; ++I) 460 ClonedArgs[I] = ArgInfos[I]; 461 462 ClassTemplatePartialSpecializationDecl *Result 463 = new (Context)ClassTemplatePartialSpecializationDecl(Context, 464 DC, L, Params, 465 SpecializedTemplate, 466 Builder, 467 ClonedArgs, N, 468 PrevDecl); 469 Result->setSpecializationKind(TSK_ExplicitSpecialization); 470 Context.getTypeDeclType(Result, PrevDecl); 471 return Result; 472} 473 474//===----------------------------------------------------------------------===// 475// FriendTemplateDecl Implementation 476//===----------------------------------------------------------------------===// 477 478FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 479 DeclContext *DC, 480 SourceLocation L, 481 unsigned NParams, 482 TemplateParameterList **Params, 483 FriendUnion Friend, 484 SourceLocation FLoc) { 485 FriendTemplateDecl *Result 486 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc); 487 return Result; 488} 489