/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/lib/AST/TemplateBase.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- TemplateBase.cpp - Common template AST class 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 common classes used throughout C++ template |
11 | | // representations. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "clang/AST/TemplateBase.h" |
16 | | #include "clang/AST/ASTContext.h" |
17 | | #include "clang/AST/DeclBase.h" |
18 | | #include "clang/AST/DeclTemplate.h" |
19 | | #include "clang/AST/Expr.h" |
20 | | #include "clang/AST/ExprCXX.h" |
21 | | #include "clang/AST/Type.h" |
22 | | #include "clang/AST/TypeLoc.h" |
23 | | #include "clang/Basic/Diagnostic.h" |
24 | | #include "llvm/ADT/FoldingSet.h" |
25 | | #include "llvm/ADT/SmallString.h" |
26 | | #include "llvm/Support/raw_ostream.h" |
27 | | #include <algorithm> |
28 | | |
29 | | using namespace clang; |
30 | | |
31 | | /// \brief Print a template integral argument value. |
32 | | /// |
33 | | /// \param TemplArg the TemplateArgument instance to print. |
34 | | /// |
35 | | /// \param Out the raw_ostream instance to use for printing. |
36 | | /// |
37 | | /// \param Policy the printing policy for EnumConstantDecl printing. |
38 | | static void printIntegral(const TemplateArgument &TemplArg, |
39 | 3.56k | raw_ostream &Out, const PrintingPolicy& Policy) { |
40 | 3.56k | const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr(); |
41 | 3.56k | const llvm::APSInt &Val = TemplArg.getAsIntegral(); |
42 | 3.56k | |
43 | 3.56k | if (const EnumType *ET3.56k = T->getAs<EnumType>()) { |
44 | 36 | for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) { |
45 | 36 | // In Sema::CheckTemplateArugment, enum template arguments value are |
46 | 36 | // extended to the size of the integer underlying the enum type. This |
47 | 36 | // may create a size difference between the enum value and template |
48 | 36 | // argument value, requiring isSameValue here instead of operator==. |
49 | 36 | if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)36 ) { |
50 | 31 | ECD->printQualifiedName(Out, Policy); |
51 | 31 | return; |
52 | 31 | } |
53 | 3.53k | } |
54 | 32 | } |
55 | 3.53k | |
56 | 3.53k | if (3.53k T->isBooleanType() && 3.53k !Policy.MSVCFormatting122 ) { |
57 | 122 | Out << (Val.getBoolValue() ? "true"67 : "false"55 ); |
58 | 3.53k | } else if (3.41k T->isCharType()3.41k ) { |
59 | 94 | const char Ch = Val.getZExtValue(); |
60 | 94 | Out << ((Ch == '\'') ? "'\\"6 : "'"88 ); |
61 | 94 | Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true); |
62 | 94 | Out << "'"; |
63 | 3.41k | } else { |
64 | 3.32k | Out << Val; |
65 | 3.32k | } |
66 | 3.56k | } |
67 | | |
68 | | //===----------------------------------------------------------------------===// |
69 | | // TemplateArgument Implementation |
70 | | //===----------------------------------------------------------------------===// |
71 | | |
72 | | TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, |
73 | 32.6k | QualType Type) { |
74 | 32.6k | Integer.Kind = Integral; |
75 | 32.6k | // Copy the APSInt value into our decomposed form. |
76 | 32.6k | Integer.BitWidth = Value.getBitWidth(); |
77 | 32.6k | Integer.IsUnsigned = Value.isUnsigned(); |
78 | 32.6k | // If the value is large, we have to get additional memory from the ASTContext |
79 | 32.6k | unsigned NumWords = Value.getNumWords(); |
80 | 32.6k | if (NumWords > 132.6k ) { |
81 | 0 | void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t)); |
82 | 0 | std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t)); |
83 | 0 | Integer.pVal = static_cast<uint64_t *>(Mem); |
84 | 32.6k | } else { |
85 | 32.6k | Integer.VAL = Value.getZExtValue(); |
86 | 32.6k | } |
87 | 32.6k | |
88 | 32.6k | Integer.Type = Type.getAsOpaquePtr(); |
89 | 32.6k | } |
90 | | |
91 | | TemplateArgument |
92 | | TemplateArgument::CreatePackCopy(ASTContext &Context, |
93 | 5.82k | ArrayRef<TemplateArgument> Args) { |
94 | 5.82k | if (Args.empty()) |
95 | 747 | return getEmptyPack(); |
96 | 5.07k | |
97 | 5.07k | return TemplateArgument(Args.copy(Context)); |
98 | 5.07k | } |
99 | | |
100 | 188k | bool TemplateArgument::isDependent() const { |
101 | 188k | switch (getKind()) { |
102 | 0 | case Null: |
103 | 0 | llvm_unreachable("Should not have a NULL template argument"); |
104 | 188k | |
105 | 140k | case Type: |
106 | 140k | return getAsType()->isDependentType() || |
107 | 83.4k | isa<PackExpansionType>(getAsType()); |
108 | 188k | |
109 | 714 | case Template: |
110 | 714 | return getAsTemplate().isDependent(); |
111 | 188k | |
112 | 14 | case TemplateExpansion: |
113 | 14 | return true; |
114 | 188k | |
115 | 0 | case Declaration: |
116 | 0 | if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) |
117 | 0 | return DC->isDependentContext(); |
118 | 0 | return getAsDecl()->getDeclContext()->isDependentContext(); |
119 | 0 |
|
120 | 0 | case NullPtr: |
121 | 0 | return false; |
122 | 0 |
|
123 | 0 | case Integral: |
124 | 0 | // Never dependent |
125 | 0 | return false; |
126 | 0 |
|
127 | 47.1k | case Expression: |
128 | 45.1k | return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() || |
129 | 47.1k | isa<PackExpansionExpr>(getAsExpr())); |
130 | 0 |
|
131 | 5 | case Pack: |
132 | 5 | for (const auto &P : pack_elements()) |
133 | 5 | if (5 P.isDependent()5 ) |
134 | 5 | return true; |
135 | 0 | return false; |
136 | 0 | } |
137 | 0 |
|
138 | 0 | llvm_unreachable0 ("Invalid TemplateArgument Kind!"); |
139 | 0 | } |
140 | | |
141 | 536k | bool TemplateArgument::isInstantiationDependent() const { |
142 | 536k | switch (getKind()) { |
143 | 0 | case Null: |
144 | 0 | llvm_unreachable("Should not have a NULL template argument"); |
145 | 536k | |
146 | 423k | case Type: |
147 | 423k | return getAsType()->isInstantiationDependentType(); |
148 | 536k | |
149 | 4.86k | case Template: |
150 | 4.86k | return getAsTemplate().isInstantiationDependent(); |
151 | 536k | |
152 | 136 | case TemplateExpansion: |
153 | 136 | return true; |
154 | 536k | |
155 | 1.27k | case Declaration: |
156 | 1.27k | if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) |
157 | 49 | return DC->isDependentContext(); |
158 | 1.22k | return getAsDecl()->getDeclContext()->isDependentContext(); |
159 | 1.22k | |
160 | 233 | case NullPtr: |
161 | 233 | return false; |
162 | 1.22k | |
163 | 8.12k | case Integral: |
164 | 8.12k | // Never dependent |
165 | 8.12k | return false; |
166 | 1.22k | |
167 | 96.3k | case Expression: |
168 | 96.3k | return getAsExpr()->isInstantiationDependent(); |
169 | 1.22k | |
170 | 2.41k | case Pack: |
171 | 2.41k | for (const auto &P : pack_elements()) |
172 | 7.08k | if (7.08k P.isInstantiationDependent()7.08k ) |
173 | 1.50k | return true; |
174 | 904 | return false; |
175 | 0 | } |
176 | 0 |
|
177 | 0 | llvm_unreachable0 ("Invalid TemplateArgument Kind!"); |
178 | 0 | } |
179 | | |
180 | 443k | bool TemplateArgument::isPackExpansion() const { |
181 | 443k | switch (getKind()) { |
182 | 19.2k | case Null: |
183 | 19.2k | case Declaration: |
184 | 19.2k | case Integral: |
185 | 19.2k | case Pack: |
186 | 19.2k | case Template: |
187 | 19.2k | case NullPtr: |
188 | 19.2k | return false; |
189 | 19.2k | |
190 | 87 | case TemplateExpansion: |
191 | 87 | return true; |
192 | 19.2k | |
193 | 339k | case Type: |
194 | 339k | return isa<PackExpansionType>(getAsType()); |
195 | 19.2k | |
196 | 83.9k | case Expression: |
197 | 83.9k | return isa<PackExpansionExpr>(getAsExpr()); |
198 | 0 | } |
199 | 0 |
|
200 | 0 | llvm_unreachable0 ("Invalid TemplateArgument Kind!"); |
201 | 0 | } |
202 | | |
203 | 393k | bool TemplateArgument::containsUnexpandedParameterPack() const { |
204 | 393k | switch (getKind()) { |
205 | 4.33k | case Null: |
206 | 4.33k | case Declaration: |
207 | 4.33k | case Integral: |
208 | 4.33k | case TemplateExpansion: |
209 | 4.33k | case NullPtr: |
210 | 4.33k | break; |
211 | 4.33k | |
212 | 305k | case Type: |
213 | 305k | if (getAsType()->containsUnexpandedParameterPack()) |
214 | 418 | return true; |
215 | 304k | break; |
216 | 304k | |
217 | 4.26k | case Template: |
218 | 4.26k | if (getAsTemplate().containsUnexpandedParameterPack()) |
219 | 3 | return true; |
220 | 4.26k | break; |
221 | 4.26k | |
222 | 78.0k | case Expression: |
223 | 78.0k | if (getAsExpr()->containsUnexpandedParameterPack()) |
224 | 55 | return true; |
225 | 78.0k | break; |
226 | 78.0k | |
227 | 2.11k | case Pack: |
228 | 2.11k | for (const auto &P : pack_elements()) |
229 | 4.84k | if (4.84k P.containsUnexpandedParameterPack()4.84k ) |
230 | 7 | return true; |
231 | 2.10k | |
232 | 2.10k | break; |
233 | 393k | } |
234 | 393k | |
235 | 393k | return false; |
236 | 393k | } |
237 | | |
238 | 107 | Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const { |
239 | 107 | assert(getKind() == TemplateExpansion); |
240 | 107 | if (TemplateArg.NumExpansions) |
241 | 3 | return TemplateArg.NumExpansions - 1; |
242 | 104 | |
243 | 104 | return None; |
244 | 104 | } |
245 | | |
246 | 10.7k | QualType TemplateArgument::getNonTypeTemplateArgumentType() const { |
247 | 10.7k | switch (getKind()) { |
248 | 10.5k | case TemplateArgument::Null: |
249 | 10.5k | case TemplateArgument::Type: |
250 | 10.5k | case TemplateArgument::Template: |
251 | 10.5k | case TemplateArgument::TemplateExpansion: |
252 | 10.5k | case TemplateArgument::Pack: |
253 | 10.5k | return QualType(); |
254 | 10.5k | |
255 | 110 | case TemplateArgument::Integral: |
256 | 110 | return getIntegralType(); |
257 | 10.5k | |
258 | 72 | case TemplateArgument::Expression: |
259 | 72 | return getAsExpr()->getType(); |
260 | 10.5k | |
261 | 8 | case TemplateArgument::Declaration: |
262 | 8 | return getParamTypeForDecl(); |
263 | 10.5k | |
264 | 0 | case TemplateArgument::NullPtr: |
265 | 0 | return getNullPtrType(); |
266 | 0 | } |
267 | 0 |
|
268 | 0 | llvm_unreachable0 ("Invalid TemplateArgument Kind!"); |
269 | 0 | } |
270 | | |
271 | | void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, |
272 | 690k | const ASTContext &Context) const { |
273 | 690k | ID.AddInteger(getKind()); |
274 | 690k | switch (getKind()) { |
275 | 0 | case Null: |
276 | 0 | break; |
277 | 690k | |
278 | 535k | case Type: |
279 | 535k | getAsType().Profile(ID); |
280 | 535k | break; |
281 | 690k | |
282 | 490 | case NullPtr: |
283 | 490 | getNullPtrType().Profile(ID); |
284 | 490 | break; |
285 | 690k | |
286 | 1.61k | case Declaration: |
287 | 1.61k | ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl()1.61k : nullptr0 ); |
288 | 1.61k | break; |
289 | 690k | |
290 | 2.09k | case Template: |
291 | 2.09k | case TemplateExpansion: { |
292 | 2.09k | TemplateName Template = getAsTemplateOrTemplatePattern(); |
293 | 2.09k | if (TemplateTemplateParmDecl *TTP |
294 | 2.09k | = dyn_cast_or_null<TemplateTemplateParmDecl>( |
295 | 916 | Template.getAsTemplateDecl())) { |
296 | 916 | ID.AddBoolean(true); |
297 | 916 | ID.AddInteger(TTP->getDepth()); |
298 | 916 | ID.AddInteger(TTP->getPosition()); |
299 | 916 | ID.AddBoolean(TTP->isParameterPack()); |
300 | 2.09k | } else { |
301 | 1.18k | ID.AddBoolean(false); |
302 | 1.18k | ID.AddPointer(Context.getCanonicalTemplateName(Template) |
303 | 1.18k | .getAsVoidPointer()); |
304 | 1.18k | } |
305 | 2.09k | break; |
306 | 2.09k | } |
307 | 2.09k | |
308 | 64.0k | case Integral: |
309 | 64.0k | getAsIntegral().Profile(ID); |
310 | 64.0k | getIntegralType().Profile(ID); |
311 | 64.0k | break; |
312 | 2.09k | |
313 | 78.4k | case Expression: |
314 | 78.4k | getAsExpr()->Profile(ID, Context, true); |
315 | 78.4k | break; |
316 | 2.09k | |
317 | 7.99k | case Pack: |
318 | 7.99k | ID.AddInteger(Args.NumArgs); |
319 | 26.6k | for (unsigned I = 0; I != Args.NumArgs26.6k ; ++I18.6k ) |
320 | 18.6k | Args.Args[I].Profile(ID, Context); |
321 | 690k | } |
322 | 690k | } |
323 | | |
324 | 584 | bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { |
325 | 584 | if (getKind() != Other.getKind()584 ) return false0 ; |
326 | 584 | |
327 | 584 | switch (getKind()) { |
328 | 584 | case Null: |
329 | 584 | case Type: |
330 | 584 | case Expression: |
331 | 584 | case Template: |
332 | 584 | case TemplateExpansion: |
333 | 584 | case NullPtr: |
334 | 584 | return TypeOrValue.V == Other.TypeOrValue.V; |
335 | 584 | |
336 | 0 | case Declaration: |
337 | 0 | return getAsDecl() == Other.getAsDecl(); |
338 | 584 | |
339 | 0 | case Integral: |
340 | 0 | return getIntegralType() == Other.getIntegralType() && |
341 | 0 | getAsIntegral() == Other.getAsIntegral(); |
342 | 584 | |
343 | 0 | case Pack: |
344 | 0 | if (Args.NumArgs != Other.Args.NumArgs0 ) return false0 ; |
345 | 0 | for (unsigned I = 0, E = Args.NumArgs; 0 I != E0 ; ++I0 ) |
346 | 0 | if (0 !Args.Args[I].structurallyEquals(Other.Args.Args[I])0 ) |
347 | 0 | return false; |
348 | 0 | return true; |
349 | 0 | } |
350 | 0 |
|
351 | 0 | llvm_unreachable0 ("Invalid TemplateArgument Kind!"); |
352 | 0 | } |
353 | | |
354 | 1.02k | TemplateArgument TemplateArgument::getPackExpansionPattern() const { |
355 | 1.02k | assert(isPackExpansion()); |
356 | 1.02k | |
357 | 1.02k | switch (getKind()) { |
358 | 826 | case Type: |
359 | 826 | return getAsType()->getAs<PackExpansionType>()->getPattern(); |
360 | 1.02k | |
361 | 155 | case Expression: |
362 | 155 | return cast<PackExpansionExpr>(getAsExpr())->getPattern(); |
363 | 1.02k | |
364 | 43 | case TemplateExpansion: |
365 | 43 | return TemplateArgument(getAsTemplateOrTemplatePattern()); |
366 | 1.02k | |
367 | 0 | case Declaration: |
368 | 0 | case Integral: |
369 | 0 | case Pack: |
370 | 0 | case Null: |
371 | 0 | case Template: |
372 | 0 | case NullPtr: |
373 | 0 | return TemplateArgument(); |
374 | 0 | } |
375 | 0 |
|
376 | 0 | llvm_unreachable0 ("Invalid TemplateArgument Kind!"); |
377 | 0 | } |
378 | | |
379 | | void TemplateArgument::print(const PrintingPolicy &Policy, |
380 | 36.8k | raw_ostream &Out) const { |
381 | 36.8k | switch (getKind()) { |
382 | 53 | case Null: |
383 | 53 | Out << "(no value)"; |
384 | 53 | break; |
385 | 36.8k | |
386 | 28.1k | case Type: { |
387 | 28.1k | PrintingPolicy SubPolicy(Policy); |
388 | 28.1k | SubPolicy.SuppressStrongLifetime = true; |
389 | 28.1k | getAsType().print(Out, SubPolicy); |
390 | 28.1k | break; |
391 | 36.8k | } |
392 | 36.8k | |
393 | 1.66k | case Declaration: { |
394 | 1.66k | NamedDecl *ND = cast<NamedDecl>(getAsDecl()); |
395 | 1.66k | Out << '&'; |
396 | 1.66k | if (ND->getDeclName()1.66k ) { |
397 | 1.66k | // FIXME: distinguish between pointer and reference args? |
398 | 1.66k | ND->printQualifiedName(Out); |
399 | 1.66k | } else { |
400 | 0 | Out << "(anonymous)"; |
401 | 0 | } |
402 | 1.66k | break; |
403 | 36.8k | } |
404 | 36.8k | |
405 | 807 | case NullPtr: |
406 | 807 | Out << "nullptr"; |
407 | 807 | break; |
408 | 36.8k | |
409 | 933 | case Template: |
410 | 933 | getAsTemplate().print(Out, Policy); |
411 | 933 | break; |
412 | 36.8k | |
413 | 2 | case TemplateExpansion: |
414 | 2 | getAsTemplateOrTemplatePattern().print(Out, Policy); |
415 | 2 | Out << "..."; |
416 | 2 | break; |
417 | 36.8k | |
418 | 3.56k | case Integral: { |
419 | 3.56k | printIntegral(*this, Out, Policy); |
420 | 3.56k | break; |
421 | 36.8k | } |
422 | 36.8k | |
423 | 1.50k | case Expression: |
424 | 1.50k | getAsExpr()->printPretty(Out, nullptr, Policy); |
425 | 1.50k | break; |
426 | 36.8k | |
427 | 151 | case Pack: |
428 | 151 | Out << "<"; |
429 | 151 | bool First = true; |
430 | 216 | for (const auto &P : pack_elements()) { |
431 | 216 | if (First) |
432 | 101 | First = false; |
433 | 216 | else |
434 | 115 | Out << ", "; |
435 | 216 | |
436 | 216 | P.print(Policy, Out); |
437 | 216 | } |
438 | 151 | Out << ">"; |
439 | 151 | break; |
440 | 36.8k | } |
441 | 36.8k | } |
442 | | |
443 | 0 | void TemplateArgument::dump(raw_ostream &Out) const { |
444 | 0 | LangOptions LO; // FIXME! see also TemplateName::dump(). |
445 | 0 | LO.CPlusPlus = true; |
446 | 0 | LO.Bool = true; |
447 | 0 | print(PrintingPolicy(LO), Out); |
448 | 0 | } |
449 | | |
450 | 0 | LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); } |
451 | | |
452 | | //===----------------------------------------------------------------------===// |
453 | | // TemplateArgumentLoc Implementation |
454 | | //===----------------------------------------------------------------------===// |
455 | | |
456 | 1.81k | SourceRange TemplateArgumentLoc::getSourceRange() const { |
457 | 1.81k | switch (Argument.getKind()) { |
458 | 454 | case TemplateArgument::Expression: |
459 | 454 | return getSourceExpression()->getSourceRange(); |
460 | 1.81k | |
461 | 0 | case TemplateArgument::Declaration: |
462 | 0 | return getSourceDeclExpression()->getSourceRange(); |
463 | 1.81k | |
464 | 0 | case TemplateArgument::NullPtr: |
465 | 0 | return getSourceNullPtrExpression()->getSourceRange(); |
466 | 1.81k | |
467 | 1.18k | case TemplateArgument::Type: |
468 | 1.18k | if (TypeSourceInfo *TSI = getTypeSourceInfo()) |
469 | 1.18k | return TSI->getTypeLoc().getSourceRange(); |
470 | 1.18k | else |
471 | 0 | return SourceRange(); |
472 | 0 |
|
473 | 173 | case TemplateArgument::Template: |
474 | 173 | if (getTemplateQualifierLoc()) |
475 | 36 | return SourceRange(getTemplateQualifierLoc().getBeginLoc(), |
476 | 36 | getTemplateNameLoc()); |
477 | 137 | return SourceRange(getTemplateNameLoc()); |
478 | 137 | |
479 | 0 | case TemplateArgument::TemplateExpansion: |
480 | 0 | if (getTemplateQualifierLoc()) |
481 | 0 | return SourceRange(getTemplateQualifierLoc().getBeginLoc(), |
482 | 0 | getTemplateEllipsisLoc()); |
483 | 0 | return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); |
484 | 0 |
|
485 | 0 | case TemplateArgument::Integral: |
486 | 0 | return getSourceIntegralExpression()->getSourceRange(); |
487 | 0 |
|
488 | 0 | case TemplateArgument::Pack: |
489 | 0 | case TemplateArgument::Null: |
490 | 0 | return SourceRange(); |
491 | 0 | } |
492 | 0 |
|
493 | 0 | llvm_unreachable0 ("Invalid TemplateArgument Kind!"); |
494 | 0 | } |
495 | | |
496 | | const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, |
497 | 1.22k | const TemplateArgument &Arg) { |
498 | 1.22k | switch (Arg.getKind()) { |
499 | 0 | case TemplateArgument::Null: |
500 | 0 | // This is bad, but not as bad as crashing because of argument |
501 | 0 | // count mismatches. |
502 | 0 | return DB << "(null template argument)"; |
503 | 1.22k | |
504 | 1.04k | case TemplateArgument::Type: |
505 | 1.04k | return DB << Arg.getAsType(); |
506 | 1.22k | |
507 | 4 | case TemplateArgument::Declaration: |
508 | 4 | return DB << Arg.getAsDecl(); |
509 | 1.22k | |
510 | 0 | case TemplateArgument::NullPtr: |
511 | 0 | return DB << "nullptr"; |
512 | 1.22k | |
513 | 44 | case TemplateArgument::Integral: |
514 | 44 | return DB << Arg.getAsIntegral().toString(10); |
515 | 1.22k | |
516 | 6 | case TemplateArgument::Template: |
517 | 6 | return DB << Arg.getAsTemplate(); |
518 | 1.22k | |
519 | 0 | case TemplateArgument::TemplateExpansion: |
520 | 0 | return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; |
521 | 1.22k | |
522 | 44 | case TemplateArgument::Expression: { |
523 | 44 | // This shouldn't actually ever happen, so it's okay that we're |
524 | 44 | // regurgitating an expression here. |
525 | 44 | // FIXME: We're guessing at LangOptions! |
526 | 44 | SmallString<32> Str; |
527 | 44 | llvm::raw_svector_ostream OS(Str); |
528 | 44 | LangOptions LangOpts; |
529 | 44 | LangOpts.CPlusPlus = true; |
530 | 44 | PrintingPolicy Policy(LangOpts); |
531 | 44 | Arg.getAsExpr()->printPretty(OS, nullptr, Policy); |
532 | 44 | return DB << OS.str(); |
533 | 1.22k | } |
534 | 1.22k | |
535 | 86 | case TemplateArgument::Pack: { |
536 | 86 | // FIXME: We're guessing at LangOptions! |
537 | 86 | SmallString<32> Str; |
538 | 86 | llvm::raw_svector_ostream OS(Str); |
539 | 86 | LangOptions LangOpts; |
540 | 86 | LangOpts.CPlusPlus = true; |
541 | 86 | PrintingPolicy Policy(LangOpts); |
542 | 86 | Arg.print(Policy, OS); |
543 | 86 | return DB << OS.str(); |
544 | 0 | } |
545 | 0 | } |
546 | 0 |
|
547 | 0 | llvm_unreachable0 ("Invalid TemplateArgument Kind!"); |
548 | 0 | } |
549 | | |
550 | | const ASTTemplateArgumentListInfo * |
551 | | ASTTemplateArgumentListInfo::Create(ASTContext &C, |
552 | 5.31k | const TemplateArgumentListInfo &List) { |
553 | 5.31k | std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size()); |
554 | 5.31k | void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo)); |
555 | 5.31k | return new (Mem) ASTTemplateArgumentListInfo(List); |
556 | 5.31k | } |
557 | | |
558 | | ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo( |
559 | 5.31k | const TemplateArgumentListInfo &Info) { |
560 | 5.31k | LAngleLoc = Info.getLAngleLoc(); |
561 | 5.31k | RAngleLoc = Info.getRAngleLoc(); |
562 | 5.31k | NumTemplateArgs = Info.size(); |
563 | 5.31k | |
564 | 5.31k | TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>(); |
565 | 15.2k | for (unsigned i = 0; i != NumTemplateArgs15.2k ; ++i9.91k ) |
566 | 9.91k | new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); |
567 | 5.31k | } |
568 | | |
569 | | void ASTTemplateKWAndArgsInfo::initializeFrom( |
570 | | SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, |
571 | 283 | TemplateArgumentLoc *OutArgArray) { |
572 | 283 | this->TemplateKWLoc = TemplateKWLoc; |
573 | 283 | LAngleLoc = Info.getLAngleLoc(); |
574 | 283 | RAngleLoc = Info.getRAngleLoc(); |
575 | 283 | NumTemplateArgs = Info.size(); |
576 | 283 | |
577 | 642 | for (unsigned i = 0; i != NumTemplateArgs642 ; ++i359 ) |
578 | 359 | new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); |
579 | 283 | } |
580 | | |
581 | 39 | void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { |
582 | 39 | assert(TemplateKWLoc.isValid()); |
583 | 39 | LAngleLoc = SourceLocation(); |
584 | 39 | RAngleLoc = SourceLocation(); |
585 | 39 | this->TemplateKWLoc = TemplateKWLoc; |
586 | 39 | NumTemplateArgs = 0; |
587 | 39 | } |
588 | | |
589 | | void ASTTemplateKWAndArgsInfo::initializeFrom( |
590 | | SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, |
591 | | TemplateArgumentLoc *OutArgArray, bool &Dependent, |
592 | 22.8k | bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) { |
593 | 22.8k | this->TemplateKWLoc = TemplateKWLoc; |
594 | 22.8k | LAngleLoc = Info.getLAngleLoc(); |
595 | 22.8k | RAngleLoc = Info.getRAngleLoc(); |
596 | 22.8k | NumTemplateArgs = Info.size(); |
597 | 22.8k | |
598 | 52.0k | for (unsigned i = 0; i != NumTemplateArgs52.0k ; ++i29.1k ) { |
599 | 28.7k | Dependent = Dependent || Info[i].getArgument().isDependent(); |
600 | 29.1k | InstantiationDependent = InstantiationDependent || |
601 | 28.7k | Info[i].getArgument().isInstantiationDependent(); |
602 | 29.1k | ContainsUnexpandedParameterPack = |
603 | 29.1k | ContainsUnexpandedParameterPack || |
604 | 29.1k | Info[i].getArgument().containsUnexpandedParameterPack(); |
605 | 29.1k | |
606 | 29.1k | new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); |
607 | 29.1k | } |
608 | 22.8k | } |
609 | | |
610 | | void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray, |
611 | 25.1k | TemplateArgumentListInfo &Info) const { |
612 | 25.1k | Info.setLAngleLoc(LAngleLoc); |
613 | 25.1k | Info.setRAngleLoc(RAngleLoc); |
614 | 57.3k | for (unsigned I = 0; I != NumTemplateArgs57.3k ; ++I32.2k ) |
615 | 32.2k | Info.addArgument(ArgArray[I]); |
616 | 25.1k | } |