Coverage Report

Created: 2022-07-16 07:03

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