clang API Documentation

DeclTemplate.cpp
Go to the documentation of this file.
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/DeclCXX.h"
00015 #include "clang/AST/DeclTemplate.h"
00016 #include "clang/AST/Expr.h"
00017 #include "clang/AST/ExprCXX.h"
00018 #include "clang/AST/ASTContext.h"
00019 #include "clang/AST/TypeLoc.h"
00020 #include "clang/AST/ASTMutationListener.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) {
00036   for (unsigned Idx = 0; Idx < NumParams; ++Idx)
00037     begin()[Idx] = Params[Idx];
00038 }
00039 
00040 TemplateParameterList *
00041 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
00042                               SourceLocation LAngleLoc, NamedDecl **Params,
00043                               unsigned NumParams, SourceLocation RAngleLoc) {
00044   unsigned Size = sizeof(TemplateParameterList) 
00045                 + sizeof(NamedDecl *) * NumParams;
00046   unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
00047   void *Mem = C.Allocate(Size, Align);
00048   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
00049                                          NumParams, RAngleLoc);
00050 }
00051 
00052 unsigned TemplateParameterList::getMinRequiredArguments() const {
00053   unsigned NumRequiredArgs = 0;
00054   for (iterator P = const_cast<TemplateParameterList *>(this)->begin(), 
00055              PEnd = const_cast<TemplateParameterList *>(this)->end(); 
00056        P != PEnd; ++P) {
00057     if ((*P)->isTemplateParameterPack()) {
00058       if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
00059         if (NTTP->isExpandedParameterPack()) {
00060           NumRequiredArgs += NTTP->getNumExpansionTypes();
00061           continue;
00062         }
00063       
00064       break;
00065     }
00066   
00067     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
00068       if (TTP->hasDefaultArgument())
00069         break;
00070     } else if (NonTypeTemplateParmDecl *NTTP 
00071                                     = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
00072       if (NTTP->hasDefaultArgument())
00073         break;
00074     } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
00075       break;
00076     
00077     ++NumRequiredArgs;
00078   }
00079   
00080   return NumRequiredArgs;
00081 }
00082 
00083 unsigned TemplateParameterList::getDepth() const {
00084   if (size() == 0)
00085     return 0;
00086   
00087   const NamedDecl *FirstParm = getParam(0);
00088   if (const TemplateTypeParmDecl *TTP
00089         = dyn_cast<TemplateTypeParmDecl>(FirstParm))
00090     return TTP->getDepth();
00091   else if (const NonTypeTemplateParmDecl *NTTP 
00092              = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
00093     return NTTP->getDepth();
00094   else
00095     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
00096 }
00097 
00098 static void AdoptTemplateParameterList(TemplateParameterList *Params,
00099                                        DeclContext *Owner) {
00100   for (TemplateParameterList::iterator P = Params->begin(), 
00101                                     PEnd = Params->end();
00102        P != PEnd; ++P) {
00103     (*P)->setDeclContext(Owner);
00104     
00105     if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
00106       AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
00107   }
00108 }
00109 
00110 //===----------------------------------------------------------------------===//
00111 // RedeclarableTemplateDecl Implementation
00112 //===----------------------------------------------------------------------===//
00113 
00114 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() {
00115   if (!Common) {
00116     // Walk the previous-declaration chain until we either find a declaration
00117     // with a common pointer or we run out of previous declarations.
00118     llvm::SmallVector<RedeclarableTemplateDecl *, 2> PrevDecls;
00119     for (RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
00120          Prev = Prev->getPreviousDecl()) {
00121       if (Prev->Common) {
00122         Common = Prev->Common;
00123         break;
00124       }
00125       
00126       PrevDecls.push_back(Prev);
00127     }
00128 
00129     // If we never found a common pointer, allocate one now.
00130     if (!Common) {
00131       // FIXME: If any of the declarations is from an AST file, we probably
00132       // need an update record to add the common data.
00133       
00134       Common = newCommon(getASTContext());
00135     }
00136     
00137     // Update any previous declarations we saw with the common pointer.
00138     for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
00139       PrevDecls[I]->Common = Common;
00140   }
00141 
00142   return Common;
00143 }
00144 
00145 template <class EntryType>
00146 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
00147 RedeclarableTemplateDecl::findSpecializationImpl(
00148                                  llvm::FoldingSetVector<EntryType> &Specs,
00149                                  const TemplateArgument *Args, unsigned NumArgs,
00150                                  void *&InsertPos) {
00151   typedef SpecEntryTraits<EntryType> SETraits;
00152   llvm::FoldingSetNodeID ID;
00153   EntryType::Profile(ID,Args,NumArgs, getASTContext());
00154   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
00155   return Entry ? SETraits::getMostRecentDecl(Entry) : 0;
00156 }
00157 
00158 /// \brief Generate the injected template arguments for the given template
00159 /// parameter list, e.g., for the injected-class-name of a class template.
00160 static void GenerateInjectedTemplateArgs(ASTContext &Context,
00161                                         TemplateParameterList *Params,
00162                                          TemplateArgument *Args) {
00163   for (TemplateParameterList::iterator Param = Params->begin(),
00164                                     ParamEnd = Params->end();
00165        Param != ParamEnd; ++Param) {
00166     TemplateArgument Arg;
00167     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
00168       QualType ArgType = Context.getTypeDeclType(TTP);
00169       if (TTP->isParameterPack())
00170         ArgType = Context.getPackExpansionType(ArgType, 
00171                                                llvm::Optional<unsigned>());
00172       
00173       Arg = TemplateArgument(ArgType);
00174     } else if (NonTypeTemplateParmDecl *NTTP =
00175                dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
00176       Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
00177                                   NTTP->getType().getNonLValueExprType(Context),
00178                                   Expr::getValueKindForType(NTTP->getType()),
00179                                           NTTP->getLocation());
00180       
00181       if (NTTP->isParameterPack())
00182         E = new (Context) PackExpansionExpr(Context.DependentTy, E,
00183                                             NTTP->getLocation(),
00184                                             llvm::Optional<unsigned>());
00185       Arg = TemplateArgument(E);
00186     } else {
00187       TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
00188       if (TTP->isParameterPack())
00189         Arg = TemplateArgument(TemplateName(TTP), llvm::Optional<unsigned>());
00190       else
00191         Arg = TemplateArgument(TemplateName(TTP));
00192     }
00193     
00194     if ((*Param)->isTemplateParameterPack())
00195       Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
00196     
00197     *Args++ = Arg;
00198   }
00199 }
00200                                       
00201 //===----------------------------------------------------------------------===//
00202 // FunctionTemplateDecl Implementation
00203 //===----------------------------------------------------------------------===//
00204 
00205 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
00206   static_cast<Common *>(Ptr)->~Common();
00207 }
00208 
00209 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
00210                                                    DeclContext *DC,
00211                                                    SourceLocation L,
00212                                                    DeclarationName Name,
00213                                                TemplateParameterList *Params,
00214                                                    NamedDecl *Decl) {
00215   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
00216   return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
00217 }
00218 
00219 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
00220                                                                unsigned ID) {
00221   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl));
00222   return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
00223                                         0, 0);
00224 }
00225 
00226 RedeclarableTemplateDecl::CommonBase *
00227 FunctionTemplateDecl::newCommon(ASTContext &C) {
00228   Common *CommonPtr = new (C) Common;
00229   C.AddDeallocation(DeallocateCommon, CommonPtr);
00230   return CommonPtr;
00231 }
00232 
00233 FunctionDecl *
00234 FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
00235                                          unsigned NumArgs, void *&InsertPos) {
00236   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
00237 }
00238 
00239 void FunctionTemplateDecl::addSpecialization(
00240       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
00241   if (InsertPos)
00242     getSpecializations().InsertNode(Info, InsertPos);
00243   else
00244     getSpecializations().GetOrInsertNode(Info);
00245   if (ASTMutationListener *L = getASTMutationListener())
00246     L->AddedCXXTemplateSpecialization(this, Info->Function);
00247 }
00248 
00249 std::pair<const TemplateArgument *, unsigned> 
00250 FunctionTemplateDecl::getInjectedTemplateArgs() {
00251   TemplateParameterList *Params = getTemplateParameters();
00252   Common *CommonPtr = getCommonPtr();
00253   if (!CommonPtr->InjectedArgs) {
00254     CommonPtr->InjectedArgs
00255       = new (getASTContext()) TemplateArgument [Params->size()];
00256     GenerateInjectedTemplateArgs(getASTContext(), Params, 
00257                                  CommonPtr->InjectedArgs);
00258   }
00259   
00260   return std::make_pair(CommonPtr->InjectedArgs, Params->size());
00261 }
00262 
00263 //===----------------------------------------------------------------------===//
00264 // ClassTemplateDecl Implementation
00265 //===----------------------------------------------------------------------===//
00266 
00267 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
00268   static_cast<Common *>(Ptr)->~Common();
00269 }
00270 
00271 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
00272                                              DeclContext *DC,
00273                                              SourceLocation L,
00274                                              DeclarationName Name,
00275                                              TemplateParameterList *Params,
00276                                              NamedDecl *Decl,
00277                                              ClassTemplateDecl *PrevDecl) {
00278   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
00279   ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
00280   New->setPreviousDeclaration(PrevDecl);
00281   return New;
00282 }
00283 
00284 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 
00285                                                          unsigned ID) {
00286   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
00287   return new (Mem) ClassTemplateDecl(EmptyShell());
00288 }
00289 
00290 void ClassTemplateDecl::LoadLazySpecializations() {
00291   Common *CommonPtr = getCommonPtr();
00292   if (CommonPtr->LazySpecializations) {
00293     ASTContext &Context = getASTContext();
00294     uint32_t *Specs = CommonPtr->LazySpecializations;
00295     CommonPtr->LazySpecializations = 0;
00296     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
00297       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
00298   }
00299 }
00300 
00301 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
00302 ClassTemplateDecl::getSpecializations() {
00303   LoadLazySpecializations();
00304   return getCommonPtr()->Specializations;
00305 }  
00306 
00307 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
00308 ClassTemplateDecl::getPartialSpecializations() {
00309   LoadLazySpecializations();
00310   return getCommonPtr()->PartialSpecializations;
00311 }  
00312 
00313 RedeclarableTemplateDecl::CommonBase *
00314 ClassTemplateDecl::newCommon(ASTContext &C) {
00315   Common *CommonPtr = new (C) Common;
00316   C.AddDeallocation(DeallocateCommon, CommonPtr);
00317   return CommonPtr;
00318 }
00319 
00320 ClassTemplateSpecializationDecl *
00321 ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
00322                                       unsigned NumArgs, void *&InsertPos) {
00323   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
00324 }
00325 
00326 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
00327                                           void *InsertPos) {
00328   if (InsertPos)
00329     getSpecializations().InsertNode(D, InsertPos);
00330   else {
00331     ClassTemplateSpecializationDecl *Existing 
00332       = getSpecializations().GetOrInsertNode(D);
00333     (void)Existing;
00334     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
00335   }
00336   if (ASTMutationListener *L = getASTMutationListener())
00337     L->AddedCXXTemplateSpecialization(this, D);
00338 }
00339 
00340 ClassTemplatePartialSpecializationDecl *
00341 ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
00342                                              unsigned NumArgs,
00343                                              void *&InsertPos) {
00344   return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
00345                                 InsertPos);
00346 }
00347 
00348 void ClassTemplateDecl::AddPartialSpecialization(
00349                                       ClassTemplatePartialSpecializationDecl *D,
00350                                       void *InsertPos) {
00351   if (InsertPos)
00352     getPartialSpecializations().InsertNode(D, InsertPos);
00353   else {
00354     ClassTemplatePartialSpecializationDecl *Existing
00355       = getPartialSpecializations().GetOrInsertNode(D);
00356     (void)Existing;
00357     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
00358   }
00359 
00360   if (ASTMutationListener *L = getASTMutationListener())
00361     L->AddedCXXTemplateSpecialization(this, D);
00362 }
00363 
00364 void ClassTemplateDecl::getPartialSpecializations(
00365           SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
00366   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
00367     = getPartialSpecializations();
00368   PS.clear();
00369   PS.resize(PartialSpecs.size());
00370   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
00371        P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
00372        P != PEnd; ++P) {
00373     assert(!PS[P->getSequenceNumber()]);
00374     PS[P->getSequenceNumber()] = P->getMostRecentDecl();
00375   }
00376 }
00377 
00378 ClassTemplatePartialSpecializationDecl *
00379 ClassTemplateDecl::findPartialSpecialization(QualType T) {
00380   ASTContext &Context = getASTContext();
00381   using llvm::FoldingSetVector;
00382   typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
00383     partial_spec_iterator;
00384   for (partial_spec_iterator P = getPartialSpecializations().begin(),
00385                           PEnd = getPartialSpecializations().end();
00386        P != PEnd; ++P) {
00387     if (Context.hasSameType(P->getInjectedSpecializationType(), T))
00388       return P->getMostRecentDecl();
00389   }
00390 
00391   return 0;
00392 }
00393 
00394 ClassTemplatePartialSpecializationDecl *
00395 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
00396                                     ClassTemplatePartialSpecializationDecl *D) {
00397   Decl *DCanon = D->getCanonicalDecl();
00398   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
00399             P = getPartialSpecializations().begin(),
00400          PEnd = getPartialSpecializations().end();
00401        P != PEnd; ++P) {
00402     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
00403       return P->getMostRecentDecl();
00404   }
00405 
00406   return 0;
00407 }
00408 
00409 QualType
00410 ClassTemplateDecl::getInjectedClassNameSpecialization() {
00411   Common *CommonPtr = getCommonPtr();
00412   if (!CommonPtr->InjectedClassNameType.isNull())
00413     return CommonPtr->InjectedClassNameType;
00414 
00415   // C++0x [temp.dep.type]p2:
00416   //  The template argument list of a primary template is a template argument 
00417   //  list in which the nth template argument has the value of the nth template
00418   //  parameter of the class template. If the nth template parameter is a 
00419   //  template parameter pack (14.5.3), the nth template argument is a pack 
00420   //  expansion (14.5.3) whose pattern is the name of the template parameter 
00421   //  pack.
00422   ASTContext &Context = getASTContext();
00423   TemplateParameterList *Params = getTemplateParameters();
00424   SmallVector<TemplateArgument, 16> TemplateArgs;
00425   TemplateArgs.resize(Params->size());
00426   GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
00427   CommonPtr->InjectedClassNameType
00428     = Context.getTemplateSpecializationType(TemplateName(this),
00429                                             &TemplateArgs[0],
00430                                             TemplateArgs.size());
00431   return CommonPtr->InjectedClassNameType;
00432 }
00433 
00434 //===----------------------------------------------------------------------===//
00435 // TemplateTypeParm Allocation/Deallocation Method Implementations
00436 //===----------------------------------------------------------------------===//
00437 
00438 TemplateTypeParmDecl *
00439 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
00440                              SourceLocation KeyLoc, SourceLocation NameLoc,
00441                              unsigned D, unsigned P, IdentifierInfo *Id,
00442                              bool Typename, bool ParameterPack) {
00443   TemplateTypeParmDecl *TTPDecl =
00444     new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
00445   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
00446   TTPDecl->TypeForDecl = TTPType.getTypePtr();
00447   return TTPDecl;
00448 }
00449 
00450 TemplateTypeParmDecl *
00451 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
00452   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
00453   return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
00454                                         0, false);
00455 }
00456 
00457 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
00458   return hasDefaultArgument()
00459     ? DefaultArgument->getTypeLoc().getBeginLoc()
00460     : SourceLocation();
00461 }
00462 
00463 SourceRange TemplateTypeParmDecl::getSourceRange() const {
00464   if (hasDefaultArgument() && !defaultArgumentWasInherited())
00465     return SourceRange(getLocStart(),
00466                        DefaultArgument->getTypeLoc().getEndLoc());
00467   else
00468     return TypeDecl::getSourceRange();
00469 }
00470 
00471 unsigned TemplateTypeParmDecl::getDepth() const {
00472   return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
00473 }
00474 
00475 unsigned TemplateTypeParmDecl::getIndex() const {
00476   return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
00477 }
00478 
00479 bool TemplateTypeParmDecl::isParameterPack() const {
00480   return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
00481 }
00482 
00483 //===----------------------------------------------------------------------===//
00484 // NonTypeTemplateParmDecl Method Implementations
00485 //===----------------------------------------------------------------------===//
00486 
00487 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 
00488                                                  SourceLocation StartLoc,
00489                                                  SourceLocation IdLoc,
00490                                                  unsigned D, unsigned P,
00491                                                  IdentifierInfo *Id, 
00492                                                  QualType T, 
00493                                                  TypeSourceInfo *TInfo,
00494                                                  const QualType *ExpandedTypes,
00495                                                  unsigned NumExpandedTypes,
00496                                                 TypeSourceInfo **ExpandedTInfos)
00497   : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
00498     TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
00499     ParameterPack(true), ExpandedParameterPack(true),
00500     NumExpandedTypes(NumExpandedTypes)
00501 {
00502   if (ExpandedTypes && ExpandedTInfos) {
00503     void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
00504     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
00505       TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
00506       TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
00507     }
00508   }
00509 }
00510 
00511 NonTypeTemplateParmDecl *
00512 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
00513                                 SourceLocation StartLoc, SourceLocation IdLoc,
00514                                 unsigned D, unsigned P, IdentifierInfo *Id,
00515                                 QualType T, bool ParameterPack,
00516                                 TypeSourceInfo *TInfo) {
00517   return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
00518                                          T, ParameterPack, TInfo);
00519 }
00520 
00521 NonTypeTemplateParmDecl *
00522 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 
00523                                 SourceLocation StartLoc, SourceLocation IdLoc,
00524                                 unsigned D, unsigned P, 
00525                                 IdentifierInfo *Id, QualType T, 
00526                                 TypeSourceInfo *TInfo,
00527                                 const QualType *ExpandedTypes, 
00528                                 unsigned NumExpandedTypes,
00529                                 TypeSourceInfo **ExpandedTInfos) {
00530   unsigned Size = sizeof(NonTypeTemplateParmDecl) 
00531                 + NumExpandedTypes * 2 * sizeof(void*);
00532   void *Mem = C.Allocate(Size);
00533   return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
00534                                            D, P, Id, T, TInfo,
00535                                            ExpandedTypes, NumExpandedTypes, 
00536                                            ExpandedTInfos);
00537 }
00538 
00539 NonTypeTemplateParmDecl *
00540 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
00541   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
00542   return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 
00543                                            SourceLocation(), 0, 0, 0, 
00544                                            QualType(), false, 0);
00545 }
00546 
00547 NonTypeTemplateParmDecl *
00548 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
00549                                             unsigned NumExpandedTypes) {
00550   unsigned Size = sizeof(NonTypeTemplateParmDecl) 
00551                 + NumExpandedTypes * 2 * sizeof(void*);
00552   
00553   void *Mem = AllocateDeserializedDecl(C, ID, Size);
00554   return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 
00555                                            SourceLocation(), 0, 0, 0,
00556                                            QualType(), 0, 0, NumExpandedTypes,
00557                                            0);
00558 }
00559 
00560 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
00561   if (hasDefaultArgument() && !defaultArgumentWasInherited())
00562     return SourceRange(getOuterLocStart(),
00563                        getDefaultArgument()->getSourceRange().getEnd());
00564   return DeclaratorDecl::getSourceRange();
00565 }
00566 
00567 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
00568   return hasDefaultArgument()
00569     ? getDefaultArgument()->getSourceRange().getBegin()
00570     : SourceLocation();
00571 }
00572 
00573 //===----------------------------------------------------------------------===//
00574 // TemplateTemplateParmDecl Method Implementations
00575 //===----------------------------------------------------------------------===//
00576 
00577 void TemplateTemplateParmDecl::anchor() { }
00578 
00579 TemplateTemplateParmDecl *
00580 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
00581                                  SourceLocation L, unsigned D, unsigned P,
00582                                  bool ParameterPack, IdentifierInfo *Id,
00583                                  TemplateParameterList *Params) {
00584   return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 
00585                                           Params);
00586 }
00587 
00588 TemplateTemplateParmDecl *
00589 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
00590   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
00591   return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
00592                                             0, 0);
00593 }
00594 
00595 //===----------------------------------------------------------------------===//
00596 // TemplateArgumentList Implementation
00597 //===----------------------------------------------------------------------===//
00598 TemplateArgumentList *
00599 TemplateArgumentList::CreateCopy(ASTContext &Context,
00600                                  const TemplateArgument *Args,
00601                                  unsigned NumArgs) {
00602   std::size_t Size = sizeof(TemplateArgumentList)
00603                    + NumArgs * sizeof(TemplateArgument);
00604   void *Mem = Context.Allocate(Size);
00605   TemplateArgument *StoredArgs 
00606     = reinterpret_cast<TemplateArgument *>(
00607                                 static_cast<TemplateArgumentList *>(Mem) + 1);
00608   std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
00609   return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
00610 }
00611 
00612 FunctionTemplateSpecializationInfo *
00613 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
00614                                            FunctionTemplateDecl *Template,
00615                                            TemplateSpecializationKind TSK,
00616                                        const TemplateArgumentList *TemplateArgs,
00617                           const TemplateArgumentListInfo *TemplateArgsAsWritten,
00618                                            SourceLocation POI) {
00619   const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
00620   if (TemplateArgsAsWritten)
00621     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
00622                                                         *TemplateArgsAsWritten);
00623 
00624   return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
00625                                                     TemplateArgs,
00626                                                     ArgsAsWritten,
00627                                                     POI);
00628 }
00629 
00630 //===----------------------------------------------------------------------===//
00631 // TemplateDecl Implementation
00632 //===----------------------------------------------------------------------===//
00633 
00634 void TemplateDecl::anchor() { }
00635 
00636 //===----------------------------------------------------------------------===//
00637 // ClassTemplateSpecializationDecl Implementation
00638 //===----------------------------------------------------------------------===//
00639 ClassTemplateSpecializationDecl::
00640 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
00641                                 DeclContext *DC, SourceLocation StartLoc,
00642                                 SourceLocation IdLoc,
00643                                 ClassTemplateDecl *SpecializedTemplate,
00644                                 const TemplateArgument *Args,
00645                                 unsigned NumArgs,
00646                                 ClassTemplateSpecializationDecl *PrevDecl)
00647   : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
00648                   SpecializedTemplate->getIdentifier(),
00649                   PrevDecl),
00650     SpecializedTemplate(SpecializedTemplate),
00651     ExplicitInfo(0),
00652     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
00653     SpecializationKind(TSK_Undeclared) {
00654 }
00655 
00656 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
00657   : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
00658     ExplicitInfo(0),
00659     SpecializationKind(TSK_Undeclared) {
00660 }
00661 
00662 ClassTemplateSpecializationDecl *
00663 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
00664                                         DeclContext *DC,
00665                                         SourceLocation StartLoc,
00666                                         SourceLocation IdLoc,
00667                                         ClassTemplateDecl *SpecializedTemplate,
00668                                         const TemplateArgument *Args,
00669                                         unsigned NumArgs,
00670                                    ClassTemplateSpecializationDecl *PrevDecl) {
00671   ClassTemplateSpecializationDecl *Result
00672     = new (Context)ClassTemplateSpecializationDecl(Context,
00673                                                    ClassTemplateSpecialization,
00674                                                    TK, DC, StartLoc, IdLoc,
00675                                                    SpecializedTemplate,
00676                                                    Args, NumArgs,
00677                                                    PrevDecl);
00678   Context.getTypeDeclType(Result, PrevDecl);
00679   return Result;
00680 }
00681 
00682 ClassTemplateSpecializationDecl *
00683 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 
00684                                                     unsigned ID) {
00685   void *Mem = AllocateDeserializedDecl(C, ID, 
00686                                        sizeof(ClassTemplateSpecializationDecl));
00687   return new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
00688 }
00689 
00690 void
00691 ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
00692                                                   const PrintingPolicy &Policy,
00693                                                       bool Qualified) const {
00694   NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
00695 
00696   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
00697   S += TemplateSpecializationType::PrintTemplateArgumentList(
00698                                                           TemplateArgs.data(),
00699                                                           TemplateArgs.size(),
00700                                                              Policy);
00701 }
00702 
00703 ClassTemplateDecl *
00704 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
00705   if (SpecializedPartialSpecialization *PartialSpec
00706       = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
00707     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
00708   return SpecializedTemplate.get<ClassTemplateDecl*>();
00709 }
00710 
00711 SourceRange
00712 ClassTemplateSpecializationDecl::getSourceRange() const {
00713   if (ExplicitInfo) {
00714     SourceLocation Begin = getExternLoc();
00715     if (Begin.isInvalid())
00716       Begin = getTemplateKeywordLoc();
00717     SourceLocation End = getRBraceLoc();
00718     if (End.isInvalid())
00719       End = getTypeAsWritten()->getTypeLoc().getEndLoc();
00720     return SourceRange(Begin, End);
00721   }
00722   else {
00723     // No explicit info available.
00724     llvm::PointerUnion<ClassTemplateDecl *,
00725                        ClassTemplatePartialSpecializationDecl *>
00726       inst_from = getInstantiatedFrom();
00727     if (inst_from.isNull())
00728       return getSpecializedTemplate()->getSourceRange();
00729     if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
00730       return ctd->getSourceRange();
00731     return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
00732       ->getSourceRange();
00733   }
00734 }
00735 
00736 //===----------------------------------------------------------------------===//
00737 // ClassTemplatePartialSpecializationDecl Implementation
00738 //===----------------------------------------------------------------------===//
00739 void ClassTemplatePartialSpecializationDecl::anchor() { }
00740 
00741 ClassTemplatePartialSpecializationDecl::
00742 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
00743                                        DeclContext *DC,
00744                                        SourceLocation StartLoc,
00745                                        SourceLocation IdLoc,
00746                                        TemplateParameterList *Params,
00747                                        ClassTemplateDecl *SpecializedTemplate,
00748                                        const TemplateArgument *Args,
00749                                        unsigned NumArgs,
00750                                        TemplateArgumentLoc *ArgInfos,
00751                                        unsigned NumArgInfos,
00752                                ClassTemplatePartialSpecializationDecl *PrevDecl,
00753                                        unsigned SequenceNumber)
00754   : ClassTemplateSpecializationDecl(Context,
00755                                     ClassTemplatePartialSpecialization,
00756                                     TK, DC, StartLoc, IdLoc,
00757                                     SpecializedTemplate,
00758                                     Args, NumArgs, PrevDecl),
00759     TemplateParams(Params), ArgsAsWritten(ArgInfos),
00760     NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
00761     InstantiatedFromMember(0, false)
00762 { 
00763   AdoptTemplateParameterList(Params, this);
00764 }
00765 
00766 ClassTemplatePartialSpecializationDecl *
00767 ClassTemplatePartialSpecializationDecl::
00768 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
00769        SourceLocation StartLoc, SourceLocation IdLoc,
00770        TemplateParameterList *Params,
00771        ClassTemplateDecl *SpecializedTemplate,
00772        const TemplateArgument *Args,
00773        unsigned NumArgs,
00774        const TemplateArgumentListInfo &ArgInfos,
00775        QualType CanonInjectedType,
00776        ClassTemplatePartialSpecializationDecl *PrevDecl,
00777        unsigned SequenceNumber) {
00778   unsigned N = ArgInfos.size();
00779   TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
00780   for (unsigned I = 0; I != N; ++I)
00781     ClonedArgs[I] = ArgInfos[I];
00782 
00783   ClassTemplatePartialSpecializationDecl *Result
00784     = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
00785                                                           StartLoc, IdLoc,
00786                                                           Params,
00787                                                           SpecializedTemplate,
00788                                                           Args, NumArgs,
00789                                                           ClonedArgs, N,
00790                                                           PrevDecl,
00791                                                           SequenceNumber);
00792   Result->setSpecializationKind(TSK_ExplicitSpecialization);
00793 
00794   Context.getInjectedClassNameType(Result, CanonInjectedType);
00795   return Result;
00796 }
00797 
00798 ClassTemplatePartialSpecializationDecl *
00799 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
00800                                                            unsigned ID) {
00801   void *Mem = AllocateDeserializedDecl(C, ID, 
00802                 sizeof(ClassTemplatePartialSpecializationDecl));
00803   return new (Mem) ClassTemplatePartialSpecializationDecl();
00804 }
00805 
00806 //===----------------------------------------------------------------------===//
00807 // FriendTemplateDecl Implementation
00808 //===----------------------------------------------------------------------===//
00809 
00810 void FriendTemplateDecl::anchor() { }
00811 
00812 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
00813                                                DeclContext *DC,
00814                                                SourceLocation L,
00815                                                unsigned NParams,
00816                                                TemplateParameterList **Params,
00817                                                FriendUnion Friend,
00818                                                SourceLocation FLoc) {
00819   FriendTemplateDecl *Result
00820     = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
00821   return Result;
00822 }
00823 
00824 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
00825                                                            unsigned ID) {
00826   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
00827   return new (Mem) FriendTemplateDecl(EmptyShell());
00828 }
00829 
00830 //===----------------------------------------------------------------------===//
00831 // TypeAliasTemplateDecl Implementation
00832 //===----------------------------------------------------------------------===//
00833 
00834 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
00835                                                      DeclContext *DC,
00836                                                      SourceLocation L,
00837                                                      DeclarationName Name,
00838                                                   TemplateParameterList *Params,
00839                                                      NamedDecl *Decl) {
00840   AdoptTemplateParameterList(Params, DC);
00841   return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
00842 }
00843 
00844 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
00845                                                                  unsigned ID) {
00846   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
00847   return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
00848                                          0, 0);
00849 }
00850 
00851 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
00852   static_cast<Common *>(Ptr)->~Common();
00853 }
00854 RedeclarableTemplateDecl::CommonBase *
00855 TypeAliasTemplateDecl::newCommon(ASTContext &C) {
00856   Common *CommonPtr = new (C) Common;
00857   C.AddDeallocation(DeallocateCommon, CommonPtr);
00858   return CommonPtr;
00859 }
00860 
00861 //===----------------------------------------------------------------------===//
00862 // ClassScopeFunctionSpecializationDecl Implementation
00863 //===----------------------------------------------------------------------===//
00864 
00865 void ClassScopeFunctionSpecializationDecl::anchor() { }
00866 
00867 ClassScopeFunctionSpecializationDecl *
00868 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
00869                                                          unsigned ID) {
00870   void *Mem = AllocateDeserializedDecl(C, ID, 
00871                 sizeof(ClassScopeFunctionSpecializationDecl));
00872   return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0);
00873 }