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