/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/TemplateBase.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- TemplateBase.cpp - Common template AST class implementation --------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file implements common classes used throughout C++ template |
10 | | // representations. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "clang/AST/TemplateBase.h" |
15 | | #include "clang/AST/ASTContext.h" |
16 | | #include "clang/AST/Decl.h" |
17 | | #include "clang/AST/DeclBase.h" |
18 | | #include "clang/AST/DeclTemplate.h" |
19 | | #include "clang/AST/DependenceFlags.h" |
20 | | #include "clang/AST/Expr.h" |
21 | | #include "clang/AST/ExprCXX.h" |
22 | | #include "clang/AST/PrettyPrinter.h" |
23 | | #include "clang/AST/TemplateName.h" |
24 | | #include "clang/AST/Type.h" |
25 | | #include "clang/AST/TypeLoc.h" |
26 | | #include "clang/Basic/Diagnostic.h" |
27 | | #include "clang/Basic/LLVM.h" |
28 | | #include "clang/Basic/LangOptions.h" |
29 | | #include "clang/Basic/SourceLocation.h" |
30 | | #include "llvm/ADT/APSInt.h" |
31 | | #include "llvm/ADT/FoldingSet.h" |
32 | | #include "llvm/ADT/None.h" |
33 | | #include "llvm/ADT/SmallString.h" |
34 | | #include "llvm/ADT/StringExtras.h" |
35 | | #include "llvm/ADT/StringRef.h" |
36 | | #include "llvm/Support/Casting.h" |
37 | | #include "llvm/Support/Compiler.h" |
38 | | #include "llvm/Support/ErrorHandling.h" |
39 | | #include "llvm/Support/raw_ostream.h" |
40 | | #include <cassert> |
41 | | #include <cstddef> |
42 | | #include <cstdint> |
43 | | #include <cstring> |
44 | | |
45 | | using namespace clang; |
46 | | |
47 | | /// Print a template integral argument value. |
48 | | /// |
49 | | /// \param TemplArg the TemplateArgument instance to print. |
50 | | /// |
51 | | /// \param Out the raw_ostream instance to use for printing. |
52 | | /// |
53 | | /// \param Policy the printing policy for EnumConstantDecl printing. |
54 | | /// |
55 | | /// \param IncludeType If set, ensure that the type of the expression printed |
56 | | /// matches the type of the template argument. |
57 | | static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out, |
58 | 201k | const PrintingPolicy &Policy, bool IncludeType) { |
59 | 201k | const Type *T = TemplArg.getIntegralType().getTypePtr(); |
60 | 201k | const llvm::APSInt &Val = TemplArg.getAsIntegral(); |
61 | | |
62 | 201k | if (Policy.UseEnumerators) { |
63 | 128k | if (const EnumType *ET = T->getAs<EnumType>()) { |
64 | 1.12k | for (const EnumConstantDecl *ECD : ET->getDecl()->enumerators()) { |
65 | | // In Sema::CheckTemplateArugment, enum template arguments value are |
66 | | // extended to the size of the integer underlying the enum type. This |
67 | | // may create a size difference between the enum value and template |
68 | | // argument value, requiring isSameValue here instead of operator==. |
69 | 1.12k | if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) { |
70 | 1.10k | ECD->printQualifiedName(Out, Policy); |
71 | 1.10k | return; |
72 | 1.10k | } |
73 | 1.12k | } |
74 | 1.10k | } |
75 | 128k | } |
76 | | |
77 | 200k | if (Policy.MSVCFormatting) |
78 | 16 | IncludeType = false; |
79 | | |
80 | 200k | if (T->isBooleanType()) { |
81 | 86.3k | if (!Policy.MSVCFormatting) |
82 | 86.3k | Out << (Val.getBoolValue() ? "true"35.5k : "false"50.7k ); |
83 | 0 | else |
84 | 0 | Out << Val; |
85 | 113k | } else if (T->isCharType()) { |
86 | 117 | if (IncludeType) { |
87 | 43 | if (T->isSpecificBuiltinType(BuiltinType::SChar)) |
88 | 4 | Out << "(signed char)"; |
89 | 39 | else if (T->isSpecificBuiltinType(BuiltinType::UChar)) |
90 | 4 | Out << "(unsigned char)"; |
91 | 43 | } |
92 | 117 | CharacterLiteral::print(Val.getZExtValue(), CharacterLiteral::Ascii, Out); |
93 | 113k | } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting104 ) { |
94 | 90 | CharacterLiteral::CharacterKind Kind; |
95 | 90 | if (T->isWideCharType()) |
96 | 21 | Kind = CharacterLiteral::Wide; |
97 | 69 | else if (T->isChar8Type()) |
98 | 46 | Kind = CharacterLiteral::UTF8; |
99 | 23 | else if (T->isChar16Type()) |
100 | 0 | Kind = CharacterLiteral::UTF16; |
101 | 23 | else if (T->isChar32Type()) |
102 | 23 | Kind = CharacterLiteral::UTF32; |
103 | 0 | else |
104 | 0 | Kind = CharacterLiteral::Ascii; |
105 | 90 | CharacterLiteral::print(Val.getExtValue(), Kind, Out); |
106 | 113k | } else if (IncludeType) { |
107 | 50.1k | if (const auto *BT = T->getAs<BuiltinType>()) { |
108 | 49.9k | switch (BT->getKind()) { |
109 | 164 | case BuiltinType::ULongLong: |
110 | 164 | Out << Val << "ULL"; |
111 | 164 | break; |
112 | 0 | case BuiltinType::LongLong: |
113 | 0 | Out << Val << "LL"; |
114 | 0 | break; |
115 | 10.6k | case BuiltinType::ULong: |
116 | 10.6k | Out << Val << "UL"; |
117 | 10.6k | break; |
118 | 22.4k | case BuiltinType::Long: |
119 | 22.4k | Out << Val << "L"; |
120 | 22.4k | break; |
121 | 783 | case BuiltinType::UInt: |
122 | 783 | Out << Val << "U"; |
123 | 783 | break; |
124 | 15.8k | case BuiltinType::Int: |
125 | 15.8k | Out << Val; |
126 | 15.8k | break; |
127 | 9 | default: |
128 | 9 | Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")" |
129 | 9 | << Val; |
130 | 9 | break; |
131 | 49.9k | } |
132 | 49.9k | } else |
133 | 140 | Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")" |
134 | 140 | << Val; |
135 | 50.1k | } else |
136 | 63.4k | Out << Val; |
137 | 200k | } |
138 | | |
139 | 168 | static unsigned getArrayDepth(QualType type) { |
140 | 168 | unsigned count = 0; |
141 | 273 | while (const auto *arrayType = type->getAsArrayTypeUnsafe()) { |
142 | 105 | count++; |
143 | 105 | type = arrayType->getElementType(); |
144 | 105 | } |
145 | 168 | return count; |
146 | 168 | } |
147 | | |
148 | 1.79k | static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) { |
149 | | // Generally, if the parameter type is a pointer, we must be taking the |
150 | | // address of something and need a &. However, if the argument is an array, |
151 | | // this could be implicit via array-to-pointer decay. |
152 | 1.79k | if (!paramType->isPointerType()) |
153 | 365 | return paramType->isMemberPointerType(); |
154 | 1.42k | if (argType->isArrayType()) |
155 | 84 | return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType()); |
156 | 1.34k | return true; |
157 | 1.42k | } |
158 | | |
159 | | //===----------------------------------------------------------------------===// |
160 | | // TemplateArgument Implementation |
161 | | //===----------------------------------------------------------------------===// |
162 | | |
163 | | TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, |
164 | 2.19M | QualType Type) { |
165 | 2.19M | Integer.Kind = Integral; |
166 | | // Copy the APSInt value into our decomposed form. |
167 | 2.19M | Integer.BitWidth = Value.getBitWidth(); |
168 | 2.19M | Integer.IsUnsigned = Value.isUnsigned(); |
169 | | // If the value is large, we have to get additional memory from the ASTContext |
170 | 2.19M | unsigned NumWords = Value.getNumWords(); |
171 | 2.19M | if (NumWords > 1) { |
172 | 36 | void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t)); |
173 | 36 | std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t)); |
174 | 36 | Integer.pVal = static_cast<uint64_t *>(Mem); |
175 | 2.19M | } else { |
176 | 2.19M | Integer.VAL = Value.getZExtValue(); |
177 | 2.19M | } |
178 | | |
179 | 2.19M | Integer.Type = Type.getAsOpaquePtr(); |
180 | 2.19M | } |
181 | | |
182 | | TemplateArgument |
183 | | TemplateArgument::CreatePackCopy(ASTContext &Context, |
184 | 652k | ArrayRef<TemplateArgument> Args) { |
185 | 652k | if (Args.empty()) |
186 | 26.1k | return getEmptyPack(); |
187 | | |
188 | 626k | return TemplateArgument(Args.copy(Context)); |
189 | 652k | } |
190 | | |
191 | 34.2M | TemplateArgumentDependence TemplateArgument::getDependence() const { |
192 | 34.2M | auto Deps = TemplateArgumentDependence::None; |
193 | 34.2M | switch (getKind()) { |
194 | 0 | case Null: |
195 | 0 | llvm_unreachable("Should not have a NULL template argument"); |
196 | |
|
197 | 26.7M | case Type: |
198 | 26.7M | Deps = toTemplateArgumentDependence(getAsType()->getDependence()); |
199 | 26.7M | if (isa<PackExpansionType>(getAsType())) |
200 | 618k | Deps |= TemplateArgumentDependence::Dependent; |
201 | 26.7M | return Deps; |
202 | | |
203 | 117k | case Template: |
204 | 117k | return toTemplateArgumentDependence(getAsTemplate().getDependence()); |
205 | | |
206 | 216 | case TemplateExpansion: |
207 | 216 | return TemplateArgumentDependence::Dependent | |
208 | 216 | TemplateArgumentDependence::Instantiation; |
209 | | |
210 | 3.94k | case Declaration: { |
211 | 3.94k | auto *DC = dyn_cast<DeclContext>(getAsDecl()); |
212 | 3.94k | if (!DC) |
213 | 2.51k | DC = getAsDecl()->getDeclContext(); |
214 | 3.94k | if (DC->isDependentContext()) |
215 | 10 | Deps = TemplateArgumentDependence::Dependent | |
216 | 10 | TemplateArgumentDependence::Instantiation; |
217 | 3.94k | return Deps; |
218 | 0 | } |
219 | | |
220 | 3.26k | case NullPtr: |
221 | 1.54M | case Integral: |
222 | 1.54M | return TemplateArgumentDependence::None; |
223 | | |
224 | 5.20M | case Expression: |
225 | 5.20M | Deps = toTemplateArgumentDependence(getAsExpr()->getDependence()); |
226 | 5.20M | if (isa<PackExpansionExpr>(getAsExpr())) |
227 | 103k | Deps |= TemplateArgumentDependence::Dependent | |
228 | 103k | TemplateArgumentDependence::Instantiation; |
229 | 5.20M | return Deps; |
230 | | |
231 | 567k | case Pack: |
232 | 567k | for (const auto &P : pack_elements()) |
233 | 951k | Deps |= P.getDependence(); |
234 | 567k | return Deps; |
235 | 34.2M | } |
236 | 0 | llvm_unreachable("unhandled ArgKind"); |
237 | 0 | } |
238 | | |
239 | 7.43M | bool TemplateArgument::isDependent() const { |
240 | 7.43M | return getDependence() & TemplateArgumentDependence::Dependent; |
241 | 7.43M | } |
242 | | |
243 | 2.96M | bool TemplateArgument::isInstantiationDependent() const { |
244 | 2.96M | return getDependence() & TemplateArgumentDependence::Instantiation; |
245 | 2.96M | } |
246 | | |
247 | 32.7M | bool TemplateArgument::isPackExpansion() const { |
248 | 32.7M | switch (getKind()) { |
249 | 0 | case Null: |
250 | 2.83k | case Declaration: |
251 | 1.90M | case Integral: |
252 | 1.95M | case Pack: |
253 | 2.03M | case Template: |
254 | 2.03M | case NullPtr: |
255 | 2.03M | return false; |
256 | | |
257 | 189 | case TemplateExpansion: |
258 | 189 | return true; |
259 | | |
260 | 25.4M | case Type: |
261 | 25.4M | return isa<PackExpansionType>(getAsType()); |
262 | | |
263 | 5.26M | case Expression: |
264 | 5.26M | return isa<PackExpansionExpr>(getAsExpr()); |
265 | 32.7M | } |
266 | | |
267 | 0 | llvm_unreachable("Invalid TemplateArgument Kind!"); |
268 | 0 | } |
269 | | |
270 | 940k | bool TemplateArgument::containsUnexpandedParameterPack() const { |
271 | 940k | return getDependence() & TemplateArgumentDependence::UnexpandedPack; |
272 | 940k | } |
273 | | |
274 | 147 | Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const { |
275 | 147 | assert(getKind() == TemplateExpansion); |
276 | 147 | if (TemplateArg.NumExpansions) |
277 | 3 | return TemplateArg.NumExpansions - 1; |
278 | | |
279 | 144 | return None; |
280 | 147 | } |
281 | | |
282 | 83.6k | QualType TemplateArgument::getNonTypeTemplateArgumentType() const { |
283 | 83.6k | switch (getKind()) { |
284 | 0 | case TemplateArgument::Null: |
285 | 81.4k | case TemplateArgument::Type: |
286 | 81.4k | case TemplateArgument::Template: |
287 | 81.4k | case TemplateArgument::TemplateExpansion: |
288 | 81.6k | case TemplateArgument::Pack: |
289 | 81.6k | return QualType(); |
290 | | |
291 | 222 | case TemplateArgument::Integral: |
292 | 222 | return getIntegralType(); |
293 | | |
294 | 1.78k | case TemplateArgument::Expression: |
295 | 1.78k | return getAsExpr()->getType(); |
296 | | |
297 | 26 | case TemplateArgument::Declaration: |
298 | 26 | return getParamTypeForDecl(); |
299 | | |
300 | 0 | case TemplateArgument::NullPtr: |
301 | 0 | return getNullPtrType(); |
302 | 83.6k | } |
303 | | |
304 | 0 | llvm_unreachable("Invalid TemplateArgument Kind!"); |
305 | 0 | } |
306 | | |
307 | | void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, |
308 | 39.7M | const ASTContext &Context) const { |
309 | 39.7M | ID.AddInteger(getKind()); |
310 | 39.7M | switch (getKind()) { |
311 | 0 | case Null: |
312 | 0 | break; |
313 | | |
314 | 30.0M | case Type: |
315 | 30.0M | getAsType().Profile(ID); |
316 | 30.0M | break; |
317 | | |
318 | 29.2k | case NullPtr: |
319 | 29.2k | getNullPtrType().Profile(ID); |
320 | 29.2k | break; |
321 | | |
322 | 10.2k | case Declaration: |
323 | 10.2k | getParamTypeForDecl().Profile(ID); |
324 | 10.2k | ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr0 ); |
325 | 10.2k | break; |
326 | | |
327 | 90.1k | case Template: |
328 | 90.3k | case TemplateExpansion: { |
329 | 90.3k | TemplateName Template = getAsTemplateOrTemplatePattern(); |
330 | 90.3k | if (TemplateTemplateParmDecl *TTP |
331 | 90.3k | = dyn_cast_or_null<TemplateTemplateParmDecl>( |
332 | 90.3k | Template.getAsTemplateDecl())) { |
333 | 15.1k | ID.AddBoolean(true); |
334 | 15.1k | ID.AddInteger(TTP->getDepth()); |
335 | 15.1k | ID.AddInteger(TTP->getPosition()); |
336 | 15.1k | ID.AddBoolean(TTP->isParameterPack()); |
337 | 75.1k | } else { |
338 | 75.1k | ID.AddBoolean(false); |
339 | 75.1k | ID.AddPointer(Context.getCanonicalTemplateName(Template) |
340 | 75.1k | .getAsVoidPointer()); |
341 | 75.1k | } |
342 | 90.3k | break; |
343 | 90.1k | } |
344 | | |
345 | 3.64M | case Integral: |
346 | 3.64M | getAsIntegral().Profile(ID); |
347 | 3.64M | getIntegralType().Profile(ID); |
348 | 3.64M | break; |
349 | | |
350 | 4.56M | case Expression: |
351 | 4.56M | getAsExpr()->Profile(ID, Context, true); |
352 | 4.56M | break; |
353 | | |
354 | 1.45M | case Pack: |
355 | 1.45M | ID.AddInteger(Args.NumArgs); |
356 | 3.72M | for (unsigned I = 0; I != Args.NumArgs; ++I2.26M ) |
357 | 2.26M | Args.Args[I].Profile(ID, Context); |
358 | 39.7M | } |
359 | 39.7M | } |
360 | | |
361 | 8.44M | bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { |
362 | 8.44M | if (getKind() != Other.getKind()) return false674 ; |
363 | | |
364 | 8.44M | switch (getKind()) { |
365 | 0 | case Null: |
366 | 6.47M | case Type: |
367 | 7.84M | case Expression: |
368 | 7.84M | case NullPtr: |
369 | 7.84M | return TypeOrValue.V == Other.TypeOrValue.V; |
370 | | |
371 | 21.7k | case Template: |
372 | 21.7k | case TemplateExpansion: |
373 | 21.7k | return TemplateArg.Name == Other.TemplateArg.Name && |
374 | 21.7k | TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions17.1k ; |
375 | | |
376 | 43 | case Declaration: |
377 | 43 | return getAsDecl() == Other.getAsDecl(); |
378 | | |
379 | 192k | case Integral: |
380 | 192k | return getIntegralType() == Other.getIntegralType() && |
381 | 192k | getAsIntegral() == Other.getAsIntegral(); |
382 | | |
383 | 388k | case Pack: |
384 | 388k | if (Args.NumArgs != Other.Args.NumArgs) return false0 ; |
385 | 840k | for (unsigned I = 0, E = Args.NumArgs; 388k I != E; ++I451k ) |
386 | 481k | if (!Args.Args[I].structurallyEquals(Other.Args.Args[I])) |
387 | 29.8k | return false; |
388 | 359k | return true; |
389 | 8.44M | } |
390 | | |
391 | 0 | llvm_unreachable("Invalid TemplateArgument Kind!"); |
392 | 0 | } |
393 | | |
394 | 94.3k | TemplateArgument TemplateArgument::getPackExpansionPattern() const { |
395 | 94.3k | assert(isPackExpansion()); |
396 | | |
397 | 0 | switch (getKind()) { |
398 | 90.1k | case Type: |
399 | 90.1k | return getAsType()->castAs<PackExpansionType>()->getPattern(); |
400 | | |
401 | 4.16k | case Expression: |
402 | 4.16k | return cast<PackExpansionExpr>(getAsExpr())->getPattern(); |
403 | | |
404 | 54 | case TemplateExpansion: |
405 | 54 | return TemplateArgument(getAsTemplateOrTemplatePattern()); |
406 | | |
407 | 0 | case Declaration: |
408 | 0 | case Integral: |
409 | 0 | case Pack: |
410 | 0 | case Null: |
411 | 0 | case Template: |
412 | 0 | case NullPtr: |
413 | 0 | return TemplateArgument(); |
414 | 94.3k | } |
415 | | |
416 | 0 | llvm_unreachable("Invalid TemplateArgument Kind!"); |
417 | 0 | } |
418 | | |
419 | | void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out, |
420 | 1.96M | bool IncludeType) const { |
421 | | |
422 | 1.96M | switch (getKind()) { |
423 | 102 | case Null: |
424 | 102 | Out << "(no value)"; |
425 | 102 | break; |
426 | | |
427 | 1.73M | case Type: { |
428 | 1.73M | PrintingPolicy SubPolicy(Policy); |
429 | 1.73M | SubPolicy.SuppressStrongLifetime = true; |
430 | 1.73M | getAsType().print(Out, SubPolicy); |
431 | 1.73M | break; |
432 | 0 | } |
433 | | |
434 | 1.86k | case Declaration: { |
435 | | // FIXME: Include the type if it's not obvious from the context. |
436 | 1.86k | NamedDecl *ND = getAsDecl(); |
437 | 1.86k | if (getParamTypeForDecl()->isRecordType()) { |
438 | 73 | if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) { |
439 | 73 | TPO->printAsInit(Out, Policy); |
440 | 73 | break; |
441 | 73 | } |
442 | 73 | } |
443 | 1.79k | if (auto *VD = dyn_cast<ValueDecl>(ND)) { |
444 | 1.79k | if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType())) |
445 | 1.36k | Out << "&"; |
446 | 1.79k | } |
447 | 1.79k | ND->printQualifiedName(Out); |
448 | 1.79k | break; |
449 | 1.86k | } |
450 | | |
451 | 1.28k | case NullPtr: |
452 | | // FIXME: Include the type if it's not obvious from the context. |
453 | 1.28k | Out << "nullptr"; |
454 | 1.28k | break; |
455 | | |
456 | 1.69k | case Template: |
457 | 1.69k | getAsTemplate().print(Out, Policy, TemplateName::Qualified::Fully); |
458 | 1.69k | break; |
459 | | |
460 | 2 | case TemplateExpansion: |
461 | 2 | getAsTemplateOrTemplatePattern().print(Out, Policy); |
462 | 2 | Out << "..."; |
463 | 2 | break; |
464 | | |
465 | 201k | case Integral: |
466 | 201k | printIntegral(*this, Out, Policy, IncludeType); |
467 | 201k | break; |
468 | | |
469 | 26.7k | case Expression: |
470 | 26.7k | getAsExpr()->printPretty(Out, nullptr, Policy); |
471 | 26.7k | break; |
472 | | |
473 | 1.32k | case Pack: |
474 | 1.32k | Out << "<"; |
475 | 1.32k | bool First = true; |
476 | 3.37k | for (const auto &P : pack_elements()) { |
477 | 3.37k | if (First) |
478 | 1.26k | First = false; |
479 | 2.10k | else |
480 | 2.10k | Out << ", "; |
481 | | |
482 | 3.37k | P.print(Policy, Out, IncludeType); |
483 | 3.37k | } |
484 | 1.32k | Out << ">"; |
485 | 1.32k | break; |
486 | 1.96M | } |
487 | 1.96M | } |
488 | | |
489 | 0 | void TemplateArgument::dump(raw_ostream &Out) const { |
490 | 0 | LangOptions LO; // FIXME! see also TemplateName::dump(). |
491 | 0 | LO.CPlusPlus = true; |
492 | 0 | LO.Bool = true; |
493 | 0 | print(PrintingPolicy(LO), Out, /*IncludeType*/ true); |
494 | 0 | } |
495 | | |
496 | 0 | LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); } |
497 | | |
498 | | //===----------------------------------------------------------------------===// |
499 | | // TemplateArgumentLoc Implementation |
500 | | //===----------------------------------------------------------------------===// |
501 | | |
502 | 356k | SourceRange TemplateArgumentLoc::getSourceRange() const { |
503 | 356k | switch (Argument.getKind()) { |
504 | 133k | case TemplateArgument::Expression: |
505 | 133k | return getSourceExpression()->getSourceRange(); |
506 | | |
507 | 0 | case TemplateArgument::Declaration: |
508 | 0 | return getSourceDeclExpression()->getSourceRange(); |
509 | | |
510 | 0 | case TemplateArgument::NullPtr: |
511 | 0 | return getSourceNullPtrExpression()->getSourceRange(); |
512 | | |
513 | 214k | case TemplateArgument::Type: |
514 | 214k | if (TypeSourceInfo *TSI = getTypeSourceInfo()) |
515 | 214k | return TSI->getTypeLoc().getSourceRange(); |
516 | 0 | else |
517 | 0 | return SourceRange(); |
518 | | |
519 | 9.01k | case TemplateArgument::Template: |
520 | 9.01k | if (getTemplateQualifierLoc()) |
521 | 43 | return SourceRange(getTemplateQualifierLoc().getBeginLoc(), |
522 | 43 | getTemplateNameLoc()); |
523 | 8.96k | return SourceRange(getTemplateNameLoc()); |
524 | | |
525 | 2 | case TemplateArgument::TemplateExpansion: |
526 | 2 | if (getTemplateQualifierLoc()) |
527 | 1 | return SourceRange(getTemplateQualifierLoc().getBeginLoc(), |
528 | 1 | getTemplateEllipsisLoc()); |
529 | 1 | return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); |
530 | | |
531 | 0 | case TemplateArgument::Integral: |
532 | 0 | return getSourceIntegralExpression()->getSourceRange(); |
533 | | |
534 | 0 | case TemplateArgument::Pack: |
535 | 0 | case TemplateArgument::Null: |
536 | 0 | return SourceRange(); |
537 | 356k | } |
538 | | |
539 | 0 | llvm_unreachable("Invalid TemplateArgument Kind!"); |
540 | 0 | } |
541 | | |
542 | | template <typename T> |
543 | 1.19k | static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) { |
544 | 1.19k | switch (Arg.getKind()) { |
545 | 0 | case TemplateArgument::Null: |
546 | | // This is bad, but not as bad as crashing because of argument |
547 | | // count mismatches. |
548 | 0 | return DB << "(null template argument)"; |
549 | | |
550 | 526 | case TemplateArgument::Type: |
551 | 526 | return DB << Arg.getAsType(); |
552 | | |
553 | 8 | case TemplateArgument::Declaration: |
554 | 8 | return DB << Arg.getAsDecl(); |
555 | | |
556 | 0 | case TemplateArgument::NullPtr: |
557 | 0 | return DB << "nullptr"; |
558 | | |
559 | 44 | case TemplateArgument::Integral: |
560 | 44 | return DB << toString(Arg.getAsIntegral(), 10); |
561 | | |
562 | 30 | case TemplateArgument::Template: |
563 | 30 | return DB << Arg.getAsTemplate(); |
564 | | |
565 | 0 | case TemplateArgument::TemplateExpansion: |
566 | 0 | return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; |
567 | | |
568 | 454 | case TemplateArgument::Expression: { |
569 | | // This shouldn't actually ever happen, so it's okay that we're |
570 | | // regurgitating an expression here. |
571 | | // FIXME: We're guessing at LangOptions! |
572 | 454 | SmallString<32> Str; |
573 | 454 | llvm::raw_svector_ostream OS(Str); |
574 | 454 | LangOptions LangOpts; |
575 | 454 | LangOpts.CPlusPlus = true; |
576 | 454 | PrintingPolicy Policy(LangOpts); |
577 | 454 | Arg.getAsExpr()->printPretty(OS, nullptr, Policy); |
578 | 454 | return DB << OS.str(); |
579 | 0 | } |
580 | | |
581 | 132 | case TemplateArgument::Pack: { |
582 | | // FIXME: We're guessing at LangOptions! |
583 | 132 | SmallString<32> Str; |
584 | 132 | llvm::raw_svector_ostream OS(Str); |
585 | 132 | LangOptions LangOpts; |
586 | 132 | LangOpts.CPlusPlus = true; |
587 | 132 | PrintingPolicy Policy(LangOpts); |
588 | 132 | Arg.print(Policy, OS, /*IncludeType*/ true); |
589 | 132 | return DB << OS.str(); |
590 | 0 | } |
591 | 1.19k | } |
592 | | |
593 | 0 | llvm_unreachable("Invalid TemplateArgument Kind!"); |
594 | 0 | } |
595 | | |
596 | | const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB, |
597 | 1.19k | const TemplateArgument &Arg) { |
598 | 1.19k | return DiagTemplateArg(DB, Arg); |
599 | 1.19k | } |
600 | | |
601 | | clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo( |
602 | | ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, |
603 | 78.9k | SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) { |
604 | 78.9k | TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo; |
605 | 78.9k | Template->Qualifier = QualifierLoc.getNestedNameSpecifier(); |
606 | 78.9k | Template->QualifierLocData = QualifierLoc.getOpaqueData(); |
607 | 78.9k | Template->TemplateNameLoc = TemplateNameLoc; |
608 | 78.9k | Template->EllipsisLoc = EllipsisLoc; |
609 | 78.9k | Pointer = Template; |
610 | 78.9k | } |
611 | | |
612 | | const ASTTemplateArgumentListInfo * |
613 | | ASTTemplateArgumentListInfo::Create(const ASTContext &C, |
614 | 200k | const TemplateArgumentListInfo &List) { |
615 | 200k | std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size()); |
616 | 200k | void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo)); |
617 | 200k | return new (Mem) ASTTemplateArgumentListInfo(List); |
618 | 200k | } |
619 | | |
620 | | ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo( |
621 | 200k | const TemplateArgumentListInfo &Info) { |
622 | 200k | LAngleLoc = Info.getLAngleLoc(); |
623 | 200k | RAngleLoc = Info.getRAngleLoc(); |
624 | 200k | NumTemplateArgs = Info.size(); |
625 | | |
626 | 200k | TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>(); |
627 | 613k | for (unsigned i = 0; i != NumTemplateArgs; ++i413k ) |
628 | 413k | new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); |
629 | 200k | } |
630 | | |
631 | | void ASTTemplateKWAndArgsInfo::initializeFrom( |
632 | | SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, |
633 | 78.3k | TemplateArgumentLoc *OutArgArray) { |
634 | 78.3k | this->TemplateKWLoc = TemplateKWLoc; |
635 | 78.3k | LAngleLoc = Info.getLAngleLoc(); |
636 | 78.3k | RAngleLoc = Info.getRAngleLoc(); |
637 | 78.3k | NumTemplateArgs = Info.size(); |
638 | | |
639 | 184k | for (unsigned i = 0; i != NumTemplateArgs; ++i105k ) |
640 | 105k | new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); |
641 | 78.3k | } |
642 | | |
643 | 307 | void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { |
644 | 307 | assert(TemplateKWLoc.isValid()); |
645 | 0 | LAngleLoc = SourceLocation(); |
646 | 307 | RAngleLoc = SourceLocation(); |
647 | 307 | this->TemplateKWLoc = TemplateKWLoc; |
648 | 307 | NumTemplateArgs = 0; |
649 | 307 | } |
650 | | |
651 | | void ASTTemplateKWAndArgsInfo::initializeFrom( |
652 | | SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, |
653 | 603k | TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) { |
654 | 603k | this->TemplateKWLoc = TemplateKWLoc; |
655 | 603k | LAngleLoc = Info.getLAngleLoc(); |
656 | 603k | RAngleLoc = Info.getRAngleLoc(); |
657 | 603k | NumTemplateArgs = Info.size(); |
658 | | |
659 | 1.44M | for (unsigned i = 0; i != NumTemplateArgs; ++i841k ) { |
660 | 841k | Deps |= Info[i].getArgument().getDependence(); |
661 | | |
662 | 841k | new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); |
663 | 841k | } |
664 | 603k | } |
665 | | |
666 | | void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray, |
667 | 316k | TemplateArgumentListInfo &Info) const { |
668 | 316k | Info.setLAngleLoc(LAngleLoc); |
669 | 316k | Info.setRAngleLoc(RAngleLoc); |
670 | 716k | for (unsigned I = 0; I != NumTemplateArgs; ++I400k ) |
671 | 400k | Info.addArgument(ArgArray[I]); |
672 | 316k | } |