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