Coverage Report

Created: 2020-09-15 12:33

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/TemplateBase.h
Line
Count
Source (jump to first uncovered line)
1
//===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===//
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 provides definitions which are common for all kinds of
10
//  template representation.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
15
#define LLVM_CLANG_AST_TEMPLATEBASE_H
16
17
#include "clang/AST/DependenceFlags.h"
18
#include "clang/AST/NestedNameSpecifier.h"
19
#include "clang/AST/TemplateName.h"
20
#include "clang/AST/Type.h"
21
#include "clang/Basic/LLVM.h"
22
#include "clang/Basic/SourceLocation.h"
23
#include "llvm/ADT/APInt.h"
24
#include "llvm/ADT/APSInt.h"
25
#include "llvm/ADT/ArrayRef.h"
26
#include "llvm/ADT/None.h"
27
#include "llvm/ADT/Optional.h"
28
#include "llvm/ADT/SmallVector.h"
29
#include "llvm/Support/Compiler.h"
30
#include "llvm/Support/TrailingObjects.h"
31
#include <cassert>
32
#include <cstddef>
33
#include <cstdint>
34
35
namespace llvm {
36
37
class FoldingSetNodeID;
38
39
} // namespace llvm
40
41
namespace clang {
42
43
class ASTContext;
44
class DiagnosticBuilder;
45
class Expr;
46
struct PrintingPolicy;
47
class TypeSourceInfo;
48
class ValueDecl;
49
50
/// Represents a template argument.
51
class TemplateArgument {
52
public:
53
  /// The kind of template argument we're storing.
54
  enum ArgKind {
55
    /// Represents an empty template argument, e.g., one that has not
56
    /// been deduced.
57
    Null = 0,
58
59
    /// The template argument is a type.
60
    Type,
61
62
    /// The template argument is a declaration that was provided for a pointer,
63
    /// reference, or pointer to member non-type template parameter.
64
    Declaration,
65
66
    /// The template argument is a null pointer or null pointer to member that
67
    /// was provided for a non-type template parameter.
68
    NullPtr,
69
70
    /// The template argument is an integral value stored in an llvm::APSInt
71
    /// that was provided for an integral non-type template parameter.
72
    Integral,
73
74
    /// The template argument is a template name that was provided for a
75
    /// template template parameter.
76
    Template,
77
78
    /// The template argument is a pack expansion of a template name that was
79
    /// provided for a template template parameter.
80
    TemplateExpansion,
81
82
    /// The template argument is an expression, and we've not resolved it to one
83
    /// of the other forms yet, either because it's dependent or because we're
84
    /// representing a non-canonical template argument (for instance, in a
85
    /// TemplateSpecializationType).
86
    Expression,
87
88
    /// The template argument is actually a parameter pack. Arguments are stored
89
    /// in the Args struct.
90
    Pack
91
  };
92
93
private:
94
  /// The kind of template argument we're storing.
95
96
  struct DA {
97
    unsigned Kind;
98
    void *QT;
99
    ValueDecl *D;
100
  };
101
  struct I {
102
    unsigned Kind;
103
    // We store a decomposed APSInt with the data allocated by ASTContext if
104
    // BitWidth > 64. The memory may be shared between multiple
105
    // TemplateArgument instances.
106
    unsigned BitWidth : 31;
107
    unsigned IsUnsigned : 1;
108
    union {
109
      /// Used to store the <= 64 bits integer value.
110
      uint64_t VAL;
111
112
      /// Used to store the >64 bits integer value.
113
      const uint64_t *pVal;
114
    };
115
    void *Type;
116
  };
117
  struct A {
118
    unsigned Kind;
119
    unsigned NumArgs;
120
    const TemplateArgument *Args;
121
  };
122
  struct TA {
123
    unsigned Kind;
124
    unsigned NumExpansions;
125
    void *Name;
126
  };
127
  struct TV {
128
    unsigned Kind;
129
    uintptr_t V;
130
  };
131
  union {
132
    struct DA DeclArg;
133
    struct I Integer;
134
    struct A Args;
135
    struct TA TemplateArg;
136
    struct TV TypeOrValue;
137
  };
138
139
public:
140
  /// Construct an empty, invalid template argument.
141
21.4M
  constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
142
143
  /// Construct a template type argument.
144
35.8M
  TemplateArgument(QualType T, bool isNullPtr = false) {
145
35.8M
    TypeOrValue.Kind = isNullPtr ? 
NullPtr431
: Type;
146
35.8M
    TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
147
35.8M
  }
148
149
  /// Construct a template argument that refers to a
150
  /// declaration, which is either an external declaration or a
151
  /// template declaration.
152
3.86k
  TemplateArgument(ValueDecl *D, QualType QT) {
153
3.86k
    assert(D && "Expected decl");
154
3.86k
    DeclArg.Kind = Declaration;
155
3.86k
    DeclArg.QT = QT.getAsOpaquePtr();
156
3.86k
    DeclArg.D = D;
157
3.86k
  }
158
159
  /// Construct an integral constant template argument. The memory to
160
  /// store the value is allocated with Ctx.
161
  TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
162
163
  /// Construct an integral constant template argument with the same
164
  /// value as Other but a different type.
165
815k
  TemplateArgument(const TemplateArgument &Other, QualType Type) {
166
815k
    Integer = Other.Integer;
167
815k
    Integer.Type = Type.getAsOpaquePtr();
168
815k
  }
169
170
  /// Construct a template argument that is a template.
171
  ///
172
  /// This form of template argument is generally used for template template
173
  /// parameters. However, the template name could be a dependent template
174
  /// name that ends up being instantiated to a function template whose address
175
  /// is taken.
176
  ///
177
  /// \param Name The template name.
178
305k
  TemplateArgument(TemplateName Name) {
179
305k
    TemplateArg.Kind = Template;
180
305k
    TemplateArg.Name = Name.getAsVoidPointer();
181
305k
    TemplateArg.NumExpansions = 0;
182
305k
  }
183
184
  /// Construct a template argument that is a template pack expansion.
185
  ///
186
  /// This form of template argument is generally used for template template
187
  /// parameters. However, the template name could be a dependent template
188
  /// name that ends up being instantiated to a function template whose address
189
  /// is taken.
190
  ///
191
  /// \param Name The template name.
192
  ///
193
  /// \param NumExpansions The number of expansions that will be generated by
194
  /// instantiating
195
220
  TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
196
220
    TemplateArg.Kind = TemplateExpansion;
197
220
    TemplateArg.Name = Name.getAsVoidPointer();
198
220
    if (NumExpansions)
199
4
      TemplateArg.NumExpansions = *NumExpansions + 1;
200
216
    else
201
216
      TemplateArg.NumExpansions = 0;
202
220
  }
203
204
  /// Construct a template argument that is an expression.
205
  ///
206
  /// This form of template argument only occurs in template argument
207
  /// lists used for dependent types and for expression; it will not
208
  /// occur in a non-dependent, canonical template argument list.
209
6.75M
  TemplateArgument(Expr *E) {
210
6.75M
    TypeOrValue.Kind = Expression;
211
6.75M
    TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
212
6.75M
  }
213
214
  /// Construct a template argument that is a template argument pack.
215
  ///
216
  /// We assume that storage for the template arguments provided
217
  /// outlives the TemplateArgument itself.
218
1.16M
  explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
219
1.16M
    this->Args.Kind = Pack;
220
1.16M
    this->Args.Args = Args.data();
221
1.16M
    this->Args.NumArgs = Args.size();
222
1.16M
  }
223
224
  TemplateArgument(TemplateName, bool) = delete;
225
226
42.6k
  static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
227
228
  /// Create a new template argument pack by copying the given set of
229
  /// template arguments.
230
  static TemplateArgument CreatePackCopy(ASTContext &Context,
231
                                         ArrayRef<TemplateArgument> Args);
232
233
  /// Return the kind of stored template argument.
234
453M
  ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
235
236
  /// Determine whether this template argument has no value.
237
12.1M
  bool isNull() const { return getKind() == Null; }
238
239
  TemplateArgumentDependence getDependence() const;
240
241
  /// Whether this template argument is dependent on a template
242
  /// parameter such that its result can change from one instantiation to
243
  /// another.
244
  bool isDependent() const;
245
246
  /// Whether this template argument is dependent on a template
247
  /// parameter.
248
  bool isInstantiationDependent() const;
249
250
  /// Whether this template argument contains an unexpanded
251
  /// parameter pack.
252
  bool containsUnexpandedParameterPack() const;
253
254
  /// Determine whether this template argument is a pack expansion.
255
  bool isPackExpansion() const;
256
257
  /// Retrieve the type for a type template argument.
258
137M
  QualType getAsType() const {
259
137M
    assert(getKind() == Type && "Unexpected kind");
260
137M
    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
261
137M
  }
262
263
  /// Retrieve the declaration for a declaration non-type
264
  /// template argument.
265
28.2k
  ValueDecl *getAsDecl() const {
266
28.2k
    assert(getKind() == Declaration && "Unexpected kind");
267
28.2k
    return DeclArg.D;
268
28.2k
  }
269
270
5.46k
  QualType getParamTypeForDecl() const {
271
5.46k
    assert(getKind() == Declaration && "Unexpected kind");
272
5.46k
    return QualType::getFromOpaquePtr(DeclArg.QT);
273
5.46k
  }
274
275
  /// Retrieve the type for null non-type template argument.
276
1.38k
  QualType getNullPtrType() const {
277
1.38k
    assert(getKind() == NullPtr && "Unexpected kind");
278
1.38k
    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
279
1.38k
  }
280
281
  /// Retrieve the template name for a template name argument.
282
176k
  TemplateName getAsTemplate() const {
283
176k
    assert(getKind() == Template && "Unexpected kind");
284
176k
    return TemplateName::getFromVoidPointer(TemplateArg.Name);
285
176k
  }
286
287
  /// Retrieve the template argument as a template name; if the argument
288
  /// is a pack expansion, return the pattern as a template name.
289
110k
  TemplateName getAsTemplateOrTemplatePattern() const {
290
110k
    assert((getKind() == Template || getKind() == TemplateExpansion) &&
291
110k
           "Unexpected kind");
292
110k
293
110k
    return TemplateName::getFromVoidPointer(TemplateArg.Name);
294
110k
  }
295
296
  /// Retrieve the number of expansions that a template template argument
297
  /// expansion will produce, if known.
298
  Optional<unsigned> getNumTemplateExpansions() const;
299
300
  /// Retrieve the template argument as an integral value.
301
  // FIXME: Provide a way to read the integral data without copying the value.
302
5.65M
  llvm::APSInt getAsIntegral() const {
303
5.65M
    assert(getKind() == Integral && "Unexpected kind");
304
5.65M
305
5.65M
    using namespace llvm;
306
5.65M
307
5.65M
    if (Integer.BitWidth <= 64)
308
5.65M
      return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
309
24
310
24
    unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
311
24
    return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
312
24
                  Integer.IsUnsigned);
313
24
  }
314
315
  /// Retrieve the type of the integral value.
316
6.17M
  QualType getIntegralType() const {
317
6.17M
    assert(getKind() == Integral && "Unexpected kind");
318
6.17M
    return QualType::getFromOpaquePtr(Integer.Type);
319
6.17M
  }
320
321
0
  void setIntegralType(QualType T) {
322
0
    assert(getKind() == Integral && "Unexpected kind");
323
0
    Integer.Type = T.getAsOpaquePtr();
324
0
  }
325
326
  /// If this is a non-type template argument, get its type. Otherwise,
327
  /// returns a null QualType.
328
  QualType getNonTypeTemplateArgumentType() const;
329
330
  /// Retrieve the template argument as an expression.
331
26.8M
  Expr *getAsExpr() const {
332
26.8M
    assert(getKind() == Expression && "Unexpected kind");
333
26.8M
    return reinterpret_cast<Expr *>(TypeOrValue.V);
334
26.8M
  }
335
336
  /// Iterator that traverses the elements of a template argument pack.
337
  using pack_iterator = const TemplateArgument *;
338
339
  /// Iterator referencing the first argument of a template argument
340
  /// pack.
341
2.02M
  pack_iterator pack_begin() const {
342
2.02M
    assert(getKind() == Pack);
343
2.02M
    return Args.Args;
344
2.02M
  }
345
346
  /// Iterator referencing one past the last argument of a template
347
  /// argument pack.
348
1.54M
  pack_iterator pack_end() const {
349
1.54M
    assert(getKind() == Pack);
350
1.54M
    return Args.Args + Args.NumArgs;
351
1.54M
  }
352
353
  /// Iterator range referencing all of the elements of a template
354
  /// argument pack.
355
1.15M
  ArrayRef<TemplateArgument> pack_elements() const {
356
1.15M
    return llvm::makeArrayRef(pack_begin(), pack_end());
357
1.15M
  }
358
359
  /// The number of template arguments in the given template argument
360
  /// pack.
361
2.11M
  unsigned pack_size() const {
362
2.11M
    assert(getKind() == Pack);
363
2.11M
    return Args.NumArgs;
364
2.11M
  }
365
366
  /// Return the array of arguments in this template argument pack.
367
127k
  ArrayRef<TemplateArgument> getPackAsArray() const {
368
127k
    assert(getKind() == Pack);
369
127k
    return llvm::makeArrayRef(Args.Args, Args.NumArgs);
370
127k
  }
371
372
  /// Determines whether two template arguments are superficially the
373
  /// same.
374
  bool structurallyEquals(const TemplateArgument &Other) const;
375
376
  /// When the template argument is a pack expansion, returns
377
  /// the pattern of the pack expansion.
378
  TemplateArgument getPackExpansionPattern() const;
379
380
  /// Print this template argument to the given output stream.
381
  void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
382
383
  /// Debugging aid that dumps the template argument.
384
  void dump(raw_ostream &Out) const;
385
386
  /// Debugging aid that dumps the template argument to standard error.
387
  void dump() const;
388
389
  /// Used to insert TemplateArguments into FoldingSets.
390
  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
391
};
392
393
/// Location information for a TemplateArgument.
394
struct TemplateArgumentLocInfo {
395
private:
396
  struct T {
397
    // FIXME: We'd like to just use the qualifier in the TemplateName,
398
    // but template arguments get canonicalized too quickly.
399
    NestedNameSpecifier *Qualifier;
400
    void *QualifierLocData;
401
    unsigned TemplateNameLoc;
402
    unsigned EllipsisLoc;
403
  };
404
405
  union {
406
    struct T Template;
407
    Expr *Expression;
408
    TypeSourceInfo *Declarator;
409
  };
410
411
public:
412
7.34M
  constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {}
413
414
11.6M
  TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
415
416
5.92M
  TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
417
418
  TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
419
                          SourceLocation TemplateNameLoc,
420
43.2k
                          SourceLocation EllipsisLoc) {
421
43.2k
    Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
422
43.2k
    Template.QualifierLocData = QualifierLoc.getOpaqueData();
423
43.2k
    Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
424
43.2k
    Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
425
43.2k
  }
426
427
15.6M
  TypeSourceInfo *getAsTypeSourceInfo() const {
428
15.6M
    return Declarator;
429
15.6M
  }
430
431
2.04M
  Expr *getAsExpr() const {
432
2.04M
    return Expression;
433
2.04M
  }
434
435
31.3k
  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
436
31.3k
    return NestedNameSpecifierLoc(Template.Qualifier,
437
31.3k
                                  Template.QualifierLocData);
438
31.3k
  }
439
440
92.7k
  SourceLocation getTemplateNameLoc() const {
441
92.7k
    return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
442
92.7k
  }
443
444
46
  SourceLocation getTemplateEllipsisLoc() const {
445
46
    return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
446
46
  }
447
};
448
449
/// Location wrapper for a TemplateArgument.  TemplateArgument is to
450
/// TemplateArgumentLoc as Type is to TypeLoc.
451
class TemplateArgumentLoc {
452
  TemplateArgument Argument;
453
  TemplateArgumentLocInfo LocInfo;
454
455
public:
456
7.32M
  constexpr TemplateArgumentLoc() {}
457
458
  TemplateArgumentLoc(const TemplateArgument &Argument,
459
                      TemplateArgumentLocInfo Opaque)
460
7.36M
      : Argument(Argument), LocInfo(Opaque) {}
461
462
  TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
463
9.99M
      : Argument(Argument), LocInfo(TInfo) {
464
9.99M
    assert(Argument.getKind() == TemplateArgument::Type);
465
9.99M
  }
466
467
  TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
468
5.14M
      : Argument(Argument), LocInfo(E) {
469
5.14M
470
    // Permit any kind of template argument that can be represented with an
471
    // expression.
472
5.14M
    assert(Argument.getKind() == TemplateArgument::NullPtr ||
473
5.14M
           Argument.getKind() == TemplateArgument::Integral ||
474
5.14M
           Argument.getKind() == TemplateArgument::Declaration ||
475
5.14M
           Argument.getKind() == TemplateArgument::Expression);
476
5.14M
  }
477
478
  TemplateArgumentLoc(const TemplateArgument &Argument,
479
                      NestedNameSpecifierLoc QualifierLoc,
480
                      SourceLocation TemplateNameLoc,
481
                      SourceLocation EllipsisLoc = SourceLocation())
482
      : Argument(Argument),
483
36.0k
        LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
484
36.0k
    assert(Argument.getKind() == TemplateArgument::Template ||
485
36.0k
           Argument.getKind() == TemplateArgument::TemplateExpansion);
486
36.0k
  }
487
488
  /// - Fetches the primary location of the argument.
489
50.3k
  SourceLocation getLocation() const {
490
50.3k
    if (Argument.getKind() == TemplateArgument::Template ||
491
18.2k
        Argument.getKind() == TemplateArgument::TemplateExpansion)
492
32.1k
      return getTemplateNameLoc();
493
18.2k
494
18.2k
    return getSourceRange().getBegin();
495
18.2k
  }
496
497
  /// - Fetches the full source range of the argument.
498
  SourceRange getSourceRange() const LLVM_READONLY;
499
500
71.6M
  const TemplateArgument &getArgument() const {
501
71.6M
    return Argument;
502
71.6M
  }
503
504
10.0M
  TemplateArgumentLocInfo getLocInfo() const {
505
10.0M
    return LocInfo;
506
10.0M
  }
507
508
15.1M
  TypeSourceInfo *getTypeSourceInfo() const {
509
15.1M
    assert(Argument.getKind() == TemplateArgument::Type);
510
15.1M
    return LocInfo.getAsTypeSourceInfo();
511
15.1M
  }
512
513
1.94M
  Expr *getSourceExpression() const {
514
1.94M
    assert(Argument.getKind() == TemplateArgument::Expression);
515
1.94M
    return LocInfo.getAsExpr();
516
1.94M
  }
517
518
0
  Expr *getSourceDeclExpression() const {
519
0
    assert(Argument.getKind() == TemplateArgument::Declaration);
520
0
    return LocInfo.getAsExpr();
521
0
  }
522
523
0
  Expr *getSourceNullPtrExpression() const {
524
0
    assert(Argument.getKind() == TemplateArgument::NullPtr);
525
0
    return LocInfo.getAsExpr();
526
0
  }
527
528
0
  Expr *getSourceIntegralExpression() const {
529
0
    assert(Argument.getKind() == TemplateArgument::Integral);
530
0
    return LocInfo.getAsExpr();
531
0
  }
532
533
30.5k
  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
534
30.5k
    if (Argument.getKind() != TemplateArgument::Template &&
535
38
        Argument.getKind() != TemplateArgument::TemplateExpansion)
536
0
      return NestedNameSpecifierLoc();
537
30.5k
    return LocInfo.getTemplateQualifierLoc();
538
30.5k
  }
539
540
91.9k
  SourceLocation getTemplateNameLoc() const {
541
91.9k
    if (Argument.getKind() != TemplateArgument::Template &&
542
56
        Argument.getKind() != TemplateArgument::TemplateExpansion)
543
0
      return SourceLocation();
544
91.9k
    return LocInfo.getTemplateNameLoc();
545
91.9k
  }
546
547
37
  SourceLocation getTemplateEllipsisLoc() const {
548
37
    if (Argument.getKind() != TemplateArgument::TemplateExpansion)
549
0
      return SourceLocation();
550
37
    return LocInfo.getTemplateEllipsisLoc();
551
37
  }
552
};
553
554
/// A convenient class for passing around template argument
555
/// information.  Designed to be passed by reference.
556
class TemplateArgumentListInfo {
557
  SmallVector<TemplateArgumentLoc, 8> Arguments;
558
  SourceLocation LAngleLoc;
559
  SourceLocation RAngleLoc;
560
561
public:
562
35.9M
  TemplateArgumentListInfo() = default;
563
564
  TemplateArgumentListInfo(SourceLocation LAngleLoc,
565
                           SourceLocation RAngleLoc)
566
2.81M
      : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
567
568
  // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
569
  // instead.
570
  void *operator new(size_t bytes, ASTContext &C) = delete;
571
572
918k
  SourceLocation getLAngleLoc() const { return LAngleLoc; }
573
13.6M
  SourceLocation getRAngleLoc() const { return RAngleLoc; }
574
575
4.35M
  void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
576
4.35M
  void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
577
578
19.4M
  unsigned size() const { return Arguments.size(); }
579
580
57
  const TemplateArgumentLoc *getArgumentArray() const {
581
57
    return Arguments.data();
582
57
  }
583
584
11.2M
  llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
585
11.2M
    return Arguments;
586
11.2M
  }
587
588
2.12M
  const TemplateArgumentLoc &operator[](unsigned I) const {
589
2.12M
    return Arguments[I];
590
2.12M
  }
591
592
29.7M
  TemplateArgumentLoc &operator[](unsigned I) {
593
29.7M
    return Arguments[I];
594
29.7M
  }
595
596
10.8M
  void addArgument(const TemplateArgumentLoc &Loc) {
597
10.8M
    Arguments.push_back(Loc);
598
10.8M
  }
599
};
600
601
/// Represents an explicit template argument list in C++, e.g.,
602
/// the "<int>" in "sort<int>".
603
/// This is safe to be used inside an AST node, in contrast with
604
/// TemplateArgumentListInfo.
605
struct ASTTemplateArgumentListInfo final
606
    : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
607
                                    TemplateArgumentLoc> {
608
private:
609
  friend class ASTNodeImporter;
610
  friend TrailingObjects;
611
612
  ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
613
614
public:
615
  /// The source location of the left angle bracket ('<').
616
  SourceLocation LAngleLoc;
617
618
  /// The source location of the right angle bracket ('>').
619
  SourceLocation RAngleLoc;
620
621
  /// The number of template arguments in TemplateArgs.
622
  unsigned NumTemplateArgs;
623
624
80
  SourceLocation getLAngleLoc() const { return LAngleLoc; }
625
83
  SourceLocation getRAngleLoc() const { return RAngleLoc; }
626
627
  /// Retrieve the template arguments
628
236k
  const TemplateArgumentLoc *getTemplateArgs() const {
629
236k
    return getTrailingObjects<TemplateArgumentLoc>();
630
236k
  }
631
1.89k
  unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
632
633
1.80k
  llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
634
1.80k
    return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
635
1.80k
  }
636
637
111
  const TemplateArgumentLoc &operator[](unsigned I) const {
638
111
    return getTemplateArgs()[I];
639
111
  }
640
641
  static const ASTTemplateArgumentListInfo *
642
  Create(const ASTContext &C, const TemplateArgumentListInfo &List);
643
};
644
645
/// Represents an explicit template argument list in C++, e.g.,
646
/// the "<int>" in "sort<int>".
647
///
648
/// It is intended to be used as a trailing object on AST nodes, and
649
/// as such, doesn't contain the array of TemplateArgumentLoc itself,
650
/// but expects the containing object to also provide storage for
651
/// that.
652
struct alignas(void *) ASTTemplateKWAndArgsInfo {
653
  /// The source location of the left angle bracket ('<').
654
  SourceLocation LAngleLoc;
655
656
  /// The source location of the right angle bracket ('>').
657
  SourceLocation RAngleLoc;
658
659
  /// The source location of the template keyword; this is used
660
  /// as part of the representation of qualified identifiers, such as
661
  /// S<T>::template apply<T>.  Will be empty if this expression does
662
  /// not have a template keyword.
663
  SourceLocation TemplateKWLoc;
664
665
  /// The number of template arguments in TemplateArgs.
666
  unsigned NumTemplateArgs;
667
668
  void initializeFrom(SourceLocation TemplateKWLoc,
669
                      const TemplateArgumentListInfo &List,
670
                      TemplateArgumentLoc *OutArgArray);
671
  // FIXME: The parameter Deps is the result populated by this method, the
672
  // caller doesn't need it since it is populated by computeDependence. remove
673
  // it.
674
  void initializeFrom(SourceLocation TemplateKWLoc,
675
                      const TemplateArgumentListInfo &List,
676
                      TemplateArgumentLoc *OutArgArray,
677
                      TemplateArgumentDependence &Deps);
678
  void initializeFrom(SourceLocation TemplateKWLoc);
679
680
  void copyInto(const TemplateArgumentLoc *ArgArray,
681
                TemplateArgumentListInfo &List) const;
682
};
683
684
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
685
                                    const TemplateArgument &Arg);
686
687
inline TemplateSpecializationType::iterator
688
377k
    TemplateSpecializationType::end() const {
689
377k
  return getArgs() + getNumArgs();
690
377k
}
691
692
inline DependentTemplateSpecializationType::iterator
693
0
    DependentTemplateSpecializationType::end() const {
694
0
  return getArgs() + getNumArgs();
695
0
}
696
697
inline const TemplateArgument &
698
9.43M
    TemplateSpecializationType::getArg(unsigned Idx) const {
699
9.43M
  assert(Idx < getNumArgs() && "Template argument out of range");
700
9.43M
  return getArgs()[Idx];
701
9.43M
}
702
703
inline const TemplateArgument &
704
139k
    DependentTemplateSpecializationType::getArg(unsigned Idx) const {
705
139k
  assert(Idx < getNumArgs() && "Template argument out of range");
706
139k
  return getArgs()[Idx];
707
139k
}
708
709
0
inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
710
0
  assert(Idx < getNumArgs() && "Template argument out of range");
711
0
  return getArgs()[Idx];
712
0
}
713
714
} // namespace clang
715
716
#endif // LLVM_CLANG_AST_TEMPLATEBASE_H