Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/AST/TemplateBase.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- TemplateBase.cpp - Common template AST class implementation --------===//
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 implements common classes used throughout C++ template
10
// representations.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/AST/TemplateBase.h"
15
#include "clang/AST/ASTContext.h"
16
#include "clang/AST/Decl.h"
17
#include "clang/AST/DeclBase.h"
18
#include "clang/AST/DeclTemplate.h"
19
#include "clang/AST/DependenceFlags.h"
20
#include "clang/AST/Expr.h"
21
#include "clang/AST/ExprCXX.h"
22
#include "clang/AST/PrettyPrinter.h"
23
#include "clang/AST/TemplateName.h"
24
#include "clang/AST/Type.h"
25
#include "clang/AST/TypeLoc.h"
26
#include "clang/Basic/Diagnostic.h"
27
#include "clang/Basic/LLVM.h"
28
#include "clang/Basic/LangOptions.h"
29
#include "clang/Basic/SourceLocation.h"
30
#include "llvm/ADT/APSInt.h"
31
#include "llvm/ADT/FoldingSet.h"
32
#include "llvm/ADT/SmallString.h"
33
#include "llvm/ADT/StringExtras.h"
34
#include "llvm/ADT/StringRef.h"
35
#include "llvm/Support/Casting.h"
36
#include "llvm/Support/Compiler.h"
37
#include "llvm/Support/ErrorHandling.h"
38
#include "llvm/Support/raw_ostream.h"
39
#include <cassert>
40
#include <cstddef>
41
#include <cstdint>
42
#include <cstring>
43
#include <optional>
44
45
using namespace clang;
46
47
/// Print a template integral argument value.
48
///
49
/// \param TemplArg the TemplateArgument instance to print.
50
///
51
/// \param Out the raw_ostream instance to use for printing.
52
///
53
/// \param Policy the printing policy for EnumConstantDecl printing.
54
///
55
/// \param IncludeType If set, ensure that the type of the expression printed
56
/// matches the type of the template argument.
57
static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
58
0
                          const PrintingPolicy &Policy, bool IncludeType) {
59
0
  const Type *T = TemplArg.getIntegralType().getTypePtr();
60
0
  const llvm::APSInt &Val = TemplArg.getAsIntegral();
61
62
0
  if (Policy.UseEnumerators) {
63
0
    if (const EnumType *ET = T->getAs<EnumType>()) {
64
0
      for (const EnumConstantDecl *ECD : ET->getDecl()->enumerators()) {
65
        // In Sema::CheckTemplateArugment, enum template arguments value are
66
        // extended to the size of the integer underlying the enum type.  This
67
        // may create a size difference between the enum value and template
68
        // argument value, requiring isSameValue here instead of operator==.
69
0
        if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
70
0
          ECD->printQualifiedName(Out, Policy);
71
0
          return;
72
0
        }
73
0
      }
74
0
    }
75
0
  }
76
77
0
  if (Policy.MSVCFormatting)
78
0
    IncludeType = false;
79
80
0
  if (T->isBooleanType()) {
81
0
    if (!Policy.MSVCFormatting)
82
0
      Out << (Val.getBoolValue() ? "true" : "false");
83
0
    else
84
0
      Out << Val;
85
0
  } else if (T->isCharType()) {
86
0
    if (IncludeType) {
87
0
      if (T->isSpecificBuiltinType(BuiltinType::SChar))
88
0
        Out << "(signed char)";
89
0
      else if (T->isSpecificBuiltinType(BuiltinType::UChar))
90
0
        Out << "(unsigned char)";
91
0
    }
92
0
    CharacterLiteral::print(Val.getZExtValue(), CharacterLiteralKind::Ascii,
93
0
                            Out);
94
0
  } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
95
0
    CharacterLiteralKind Kind;
96
0
    if (T->isWideCharType())
97
0
      Kind = CharacterLiteralKind::Wide;
98
0
    else if (T->isChar8Type())
99
0
      Kind = CharacterLiteralKind::UTF8;
100
0
    else if (T->isChar16Type())
101
0
      Kind = CharacterLiteralKind::UTF16;
102
0
    else if (T->isChar32Type())
103
0
      Kind = CharacterLiteralKind::UTF32;
104
0
    else
105
0
      Kind = CharacterLiteralKind::Ascii;
106
0
    CharacterLiteral::print(Val.getExtValue(), Kind, Out);
107
0
  } else if (IncludeType) {
108
0
    if (const auto *BT = T->getAs<BuiltinType>()) {
109
0
      switch (BT->getKind()) {
110
0
      case BuiltinType::ULongLong:
111
0
        Out << Val << "ULL";
112
0
        break;
113
0
      case BuiltinType::LongLong:
114
0
        Out << Val << "LL";
115
0
        break;
116
0
      case BuiltinType::ULong:
117
0
        Out << Val << "UL";
118
0
        break;
119
0
      case BuiltinType::Long:
120
0
        Out << Val << "L";
121
0
        break;
122
0
      case BuiltinType::UInt:
123
0
        Out << Val << "U";
124
0
        break;
125
0
      case BuiltinType::Int:
126
0
        Out << Val;
127
0
        break;
128
0
      default:
129
0
        Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
130
0
            << Val;
131
0
        break;
132
0
      }
133
0
    } else
134
0
      Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
135
0
          << Val;
136
0
  } else
137
0
    Out << Val;
138
0
}
139
140
0
static unsigned getArrayDepth(QualType type) {
141
0
  unsigned count = 0;
142
0
  while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
143
0
    count++;
144
0
    type = arrayType->getElementType();
145
0
  }
146
0
  return count;
147
0
}
148
149
0
static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) {
150
  // Generally, if the parameter type is a pointer, we must be taking the
151
  // address of something and need a &.  However, if the argument is an array,
152
  // this could be implicit via array-to-pointer decay.
153
0
  if (!paramType->isPointerType())
154
0
    return paramType->isMemberPointerType();
155
0
  if (argType->isArrayType())
156
0
    return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType());
157
0
  return true;
158
0
}
159
160
//===----------------------------------------------------------------------===//
161
// TemplateArgument Implementation
162
//===----------------------------------------------------------------------===//
163
164
TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
165
0
                                   QualType Type, bool IsDefaulted) {
166
0
  Integer.Kind = Integral;
167
0
  Integer.IsDefaulted = IsDefaulted;
168
  // Copy the APSInt value into our decomposed form.
169
0
  Integer.BitWidth = Value.getBitWidth();
170
0
  Integer.IsUnsigned = Value.isUnsigned();
171
  // If the value is large, we have to get additional memory from the ASTContext
172
0
  unsigned NumWords = Value.getNumWords();
173
0
  if (NumWords > 1) {
174
0
    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
175
0
    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
176
0
    Integer.pVal = static_cast<uint64_t *>(Mem);
177
0
  } else {
178
0
    Integer.VAL = Value.getZExtValue();
179
0
  }
180
181
0
  Integer.Type = Type.getAsOpaquePtr();
182
0
}
183
184
TemplateArgument
185
TemplateArgument::CreatePackCopy(ASTContext &Context,
186
0
                                 ArrayRef<TemplateArgument> Args) {
187
0
  if (Args.empty())
188
0
    return getEmptyPack();
189
190
0
  return TemplateArgument(Args.copy(Context));
191
0
}
192
193
0
TemplateArgumentDependence TemplateArgument::getDependence() const {
194
0
  auto Deps = TemplateArgumentDependence::None;
195
0
  switch (getKind()) {
196
0
  case Null:
197
0
    llvm_unreachable("Should not have a NULL template argument");
198
199
0
  case Type:
200
0
    Deps = toTemplateArgumentDependence(getAsType()->getDependence());
201
0
    if (isa<PackExpansionType>(getAsType()))
202
0
      Deps |= TemplateArgumentDependence::Dependent;
203
0
    return Deps;
204
205
0
  case Template:
206
0
    return toTemplateArgumentDependence(getAsTemplate().getDependence());
207
208
0
  case TemplateExpansion:
209
0
    return TemplateArgumentDependence::Dependent |
210
0
           TemplateArgumentDependence::Instantiation;
211
212
0
  case Declaration: {
213
0
    auto *DC = dyn_cast<DeclContext>(getAsDecl());
214
0
    if (!DC)
215
0
      DC = getAsDecl()->getDeclContext();
216
0
    if (DC->isDependentContext())
217
0
      Deps = TemplateArgumentDependence::Dependent |
218
0
             TemplateArgumentDependence::Instantiation;
219
0
    return Deps;
220
0
  }
221
222
0
  case NullPtr:
223
0
  case Integral:
224
0
    return TemplateArgumentDependence::None;
225
226
0
  case Expression:
227
0
    Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
228
0
    if (isa<PackExpansionExpr>(getAsExpr()))
229
0
      Deps |= TemplateArgumentDependence::Dependent |
230
0
              TemplateArgumentDependence::Instantiation;
231
0
    return Deps;
232
233
0
  case Pack:
234
0
    for (const auto &P : pack_elements())
235
0
      Deps |= P.getDependence();
236
0
    return Deps;
237
0
  }
238
0
  llvm_unreachable("unhandled ArgKind");
239
0
}
240
241
0
bool TemplateArgument::isDependent() const {
242
0
  return getDependence() & TemplateArgumentDependence::Dependent;
243
0
}
244
245
0
bool TemplateArgument::isInstantiationDependent() const {
246
0
  return getDependence() & TemplateArgumentDependence::Instantiation;
247
0
}
248
249
0
bool TemplateArgument::isPackExpansion() const {
250
0
  switch (getKind()) {
251
0
  case Null:
252
0
  case Declaration:
253
0
  case Integral:
254
0
  case Pack:
255
0
  case Template:
256
0
  case NullPtr:
257
0
    return false;
258
259
0
  case TemplateExpansion:
260
0
    return true;
261
262
0
  case Type:
263
0
    return isa<PackExpansionType>(getAsType());
264
265
0
  case Expression:
266
0
    return isa<PackExpansionExpr>(getAsExpr());
267
0
  }
268
269
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
270
0
}
271
272
0
bool TemplateArgument::containsUnexpandedParameterPack() const {
273
0
  return getDependence() & TemplateArgumentDependence::UnexpandedPack;
274
0
}
275
276
0
std::optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
277
0
  assert(getKind() == TemplateExpansion);
278
0
  if (TemplateArg.NumExpansions)
279
0
    return TemplateArg.NumExpansions - 1;
280
281
0
  return std::nullopt;
282
0
}
283
284
0
QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
285
0
  switch (getKind()) {
286
0
  case TemplateArgument::Null:
287
0
  case TemplateArgument::Type:
288
0
  case TemplateArgument::Template:
289
0
  case TemplateArgument::TemplateExpansion:
290
0
  case TemplateArgument::Pack:
291
0
    return QualType();
292
293
0
  case TemplateArgument::Integral:
294
0
    return getIntegralType();
295
296
0
  case TemplateArgument::Expression:
297
0
    return getAsExpr()->getType();
298
299
0
  case TemplateArgument::Declaration:
300
0
    return getParamTypeForDecl();
301
302
0
  case TemplateArgument::NullPtr:
303
0
    return getNullPtrType();
304
0
  }
305
306
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
307
0
}
308
309
void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
310
0
                               const ASTContext &Context) const {
311
0
  ID.AddInteger(getKind());
312
0
  switch (getKind()) {
313
0
  case Null:
314
0
    break;
315
316
0
  case Type:
317
0
    getAsType().Profile(ID);
318
0
    break;
319
320
0
  case NullPtr:
321
0
    getNullPtrType().Profile(ID);
322
0
    break;
323
324
0
  case Declaration:
325
0
    getParamTypeForDecl().Profile(ID);
326
0
    ID.AddPointer(getAsDecl());
327
0
    break;
328
329
0
  case TemplateExpansion:
330
0
    ID.AddInteger(TemplateArg.NumExpansions);
331
0
    [[fallthrough]];
332
0
  case Template:
333
0
    ID.AddPointer(TemplateArg.Name);
334
0
    break;
335
336
0
  case Integral:
337
0
    getAsIntegral().Profile(ID);
338
0
    getIntegralType().Profile(ID);
339
0
    break;
340
341
0
  case Expression:
342
0
    getAsExpr()->Profile(ID, Context, true);
343
0
    break;
344
345
0
  case Pack:
346
0
    ID.AddInteger(Args.NumArgs);
347
0
    for (unsigned I = 0; I != Args.NumArgs; ++I)
348
0
      Args.Args[I].Profile(ID, Context);
349
0
  }
350
0
}
351
352
0
bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
353
0
  if (getKind() != Other.getKind()) return false;
354
355
0
  switch (getKind()) {
356
0
  case Null:
357
0
  case Type:
358
0
  case Expression:
359
0
  case NullPtr:
360
0
    return TypeOrValue.V == Other.TypeOrValue.V;
361
362
0
  case Template:
363
0
  case TemplateExpansion:
364
0
    return TemplateArg.Name == Other.TemplateArg.Name &&
365
0
           TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
366
367
0
  case Declaration:
368
0
    return getAsDecl() == Other.getAsDecl() &&
369
0
           getParamTypeForDecl() == Other.getParamTypeForDecl();
370
371
0
  case Integral:
372
0
    return getIntegralType() == Other.getIntegralType() &&
373
0
           getAsIntegral() == Other.getAsIntegral();
374
375
0
  case Pack:
376
0
    if (Args.NumArgs != Other.Args.NumArgs) return false;
377
0
    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
378
0
      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
379
0
        return false;
380
0
    return true;
381
0
  }
382
383
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
384
0
}
385
386
0
TemplateArgument TemplateArgument::getPackExpansionPattern() const {
387
0
  assert(isPackExpansion());
388
389
0
  switch (getKind()) {
390
0
  case Type:
391
0
    return getAsType()->castAs<PackExpansionType>()->getPattern();
392
393
0
  case Expression:
394
0
    return cast<PackExpansionExpr>(getAsExpr())->getPattern();
395
396
0
  case TemplateExpansion:
397
0
    return TemplateArgument(getAsTemplateOrTemplatePattern());
398
399
0
  case Declaration:
400
0
  case Integral:
401
0
  case Pack:
402
0
  case Null:
403
0
  case Template:
404
0
  case NullPtr:
405
0
    return TemplateArgument();
406
0
  }
407
408
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
409
0
}
410
411
void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
412
0
                             bool IncludeType) const {
413
414
0
  switch (getKind()) {
415
0
  case Null:
416
0
    Out << "(no value)";
417
0
    break;
418
419
0
  case Type: {
420
0
    PrintingPolicy SubPolicy(Policy);
421
0
    SubPolicy.SuppressStrongLifetime = true;
422
0
    getAsType().print(Out, SubPolicy);
423
0
    break;
424
0
  }
425
426
0
  case Declaration: {
427
0
    NamedDecl *ND = getAsDecl();
428
0
    if (getParamTypeForDecl()->isRecordType()) {
429
0
      if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
430
0
        TPO->getType().getUnqualifiedType().print(Out, Policy);
431
0
        TPO->printAsInit(Out, Policy);
432
0
        break;
433
0
      }
434
0
    }
435
0
    if (auto *VD = dyn_cast<ValueDecl>(ND)) {
436
0
      if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType()))
437
0
        Out << "&";
438
0
    }
439
0
    ND->printQualifiedName(Out);
440
0
    break;
441
0
  }
442
443
0
  case NullPtr:
444
    // FIXME: Include the type if it's not obvious from the context.
445
0
    Out << "nullptr";
446
0
    break;
447
448
0
  case Template:
449
0
    getAsTemplate().print(Out, Policy, TemplateName::Qualified::Fully);
450
0
    break;
451
452
0
  case TemplateExpansion:
453
0
    getAsTemplateOrTemplatePattern().print(Out, Policy);
454
0
    Out << "...";
455
0
    break;
456
457
0
  case Integral:
458
0
    printIntegral(*this, Out, Policy, IncludeType);
459
0
    break;
460
461
0
  case Expression:
462
0
    getAsExpr()->printPretty(Out, nullptr, Policy);
463
0
    break;
464
465
0
  case Pack:
466
0
    Out << "<";
467
0
    bool First = true;
468
0
    for (const auto &P : pack_elements()) {
469
0
      if (First)
470
0
        First = false;
471
0
      else
472
0
        Out << ", ";
473
474
0
      P.print(Policy, Out, IncludeType);
475
0
    }
476
0
    Out << ">";
477
0
    break;
478
0
  }
479
0
}
480
481
0
void TemplateArgument::dump(raw_ostream &Out) const {
482
0
  LangOptions LO; // FIXME! see also TemplateName::dump().
483
0
  LO.CPlusPlus = true;
484
0
  LO.Bool = true;
485
0
  print(PrintingPolicy(LO), Out, /*IncludeType*/ true);
486
0
}
487
488
0
LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
489
490
//===----------------------------------------------------------------------===//
491
// TemplateArgumentLoc Implementation
492
//===----------------------------------------------------------------------===//
493
494
0
SourceRange TemplateArgumentLoc::getSourceRange() const {
495
0
  switch (Argument.getKind()) {
496
0
  case TemplateArgument::Expression:
497
0
    return getSourceExpression()->getSourceRange();
498
499
0
  case TemplateArgument::Declaration:
500
0
    return getSourceDeclExpression()->getSourceRange();
501
502
0
  case TemplateArgument::NullPtr:
503
0
    return getSourceNullPtrExpression()->getSourceRange();
504
505
0
  case TemplateArgument::Type:
506
0
    if (TypeSourceInfo *TSI = getTypeSourceInfo())
507
0
      return TSI->getTypeLoc().getSourceRange();
508
0
    else
509
0
      return SourceRange();
510
511
0
  case TemplateArgument::Template:
512
0
    if (getTemplateQualifierLoc())
513
0
      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
514
0
                         getTemplateNameLoc());
515
0
    return SourceRange(getTemplateNameLoc());
516
517
0
  case TemplateArgument::TemplateExpansion:
518
0
    if (getTemplateQualifierLoc())
519
0
      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
520
0
                         getTemplateEllipsisLoc());
521
0
    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
522
523
0
  case TemplateArgument::Integral:
524
0
    return getSourceIntegralExpression()->getSourceRange();
525
526
0
  case TemplateArgument::Pack:
527
0
  case TemplateArgument::Null:
528
0
    return SourceRange();
529
0
  }
530
531
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
532
0
}
533
534
template <typename T>
535
0
static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
536
0
  switch (Arg.getKind()) {
537
0
  case TemplateArgument::Null:
538
    // This is bad, but not as bad as crashing because of argument
539
    // count mismatches.
540
0
    return DB << "(null template argument)";
541
542
0
  case TemplateArgument::Type:
543
0
    return DB << Arg.getAsType();
544
545
0
  case TemplateArgument::Declaration:
546
0
    return DB << Arg.getAsDecl();
547
548
0
  case TemplateArgument::NullPtr:
549
0
    return DB << "nullptr";
550
551
0
  case TemplateArgument::Integral:
552
0
    return DB << toString(Arg.getAsIntegral(), 10);
553
554
0
  case TemplateArgument::Template:
555
0
    return DB << Arg.getAsTemplate();
556
557
0
  case TemplateArgument::TemplateExpansion:
558
0
    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
559
560
0
  case TemplateArgument::Expression: {
561
    // This shouldn't actually ever happen, so it's okay that we're
562
    // regurgitating an expression here.
563
    // FIXME: We're guessing at LangOptions!
564
0
    SmallString<32> Str;
565
0
    llvm::raw_svector_ostream OS(Str);
566
0
    LangOptions LangOpts;
567
0
    LangOpts.CPlusPlus = true;
568
0
    PrintingPolicy Policy(LangOpts);
569
0
    Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
570
0
    return DB << OS.str();
571
0
  }
572
573
0
  case TemplateArgument::Pack: {
574
    // FIXME: We're guessing at LangOptions!
575
0
    SmallString<32> Str;
576
0
    llvm::raw_svector_ostream OS(Str);
577
0
    LangOptions LangOpts;
578
0
    LangOpts.CPlusPlus = true;
579
0
    PrintingPolicy Policy(LangOpts);
580
0
    Arg.print(Policy, OS, /*IncludeType*/ true);
581
0
    return DB << OS.str();
582
0
  }
583
0
  }
584
585
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
586
0
}
587
588
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
589
0
                                             const TemplateArgument &Arg) {
590
0
  return DiagTemplateArg(DB, Arg);
591
0
}
592
593
clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
594
    ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
595
0
    SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
596
0
  TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
597
0
  Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
598
0
  Template->QualifierLocData = QualifierLoc.getOpaqueData();
599
0
  Template->TemplateNameLoc = TemplateNameLoc;
600
0
  Template->EllipsisLoc = EllipsisLoc;
601
0
  Pointer = Template;
602
0
}
603
604
const ASTTemplateArgumentListInfo *
605
ASTTemplateArgumentListInfo::Create(const ASTContext &C,
606
0
                                    const TemplateArgumentListInfo &List) {
607
0
  std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
608
0
  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
609
0
  return new (Mem) ASTTemplateArgumentListInfo(List);
610
0
}
611
612
const ASTTemplateArgumentListInfo *
613
ASTTemplateArgumentListInfo::Create(const ASTContext &C,
614
0
                                    const ASTTemplateArgumentListInfo *List) {
615
0
  if (!List)
616
0
    return nullptr;
617
0
  std::size_t size =
618
0
      totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
619
0
  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
620
0
  return new (Mem) ASTTemplateArgumentListInfo(List);
621
0
}
622
623
ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
624
0
    const TemplateArgumentListInfo &Info) {
625
0
  LAngleLoc = Info.getLAngleLoc();
626
0
  RAngleLoc = Info.getRAngleLoc();
627
0
  NumTemplateArgs = Info.size();
628
629
0
  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
630
0
  for (unsigned i = 0; i != NumTemplateArgs; ++i)
631
0
    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
632
0
}
633
634
ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
635
0
    const ASTTemplateArgumentListInfo *Info) {
636
0
  LAngleLoc = Info->getLAngleLoc();
637
0
  RAngleLoc = Info->getRAngleLoc();
638
0
  NumTemplateArgs = Info->getNumTemplateArgs();
639
640
0
  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
641
0
  for (unsigned i = 0; i != NumTemplateArgs; ++i)
642
0
    new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
643
0
}
644
645
void ASTTemplateKWAndArgsInfo::initializeFrom(
646
    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
647
0
    TemplateArgumentLoc *OutArgArray) {
648
0
  this->TemplateKWLoc = TemplateKWLoc;
649
0
  LAngleLoc = Info.getLAngleLoc();
650
0
  RAngleLoc = Info.getRAngleLoc();
651
0
  NumTemplateArgs = Info.size();
652
653
0
  for (unsigned i = 0; i != NumTemplateArgs; ++i)
654
0
    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
655
0
}
656
657
0
void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
658
0
  assert(TemplateKWLoc.isValid());
659
0
  LAngleLoc = SourceLocation();
660
0
  RAngleLoc = SourceLocation();
661
0
  this->TemplateKWLoc = TemplateKWLoc;
662
0
  NumTemplateArgs = 0;
663
0
}
664
665
void ASTTemplateKWAndArgsInfo::initializeFrom(
666
    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
667
0
    TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
668
0
  this->TemplateKWLoc = TemplateKWLoc;
669
0
  LAngleLoc = Info.getLAngleLoc();
670
0
  RAngleLoc = Info.getRAngleLoc();
671
0
  NumTemplateArgs = Info.size();
672
673
0
  for (unsigned i = 0; i != NumTemplateArgs; ++i) {
674
0
    Deps |= Info[i].getArgument().getDependence();
675
676
0
    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
677
0
  }
678
0
}
679
680
void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
681
0
                                        TemplateArgumentListInfo &Info) const {
682
0
  Info.setLAngleLoc(LAngleLoc);
683
0
  Info.setRAngleLoc(RAngleLoc);
684
0
  for (unsigned I = 0; I != NumTemplateArgs; ++I)
685
0
    Info.addArgument(ArgArray[I]);
686
0
}