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" 20 using namespace clang; 21 22 //===----------------------------------------------------------------------===// 23 // TemplateParameterList Implementation 24 //===----------------------------------------------------------------------===// 25 26 TemplateParameterList::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 36 TemplateParameterList * 37 TemplateParameterList::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 47 unsigned 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 73 TemplateDecl::~TemplateDecl() { 74 } 75 76 //===----------------------------------------------------------------------===// 77 // FunctionTemplateDecl Implementation 78 //===----------------------------------------------------------------------===// 79 80 FunctionTemplateDecl *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 89 void 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 101 FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() { 102 FunctionTemplateDecl *FunTmpl = this; 103 while (FunTmpl->getPreviousDeclaration()) 104 FunTmpl = FunTmpl->getPreviousDeclaration(); 105 return FunTmpl; 106 } 107 108 FunctionTemplateDecl::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 125 ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() { 126 ClassTemplateDecl *Template = this; 127 while (Template->getPreviousDeclaration()) 128 Template = Template->getPreviousDeclaration(); 129 return Template; 130 } 131 132 ClassTemplateDecl *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 149 ClassTemplateDecl::~ClassTemplateDecl() { 150 assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed"); 151 } 152 153 void 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 164 ClassTemplatePartialSpecializationDecl * 165 ClassTemplateDecl::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 179 QualType 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 222 TemplateTypeParmDecl * 223 TemplateTypeParmDecl::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 235 NonTypeTemplateParmDecl * 236 NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, 237 SourceLocation L, unsigned D, unsigned P, 238 IdentifierInfo *Id, QualType T, 239 SourceLocation TypeSpecStartLoc) { 240 return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, 241 TypeSpecStartLoc); 242 } 243 244 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 245 return DefaultArgument? DefaultArgument->getSourceRange().getBegin() 246 : SourceLocation(); 247 } 248 249 //===----------------------------------------------------------------------===// 250 // TemplateTemplateParmDecl Method Implementations 251 //===----------------------------------------------------------------------===// 252 253 TemplateTemplateParmDecl * 254 TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, 255 SourceLocation L, unsigned D, unsigned P, 256 IdentifierInfo *Id, 257 TemplateParameterList *Params) { 258 return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params); 259 } 260 261 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 262 return DefaultArgument? DefaultArgument->getSourceRange().getBegin() 263 : SourceLocation(); 264 } 265 266 //===----------------------------------------------------------------------===// 267 // TemplateArgument Implementation 268 //===----------------------------------------------------------------------===// 269 270 TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) { 271 TypeOrValue = reinterpret_cast<uintptr_t>(E); 272 StartLoc = E->getSourceRange().getBegin(); 273 } 274 275 /// \brief Construct a template argument pack. 276 void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs, 277 bool CopyArgs) { 278 assert(isNull() && "Must call setArgumentPack on a null argument"); 279 280 Kind = Pack; 281 Args.NumArgs = NumArgs; 282 Args.CopyArgs = CopyArgs; 283 if (!Args.CopyArgs) { 284 Args.Args = args; 285 return; 286 } 287 288 // FIXME: Allocate in ASTContext 289 Args.Args = new TemplateArgument[NumArgs]; 290 for (unsigned I = 0; I != Args.NumArgs; ++I) 291 Args.Args[I] = args[I]; 292 } 293 294 //===----------------------------------------------------------------------===// 295 // TemplateArgumentListBuilder Implementation 296 //===----------------------------------------------------------------------===// 297 298 void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) { 299 switch (Arg.getKind()) { 300 default: break; 301 case TemplateArgument::Type: 302 assert(Arg.getAsType()->isCanonical() && "Type must be canonical!"); 303 break; 304 } 305 306 assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!"); 307 assert(!StructuredArgs && 308 "Can't append arguments when an argument pack has been added!"); 309 310 if (!FlatArgs) 311 FlatArgs = new TemplateArgument[MaxFlatArgs]; 312 313 FlatArgs[NumFlatArgs++] = Arg; 314 } 315 316 void TemplateArgumentListBuilder::BeginPack() { 317 assert(!AddingToPack && "Already adding to pack!"); 318 assert(!StructuredArgs && "Argument list already contains a pack!"); 319 320 AddingToPack = true; 321 PackBeginIndex = NumFlatArgs; 322 } 323 324 void TemplateArgumentListBuilder::EndPack() { 325 assert(AddingToPack && "Not adding to pack!"); 326 assert(!StructuredArgs && "Argument list already contains a pack!"); 327 328 AddingToPack = false; 329 330 StructuredArgs = new TemplateArgument[MaxStructuredArgs]; 331 332 // First copy the flat entries over to the list (if any) 333 for (unsigned I = 0; I != PackBeginIndex; ++I) { 334 NumStructuredArgs++; 335 StructuredArgs[I] = FlatArgs[I]; 336 } 337 338 // Next, set the pack. 339 TemplateArgument *PackArgs = 0; 340 unsigned NumPackArgs = NumFlatArgs - PackBeginIndex; 341 if (NumPackArgs) 342 PackArgs = &FlatArgs[PackBeginIndex]; 343 344 StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs, 345 /*CopyArgs=*/false); 346 } 347 348 void TemplateArgumentListBuilder::ReleaseArgs() { 349 FlatArgs = 0; 350 NumFlatArgs = 0; 351 MaxFlatArgs = 0; 352 StructuredArgs = 0; 353 NumStructuredArgs = 0; 354 MaxStructuredArgs = 0; 355 } 356 357 //===----------------------------------------------------------------------===// 358 // TemplateArgumentList Implementation 359 //===----------------------------------------------------------------------===// 360 TemplateArgumentList::TemplateArgumentList(ASTContext &Context, 361 TemplateArgumentListBuilder &Builder, 362 bool TakeArgs) 363 : FlatArguments(Builder.getFlatArguments(), TakeArgs), 364 NumFlatArguments(Builder.flatSize()), 365 StructuredArguments(Builder.getStructuredArguments(), TakeArgs), 366 NumStructuredArguments(Builder.structuredSize()) { 367 368 if (!TakeArgs) 369 return; 370 371 if (Builder.getStructuredArguments() == Builder.getFlatArguments()) 372 StructuredArguments.setInt(0); 373 Builder.ReleaseArgs(); 374 } 375 376 TemplateArgumentList::~TemplateArgumentList() { 377 // FIXME: Deallocate template arguments 378 } 379 380 //===----------------------------------------------------------------------===// 381 // ClassTemplateSpecializationDecl Implementation 382 //===----------------------------------------------------------------------===// 383 ClassTemplateSpecializationDecl:: 384 ClassTemplateSpecializationDecl(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 401 ClassTemplateSpecializationDecl * 402 ClassTemplateSpecializationDecl::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 418 void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) { 419 if (SpecializedPartialSpecialization *PartialSpec 420 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 421 C.Deallocate(PartialSpec); 422 423 CXXRecordDecl::Destroy(C); 424 } 425 426 ClassTemplateDecl * 427 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 428 if (SpecializedPartialSpecialization *PartialSpec 429 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 430 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 431 return SpecializedTemplate.get<ClassTemplateDecl*>(); 432 } 433 434 //===----------------------------------------------------------------------===// 435 // ClassTemplatePartialSpecializationDecl Implementation 436 //===----------------------------------------------------------------------===// 437 ClassTemplatePartialSpecializationDecl * 438 ClassTemplatePartialSpecializationDecl:: 439 Create(ASTContext &Context, DeclContext *DC, SourceLocation L, 440 TemplateParameterList *Params, 441 ClassTemplateDecl *SpecializedTemplate, 442 TemplateArgumentListBuilder &Builder, 443 ClassTemplatePartialSpecializationDecl *PrevDecl) { 444 ClassTemplatePartialSpecializationDecl *Result 445 = new (Context)ClassTemplatePartialSpecializationDecl(Context, 446 DC, L, Params, 447 SpecializedTemplate, 448 Builder, PrevDecl); 449 Result->setSpecializationKind(TSK_ExplicitSpecialization); 450 Context.getTypeDeclType(Result, PrevDecl); 451 return Result; 452 } 453