Coverage Report

Created: 2019-03-22 08:08

/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
// 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/NestedNameSpecifier.h"
18
#include "clang/AST/TemplateName.h"
19
#include "clang/AST/Type.h"
20
#include "clang/Basic/LLVM.h"
21
#include "clang/Basic/SourceLocation.h"
22
#include "llvm/ADT/APInt.h"
23
#include "llvm/ADT/APSInt.h"
24
#include "llvm/ADT/ArrayRef.h"
25
#include "llvm/ADT/None.h"
26
#include "llvm/ADT/Optional.h"
27
#include "llvm/ADT/SmallVector.h"
28
#include "llvm/Support/Compiler.h"
29
#include "llvm/Support/TrailingObjects.h"
30
#include <cassert>
31
#include <cstddef>
32
#include <cstdint>
33
34
namespace llvm {
35
36
class FoldingSetNodeID;
37
38
} // namespace llvm
39
40
namespace clang {
41
42
class ASTContext;
43
class DiagnosticBuilder;
44
class Expr;
45
struct PrintingPolicy;
46
class TypeSourceInfo;
47
class ValueDecl;
48
49
/// Represents a template argument.
50
0
class TemplateArgument {
51
public:
52
  /// The kind of template argument we're storing.
53
  enum ArgKind {
54
    /// Represents an empty template argument, e.g., one that has not
55
    /// been deduced.
56
    Null = 0,
57
58
    /// The template argument is a type.
59
    Type,
60
61
    /// The template argument is a declaration that was provided for a pointer,
62
    /// reference, or pointer to member non-type template parameter.
63
    Declaration,
64
65
    /// The template argument is a null pointer or null pointer to member that
66
    /// was provided for a non-type template parameter.
67
    NullPtr,
68
69
    /// The template argument is an integral value stored in an llvm::APSInt
70
    /// that was provided for an integral non-type template parameter.
71
    Integral,
72
73
    /// The template argument is a template name that was provided for a
74
    /// template template parameter.
75
    Template,
76
77
    /// The template argument is a pack expansion of a template name that was
78
    /// provided for a template template parameter.
79
    TemplateExpansion,
80
81
    /// The template argument is an expression, and we've not resolved it to one
82
    /// of the other forms yet, either because it's dependent or because we're
83
    /// representing a non-canonical template argument (for instance, in a
84
    /// TemplateSpecializationType). Also used to represent a non-dependent
85
    /// __uuidof expression (a Microsoft extension).
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
0
  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
0
  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
26.6M
  constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
142
143
  /// Construct a template type argument.
144
36.1M
  TemplateArgument(QualType T, bool isNullPtr = false) {
145
36.1M
    TypeOrValue.Kind = isNullPtr ? 
NullPtr343
:
Type36.1M
;
146
36.1M
    TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
147
36.1M
  }
148
149
  /// Construct a template argument that refers to a
150
  /// declaration, which is either an external declaration or a
151
  /// template declaration.
152
4.33k
  TemplateArgument(ValueDecl *D, QualType QT) {
153
4.33k
    assert(D && "Expected decl");
154
4.33k
    DeclArg.Kind = Declaration;
155
4.33k
    DeclArg.QT = QT.getAsOpaquePtr();
156
4.33k
    DeclArg.D = D;
157
4.33k
  }
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
448k
  TemplateArgument(const TemplateArgument &Other, QualType Type) {
166
448k
    Integer = Other.Integer;
167
448k
    Integer.Type = Type.getAsOpaquePtr();
168
448k
  }
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
998k
  TemplateArgument(TemplateName Name) {
179
998k
    TemplateArg.Kind = Template;
180
998k
    TemplateArg.Name = Name.getAsVoidPointer();
181
998k
    TemplateArg.NumExpansions = 0;
182
998k
  }
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
177
  TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
196
177
    TemplateArg.Kind = TemplateExpansion;
197
177
    TemplateArg.Name = Name.getAsVoidPointer();
198
177
    if (NumExpansions)
199
4
      TemplateArg.NumExpansions = *NumExpansions + 1;
200
173
    else
201
173
      TemplateArg.NumExpansions = 0;
202
177
  }
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
5.21M
  TemplateArgument(Expr *E) {
210
5.21M
    TypeOrValue.Kind = Expression;
211
5.21M
    TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
212
5.21M
  }
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
892k
  explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
219
892k
    this->Args.Kind = Pack;
220
892k
    this->Args.Args = Args.data();
221
892k
    this->Args.NumArgs = Args.size();
222
892k
  }
223
224
  TemplateArgument(TemplateName, bool) = delete;
225
226
73.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
230M
  ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
235
236
  /// Determine whether this template argument has no value.
237
14.5M
  bool isNull() const { return getKind() == Null; }
238
239
  /// Whether this template argument is dependent on a template
240
  /// parameter such that its result can change from one instantiation to
241
  /// another.
242
  bool isDependent() const;
243
244
  /// Whether this template argument is dependent on a template
245
  /// parameter.
246
  bool isInstantiationDependent() const;
247
248
  /// Whether this template argument contains an unexpanded
249
  /// parameter pack.
250
  bool containsUnexpandedParameterPack() const;
251
252
  /// Determine whether this template argument is a pack expansion.
253
  bool isPackExpansion() const;
254
255
  /// Retrieve the type for a type template argument.
256
133M
  QualType getAsType() const {
257
133M
    assert(getKind() == Type && "Unexpected kind");
258
133M
    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
259
133M
  }
260
261
  /// Retrieve the declaration for a declaration non-type
262
  /// template argument.
263
24.5k
  ValueDecl *getAsDecl() const {
264
24.5k
    assert(getKind() == Declaration && "Unexpected kind");
265
24.5k
    return DeclArg.D;
266
24.5k
  }
267
268
4.52k
  QualType getParamTypeForDecl() const {
269
4.52k
    assert(getKind() == Declaration && "Unexpected kind");
270
4.52k
    return QualType::getFromOpaquePtr(DeclArg.QT);
271
4.52k
  }
272
273
  /// Retrieve the type for null non-type template argument.
274
914
  QualType getNullPtrType() const {
275
914
    assert(getKind() == NullPtr && "Unexpected kind");
276
914
    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
277
914
  }
278
279
  /// Retrieve the template name for a template name argument.
280
166k
  TemplateName getAsTemplate() const {
281
166k
    assert(getKind() == Template && "Unexpected kind");
282
166k
    return TemplateName::getFromVoidPointer(TemplateArg.Name);
283
166k
  }
284
285
  /// Retrieve the template argument as a template name; if the argument
286
  /// is a pack expansion, return the pattern as a template name.
287
61.3k
  TemplateName getAsTemplateOrTemplatePattern() const {
288
61.3k
    assert((getKind() == Template || getKind() == TemplateExpansion) &&
289
61.3k
           "Unexpected kind");
290
61.3k
291
61.3k
    return TemplateName::getFromVoidPointer(TemplateArg.Name);
292
61.3k
  }
293
294
  /// Retrieve the number of expansions that a template template argument
295
  /// expansion will produce, if known.
296
  Optional<unsigned> getNumTemplateExpansions() const;
297
298
  /// Retrieve the template argument as an integral value.
299
  // FIXME: Provide a way to read the integral data without copying the value.
300
4.64M
  llvm::APSInt getAsIntegral() const {
301
4.64M
    assert(getKind() == Integral && "Unexpected kind");
302
4.64M
303
4.64M
    using namespace llvm;
304
4.64M
305
4.64M
    if (Integer.BitWidth <= 64)
306
4.64M
      return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
307
0
308
0
    unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
309
0
    return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
310
0
                  Integer.IsUnsigned);
311
0
  }
312
313
  /// Retrieve the type of the integral value.
314
4.31M
  QualType getIntegralType() const {
315
4.31M
    assert(getKind() == Integral && "Unexpected kind");
316
4.31M
    return QualType::getFromOpaquePtr(Integer.Type);
317
4.31M
  }
318
319
0
  void setIntegralType(QualType T) {
320
0
    assert(getKind() == Integral && "Unexpected kind");
321
0
    Integer.Type = T.getAsOpaquePtr();
322
0
  }
323
324
  /// If this is a non-type template argument, get its type. Otherwise,
325
  /// returns a null QualType.
326
  QualType getNonTypeTemplateArgumentType() const;
327
328
  /// Retrieve the template argument as an expression.
329
21.3M
  Expr *getAsExpr() const {
330
21.3M
    assert(getKind() == Expression && "Unexpected kind");
331
21.3M
    return reinterpret_cast<Expr *>(TypeOrValue.V);
332
21.3M
  }
333
334
  /// Iterator that traverses the elements of a template argument pack.
335
  using pack_iterator = const TemplateArgument *;
336
337
  /// Iterator referencing the first argument of a template argument
338
  /// pack.
339
1.72M
  pack_iterator pack_begin() const {
340
1.72M
    assert(getKind() == Pack);
341
1.72M
    return Args.Args;
342
1.72M
  }
343
344
  /// Iterator referencing one past the last argument of a template
345
  /// argument pack.
346
1.30M
  pack_iterator pack_end() const {
347
1.30M
    assert(getKind() == Pack);
348
1.30M
    return Args.Args + Args.NumArgs;
349
1.30M
  }
350
351
  /// Iterator range referencing all of the elements of a template
352
  /// argument pack.
353
995k
  ArrayRef<TemplateArgument> pack_elements() const {
354
995k
    return llvm::makeArrayRef(pack_begin(), pack_end());
355
995k
  }
356
357
  /// The number of template arguments in the given template argument
358
  /// pack.
359
1.20M
  unsigned pack_size() const {
360
1.20M
    assert(getKind() == Pack);
361
1.20M
    return Args.NumArgs;
362
1.20M
  }
363
364
  /// Return the array of arguments in this template argument pack.
365
49.7k
  ArrayRef<TemplateArgument> getPackAsArray() const {
366
49.7k
    assert(getKind() == Pack);
367
49.7k
    return llvm::makeArrayRef(Args.Args, Args.NumArgs);
368
49.7k
  }
369
370
  /// Determines whether two template arguments are superficially the
371
  /// same.
372
  bool structurallyEquals(const TemplateArgument &Other) const;
373
374
  /// When the template argument is a pack expansion, returns
375
  /// the pattern of the pack expansion.
376
  TemplateArgument getPackExpansionPattern() const;
377
378
  /// Print this template argument to the given output stream.
379
  void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
380
381
  /// Debugging aid that dumps the template argument.
382
  void dump(raw_ostream &Out) const;
383
384
  /// Debugging aid that dumps the template argument to standard error.
385
  void dump() const;
386
387
  /// Used to insert TemplateArguments into FoldingSets.
388
  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
389
};
390
391
/// Location information for a TemplateArgument.
392
0
struct TemplateArgumentLocInfo {
393
private:
394
  struct T {
395
    // FIXME: We'd like to just use the qualifier in the TemplateName,
396
    // but template arguments get canonicalized too quickly.
397
    NestedNameSpecifier *Qualifier;
398
    void *QualifierLocData;
399
    unsigned TemplateNameLoc;
400
    unsigned EllipsisLoc;
401
  };
402
403
0
  union {
404
    struct T Template;
405
    Expr *Expression;
406
    TypeSourceInfo *Declarator;
407
  };
408
409
public:
410
7.24M
  constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {}
411
412
11.1M
  TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
413
414
4.24M
  TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
415
416
  TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
417
                          SourceLocation TemplateNameLoc,
418
30.0k
                          SourceLocation EllipsisLoc) {
419
30.0k
    Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
420
30.0k
    Template.QualifierLocData = QualifierLoc.getOpaqueData();
421
30.0k
    Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
422
30.0k
    Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
423
30.0k
  }
424
425
16.2M
  TypeSourceInfo *getAsTypeSourceInfo() const {
426
16.2M
    return Declarator;
427
16.2M
  }
428
429
1.51M
  Expr *getAsExpr() const {
430
1.51M
    return Expression;
431
1.51M
  }
432
433
22.8k
  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
434
22.8k
    return NestedNameSpecifierLoc(Template.Qualifier,
435
22.8k
                                  Template.QualifierLocData);
436
22.8k
  }
437
438
70.7k
  SourceLocation getTemplateNameLoc() const {
439
70.7k
    return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
440
70.7k
  }
441
442
29
  SourceLocation getTemplateEllipsisLoc() const {
443
29
    return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
444
29
  }
445
};
446
447
/// Location wrapper for a TemplateArgument.  TemplateArgument is to
448
/// TemplateArgumentLoc as Type is to TypeLoc.
449
class TemplateArgumentLoc {
450
  TemplateArgument Argument;
451
  TemplateArgumentLocInfo LocInfo;
452
453
public:
454
7.23M
  constexpr TemplateArgumentLoc() {}
455
456
  TemplateArgumentLoc(const TemplateArgument &Argument,
457
                      TemplateArgumentLocInfo Opaque)
458
5.83M
      : Argument(Argument), LocInfo(Opaque) {}
459
460
  TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
461
10.8M
      : Argument(Argument), LocInfo(TInfo) {
462
10.8M
    assert(Argument.getKind() == TemplateArgument::Type);
463
10.8M
  }
464
465
  TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
466
4.03M
      : Argument(Argument), LocInfo(E) {
467
4.03M
468
4.03M
    // Permit any kind of template argument that can be represented with an
469
4.03M
    // expression.
470
4.03M
    assert(Argument.getKind() == TemplateArgument::NullPtr ||
471
4.03M
           Argument.getKind() == TemplateArgument::Integral ||
472
4.03M
           Argument.getKind() == TemplateArgument::Declaration ||
473
4.03M
           Argument.getKind() == TemplateArgument::Expression);
474
4.03M
  }
475
476
  TemplateArgumentLoc(const TemplateArgument &Argument,
477
                      NestedNameSpecifierLoc QualifierLoc,
478
                      SourceLocation TemplateNameLoc,
479
                      SourceLocation EllipsisLoc = SourceLocation())
480
      : Argument(Argument),
481
26.3k
        LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
482
26.3k
    assert(Argument.getKind() == TemplateArgument::Template ||
483
26.3k
           Argument.getKind() == TemplateArgument::TemplateExpansion);
484
26.3k
  }
485
486
  /// - Fetches the primary location of the argument.
487
43.5k
  SourceLocation getLocation() const {
488
43.5k
    if (Argument.getKind() == TemplateArgument::Template ||
489
43.5k
        
Argument.getKind() == TemplateArgument::TemplateExpansion17.7k
)
490
25.7k
      return getTemplateNameLoc();
491
17.7k
492
17.7k
    return getSourceRange().getBegin();
493
17.7k
  }
494
495
  /// - Fetches the full source range of the argument.
496
  SourceRange getSourceRange() const LLVM_READONLY;
497
498
73.1M
  const TemplateArgument &getArgument() const {
499
73.1M
    return Argument;
500
73.1M
  }
501
502
9.65M
  TemplateArgumentLocInfo getLocInfo() const {
503
9.65M
    return LocInfo;
504
9.65M
  }
505
506
16.2M
  TypeSourceInfo *getTypeSourceInfo() const {
507
16.2M
    assert(Argument.getKind() == TemplateArgument::Type);
508
16.2M
    return LocInfo.getAsTypeSourceInfo();
509
16.2M
  }
510
511
1.50M
  Expr *getSourceExpression() const {
512
1.50M
    assert(Argument.getKind() == TemplateArgument::Expression);
513
1.50M
    return LocInfo.getAsExpr();
514
1.50M
  }
515
516
0
  Expr *getSourceDeclExpression() const {
517
0
    assert(Argument.getKind() == TemplateArgument::Declaration);
518
0
    return LocInfo.getAsExpr();
519
0
  }
520
521
0
  Expr *getSourceNullPtrExpression() const {
522
0
    assert(Argument.getKind() == TemplateArgument::NullPtr);
523
0
    return LocInfo.getAsExpr();
524
0
  }
525
526
0
  Expr *getSourceIntegralExpression() const {
527
0
    assert(Argument.getKind() == TemplateArgument::Integral);
528
0
    return LocInfo.getAsExpr();
529
0
  }
530
531
22.6k
  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
532
22.6k
    if (Argument.getKind() != TemplateArgument::Template &&
533
22.6k
        
Argument.getKind() != TemplateArgument::TemplateExpansion30
)
534
0
      return NestedNameSpecifierLoc();
535
22.6k
    return LocInfo.getTemplateQualifierLoc();
536
22.6k
  }
537
538
70.6k
  SourceLocation getTemplateNameLoc() const {
539
70.6k
    if (Argument.getKind() != TemplateArgument::Template &&
540
70.6k
        
Argument.getKind() != TemplateArgument::TemplateExpansion47
)
541
0
      return SourceLocation();
542
70.6k
    return LocInfo.getTemplateNameLoc();
543
70.6k
  }
544
545
29
  SourceLocation getTemplateEllipsisLoc() const {
546
29
    if (Argument.getKind() != TemplateArgument::TemplateExpansion)
547
0
      return SourceLocation();
548
29
    return LocInfo.getTemplateEllipsisLoc();
549
29
  }
550
};
551
552
/// A convenient class for passing around template argument
553
/// information.  Designed to be passed by reference.
554
class TemplateArgumentListInfo {
555
  SmallVector<TemplateArgumentLoc, 8> Arguments;
556
  SourceLocation LAngleLoc;
557
  SourceLocation RAngleLoc;
558
559
public:
560
29.9M
  TemplateArgumentListInfo() = default;
561
562
  TemplateArgumentListInfo(SourceLocation LAngleLoc,
563
                           SourceLocation RAngleLoc)
564
2.94M
      : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
565
566
  // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
567
  // instead.
568
  void *operator new(size_t bytes, ASTContext &C) = delete;
569
570
1.08M
  SourceLocation getLAngleLoc() const { return LAngleLoc; }
571
7.76M
  SourceLocation getRAngleLoc() const { return RAngleLoc; }
572
573
4.31M
  void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
574
4.31M
  void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
575
576
20.0M
  unsigned size() const { return Arguments.size(); }
577
578
15
  const TemplateArgumentLoc *getArgumentArray() const {
579
15
    return Arguments.data();
580
15
  }
581
582
11.7M
  llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
583
11.7M
    return Arguments;
584
11.7M
  }
585
586
3.82M
  const TemplateArgumentLoc &operator[](unsigned I) const {
587
3.82M
    return Arguments[I];
588
3.82M
  }
589
590
30.8M
  TemplateArgumentLoc &operator[](unsigned I) {
591
30.8M
    return Arguments[I];
592
30.8M
  }
593
594
11.3M
  void addArgument(const TemplateArgumentLoc &Loc) {
595
11.3M
    Arguments.push_back(Loc);
596
11.3M
  }
597
};
598
599
/// Represents an explicit template argument list in C++, e.g.,
600
/// the "<int>" in "sort<int>".
601
/// This is safe to be used inside an AST node, in contrast with
602
/// TemplateArgumentListInfo.
603
struct ASTTemplateArgumentListInfo final
604
    : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
605
                                    TemplateArgumentLoc> {
606
private:
607
  friend class ASTNodeImporter;
608
  friend TrailingObjects;
609
610
  ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
611
612
public:
613
  /// The source location of the left angle bracket ('<').
614
  SourceLocation LAngleLoc;
615
616
  /// The source location of the right angle bracket ('>').
617
  SourceLocation RAngleLoc;
618
619
  /// The number of template arguments in TemplateArgs.
620
  unsigned NumTemplateArgs;
621
622
2
  SourceLocation getLAngleLoc() const { return LAngleLoc; }
623
2
  SourceLocation getRAngleLoc() const { return RAngleLoc; }
624
625
  /// Retrieve the template arguments
626
279k
  const TemplateArgumentLoc *getTemplateArgs() const {
627
279k
    return getTrailingObjects<TemplateArgumentLoc>();
628
279k
  }
629
218
  unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
630
631
216
  llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
632
216
    return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
633
216
  }
634
635
55
  const TemplateArgumentLoc &operator[](unsigned I) const {
636
55
    return getTemplateArgs()[I];
637
55
  }
638
639
  static const ASTTemplateArgumentListInfo *
640
  Create(ASTContext &C, const TemplateArgumentListInfo &List);
641
};
642
643
/// Represents an explicit template argument list in C++, e.g.,
644
/// the "<int>" in "sort<int>".
645
///
646
/// It is intended to be used as a trailing object on AST nodes, and
647
/// as such, doesn't contain the array of TemplateArgumentLoc itself,
648
/// but expects the containing object to also provide storage for
649
/// that.
650
struct alignas(void *) ASTTemplateKWAndArgsInfo {
651
  /// The source location of the left angle bracket ('<').
652
  SourceLocation LAngleLoc;
653
654
  /// The source location of the right angle bracket ('>').
655
  SourceLocation RAngleLoc;
656
657
  /// The source location of the template keyword; this is used
658
  /// as part of the representation of qualified identifiers, such as
659
  /// S<T>::template apply<T>.  Will be empty if this expression does
660
  /// not have a template keyword.
661
  SourceLocation TemplateKWLoc;
662
663
  /// The number of template arguments in TemplateArgs.
664
  unsigned NumTemplateArgs;
665
666
  void initializeFrom(SourceLocation TemplateKWLoc,
667
                      const TemplateArgumentListInfo &List,
668
                      TemplateArgumentLoc *OutArgArray);
669
  void initializeFrom(SourceLocation TemplateKWLoc,
670
                      const TemplateArgumentListInfo &List,
671
                      TemplateArgumentLoc *OutArgArray, bool &Dependent,
672
                      bool &InstantiationDependent,
673
                      bool &ContainsUnexpandedParameterPack);
674
  void initializeFrom(SourceLocation TemplateKWLoc);
675
676
  void copyInto(const TemplateArgumentLoc *ArgArray,
677
                TemplateArgumentListInfo &List) const;
678
};
679
680
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
681
                                    const TemplateArgument &Arg);
682
683
inline TemplateSpecializationType::iterator
684
147k
    TemplateSpecializationType::end() const {
685
147k
  return getArgs() + getNumArgs();
686
147k
}
687
688
inline DependentTemplateSpecializationType::iterator
689
7
    DependentTemplateSpecializationType::end() const {
690
7
  return getArgs() + getNumArgs();
691
7
}
692
693
inline const TemplateArgument &
694
7.93M
    TemplateSpecializationType::getArg(unsigned Idx) const {
695
7.93M
  assert(Idx < getNumArgs() && "Template argument out of range");
696
7.93M
  return getArgs()[Idx];
697
7.93M
}
698
699
inline const TemplateArgument &
700
20.9k
    DependentTemplateSpecializationType::getArg(unsigned Idx) const {
701
20.9k
  assert(Idx < getNumArgs() && "Template argument out of range");
702
20.9k
  return getArgs()[Idx];
703
20.9k
}
704
705
} // namespace clang
706
707
#endif // LLVM_CLANG_AST_TEMPLATEBASE_H