clang API Documentation
00001 //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the C++ related Decl classes for templates. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/AST/DeclTemplate.h" 00015 #include "clang/AST/ASTContext.h" 00016 #include "clang/AST/ASTMutationListener.h" 00017 #include "clang/AST/DeclCXX.h" 00018 #include "clang/AST/Expr.h" 00019 #include "clang/AST/ExprCXX.h" 00020 #include "clang/AST/TypeLoc.h" 00021 #include "clang/Basic/IdentifierTable.h" 00022 #include "llvm/ADT/STLExtras.h" 00023 #include <memory> 00024 using namespace clang; 00025 00026 //===----------------------------------------------------------------------===// 00027 // TemplateParameterList Implementation 00028 //===----------------------------------------------------------------------===// 00029 00030 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, 00031 SourceLocation LAngleLoc, 00032 NamedDecl **Params, unsigned NumParams, 00033 SourceLocation RAngleLoc) 00034 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), 00035 NumParams(NumParams), ContainsUnexpandedParameterPack(false) { 00036 assert(this->NumParams == NumParams && "Too many template parameters"); 00037 for (unsigned Idx = 0; Idx < NumParams; ++Idx) { 00038 NamedDecl *P = Params[Idx]; 00039 begin()[Idx] = P; 00040 00041 if (!P->isTemplateParameterPack()) { 00042 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) 00043 if (NTTP->getType()->containsUnexpandedParameterPack()) 00044 ContainsUnexpandedParameterPack = true; 00045 00046 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) 00047 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack()) 00048 ContainsUnexpandedParameterPack = true; 00049 00050 // FIXME: If a default argument contains an unexpanded parameter pack, the 00051 // template parameter list does too. 00052 } 00053 } 00054 } 00055 00056 TemplateParameterList * 00057 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, 00058 SourceLocation LAngleLoc, NamedDecl **Params, 00059 unsigned NumParams, SourceLocation RAngleLoc) { 00060 unsigned Size = sizeof(TemplateParameterList) 00061 + sizeof(NamedDecl *) * NumParams; 00062 unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(), 00063 llvm::alignOf<NamedDecl*>()); 00064 void *Mem = C.Allocate(Size, Align); 00065 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, 00066 NumParams, RAngleLoc); 00067 } 00068 00069 unsigned TemplateParameterList::getMinRequiredArguments() const { 00070 unsigned NumRequiredArgs = 0; 00071 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(), 00072 PEnd = const_cast<TemplateParameterList *>(this)->end(); 00073 P != PEnd; ++P) { 00074 if ((*P)->isTemplateParameterPack()) { 00075 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) 00076 if (NTTP->isExpandedParameterPack()) { 00077 NumRequiredArgs += NTTP->getNumExpansionTypes(); 00078 continue; 00079 } 00080 00081 break; 00082 } 00083 00084 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { 00085 if (TTP->hasDefaultArgument()) 00086 break; 00087 } else if (NonTypeTemplateParmDecl *NTTP 00088 = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 00089 if (NTTP->hasDefaultArgument()) 00090 break; 00091 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument()) 00092 break; 00093 00094 ++NumRequiredArgs; 00095 } 00096 00097 return NumRequiredArgs; 00098 } 00099 00100 unsigned TemplateParameterList::getDepth() const { 00101 if (size() == 0) 00102 return 0; 00103 00104 const NamedDecl *FirstParm = getParam(0); 00105 if (const TemplateTypeParmDecl *TTP 00106 = dyn_cast<TemplateTypeParmDecl>(FirstParm)) 00107 return TTP->getDepth(); 00108 else if (const NonTypeTemplateParmDecl *NTTP 00109 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm)) 00110 return NTTP->getDepth(); 00111 else 00112 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth(); 00113 } 00114 00115 static void AdoptTemplateParameterList(TemplateParameterList *Params, 00116 DeclContext *Owner) { 00117 for (TemplateParameterList::iterator P = Params->begin(), 00118 PEnd = Params->end(); 00119 P != PEnd; ++P) { 00120 (*P)->setDeclContext(Owner); 00121 00122 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P)) 00123 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner); 00124 } 00125 } 00126 00127 //===----------------------------------------------------------------------===// 00128 // RedeclarableTemplateDecl Implementation 00129 //===----------------------------------------------------------------------===// 00130 00131 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const { 00132 if (Common) 00133 return Common; 00134 00135 // Walk the previous-declaration chain until we either find a declaration 00136 // with a common pointer or we run out of previous declarations. 00137 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls; 00138 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev; 00139 Prev = Prev->getPreviousDecl()) { 00140 if (Prev->Common) { 00141 Common = Prev->Common; 00142 break; 00143 } 00144 00145 PrevDecls.push_back(Prev); 00146 } 00147 00148 // If we never found a common pointer, allocate one now. 00149 if (!Common) { 00150 // FIXME: If any of the declarations is from an AST file, we probably 00151 // need an update record to add the common data. 00152 00153 Common = newCommon(getASTContext()); 00154 } 00155 00156 // Update any previous declarations we saw with the common pointer. 00157 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I) 00158 PrevDecls[I]->Common = Common; 00159 00160 return Common; 00161 } 00162 00163 template <class EntryType> 00164 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType* 00165 RedeclarableTemplateDecl::findSpecializationImpl( 00166 llvm::FoldingSetVector<EntryType> &Specs, 00167 ArrayRef<TemplateArgument> Args, 00168 void *&InsertPos) { 00169 typedef SpecEntryTraits<EntryType> SETraits; 00170 llvm::FoldingSetNodeID ID; 00171 EntryType::Profile(ID,Args, getASTContext()); 00172 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 00173 return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr; 00174 } 00175 00176 /// \brief Generate the injected template arguments for the given template 00177 /// parameter list, e.g., for the injected-class-name of a class template. 00178 static void GenerateInjectedTemplateArgs(ASTContext &Context, 00179 TemplateParameterList *Params, 00180 TemplateArgument *Args) { 00181 for (TemplateParameterList::iterator Param = Params->begin(), 00182 ParamEnd = Params->end(); 00183 Param != ParamEnd; ++Param) { 00184 TemplateArgument Arg; 00185 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { 00186 QualType ArgType = Context.getTypeDeclType(TTP); 00187 if (TTP->isParameterPack()) 00188 ArgType = Context.getPackExpansionType(ArgType, None); 00189 00190 Arg = TemplateArgument(ArgType); 00191 } else if (NonTypeTemplateParmDecl *NTTP = 00192 dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 00193 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false, 00194 NTTP->getType().getNonLValueExprType(Context), 00195 Expr::getValueKindForType(NTTP->getType()), 00196 NTTP->getLocation()); 00197 00198 if (NTTP->isParameterPack()) 00199 E = new (Context) PackExpansionExpr(Context.DependentTy, E, 00200 NTTP->getLocation(), None); 00201 Arg = TemplateArgument(E); 00202 } else { 00203 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 00204 if (TTP->isParameterPack()) 00205 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>()); 00206 else 00207 Arg = TemplateArgument(TemplateName(TTP)); 00208 } 00209 00210 if ((*Param)->isTemplateParameterPack()) 00211 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1); 00212 00213 *Args++ = Arg; 00214 } 00215 } 00216 00217 //===----------------------------------------------------------------------===// 00218 // FunctionTemplateDecl Implementation 00219 //===----------------------------------------------------------------------===// 00220 00221 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) { 00222 static_cast<Common *>(Ptr)->~Common(); 00223 } 00224 00225 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 00226 DeclContext *DC, 00227 SourceLocation L, 00228 DeclarationName Name, 00229 TemplateParameterList *Params, 00230 NamedDecl *Decl) { 00231 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 00232 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl); 00233 } 00234 00235 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, 00236 unsigned ID) { 00237 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), 00238 DeclarationName(), nullptr, nullptr); 00239 } 00240 00241 RedeclarableTemplateDecl::CommonBase * 00242 FunctionTemplateDecl::newCommon(ASTContext &C) const { 00243 Common *CommonPtr = new (C) Common; 00244 C.AddDeallocation(DeallocateCommon, CommonPtr); 00245 return CommonPtr; 00246 } 00247 00248 void FunctionTemplateDecl::LoadLazySpecializations() const { 00249 Common *CommonPtr = getCommonPtr(); 00250 if (CommonPtr->LazySpecializations) { 00251 ASTContext &Context = getASTContext(); 00252 uint32_t *Specs = CommonPtr->LazySpecializations; 00253 CommonPtr->LazySpecializations = nullptr; 00254 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 00255 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 00256 } 00257 } 00258 00259 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & 00260 FunctionTemplateDecl::getSpecializations() const { 00261 LoadLazySpecializations(); 00262 return getCommonPtr()->Specializations; 00263 } 00264 00265 FunctionDecl * 00266 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 00267 void *&InsertPos) { 00268 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 00269 } 00270 00271 void FunctionTemplateDecl::addSpecialization( 00272 FunctionTemplateSpecializationInfo *Info, void *InsertPos) { 00273 if (InsertPos) 00274 getSpecializations().InsertNode(Info, InsertPos); 00275 else 00276 getSpecializations().GetOrInsertNode(Info); 00277 if (ASTMutationListener *L = getASTMutationListener()) 00278 L->AddedCXXTemplateSpecialization(this, Info->Function); 00279 } 00280 00281 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() { 00282 TemplateParameterList *Params = getTemplateParameters(); 00283 Common *CommonPtr = getCommonPtr(); 00284 if (!CommonPtr->InjectedArgs) { 00285 CommonPtr->InjectedArgs 00286 = new (getASTContext()) TemplateArgument[Params->size()]; 00287 GenerateInjectedTemplateArgs(getASTContext(), Params, 00288 CommonPtr->InjectedArgs); 00289 } 00290 00291 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size()); 00292 } 00293 00294 //===----------------------------------------------------------------------===// 00295 // ClassTemplateDecl Implementation 00296 //===----------------------------------------------------------------------===// 00297 00298 void ClassTemplateDecl::DeallocateCommon(void *Ptr) { 00299 static_cast<Common *>(Ptr)->~Common(); 00300 } 00301 00302 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 00303 DeclContext *DC, 00304 SourceLocation L, 00305 DeclarationName Name, 00306 TemplateParameterList *Params, 00307 NamedDecl *Decl, 00308 ClassTemplateDecl *PrevDecl) { 00309 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 00310 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name, 00311 Params, Decl); 00312 New->setPreviousDecl(PrevDecl); 00313 return New; 00314 } 00315 00316 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 00317 unsigned ID) { 00318 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), 00319 DeclarationName(), nullptr, nullptr); 00320 } 00321 00322 void ClassTemplateDecl::LoadLazySpecializations() const { 00323 Common *CommonPtr = getCommonPtr(); 00324 if (CommonPtr->LazySpecializations) { 00325 ASTContext &Context = getASTContext(); 00326 uint32_t *Specs = CommonPtr->LazySpecializations; 00327 CommonPtr->LazySpecializations = nullptr; 00328 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 00329 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 00330 } 00331 } 00332 00333 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 00334 ClassTemplateDecl::getSpecializations() const { 00335 LoadLazySpecializations(); 00336 return getCommonPtr()->Specializations; 00337 } 00338 00339 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 00340 ClassTemplateDecl::getPartialSpecializations() { 00341 LoadLazySpecializations(); 00342 return getCommonPtr()->PartialSpecializations; 00343 } 00344 00345 RedeclarableTemplateDecl::CommonBase * 00346 ClassTemplateDecl::newCommon(ASTContext &C) const { 00347 Common *CommonPtr = new (C) Common; 00348 C.AddDeallocation(DeallocateCommon, CommonPtr); 00349 return CommonPtr; 00350 } 00351 00352 ClassTemplateSpecializationDecl * 00353 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 00354 void *&InsertPos) { 00355 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 00356 } 00357 00358 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 00359 void *InsertPos) { 00360 if (InsertPos) 00361 getSpecializations().InsertNode(D, InsertPos); 00362 else { 00363 ClassTemplateSpecializationDecl *Existing 00364 = getSpecializations().GetOrInsertNode(D); 00365 (void)Existing; 00366 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 00367 } 00368 if (ASTMutationListener *L = getASTMutationListener()) 00369 L->AddedCXXTemplateSpecialization(this, D); 00370 } 00371 00372 ClassTemplatePartialSpecializationDecl * 00373 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 00374 void *&InsertPos) { 00375 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); 00376 } 00377 00378 void ClassTemplateDecl::AddPartialSpecialization( 00379 ClassTemplatePartialSpecializationDecl *D, 00380 void *InsertPos) { 00381 if (InsertPos) 00382 getPartialSpecializations().InsertNode(D, InsertPos); 00383 else { 00384 ClassTemplatePartialSpecializationDecl *Existing 00385 = getPartialSpecializations().GetOrInsertNode(D); 00386 (void)Existing; 00387 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 00388 } 00389 00390 if (ASTMutationListener *L = getASTMutationListener()) 00391 L->AddedCXXTemplateSpecialization(this, D); 00392 } 00393 00394 void ClassTemplateDecl::getPartialSpecializations( 00395 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) { 00396 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs 00397 = getPartialSpecializations(); 00398 PS.clear(); 00399 PS.reserve(PartialSpecs.size()); 00400 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 00401 P = PartialSpecs.begin(), PEnd = PartialSpecs.end(); 00402 P != PEnd; ++P) 00403 PS.push_back(P->getMostRecentDecl()); 00404 } 00405 00406 ClassTemplatePartialSpecializationDecl * 00407 ClassTemplateDecl::findPartialSpecialization(QualType T) { 00408 ASTContext &Context = getASTContext(); 00409 using llvm::FoldingSetVector; 00410 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 00411 partial_spec_iterator; 00412 for (partial_spec_iterator P = getPartialSpecializations().begin(), 00413 PEnd = getPartialSpecializations().end(); 00414 P != PEnd; ++P) { 00415 if (Context.hasSameType(P->getInjectedSpecializationType(), T)) 00416 return P->getMostRecentDecl(); 00417 } 00418 00419 return nullptr; 00420 } 00421 00422 ClassTemplatePartialSpecializationDecl * 00423 ClassTemplateDecl::findPartialSpecInstantiatedFromMember( 00424 ClassTemplatePartialSpecializationDecl *D) { 00425 Decl *DCanon = D->getCanonicalDecl(); 00426 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 00427 P = getPartialSpecializations().begin(), 00428 PEnd = getPartialSpecializations().end(); 00429 P != PEnd; ++P) { 00430 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 00431 return P->getMostRecentDecl(); 00432 } 00433 00434 return nullptr; 00435 } 00436 00437 QualType 00438 ClassTemplateDecl::getInjectedClassNameSpecialization() { 00439 Common *CommonPtr = getCommonPtr(); 00440 if (!CommonPtr->InjectedClassNameType.isNull()) 00441 return CommonPtr->InjectedClassNameType; 00442 00443 // C++0x [temp.dep.type]p2: 00444 // The template argument list of a primary template is a template argument 00445 // list in which the nth template argument has the value of the nth template 00446 // parameter of the class template. If the nth template parameter is a 00447 // template parameter pack (14.5.3), the nth template argument is a pack 00448 // expansion (14.5.3) whose pattern is the name of the template parameter 00449 // pack. 00450 ASTContext &Context = getASTContext(); 00451 TemplateParameterList *Params = getTemplateParameters(); 00452 SmallVector<TemplateArgument, 16> TemplateArgs; 00453 TemplateArgs.resize(Params->size()); 00454 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data()); 00455 CommonPtr->InjectedClassNameType 00456 = Context.getTemplateSpecializationType(TemplateName(this), 00457 &TemplateArgs[0], 00458 TemplateArgs.size()); 00459 return CommonPtr->InjectedClassNameType; 00460 } 00461 00462 //===----------------------------------------------------------------------===// 00463 // TemplateTypeParm Allocation/Deallocation Method Implementations 00464 //===----------------------------------------------------------------------===// 00465 00466 TemplateTypeParmDecl * 00467 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC, 00468 SourceLocation KeyLoc, SourceLocation NameLoc, 00469 unsigned D, unsigned P, IdentifierInfo *Id, 00470 bool Typename, bool ParameterPack) { 00471 TemplateTypeParmDecl *TTPDecl = 00472 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename); 00473 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 00474 TTPDecl->setTypeForDecl(TTPType.getTypePtr()); 00475 return TTPDecl; 00476 } 00477 00478 TemplateTypeParmDecl * 00479 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { 00480 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), 00481 SourceLocation(), nullptr, false); 00482 } 00483 00484 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 00485 return hasDefaultArgument() 00486 ? DefaultArgument->getTypeLoc().getBeginLoc() 00487 : SourceLocation(); 00488 } 00489 00490 SourceRange TemplateTypeParmDecl::getSourceRange() const { 00491 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 00492 return SourceRange(getLocStart(), 00493 DefaultArgument->getTypeLoc().getEndLoc()); 00494 else 00495 return TypeDecl::getSourceRange(); 00496 } 00497 00498 unsigned TemplateTypeParmDecl::getDepth() const { 00499 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth(); 00500 } 00501 00502 unsigned TemplateTypeParmDecl::getIndex() const { 00503 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex(); 00504 } 00505 00506 bool TemplateTypeParmDecl::isParameterPack() const { 00507 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack(); 00508 } 00509 00510 //===----------------------------------------------------------------------===// 00511 // NonTypeTemplateParmDecl Method Implementations 00512 //===----------------------------------------------------------------------===// 00513 00514 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 00515 SourceLocation StartLoc, 00516 SourceLocation IdLoc, 00517 unsigned D, unsigned P, 00518 IdentifierInfo *Id, 00519 QualType T, 00520 TypeSourceInfo *TInfo, 00521 const QualType *ExpandedTypes, 00522 unsigned NumExpandedTypes, 00523 TypeSourceInfo **ExpandedTInfos) 00524 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 00525 TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false), 00526 ParameterPack(true), ExpandedParameterPack(true), 00527 NumExpandedTypes(NumExpandedTypes) 00528 { 00529 if (ExpandedTypes && ExpandedTInfos) { 00530 void **TypesAndInfos = reinterpret_cast<void **>(this + 1); 00531 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 00532 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr(); 00533 TypesAndInfos[2*I + 1] = ExpandedTInfos[I]; 00534 } 00535 } 00536 } 00537 00538 NonTypeTemplateParmDecl * 00539 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 00540 SourceLocation StartLoc, SourceLocation IdLoc, 00541 unsigned D, unsigned P, IdentifierInfo *Id, 00542 QualType T, bool ParameterPack, 00543 TypeSourceInfo *TInfo) { 00544 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 00545 T, ParameterPack, TInfo); 00546 } 00547 00548 NonTypeTemplateParmDecl * 00549 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 00550 SourceLocation StartLoc, SourceLocation IdLoc, 00551 unsigned D, unsigned P, 00552 IdentifierInfo *Id, QualType T, 00553 TypeSourceInfo *TInfo, 00554 const QualType *ExpandedTypes, 00555 unsigned NumExpandedTypes, 00556 TypeSourceInfo **ExpandedTInfos) { 00557 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*); 00558 return new (C, DC, Extra) NonTypeTemplateParmDecl( 00559 DC, StartLoc, IdLoc, D, P, Id, T, TInfo, 00560 ExpandedTypes, NumExpandedTypes, ExpandedTInfos); 00561 } 00562 00563 NonTypeTemplateParmDecl * 00564 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 00565 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(), 00566 SourceLocation(), 0, 0, nullptr, 00567 QualType(), false, nullptr); 00568 } 00569 00570 NonTypeTemplateParmDecl * 00571 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 00572 unsigned NumExpandedTypes) { 00573 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*); 00574 return new (C, ID, Extra) NonTypeTemplateParmDecl( 00575 nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(), 00576 nullptr, nullptr, NumExpandedTypes, nullptr); 00577 } 00578 00579 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 00580 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 00581 return SourceRange(getOuterLocStart(), 00582 getDefaultArgument()->getSourceRange().getEnd()); 00583 return DeclaratorDecl::getSourceRange(); 00584 } 00585 00586 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 00587 return hasDefaultArgument() 00588 ? getDefaultArgument()->getSourceRange().getBegin() 00589 : SourceLocation(); 00590 } 00591 00592 //===----------------------------------------------------------------------===// 00593 // TemplateTemplateParmDecl Method Implementations 00594 //===----------------------------------------------------------------------===// 00595 00596 void TemplateTemplateParmDecl::anchor() { } 00597 00598 TemplateTemplateParmDecl::TemplateTemplateParmDecl( 00599 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 00600 IdentifierInfo *Id, TemplateParameterList *Params, 00601 unsigned NumExpansions, TemplateParameterList * const *Expansions) 00602 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 00603 TemplateParmPosition(D, P), DefaultArgument(), 00604 DefaultArgumentWasInherited(false), ParameterPack(true), 00605 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) { 00606 if (Expansions) 00607 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions, 00608 sizeof(TemplateParameterList*) * NumExpandedParams); 00609 } 00610 00611 TemplateTemplateParmDecl * 00612 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 00613 SourceLocation L, unsigned D, unsigned P, 00614 bool ParameterPack, IdentifierInfo *Id, 00615 TemplateParameterList *Params) { 00616 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 00617 Params); 00618 } 00619 00620 TemplateTemplateParmDecl * 00621 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 00622 SourceLocation L, unsigned D, unsigned P, 00623 IdentifierInfo *Id, 00624 TemplateParameterList *Params, 00625 ArrayRef<TemplateParameterList *> Expansions) { 00626 return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size()) 00627 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, 00628 Expansions.size(), Expansions.data()); 00629 } 00630 00631 TemplateTemplateParmDecl * 00632 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 00633 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, 00634 false, nullptr, nullptr); 00635 } 00636 00637 TemplateTemplateParmDecl * 00638 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 00639 unsigned NumExpansions) { 00640 return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions) 00641 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, 00642 nullptr, NumExpansions, nullptr); 00643 } 00644 00645 //===----------------------------------------------------------------------===// 00646 // TemplateArgumentList Implementation 00647 //===----------------------------------------------------------------------===// 00648 TemplateArgumentList * 00649 TemplateArgumentList::CreateCopy(ASTContext &Context, 00650 const TemplateArgument *Args, 00651 unsigned NumArgs) { 00652 std::size_t Size = sizeof(TemplateArgumentList) 00653 + NumArgs * sizeof(TemplateArgument); 00654 void *Mem = Context.Allocate(Size); 00655 TemplateArgument *StoredArgs 00656 = reinterpret_cast<TemplateArgument *>( 00657 static_cast<TemplateArgumentList *>(Mem) + 1); 00658 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs); 00659 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true); 00660 } 00661 00662 FunctionTemplateSpecializationInfo * 00663 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 00664 FunctionTemplateDecl *Template, 00665 TemplateSpecializationKind TSK, 00666 const TemplateArgumentList *TemplateArgs, 00667 const TemplateArgumentListInfo *TemplateArgsAsWritten, 00668 SourceLocation POI) { 00669 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; 00670 if (TemplateArgsAsWritten) 00671 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 00672 *TemplateArgsAsWritten); 00673 00674 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 00675 TemplateArgs, 00676 ArgsAsWritten, 00677 POI); 00678 } 00679 00680 //===----------------------------------------------------------------------===// 00681 // TemplateDecl Implementation 00682 //===----------------------------------------------------------------------===// 00683 00684 void TemplateDecl::anchor() { } 00685 00686 //===----------------------------------------------------------------------===// 00687 // ClassTemplateSpecializationDecl Implementation 00688 //===----------------------------------------------------------------------===// 00689 ClassTemplateSpecializationDecl:: 00690 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 00691 DeclContext *DC, SourceLocation StartLoc, 00692 SourceLocation IdLoc, 00693 ClassTemplateDecl *SpecializedTemplate, 00694 const TemplateArgument *Args, 00695 unsigned NumArgs, 00696 ClassTemplateSpecializationDecl *PrevDecl) 00697 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, 00698 SpecializedTemplate->getIdentifier(), 00699 PrevDecl), 00700 SpecializedTemplate(SpecializedTemplate), 00701 ExplicitInfo(nullptr), 00702 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 00703 SpecializationKind(TSK_Undeclared) { 00704 } 00705 00706 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, 00707 Kind DK) 00708 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(), 00709 SourceLocation(), nullptr, nullptr), 00710 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {} 00711 00712 ClassTemplateSpecializationDecl * 00713 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 00714 DeclContext *DC, 00715 SourceLocation StartLoc, 00716 SourceLocation IdLoc, 00717 ClassTemplateDecl *SpecializedTemplate, 00718 const TemplateArgument *Args, 00719 unsigned NumArgs, 00720 ClassTemplateSpecializationDecl *PrevDecl) { 00721 ClassTemplateSpecializationDecl *Result = 00722 new (Context, DC) ClassTemplateSpecializationDecl( 00723 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, 00724 SpecializedTemplate, Args, NumArgs, PrevDecl); 00725 Result->MayHaveOutOfDateDef = false; 00726 00727 Context.getTypeDeclType(Result, PrevDecl); 00728 return Result; 00729 } 00730 00731 ClassTemplateSpecializationDecl * 00732 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 00733 unsigned ID) { 00734 ClassTemplateSpecializationDecl *Result = 00735 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); 00736 Result->MayHaveOutOfDateDef = false; 00737 return Result; 00738 } 00739 00740 void ClassTemplateSpecializationDecl::getNameForDiagnostic( 00741 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 00742 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 00743 00744 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 00745 TemplateSpecializationType::PrintTemplateArgumentList( 00746 OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 00747 } 00748 00749 ClassTemplateDecl * 00750 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 00751 if (SpecializedPartialSpecialization *PartialSpec 00752 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 00753 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 00754 return SpecializedTemplate.get<ClassTemplateDecl*>(); 00755 } 00756 00757 SourceRange 00758 ClassTemplateSpecializationDecl::getSourceRange() const { 00759 if (ExplicitInfo) { 00760 SourceLocation Begin = getTemplateKeywordLoc(); 00761 if (Begin.isValid()) { 00762 // Here we have an explicit (partial) specialization or instantiation. 00763 assert(getSpecializationKind() == TSK_ExplicitSpecialization || 00764 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || 00765 getSpecializationKind() == TSK_ExplicitInstantiationDefinition); 00766 if (getExternLoc().isValid()) 00767 Begin = getExternLoc(); 00768 SourceLocation End = getRBraceLoc(); 00769 if (End.isInvalid()) 00770 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 00771 return SourceRange(Begin, End); 00772 } 00773 // An implicit instantiation of a class template partial specialization 00774 // uses ExplicitInfo to record the TypeAsWritten, but the source 00775 // locations should be retrieved from the instantiation pattern. 00776 typedef ClassTemplatePartialSpecializationDecl CTPSDecl; 00777 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this)); 00778 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); 00779 assert(inst_from != nullptr); 00780 return inst_from->getSourceRange(); 00781 } 00782 else { 00783 // No explicit info available. 00784 llvm::PointerUnion<ClassTemplateDecl *, 00785 ClassTemplatePartialSpecializationDecl *> 00786 inst_from = getInstantiatedFrom(); 00787 if (inst_from.isNull()) 00788 return getSpecializedTemplate()->getSourceRange(); 00789 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>()) 00790 return ctd->getSourceRange(); 00791 return inst_from.get<ClassTemplatePartialSpecializationDecl*>() 00792 ->getSourceRange(); 00793 } 00794 } 00795 00796 //===----------------------------------------------------------------------===// 00797 // ClassTemplatePartialSpecializationDecl Implementation 00798 //===----------------------------------------------------------------------===// 00799 void ClassTemplatePartialSpecializationDecl::anchor() { } 00800 00801 ClassTemplatePartialSpecializationDecl:: 00802 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 00803 DeclContext *DC, 00804 SourceLocation StartLoc, 00805 SourceLocation IdLoc, 00806 TemplateParameterList *Params, 00807 ClassTemplateDecl *SpecializedTemplate, 00808 const TemplateArgument *Args, 00809 unsigned NumArgs, 00810 const ASTTemplateArgumentListInfo *ArgInfos, 00811 ClassTemplatePartialSpecializationDecl *PrevDecl) 00812 : ClassTemplateSpecializationDecl(Context, 00813 ClassTemplatePartialSpecialization, 00814 TK, DC, StartLoc, IdLoc, 00815 SpecializedTemplate, 00816 Args, NumArgs, PrevDecl), 00817 TemplateParams(Params), ArgsAsWritten(ArgInfos), 00818 InstantiatedFromMember(nullptr, false) 00819 { 00820 AdoptTemplateParameterList(Params, this); 00821 } 00822 00823 ClassTemplatePartialSpecializationDecl * 00824 ClassTemplatePartialSpecializationDecl:: 00825 Create(ASTContext &Context, TagKind TK,DeclContext *DC, 00826 SourceLocation StartLoc, SourceLocation IdLoc, 00827 TemplateParameterList *Params, 00828 ClassTemplateDecl *SpecializedTemplate, 00829 const TemplateArgument *Args, 00830 unsigned NumArgs, 00831 const TemplateArgumentListInfo &ArgInfos, 00832 QualType CanonInjectedType, 00833 ClassTemplatePartialSpecializationDecl *PrevDecl) { 00834 const ASTTemplateArgumentListInfo *ASTArgInfos = 00835 ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 00836 00837 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC) 00838 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc, 00839 Params, SpecializedTemplate, Args, 00840 NumArgs, ASTArgInfos, PrevDecl); 00841 Result->setSpecializationKind(TSK_ExplicitSpecialization); 00842 Result->MayHaveOutOfDateDef = false; 00843 00844 Context.getInjectedClassNameType(Result, CanonInjectedType); 00845 return Result; 00846 } 00847 00848 ClassTemplatePartialSpecializationDecl * 00849 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 00850 unsigned ID) { 00851 ClassTemplatePartialSpecializationDecl *Result = 00852 new (C, ID) ClassTemplatePartialSpecializationDecl(C); 00853 Result->MayHaveOutOfDateDef = false; 00854 return Result; 00855 } 00856 00857 //===----------------------------------------------------------------------===// 00858 // FriendTemplateDecl Implementation 00859 //===----------------------------------------------------------------------===// 00860 00861 void FriendTemplateDecl::anchor() { } 00862 00863 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 00864 DeclContext *DC, 00865 SourceLocation L, 00866 unsigned NParams, 00867 TemplateParameterList **Params, 00868 FriendUnion Friend, 00869 SourceLocation FLoc) { 00870 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params, 00871 Friend, FLoc); 00872 } 00873 00874 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 00875 unsigned ID) { 00876 return new (C, ID) FriendTemplateDecl(EmptyShell()); 00877 } 00878 00879 //===----------------------------------------------------------------------===// 00880 // TypeAliasTemplateDecl Implementation 00881 //===----------------------------------------------------------------------===// 00882 00883 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 00884 DeclContext *DC, 00885 SourceLocation L, 00886 DeclarationName Name, 00887 TemplateParameterList *Params, 00888 NamedDecl *Decl) { 00889 AdoptTemplateParameterList(Params, DC); 00890 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); 00891 } 00892 00893 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 00894 unsigned ID) { 00895 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), 00896 DeclarationName(), nullptr, nullptr); 00897 } 00898 00899 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) { 00900 static_cast<Common *>(Ptr)->~Common(); 00901 } 00902 RedeclarableTemplateDecl::CommonBase * 00903 TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 00904 Common *CommonPtr = new (C) Common; 00905 C.AddDeallocation(DeallocateCommon, CommonPtr); 00906 return CommonPtr; 00907 } 00908 00909 //===----------------------------------------------------------------------===// 00910 // ClassScopeFunctionSpecializationDecl Implementation 00911 //===----------------------------------------------------------------------===// 00912 00913 void ClassScopeFunctionSpecializationDecl::anchor() { } 00914 00915 ClassScopeFunctionSpecializationDecl * 00916 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 00917 unsigned ID) { 00918 return new (C, ID) ClassScopeFunctionSpecializationDecl( 00919 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo()); 00920 } 00921 00922 //===----------------------------------------------------------------------===// 00923 // VarTemplateDecl Implementation 00924 //===----------------------------------------------------------------------===// 00925 00926 void VarTemplateDecl::DeallocateCommon(void *Ptr) { 00927 static_cast<Common *>(Ptr)->~Common(); 00928 } 00929 00930 VarTemplateDecl *VarTemplateDecl::getDefinition() { 00931 VarTemplateDecl *CurD = this; 00932 while (CurD) { 00933 if (CurD->isThisDeclarationADefinition()) 00934 return CurD; 00935 CurD = CurD->getPreviousDecl(); 00936 } 00937 return nullptr; 00938 } 00939 00940 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 00941 SourceLocation L, DeclarationName Name, 00942 TemplateParameterList *Params, 00943 VarDecl *Decl) { 00944 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); 00945 } 00946 00947 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 00948 unsigned ID) { 00949 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), 00950 DeclarationName(), nullptr, nullptr); 00951 } 00952 00953 // TODO: Unify across class, function and variable templates? 00954 // May require moving this and Common to RedeclarableTemplateDecl. 00955 void VarTemplateDecl::LoadLazySpecializations() const { 00956 Common *CommonPtr = getCommonPtr(); 00957 if (CommonPtr->LazySpecializations) { 00958 ASTContext &Context = getASTContext(); 00959 uint32_t *Specs = CommonPtr->LazySpecializations; 00960 CommonPtr->LazySpecializations = nullptr; 00961 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 00962 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 00963 } 00964 } 00965 00966 llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 00967 VarTemplateDecl::getSpecializations() const { 00968 LoadLazySpecializations(); 00969 return getCommonPtr()->Specializations; 00970 } 00971 00972 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 00973 VarTemplateDecl::getPartialSpecializations() { 00974 LoadLazySpecializations(); 00975 return getCommonPtr()->PartialSpecializations; 00976 } 00977 00978 RedeclarableTemplateDecl::CommonBase * 00979 VarTemplateDecl::newCommon(ASTContext &C) const { 00980 Common *CommonPtr = new (C) Common; 00981 C.AddDeallocation(DeallocateCommon, CommonPtr); 00982 return CommonPtr; 00983 } 00984 00985 VarTemplateSpecializationDecl * 00986 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 00987 void *&InsertPos) { 00988 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 00989 } 00990 00991 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 00992 void *InsertPos) { 00993 if (InsertPos) 00994 getSpecializations().InsertNode(D, InsertPos); 00995 else { 00996 VarTemplateSpecializationDecl *Existing = 00997 getSpecializations().GetOrInsertNode(D); 00998 (void)Existing; 00999 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 01000 } 01001 if (ASTMutationListener *L = getASTMutationListener()) 01002 L->AddedCXXTemplateSpecialization(this, D); 01003 } 01004 01005 VarTemplatePartialSpecializationDecl * 01006 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 01007 void *&InsertPos) { 01008 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); 01009 } 01010 01011 void VarTemplateDecl::AddPartialSpecialization( 01012 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 01013 if (InsertPos) 01014 getPartialSpecializations().InsertNode(D, InsertPos); 01015 else { 01016 VarTemplatePartialSpecializationDecl *Existing = 01017 getPartialSpecializations().GetOrInsertNode(D); 01018 (void)Existing; 01019 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 01020 } 01021 01022 if (ASTMutationListener *L = getASTMutationListener()) 01023 L->AddedCXXTemplateSpecialization(this, D); 01024 } 01025 01026 void VarTemplateDecl::getPartialSpecializations( 01027 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) { 01028 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 01029 getPartialSpecializations(); 01030 PS.clear(); 01031 PS.reserve(PartialSpecs.size()); 01032 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 01033 P = PartialSpecs.begin(), 01034 PEnd = PartialSpecs.end(); 01035 P != PEnd; ++P) 01036 PS.push_back(P->getMostRecentDecl()); 01037 } 01038 01039 VarTemplatePartialSpecializationDecl * 01040 VarTemplateDecl::findPartialSpecInstantiatedFromMember( 01041 VarTemplatePartialSpecializationDecl *D) { 01042 Decl *DCanon = D->getCanonicalDecl(); 01043 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 01044 P = getPartialSpecializations().begin(), 01045 PEnd = getPartialSpecializations().end(); 01046 P != PEnd; ++P) { 01047 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 01048 return P->getMostRecentDecl(); 01049 } 01050 01051 return nullptr; 01052 } 01053 01054 //===----------------------------------------------------------------------===// 01055 // VarTemplateSpecializationDecl Implementation 01056 //===----------------------------------------------------------------------===// 01057 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 01058 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 01059 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 01060 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 01061 unsigned NumArgs) 01062 : VarDecl(DK, Context, DC, StartLoc, IdLoc, 01063 SpecializedTemplate->getIdentifier(), T, TInfo, S), 01064 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr), 01065 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 01066 SpecializationKind(TSK_Undeclared) {} 01067 01068 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, 01069 ASTContext &C) 01070 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, 01071 QualType(), nullptr, SC_None), 01072 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {} 01073 01074 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 01075 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 01076 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 01077 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 01078 unsigned NumArgs) { 01079 return new (Context, DC) VarTemplateSpecializationDecl( 01080 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, 01081 SpecializedTemplate, T, TInfo, S, Args, NumArgs); 01082 } 01083 01084 VarTemplateSpecializationDecl * 01085 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 01086 return new (C, ID) 01087 VarTemplateSpecializationDecl(VarTemplateSpecialization, C); 01088 } 01089 01090 void VarTemplateSpecializationDecl::getNameForDiagnostic( 01091 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 01092 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 01093 01094 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 01095 TemplateSpecializationType::PrintTemplateArgumentList( 01096 OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 01097 } 01098 01099 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 01100 if (SpecializedPartialSpecialization *PartialSpec = 01101 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 01102 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 01103 return SpecializedTemplate.get<VarTemplateDecl *>(); 01104 } 01105 01106 void VarTemplateSpecializationDecl::setTemplateArgsInfo( 01107 const TemplateArgumentListInfo &ArgsInfo) { 01108 unsigned N = ArgsInfo.size(); 01109 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc()); 01110 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc()); 01111 for (unsigned I = 0; I != N; ++I) 01112 TemplateArgsInfo.addArgument(ArgsInfo[I]); 01113 } 01114 01115 //===----------------------------------------------------------------------===// 01116 // VarTemplatePartialSpecializationDecl Implementation 01117 //===----------------------------------------------------------------------===// 01118 void VarTemplatePartialSpecializationDecl::anchor() {} 01119 01120 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 01121 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 01122 SourceLocation IdLoc, TemplateParameterList *Params, 01123 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 01124 StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 01125 const ASTTemplateArgumentListInfo *ArgInfos) 01126 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, 01127 DC, StartLoc, IdLoc, SpecializedTemplate, T, 01128 TInfo, S, Args, NumArgs), 01129 TemplateParams(Params), ArgsAsWritten(ArgInfos), 01130 InstantiatedFromMember(nullptr, false) { 01131 // TODO: The template parameters should be in DC by now. Verify. 01132 // AdoptTemplateParameterList(Params, DC); 01133 } 01134 01135 VarTemplatePartialSpecializationDecl * 01136 VarTemplatePartialSpecializationDecl::Create( 01137 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 01138 SourceLocation IdLoc, TemplateParameterList *Params, 01139 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 01140 StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 01141 const TemplateArgumentListInfo &ArgInfos) { 01142 const ASTTemplateArgumentListInfo *ASTArgInfos 01143 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 01144 01145 VarTemplatePartialSpecializationDecl *Result = 01146 new (Context, DC) VarTemplatePartialSpecializationDecl( 01147 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, 01148 S, Args, NumArgs, ASTArgInfos); 01149 Result->setSpecializationKind(TSK_ExplicitSpecialization); 01150 return Result; 01151 } 01152 01153 VarTemplatePartialSpecializationDecl * 01154 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 01155 unsigned ID) { 01156 return new (C, ID) VarTemplatePartialSpecializationDecl(C); 01157 }