| Sebastian Redl | e2530ec | 2009-10-23 22:13:42 +0000 | [diff] [blame] | 1 | //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===// | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 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" | 
| Douglas Gregor | 8bf4205 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 16 | #include "clang/AST/Expr.h" | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 17 | #include "clang/AST/ASTContext.h" | 
| John McCall | 0ad1666 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 18 | #include "clang/AST/TypeLoc.h" | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 19 | #include "clang/Basic/IdentifierTable.h" | 
|  | 20 | #include "llvm/ADT/STLExtras.h" | 
|  | 21 | using namespace clang; | 
|  | 22 |  | 
|  | 23 | //===----------------------------------------------------------------------===// | 
|  | 24 | // TemplateParameterList Implementation | 
|  | 25 | //===----------------------------------------------------------------------===// | 
|  | 26 |  | 
| Douglas Gregor | cd72ba9 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 27 | TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, | 
|  | 28 | SourceLocation LAngleLoc, | 
| Douglas Gregor | be99939 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 29 | NamedDecl **Params, unsigned NumParams, | 
| Douglas Gregor | cd72ba9 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 30 | SourceLocation RAngleLoc) | 
|  | 31 | : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), | 
|  | 32 | NumParams(NumParams) { | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 33 | for (unsigned Idx = 0; Idx < NumParams; ++Idx) | 
|  | 34 | begin()[Idx] = Params[Idx]; | 
|  | 35 | } | 
|  | 36 |  | 
|  | 37 | TemplateParameterList * | 
| Douglas Gregor | cd72ba9 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 38 | TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc, | 
| Douglas Gregor | be99939 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 39 | SourceLocation LAngleLoc, NamedDecl **Params, | 
| Douglas Gregor | cd72ba9 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 40 | unsigned NumParams, SourceLocation RAngleLoc) { | 
| Douglas Gregor | be99939 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 41 | unsigned Size = sizeof(TemplateParameterList) | 
|  | 42 | + sizeof(NamedDecl *) * NumParams; | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 43 | unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment; | 
|  | 44 | void *Mem = C.Allocate(Size, Align); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 45 | return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, | 
| Douglas Gregor | cd72ba9 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 46 | NumParams, RAngleLoc); | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 47 | } | 
|  | 48 |  | 
| Douglas Gregor | f8f8683 | 2009-02-11 18:16:40 +0000 | [diff] [blame] | 49 | unsigned TemplateParameterList::getMinRequiredArguments() const { | 
|  | 50 | unsigned NumRequiredArgs = size(); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 51 | iterator Param = const_cast<TemplateParameterList *>(this)->end(), | 
| Douglas Gregor | f8f8683 | 2009-02-11 18:16:40 +0000 | [diff] [blame] | 52 | ParamBegin = const_cast<TemplateParameterList *>(this)->begin(); | 
|  | 53 | while (Param != ParamBegin) { | 
|  | 54 | --Param; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 55 |  | 
| Anders Carlsson | 15201f1 | 2009-06-13 02:08:00 +0000 | [diff] [blame] | 56 | if (!(*Param)->isTemplateParameterPack() && | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 57 | !(isa<TemplateTypeParmDecl>(*Param) && | 
| Douglas Gregor | f8f8683 | 2009-02-11 18:16:40 +0000 | [diff] [blame] | 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; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 64 |  | 
| Douglas Gregor | f8f8683 | 2009-02-11 18:16:40 +0000 | [diff] [blame] | 65 | --NumRequiredArgs; | 
|  | 66 | } | 
|  | 67 |  | 
|  | 68 | return NumRequiredArgs; | 
|  | 69 | } | 
|  | 70 |  | 
| Douglas Gregor | 2161038 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 71 | unsigned 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 |  | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 86 | //===----------------------------------------------------------------------===// | 
|  | 87 | // TemplateDecl Implementation | 
|  | 88 | //===----------------------------------------------------------------------===// | 
|  | 89 |  | 
|  | 90 | TemplateDecl::~TemplateDecl() { | 
|  | 91 | } | 
|  | 92 |  | 
|  | 93 | //===----------------------------------------------------------------------===// | 
|  | 94 | // FunctionTemplateDecl Implementation | 
|  | 95 | //===----------------------------------------------------------------------===// | 
|  | 96 |  | 
|  | 97 | FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, | 
|  | 98 | DeclContext *DC, | 
|  | 99 | SourceLocation L, | 
|  | 100 | DeclarationName Name, | 
| Douglas Gregor | 8f5d442 | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 101 | TemplateParameterList *Params, | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 102 | NamedDecl *Decl) { | 
|  | 103 | return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl); | 
|  | 104 | } | 
|  | 105 |  | 
| Douglas Gregor | 8f5d442 | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 106 | void 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 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 114 |  | 
| Douglas Gregor | 8f5d442 | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 115 | Decl::Destroy(C); | 
|  | 116 | } | 
|  | 117 |  | 
| Argyrios Kyrtzidis | 5614aef | 2009-07-18 00:34:07 +0000 | [diff] [blame] | 118 | FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() { | 
|  | 119 | FunctionTemplateDecl *FunTmpl = this; | 
|  | 120 | while (FunTmpl->getPreviousDeclaration()) | 
|  | 121 | FunTmpl = FunTmpl->getPreviousDeclaration(); | 
|  | 122 | return FunTmpl; | 
|  | 123 | } | 
|  | 124 |  | 
| Douglas Gregor | 8f5d442 | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 125 | FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() { | 
|  | 126 | // Find the first declaration of this function template. | 
|  | 127 | FunctionTemplateDecl *First = this; | 
|  | 128 | while (First->getPreviousDeclaration()) | 
|  | 129 | First = First->getPreviousDeclaration(); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 130 |  | 
| Douglas Gregor | 8f5d442 | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 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 |  | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 138 | //===----------------------------------------------------------------------===// | 
|  | 139 | // ClassTemplateDecl Implementation | 
|  | 140 | //===----------------------------------------------------------------------===// | 
|  | 141 |  | 
| Argyrios Kyrtzidis | 5614aef | 2009-07-18 00:34:07 +0000 | [diff] [blame] | 142 | ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() { | 
|  | 143 | ClassTemplateDecl *Template = this; | 
|  | 144 | while (Template->getPreviousDeclaration()) | 
|  | 145 | Template = Template->getPreviousDeclaration(); | 
|  | 146 | return Template; | 
|  | 147 | } | 
|  | 148 |  | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 149 | ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, | 
|  | 150 | DeclContext *DC, | 
|  | 151 | SourceLocation L, | 
|  | 152 | DeclarationName Name, | 
|  | 153 | TemplateParameterList *Params, | 
| Douglas Gregor | 90a1a65 | 2009-03-19 17:26:29 +0000 | [diff] [blame] | 154 | NamedDecl *Decl, | 
|  | 155 | ClassTemplateDecl *PrevDecl) { | 
|  | 156 | Common *CommonPtr; | 
|  | 157 | if (PrevDecl) | 
|  | 158 | CommonPtr = PrevDecl->CommonPtr; | 
|  | 159 | else | 
|  | 160 | CommonPtr = new (C) Common; | 
|  | 161 |  | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 162 | return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl, | 
| Douglas Gregor | 90a1a65 | 2009-03-19 17:26:29 +0000 | [diff] [blame] | 163 | CommonPtr); | 
|  | 164 | } | 
|  | 165 |  | 
|  | 166 | ClassTemplateDecl::~ClassTemplateDecl() { | 
|  | 167 | assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed"); | 
|  | 168 | } | 
|  | 169 |  | 
|  | 170 | void 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); | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 179 | } | 
|  | 180 |  | 
| Douglas Gregor | 1530138 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 181 | ClassTemplatePartialSpecializationDecl * | 
|  | 182 | ClassTemplateDecl::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 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 192 |  | 
| Douglas Gregor | 1530138 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 193 | return 0; | 
|  | 194 | } | 
|  | 195 |  | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 196 | QualType 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(); | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 206 | llvm::SmallVector<TemplateArgument, 16> TemplateArgs; | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 207 | TemplateArgs.reserve(Params->size()); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 208 | for (TemplateParameterList::iterator Param = Params->begin(), | 
|  | 209 | ParamEnd = Params->end(); | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 210 | Param != ParamEnd; ++Param) { | 
|  | 211 | if (isa<TemplateTypeParmDecl>(*Param)) { | 
|  | 212 | QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param)); | 
| John McCall | 0ad1666 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 213 | TemplateArgs.push_back(TemplateArgument(ParamType)); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 214 | } else if (NonTypeTemplateParmDecl *NTTP = | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 215 | dyn_cast<NonTypeTemplateParmDecl>(*Param)) { | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 216 | Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(), | 
|  | 217 | NTTP->getLocation(), | 
|  | 218 | NTTP->getType()->isDependentType(), | 
|  | 219 | /*Value-dependent=*/true); | 
|  | 220 | TemplateArgs.push_back(TemplateArgument(E)); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 221 | } else { | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 222 | TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); | 
| John McCall | 0ad1666 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 223 | TemplateArgs.push_back(TemplateArgument(TTP)); | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 224 | } | 
|  | 225 | } | 
|  | 226 |  | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 227 | CommonPtr->InjectedClassNameType | 
| Douglas Gregor | a8e02e7 | 2009-07-28 23:00:59 +0000 | [diff] [blame] | 228 | = Context.getTemplateSpecializationType(TemplateName(this), | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 229 | &TemplateArgs[0], | 
| Douglas Gregor | a8e02e7 | 2009-07-28 23:00:59 +0000 | [diff] [blame] | 230 | TemplateArgs.size()); | 
| Douglas Gregor | e362cea | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 231 | return CommonPtr->InjectedClassNameType; | 
|  | 232 | } | 
|  | 233 |  | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 234 | //===----------------------------------------------------------------------===// | 
|  | 235 | // TemplateTypeParm Allocation/Deallocation Method Implementations | 
|  | 236 | //===----------------------------------------------------------------------===// | 
|  | 237 |  | 
|  | 238 | TemplateTypeParmDecl * | 
|  | 239 | TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, | 
|  | 240 | SourceLocation L, unsigned D, unsigned P, | 
| Anders Carlsson | fb1d776 | 2009-06-12 22:23:22 +0000 | [diff] [blame] | 241 | IdentifierInfo *Id, bool Typename, | 
|  | 242 | bool ParameterPack) { | 
| Anders Carlsson | 90036dc | 2009-06-16 00:30:48 +0000 | [diff] [blame] | 243 | QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id); | 
| Anders Carlsson | fb1d776 | 2009-06-12 22:23:22 +0000 | [diff] [blame] | 244 | return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack); | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 245 | } | 
|  | 246 |  | 
| John McCall | 0ad1666 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 247 | SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { | 
|  | 248 | return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin(); | 
|  | 249 | } | 
|  | 250 |  | 
| Douglas Gregor | 2161038 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 251 | unsigned TemplateTypeParmDecl::getDepth() const { | 
|  | 252 | return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth(); | 
|  | 253 | } | 
|  | 254 |  | 
|  | 255 | unsigned TemplateTypeParmDecl::getIndex() const { | 
|  | 256 | return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex(); | 
|  | 257 | } | 
|  | 258 |  | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 259 | //===----------------------------------------------------------------------===// | 
|  | 260 | // NonTypeTemplateParmDecl Method Implementations | 
|  | 261 | //===----------------------------------------------------------------------===// | 
|  | 262 |  | 
|  | 263 | NonTypeTemplateParmDecl * | 
|  | 264 | NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, | 
|  | 265 | SourceLocation L, unsigned D, unsigned P, | 
|  | 266 | IdentifierInfo *Id, QualType T, | 
| Argyrios Kyrtzidis | 6032ef1 | 2009-08-21 00:31:54 +0000 | [diff] [blame] | 267 | DeclaratorInfo *DInfo) { | 
|  | 268 | return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, DInfo); | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 269 | } | 
|  | 270 |  | 
| Douglas Gregor | dba3263 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 271 | SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { | 
|  | 272 | return DefaultArgument? DefaultArgument->getSourceRange().getBegin() | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 273 | : SourceLocation(); | 
| Douglas Gregor | dba3263 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 274 | } | 
|  | 275 |  | 
| Douglas Gregor | ded2d7b | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 276 | //===----------------------------------------------------------------------===// | 
|  | 277 | // TemplateTemplateParmDecl Method Implementations | 
|  | 278 | //===----------------------------------------------------------------------===// | 
|  | 279 |  | 
|  | 280 | TemplateTemplateParmDecl * | 
|  | 281 | TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, | 
|  | 282 | SourceLocation L, unsigned D, unsigned P, | 
|  | 283 | IdentifierInfo *Id, | 
|  | 284 | TemplateParameterList *Params) { | 
|  | 285 | return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params); | 
|  | 286 | } | 
|  | 287 |  | 
| Douglas Gregor | dba3263 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 288 | SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { | 
|  | 289 | return DefaultArgument? DefaultArgument->getSourceRange().getBegin() | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 290 | : SourceLocation(); | 
| Douglas Gregor | dba3263 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 291 | } | 
| Douglas Gregor | 264ec4f | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 292 |  | 
|  | 293 | //===----------------------------------------------------------------------===// | 
| Anders Carlsson | 184cb41 | 2009-06-05 05:31:27 +0000 | [diff] [blame] | 294 | // TemplateArgumentListBuilder Implementation | 
|  | 295 | //===----------------------------------------------------------------------===// | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 296 |  | 
|  | 297 | void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) { | 
| Anders Carlsson | 184cb41 | 2009-06-05 05:31:27 +0000 | [diff] [blame] | 298 | switch (Arg.getKind()) { | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 299 | default: break; | 
|  | 300 | case TemplateArgument::Type: | 
| John McCall | b692a09 | 2009-10-22 20:10:53 +0000 | [diff] [blame] | 301 | assert(Arg.getAsType().isCanonical() && "Type must be canonical!"); | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 302 | break; | 
| Anders Carlsson | 184cb41 | 2009-06-05 05:31:27 +0000 | [diff] [blame] | 303 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 304 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 305 | assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!"); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 306 | assert(!StructuredArgs && | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 307 | "Can't append arguments when an argument pack has been added!"); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 308 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 309 | if (!FlatArgs) | 
|  | 310 | FlatArgs = new TemplateArgument[MaxFlatArgs]; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 311 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 312 | FlatArgs[NumFlatArgs++] = Arg; | 
| Anders Carlsson | 184cb41 | 2009-06-05 05:31:27 +0000 | [diff] [blame] | 313 | } | 
|  | 314 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 315 | void TemplateArgumentListBuilder::BeginPack() { | 
|  | 316 | assert(!AddingToPack && "Already adding to pack!"); | 
|  | 317 | assert(!StructuredArgs && "Argument list already contains a pack!"); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 318 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 319 | AddingToPack = true; | 
|  | 320 | PackBeginIndex = NumFlatArgs; | 
| Anders Carlsson | aa73b91 | 2009-06-13 00:08:58 +0000 | [diff] [blame] | 321 | } | 
|  | 322 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 323 | void TemplateArgumentListBuilder::EndPack() { | 
|  | 324 | assert(AddingToPack && "Not adding to pack!"); | 
|  | 325 | assert(!StructuredArgs && "Argument list already contains a pack!"); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 326 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 327 | AddingToPack = false; | 
| Anders Carlsson | 475501b | 2009-06-15 17:56:45 +0000 | [diff] [blame] | 328 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 329 | StructuredArgs = new TemplateArgument[MaxStructuredArgs]; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 330 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 331 | // First copy the flat entries over to the list  (if any) | 
|  | 332 | for (unsigned I = 0; I != PackBeginIndex; ++I) { | 
|  | 333 | NumStructuredArgs++; | 
|  | 334 | StructuredArgs[I] = FlatArgs[I]; | 
|  | 335 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 336 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 337 | // Next, set the pack. | 
|  | 338 | TemplateArgument *PackArgs = 0; | 
|  | 339 | unsigned NumPackArgs = NumFlatArgs - PackBeginIndex; | 
|  | 340 | if (NumPackArgs) | 
|  | 341 | PackArgs = &FlatArgs[PackBeginIndex]; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 342 |  | 
|  | 343 | StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs, | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 344 | /*CopyArgs=*/false); | 
|  | 345 | } | 
|  | 346 |  | 
|  | 347 | void TemplateArgumentListBuilder::ReleaseArgs() { | 
|  | 348 | FlatArgs = 0; | 
|  | 349 | NumFlatArgs = 0; | 
|  | 350 | MaxFlatArgs = 0; | 
|  | 351 | StructuredArgs = 0; | 
|  | 352 | NumStructuredArgs = 0; | 
|  | 353 | MaxStructuredArgs = 0; | 
|  | 354 | } | 
| Anders Carlsson | aa73b91 | 2009-06-13 00:08:58 +0000 | [diff] [blame] | 355 |  | 
| Anders Carlsson | 184cb41 | 2009-06-05 05:31:27 +0000 | [diff] [blame] | 356 | //===----------------------------------------------------------------------===// | 
| Douglas Gregor | d002c7b | 2009-05-11 23:53:27 +0000 | [diff] [blame] | 357 | // TemplateArgumentList Implementation | 
|  | 358 | //===----------------------------------------------------------------------===// | 
|  | 359 | TemplateArgumentList::TemplateArgumentList(ASTContext &Context, | 
| Anders Carlsson | c8e7113 | 2009-06-05 04:47:51 +0000 | [diff] [blame] | 360 | TemplateArgumentListBuilder &Builder, | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 361 | bool TakeArgs) | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 362 | : FlatArguments(Builder.getFlatArguments(), TakeArgs), | 
|  | 363 | NumFlatArguments(Builder.flatSize()), | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 364 | StructuredArguments(Builder.getStructuredArguments(), TakeArgs), | 
|  | 365 | NumStructuredArguments(Builder.structuredSize()) { | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 366 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 367 | if (!TakeArgs) | 
|  | 368 | return; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 369 |  | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 370 | if (Builder.getStructuredArguments() == Builder.getFlatArguments()) | 
|  | 371 | StructuredArguments.setInt(0); | 
|  | 372 | Builder.ReleaseArgs(); | 
| Douglas Gregor | d002c7b | 2009-05-11 23:53:27 +0000 | [diff] [blame] | 373 | } | 
|  | 374 |  | 
| Douglas Gregor | 3a923c2d | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 375 | TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other) | 
|  | 376 | : FlatArguments(Other.FlatArguments.getPointer(), 1), | 
|  | 377 | NumFlatArguments(Other.flat_size()), | 
|  | 378 | StructuredArguments(Other.StructuredArguments.getPointer(), 1), | 
|  | 379 | NumStructuredArguments(Other.NumStructuredArguments) { } | 
|  | 380 |  | 
| Douglas Gregor | d002c7b | 2009-05-11 23:53:27 +0000 | [diff] [blame] | 381 | TemplateArgumentList::~TemplateArgumentList() { | 
|  | 382 | // FIXME: Deallocate template arguments | 
|  | 383 | } | 
|  | 384 |  | 
|  | 385 | //===----------------------------------------------------------------------===// | 
| Douglas Gregor | 264ec4f | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 386 | // ClassTemplateSpecializationDecl Implementation | 
|  | 387 | //===----------------------------------------------------------------------===// | 
|  | 388 | ClassTemplateSpecializationDecl:: | 
| Douglas Gregor | 2373c59 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 389 | ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, | 
| Douglas Gregor | d002c7b | 2009-05-11 23:53:27 +0000 | [diff] [blame] | 390 | DeclContext *DC, SourceLocation L, | 
| Douglas Gregor | 264ec4f | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 391 | ClassTemplateDecl *SpecializedTemplate, | 
| Douglas Gregor | b6b8f9e | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 392 | TemplateArgumentListBuilder &Builder, | 
|  | 393 | ClassTemplateSpecializationDecl *PrevDecl) | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 394 | : CXXRecordDecl(DK, | 
|  | 395 | SpecializedTemplate->getTemplatedDecl()->getTagKind(), | 
| Douglas Gregor | 264ec4f | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 396 | DC, L, | 
|  | 397 | // FIXME: Should we use DeclarationName for the name of | 
|  | 398 | // class template specializations? | 
| Douglas Gregor | b6b8f9e | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 399 | SpecializedTemplate->getIdentifier(), | 
|  | 400 | PrevDecl), | 
| Douglas Gregor | 264ec4f | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 401 | SpecializedTemplate(SpecializedTemplate), | 
| Anders Carlsson | 5947ddf | 2009-06-23 01:26:57 +0000 | [diff] [blame] | 402 | TemplateArgs(Context, Builder, /*TakeArgs=*/true), | 
| Douglas Gregor | d002c7b | 2009-05-11 23:53:27 +0000 | [diff] [blame] | 403 | SpecializationKind(TSK_Undeclared) { | 
| Douglas Gregor | 264ec4f | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 404 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 405 |  | 
| Douglas Gregor | 264ec4f | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 406 | ClassTemplateSpecializationDecl * | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 407 | ClassTemplateSpecializationDecl::Create(ASTContext &Context, | 
| Douglas Gregor | 264ec4f | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 408 | DeclContext *DC, SourceLocation L, | 
|  | 409 | ClassTemplateDecl *SpecializedTemplate, | 
| Anders Carlsson | 1b28c3e | 2009-06-05 04:06:48 +0000 | [diff] [blame] | 410 | TemplateArgumentListBuilder &Builder, | 
| Douglas Gregor | 67a6564 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 411 | ClassTemplateSpecializationDecl *PrevDecl) { | 
| Douglas Gregor | 67a6564 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 412 | ClassTemplateSpecializationDecl *Result | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 413 | = new (Context)ClassTemplateSpecializationDecl(Context, | 
| Douglas Gregor | 2373c59 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 414 | ClassTemplateSpecialization, | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 415 | DC, L, | 
| Douglas Gregor | d002c7b | 2009-05-11 23:53:27 +0000 | [diff] [blame] | 416 | SpecializedTemplate, | 
| Douglas Gregor | b6b8f9e | 2009-07-29 23:36:44 +0000 | [diff] [blame] | 417 | Builder, | 
|  | 418 | PrevDecl); | 
| Douglas Gregor | 67a6564 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 419 | Context.getTypeDeclType(Result, PrevDecl); | 
|  | 420 | return Result; | 
| Douglas Gregor | 264ec4f | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 421 | } | 
| Douglas Gregor | 2373c59 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 422 |  | 
| Douglas Gregor | 9dc8bd3 | 2009-08-02 23:24:31 +0000 | [diff] [blame] | 423 | void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) { | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 424 | if (SpecializedPartialSpecialization *PartialSpec | 
| Douglas Gregor | 9dc8bd3 | 2009-08-02 23:24:31 +0000 | [diff] [blame] | 425 | = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) | 
|  | 426 | C.Deallocate(PartialSpec); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 427 |  | 
| Douglas Gregor | 9dc8bd3 | 2009-08-02 23:24:31 +0000 | [diff] [blame] | 428 | CXXRecordDecl::Destroy(C); | 
|  | 429 | } | 
|  | 430 |  | 
| John McCall | e1f2ec2 | 2009-09-11 06:45:03 +0000 | [diff] [blame] | 431 | void | 
|  | 432 | ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S, | 
|  | 433 | const PrintingPolicy &Policy, | 
|  | 434 | bool Qualified) const { | 
|  | 435 | NamedDecl::getNameForDiagnostic(S, Policy, Qualified); | 
|  | 436 |  | 
|  | 437 | const TemplateArgumentList &TemplateArgs = getTemplateArgs(); | 
|  | 438 | S += TemplateSpecializationType::PrintTemplateArgumentList( | 
|  | 439 | TemplateArgs.getFlatArgumentList(), | 
|  | 440 | TemplateArgs.flat_size(), | 
|  | 441 | Policy); | 
|  | 442 | } | 
|  | 443 |  | 
| Douglas Gregor | 9dc8bd3 | 2009-08-02 23:24:31 +0000 | [diff] [blame] | 444 | ClassTemplateDecl * | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 445 | ClassTemplateSpecializationDecl::getSpecializedTemplate() const { | 
|  | 446 | if (SpecializedPartialSpecialization *PartialSpec | 
| Douglas Gregor | 9dc8bd3 | 2009-08-02 23:24:31 +0000 | [diff] [blame] | 447 | = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) | 
|  | 448 | return PartialSpec->PartialSpecialization->getSpecializedTemplate(); | 
|  | 449 | return SpecializedTemplate.get<ClassTemplateDecl*>(); | 
|  | 450 | } | 
|  | 451 |  | 
| Douglas Gregor | 2373c59 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 452 | //===----------------------------------------------------------------------===// | 
|  | 453 | // ClassTemplatePartialSpecializationDecl Implementation | 
|  | 454 | //===----------------------------------------------------------------------===// | 
|  | 455 | ClassTemplatePartialSpecializationDecl * | 
|  | 456 | ClassTemplatePartialSpecializationDecl:: | 
|  | 457 | Create(ASTContext &Context, DeclContext *DC, SourceLocation L, | 
|  | 458 | TemplateParameterList *Params, | 
|  | 459 | ClassTemplateDecl *SpecializedTemplate, | 
| Anders Carlsson | 1b28c3e | 2009-06-05 04:06:48 +0000 | [diff] [blame] | 460 | TemplateArgumentListBuilder &Builder, | 
| John McCall | 0ad1666 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 461 | TemplateArgumentLoc *ArgInfos, unsigned N, | 
| Douglas Gregor | 2373c59 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 462 | ClassTemplatePartialSpecializationDecl *PrevDecl) { | 
| John McCall | 0ad1666 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 463 | TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N]; | 
|  | 464 | for (unsigned I = 0; I != N; ++I) | 
|  | 465 | ClonedArgs[I] = ArgInfos[I]; | 
|  | 466 |  | 
| Douglas Gregor | 2373c59 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 467 | ClassTemplatePartialSpecializationDecl *Result | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 468 | = new (Context)ClassTemplatePartialSpecializationDecl(Context, | 
| Douglas Gregor | 2373c59 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 469 | DC, L, Params, | 
|  | 470 | SpecializedTemplate, | 
| John McCall | 0ad1666 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 471 | Builder, | 
|  | 472 | ClonedArgs, N, | 
|  | 473 | PrevDecl); | 
| Douglas Gregor | 2373c59 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 474 | Result->setSpecializationKind(TSK_ExplicitSpecialization); | 
|  | 475 | Context.getTypeDeclType(Result, PrevDecl); | 
|  | 476 | return Result; | 
|  | 477 | } | 
| John McCall | 11083da | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 478 |  | 
|  | 479 | //===----------------------------------------------------------------------===// | 
|  | 480 | // FriendTemplateDecl Implementation | 
|  | 481 | //===----------------------------------------------------------------------===// | 
|  | 482 |  | 
|  | 483 | FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, | 
|  | 484 | DeclContext *DC, | 
|  | 485 | SourceLocation L, | 
|  | 486 | unsigned NParams, | 
|  | 487 | TemplateParameterList **Params, | 
|  | 488 | FriendUnion Friend, | 
|  | 489 | SourceLocation FLoc) { | 
|  | 490 | FriendTemplateDecl *Result | 
|  | 491 | = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc); | 
|  | 492 | return Result; | 
|  | 493 | } |