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::Common *FunctionTemplateDecl::getCommonPtr() { 102 // Find the first declaration of this function template. 103 FunctionTemplateDecl *First = this; 104 while (First->getPreviousDeclaration()) 105 First = First->getPreviousDeclaration(); 106 107 if (First->CommonOrPrev.isNull()) { 108 // FIXME: Allocate with the ASTContext 109 First->CommonOrPrev = new Common; 110 } 111 return First->CommonOrPrev.get<Common*>(); 112 } 113 114 //===----------------------------------------------------------------------===// 115 // ClassTemplateDecl Implementation 116 //===----------------------------------------------------------------------===// 117 118 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 119 DeclContext *DC, 120 SourceLocation L, 121 DeclarationName Name, 122 TemplateParameterList *Params, 123 NamedDecl *Decl, 124 ClassTemplateDecl *PrevDecl) { 125 Common *CommonPtr; 126 if (PrevDecl) 127 CommonPtr = PrevDecl->CommonPtr; 128 else 129 CommonPtr = new (C) Common; 130 131 return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl, 132 CommonPtr); 133 } 134 135 ClassTemplateDecl::~ClassTemplateDecl() { 136 assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed"); 137 } 138 139 void ClassTemplateDecl::Destroy(ASTContext& C) { 140 if (!PreviousDeclaration) { 141 CommonPtr->~Common(); 142 C.Deallocate((void*)CommonPtr); 143 } 144 CommonPtr = 0; 145 146 this->~ClassTemplateDecl(); 147 C.Deallocate((void*)this); 148 } 149 150 QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) { 151 if (!CommonPtr->InjectedClassNameType.isNull()) 152 return CommonPtr->InjectedClassNameType; 153 154 // FIXME: n2800 14.6.1p1 should say how the template arguments 155 // corresponding to template parameter packs should be pack 156 // expansions. We already say that in 14.6.2.1p2, so it would be 157 // better to fix that redundancy. 158 159 TemplateParameterList *Params = getTemplateParameters(); 160 161 llvm::SmallVector<TemplateArgument, 16> TemplateArgs; 162 llvm::SmallVector<TemplateArgument, 16> CanonTemplateArgs; 163 TemplateArgs.reserve(Params->size()); 164 CanonTemplateArgs.reserve(Params->size()); 165 166 for (TemplateParameterList::iterator 167 Param = Params->begin(), ParamEnd = Params->end(); 168 Param != ParamEnd; ++Param) { 169 if (isa<TemplateTypeParmDecl>(*Param)) { 170 QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param)); 171 TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(), 172 ParamType)); 173 CanonTemplateArgs.push_back( 174 TemplateArgument((*Param)->getLocation(), 175 Context.getCanonicalType(ParamType))); 176 } else if (NonTypeTemplateParmDecl *NTTP = 177 dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 178 // FIXME: Build canonical expression, too! 179 Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(), 180 NTTP->getLocation(), 181 NTTP->getType()->isDependentType(), 182 /*Value-dependent=*/true); 183 TemplateArgs.push_back(TemplateArgument(E)); 184 CanonTemplateArgs.push_back(TemplateArgument(E)); 185 } else { 186 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 187 TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP)); 188 CanonTemplateArgs.push_back(TemplateArgument(TTP->getLocation(), 189 Context.getCanonicalDecl(TTP))); 190 } 191 } 192 193 // FIXME: I should really move the "build-the-canonical-type" logic 194 // into ASTContext::getTemplateSpecializationType. 195 TemplateName Name = TemplateName(this); 196 QualType CanonType = Context.getTemplateSpecializationType( 197 Context.getCanonicalTemplateName(Name), 198 &CanonTemplateArgs[0], 199 CanonTemplateArgs.size()); 200 201 CommonPtr->InjectedClassNameType 202 = Context.getTemplateSpecializationType(Name, 203 &TemplateArgs[0], 204 TemplateArgs.size(), 205 CanonType); 206 return CommonPtr->InjectedClassNameType; 207 } 208 209 //===----------------------------------------------------------------------===// 210 // TemplateTypeParm Allocation/Deallocation Method Implementations 211 //===----------------------------------------------------------------------===// 212 213 TemplateTypeParmDecl * 214 TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, 215 SourceLocation L, unsigned D, unsigned P, 216 IdentifierInfo *Id, bool Typename, 217 bool ParameterPack) { 218 QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id); 219 return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack); 220 } 221 222 //===----------------------------------------------------------------------===// 223 // NonTypeTemplateParmDecl Method Implementations 224 //===----------------------------------------------------------------------===// 225 226 NonTypeTemplateParmDecl * 227 NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, 228 SourceLocation L, unsigned D, unsigned P, 229 IdentifierInfo *Id, QualType T, 230 SourceLocation TypeSpecStartLoc) { 231 return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, 232 TypeSpecStartLoc); 233 } 234 235 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 236 return DefaultArgument? DefaultArgument->getSourceRange().getBegin() 237 : SourceLocation(); 238 } 239 240 //===----------------------------------------------------------------------===// 241 // TemplateTemplateParmDecl Method Implementations 242 //===----------------------------------------------------------------------===// 243 244 TemplateTemplateParmDecl * 245 TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, 246 SourceLocation L, unsigned D, unsigned P, 247 IdentifierInfo *Id, 248 TemplateParameterList *Params) { 249 return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params); 250 } 251 252 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 253 return DefaultArgument? DefaultArgument->getSourceRange().getBegin() 254 : SourceLocation(); 255 } 256 257 //===----------------------------------------------------------------------===// 258 // TemplateArgument Implementation 259 //===----------------------------------------------------------------------===// 260 261 TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) { 262 TypeOrValue = reinterpret_cast<uintptr_t>(E); 263 StartLoc = E->getSourceRange().getBegin(); 264 } 265 266 /// \brief Construct a template argument pack. 267 void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs, 268 bool CopyArgs) { 269 assert(isNull() && "Must call setArgumentPack on a null argument"); 270 271 Kind = Pack; 272 Args.NumArgs = NumArgs; 273 Args.CopyArgs = CopyArgs; 274 if (!Args.CopyArgs) { 275 Args.Args = args; 276 return; 277 } 278 279 Args.Args = new TemplateArgument[NumArgs]; 280 for (unsigned I = 0; I != Args.NumArgs; ++I) 281 Args.Args[I] = args[I]; 282 } 283 284 //===----------------------------------------------------------------------===// 285 // TemplateArgumentListBuilder Implementation 286 //===----------------------------------------------------------------------===// 287 288 void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) { 289 switch (Arg.getKind()) { 290 default: break; 291 case TemplateArgument::Type: 292 assert(Arg.getAsType()->isCanonical() && "Type must be canonical!"); 293 break; 294 } 295 296 assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!"); 297 assert(!StructuredArgs && 298 "Can't append arguments when an argument pack has been added!"); 299 300 if (!FlatArgs) 301 FlatArgs = new TemplateArgument[MaxFlatArgs]; 302 303 FlatArgs[NumFlatArgs++] = Arg; 304 } 305 306 void TemplateArgumentListBuilder::BeginPack() { 307 assert(!AddingToPack && "Already adding to pack!"); 308 assert(!StructuredArgs && "Argument list already contains a pack!"); 309 310 AddingToPack = true; 311 PackBeginIndex = NumFlatArgs; 312 } 313 314 void TemplateArgumentListBuilder::EndPack() { 315 assert(AddingToPack && "Not adding to pack!"); 316 assert(!StructuredArgs && "Argument list already contains a pack!"); 317 318 AddingToPack = false; 319 320 StructuredArgs = new TemplateArgument[MaxStructuredArgs]; 321 322 // First copy the flat entries over to the list (if any) 323 for (unsigned I = 0; I != PackBeginIndex; ++I) { 324 NumStructuredArgs++; 325 StructuredArgs[I] = FlatArgs[I]; 326 } 327 328 // Next, set the pack. 329 TemplateArgument *PackArgs = 0; 330 unsigned NumPackArgs = NumFlatArgs - PackBeginIndex; 331 if (NumPackArgs) 332 PackArgs = &FlatArgs[PackBeginIndex]; 333 334 StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs, 335 /*CopyArgs=*/false); 336 } 337 338 void TemplateArgumentListBuilder::ReleaseArgs() { 339 FlatArgs = 0; 340 NumFlatArgs = 0; 341 MaxFlatArgs = 0; 342 StructuredArgs = 0; 343 NumStructuredArgs = 0; 344 MaxStructuredArgs = 0; 345 } 346 347 //===----------------------------------------------------------------------===// 348 // TemplateArgumentList Implementation 349 //===----------------------------------------------------------------------===// 350 TemplateArgumentList::TemplateArgumentList(ASTContext &Context, 351 TemplateArgumentListBuilder &Builder, 352 bool TakeArgs) 353 : FlatArguments(Builder.getFlatArguments(), TakeArgs), 354 NumFlatArguments(Builder.flatSize()), 355 StructuredArguments(Builder.getStructuredArguments(), TakeArgs), 356 NumStructuredArguments(Builder.structuredSize()) { 357 358 if (!TakeArgs) 359 return; 360 361 if (Builder.getStructuredArguments() == Builder.getFlatArguments()) 362 StructuredArguments.setInt(0); 363 Builder.ReleaseArgs(); 364 } 365 366 TemplateArgumentList::~TemplateArgumentList() { 367 // FIXME: Deallocate template arguments 368 } 369 370 //===----------------------------------------------------------------------===// 371 // ClassTemplateSpecializationDecl Implementation 372 //===----------------------------------------------------------------------===// 373 ClassTemplateSpecializationDecl:: 374 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, 375 DeclContext *DC, SourceLocation L, 376 ClassTemplateDecl *SpecializedTemplate, 377 TemplateArgumentListBuilder &Builder) 378 : CXXRecordDecl(DK, 379 SpecializedTemplate->getTemplatedDecl()->getTagKind(), 380 DC, L, 381 // FIXME: Should we use DeclarationName for the name of 382 // class template specializations? 383 SpecializedTemplate->getIdentifier()), 384 SpecializedTemplate(SpecializedTemplate), 385 TemplateArgs(Context, Builder, /*TakeArgs=*/true), 386 SpecializationKind(TSK_Undeclared) { 387 } 388 389 ClassTemplateSpecializationDecl * 390 ClassTemplateSpecializationDecl::Create(ASTContext &Context, 391 DeclContext *DC, SourceLocation L, 392 ClassTemplateDecl *SpecializedTemplate, 393 TemplateArgumentListBuilder &Builder, 394 ClassTemplateSpecializationDecl *PrevDecl) { 395 ClassTemplateSpecializationDecl *Result 396 = new (Context)ClassTemplateSpecializationDecl(Context, 397 ClassTemplateSpecialization, 398 DC, L, 399 SpecializedTemplate, 400 Builder); 401 Context.getTypeDeclType(Result, PrevDecl); 402 return Result; 403 } 404 405 //===----------------------------------------------------------------------===// 406 // ClassTemplatePartialSpecializationDecl Implementation 407 //===----------------------------------------------------------------------===// 408 ClassTemplatePartialSpecializationDecl * 409 ClassTemplatePartialSpecializationDecl:: 410 Create(ASTContext &Context, DeclContext *DC, SourceLocation L, 411 TemplateParameterList *Params, 412 ClassTemplateDecl *SpecializedTemplate, 413 TemplateArgumentListBuilder &Builder, 414 ClassTemplatePartialSpecializationDecl *PrevDecl) { 415 ClassTemplatePartialSpecializationDecl *Result 416 = new (Context)ClassTemplatePartialSpecializationDecl(Context, 417 DC, L, Params, 418 SpecializedTemplate, 419 Builder); 420 Result->setSpecializationKind(TSK_ExplicitSpecialization); 421 Context.getTypeDeclType(Result, PrevDecl); 422 return Result; 423 } 424