Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

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