Coverage Report

Created: 2018-12-11 17:59

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