Coverage Report

Created: 2020-11-24 06:42

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