Coverage Report

Created: 2021-01-26 06:56

/Users/buildslave/jenkins/workspace/coverage/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/None.h"
33
#include "llvm/ADT/SmallString.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
44
using namespace clang;
45
46
/// Print a template integral argument value.
47
///
48
/// \param TemplArg the TemplateArgument instance to print.
49
///
50
/// \param Out the raw_ostream instance to use for printing.
51
///
52
/// \param Policy the printing policy for EnumConstantDecl printing.
53
static void printIntegral(const TemplateArgument &TemplArg,
54
192k
                          raw_ostream &Out, const PrintingPolicy& Policy) {
55
192k
  const Type *T = TemplArg.getIntegralType().getTypePtr();
56
192k
  const llvm::APSInt &Val = TemplArg.getAsIntegral();
57
58
192k
  if (const EnumType *ET = T->getAs<EnumType>()) {
59
1.26k
    for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
60
      // In Sema::CheckTemplateArugment, enum template arguments value are
61
      // extended to the size of the integer underlying the enum type.  This
62
      // may create a size difference between the enum value and template
63
      // argument value, requiring isSameValue here instead of operator==.
64
1.26k
      if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
65
1.23k
        ECD->printQualifiedName(Out, Policy);
66
1.23k
        return;
67
1.23k
      }
68
1.26k
    }
69
1.23k
  }
70
71
190k
  if (T->isBooleanType() && 
!Policy.MSVCFormatting81.5k
) {
72
47.3k
    Out << (Val.getBoolValue() ? 
"true"34.1k
: "false");
73
109k
  } else if (T->isCharType()) {
74
99
    const char Ch = Val.getZExtValue();
75
93
    Out << ((Ch == '\'') ? 
"'\\"6
: "'");
76
99
    Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
77
99
    Out << "'";
78
109k
  } else {
79
109k
    Out << Val;
80
109k
  }
81
190k
}
82
83
//===----------------------------------------------------------------------===//
84
// TemplateArgument Implementation
85
//===----------------------------------------------------------------------===//
86
87
TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
88
2.13M
                                   QualType Type) {
89
2.13M
  Integer.Kind = Integral;
90
  // Copy the APSInt value into our decomposed form.
91
2.13M
  Integer.BitWidth = Value.getBitWidth();
92
2.13M
  Integer.IsUnsigned = Value.isUnsigned();
93
  // If the value is large, we have to get additional memory from the ASTContext
94
2.13M
  unsigned NumWords = Value.getNumWords();
95
2.13M
  if (NumWords > 1) {
96
20
    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
97
20
    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
98
20
    Integer.pVal = static_cast<uint64_t *>(Mem);
99
2.13M
  } else {
100
2.13M
    Integer.VAL = Value.getZExtValue();
101
2.13M
  }
102
103
2.13M
  Integer.Type = Type.getAsOpaquePtr();
104
2.13M
}
105
106
TemplateArgument
107
TemplateArgument::CreatePackCopy(ASTContext &Context,
108
521k
                                 ArrayRef<TemplateArgument> Args) {
109
521k
  if (Args.empty())
110
30.3k
    return getEmptyPack();
111
112
490k
  return TemplateArgument(Args.copy(Context));
113
490k
}
114
115
30.0M
TemplateArgumentDependence TemplateArgument::getDependence() const {
116
30.0M
  auto Deps = TemplateArgumentDependence::None;
117
30.0M
  switch (getKind()) {
118
0
  case Null:
119
0
    llvm_unreachable("Should not have a NULL template argument");
120
121
23.1M
  case Type:
122
23.1M
    Deps = toTemplateArgumentDependence(getAsType()->getDependence());
123
23.1M
    if (isa<PackExpansionType>(getAsType()))
124
398k
      Deps |= TemplateArgumentDependence::Dependent;
125
23.1M
    return Deps;
126
127
90.3k
  case Template:
128
90.3k
    return toTemplateArgumentDependence(getAsTemplate().getDependence());
129
130
216
  case TemplateExpansion:
131
216
    return TemplateArgumentDependence::Dependent |
132
216
           TemplateArgumentDependence::Instantiation;
133
134
3.71k
  case Declaration: {
135
3.71k
    auto *DC = dyn_cast<DeclContext>(getAsDecl());
136
3.71k
    if (!DC)
137
2.33k
      DC = getAsDecl()->getDeclContext();
138
3.71k
    if (DC->isDependentContext())
139
10
      Deps = TemplateArgumentDependence::Dependent |
140
10
             TemplateArgumentDependence::Instantiation;
141
3.71k
    return Deps;
142
0
  }
143
144
556
  case NullPtr:
145
1.57M
  case Integral:
146
1.57M
    return TemplateArgumentDependence::None;
147
148
4.63M
  case Expression:
149
4.63M
    Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
150
4.63M
    if (isa<PackExpansionExpr>(getAsExpr()))
151
160k
      Deps |= TemplateArgumentDependence::Dependent |
152
160k
              TemplateArgumentDependence::Instantiation;
153
4.63M
    return Deps;
154
155
517k
  case Pack:
156
517k
    for (const auto &P : pack_elements())
157
867k
      Deps |= P.getDependence();
158
517k
    return Deps;
159
0
  }
160
0
  llvm_unreachable("unhandled ArgKind");
161
0
}
162
163
7.13M
bool TemplateArgument::isDependent() const {
164
7.13M
  return getDependence() & TemplateArgumentDependence::Dependent;
165
7.13M
}
166
167
2.83M
bool TemplateArgument::isInstantiationDependent() const {
168
2.83M
  return getDependence() & TemplateArgumentDependence::Instantiation;
169
2.83M
}
170
171
30.0M
bool TemplateArgument::isPackExpansion() const {
172
30.0M
  switch (getKind()) {
173
0
  case Null:
174
2.64k
  case Declaration:
175
1.95M
  case Integral:
176
2.01M
  case Pack:
177
2.07M
  case Template:
178
2.07M
  case NullPtr:
179
2.07M
    return false;
180
181
189
  case TemplateExpansion:
182
189
    return true;
183
184
22.9M
  case Type:
185
22.9M
    return isa<PackExpansionType>(getAsType());
186
187
5.09M
  case Expression:
188
5.09M
    return isa<PackExpansionExpr>(getAsExpr());
189
0
  }
190
191
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
192
0
}
193
194
776k
bool TemplateArgument::containsUnexpandedParameterPack() const {
195
776k
  return getDependence() & TemplateArgumentDependence::UnexpandedPack;
196
776k
}
197
198
147
Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
199
147
  assert(getKind() == TemplateExpansion);
200
147
  if (TemplateArg.NumExpansions)
201
3
    return TemplateArg.NumExpansions - 1;
202
203
144
  return None;
204
144
}
205
206
83.0k
QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
207
83.0k
  switch (getKind()) {
208
0
  case TemplateArgument::Null:
209
80.8k
  case TemplateArgument::Type:
210
80.9k
  case TemplateArgument::Template:
211
80.9k
  case TemplateArgument::TemplateExpansion:
212
81.0k
  case TemplateArgument::Pack:
213
81.0k
    return QualType();
214
215
208
  case TemplateArgument::Integral:
216
208
    return getIntegralType();
217
218
1.72k
  case TemplateArgument::Expression:
219
1.72k
    return getAsExpr()->getType();
220
221
26
  case TemplateArgument::Declaration:
222
26
    return getParamTypeForDecl();
223
224
0
  case TemplateArgument::NullPtr:
225
0
    return getNullPtrType();
226
0
  }
227
228
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
229
0
}
230
231
void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
232
36.2M
                               const ASTContext &Context) const {
233
36.2M
  ID.AddInteger(getKind());
234
36.2M
  switch (getKind()) {
235
0
  case Null:
236
0
    break;
237
238
27.2M
  case Type:
239
27.2M
    getAsType().Profile(ID);
240
27.2M
    break;
241
242
764
  case NullPtr:
243
764
    getNullPtrType().Profile(ID);
244
764
    break;
245
246
9.56k
  case Declaration:
247
9.56k
    getParamTypeForDecl().Profile(ID);
248
9.56k
    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 
nullptr0
);
249
9.56k
    break;
250
251
56.4k
  case Template:
252
56.6k
  case TemplateExpansion: {
253
56.6k
    TemplateName Template = getAsTemplateOrTemplatePattern();
254
56.6k
    if (TemplateTemplateParmDecl *TTP
255
7.09k
          = dyn_cast_or_null<TemplateTemplateParmDecl>(
256
7.09k
                                                Template.getAsTemplateDecl())) {
257
7.09k
      ID.AddBoolean(true);
258
7.09k
      ID.AddInteger(TTP->getDepth());
259
7.09k
      ID.AddInteger(TTP->getPosition());
260
7.09k
      ID.AddBoolean(TTP->isParameterPack());
261
49.5k
    } else {
262
49.5k
      ID.AddBoolean(false);
263
49.5k
      ID.AddPointer(Context.getCanonicalTemplateName(Template)
264
49.5k
                                                          .getAsVoidPointer());
265
49.5k
    }
266
56.6k
    break;
267
56.4k
  }
268
269
3.45M
  case Integral:
270
3.45M
    getAsIntegral().Profile(ID);
271
3.45M
    getIntegralType().Profile(ID);
272
3.45M
    break;
273
274
4.31M
  case Expression:
275
4.31M
    getAsExpr()->Profile(ID, Context, true);
276
4.31M
    break;
277
278
1.23M
  case Pack:
279
1.23M
    ID.AddInteger(Args.NumArgs);
280
3.14M
    for (unsigned I = 0; I != Args.NumArgs; 
++I1.91M
)
281
1.91M
      Args.Args[I].Profile(ID, Context);
282
36.2M
  }
283
36.2M
}
284
285
312k
bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
286
312k
  if (getKind() != Other.getKind()) 
return false5.97k
;
287
288
306k
  switch (getKind()) {
289
0
  case Null:
290
291k
  case Type:
291
299k
  case Expression:
292
299k
  case NullPtr:
293
299k
    return TypeOrValue.V == Other.TypeOrValue.V;
294
295
7.01k
  case Template:
296
7.01k
  case TemplateExpansion:
297
7.01k
    return TemplateArg.Name == Other.TemplateArg.Name &&
298
6.78k
           TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
299
300
0
  case Declaration:
301
0
    return getAsDecl() == Other.getAsDecl();
302
303
1
  case Integral:
304
1
    return getIntegralType() == Other.getIntegralType() &&
305
1
           getAsIntegral() == Other.getAsIntegral();
306
307
0
  case Pack:
308
0
    if (Args.NumArgs != Other.Args.NumArgs) return false;
309
0
    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
310
0
      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
311
0
        return false;
312
0
    return true;
313
0
  }
314
315
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
316
0
}
317
318
67.7k
TemplateArgument TemplateArgument::getPackExpansionPattern() const {
319
67.7k
  assert(isPackExpansion());
320
321
67.7k
  switch (getKind()) {
322
41.2k
  case Type:
323
41.2k
    return getAsType()->castAs<PackExpansionType>()->getPattern();
324
325
26.4k
  case Expression:
326
26.4k
    return cast<PackExpansionExpr>(getAsExpr())->getPattern();
327
328
54
  case TemplateExpansion:
329
54
    return TemplateArgument(getAsTemplateOrTemplatePattern());
330
331
0
  case Declaration:
332
0
  case Integral:
333
0
  case Pack:
334
0
  case Null:
335
0
  case Template:
336
0
  case NullPtr:
337
0
    return TemplateArgument();
338
0
  }
339
340
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
341
0
}
342
343
void TemplateArgument::print(const PrintingPolicy &Policy,
344
1.46M
                             raw_ostream &Out) const {
345
1.46M
  switch (getKind()) {
346
95
  case Null:
347
95
    Out << "(no value)";
348
95
    break;
349
350
1.24M
  case Type: {
351
1.24M
    PrintingPolicy SubPolicy(Policy);
352
1.24M
    SubPolicy.SuppressStrongLifetime = true;
353
1.24M
    getAsType().print(Out, SubPolicy);
354
1.24M
    break;
355
0
  }
356
357
1.73k
  case Declaration: {
358
1.73k
    NamedDecl *ND = getAsDecl();
359
1.73k
    if (getParamTypeForDecl()->isRecordType()) {
360
19
      if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
361
        // FIXME: Include the type if it's not obvious from the context.
362
19
        TPO->printAsInit(Out);
363
19
        break;
364
19
      }
365
1.71k
    }
366
1.71k
    if (!getParamTypeForDecl()->isReferenceType())
367
1.39k
      Out << '&';
368
1.71k
    ND->printQualifiedName(Out);
369
1.71k
    break;
370
1.71k
  }
371
372
868
  case NullPtr:
373
868
    Out << "nullptr";
374
868
    break;
375
376
901
  case Template:
377
901
    getAsTemplate().print(Out, Policy);
378
901
    break;
379
380
2
  case TemplateExpansion:
381
2
    getAsTemplateOrTemplatePattern().print(Out, Policy);
382
2
    Out << "...";
383
2
    break;
384
385
192k
  case Integral:
386
192k
    printIntegral(*this, Out, Policy);
387
192k
    break;
388
389
19.2k
  case Expression:
390
19.2k
    getAsExpr()->printPretty(Out, nullptr, Policy);
391
19.2k
    break;
392
393
1.26k
  case Pack:
394
1.26k
    Out << "<";
395
1.26k
    bool First = true;
396
2.43k
    for (const auto &P : pack_elements()) {
397
2.43k
      if (First)
398
1.20k
        First = false;
399
1.22k
      else
400
1.22k
        Out << ", ";
401
402
2.43k
      P.print(Policy, Out);
403
2.43k
    }
404
1.26k
    Out << ">";
405
1.26k
    break;
406
1.46M
  }
407
1.46M
}
408
409
0
void TemplateArgument::dump(raw_ostream &Out) const {
410
0
  LangOptions LO; // FIXME! see also TemplateName::dump().
411
0
  LO.CPlusPlus = true;
412
0
  LO.Bool = true;
413
0
  print(PrintingPolicy(LO), Out);
414
0
}
415
416
0
LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
417
418
//===----------------------------------------------------------------------===//
419
// TemplateArgumentLoc Implementation
420
//===----------------------------------------------------------------------===//
421
422
230k
SourceRange TemplateArgumentLoc::getSourceRange() const {
423
230k
  switch (Argument.getKind()) {
424
112k
  case TemplateArgument::Expression:
425
112k
    return getSourceExpression()->getSourceRange();
426
427
0
  case TemplateArgument::Declaration:
428
0
    return getSourceDeclExpression()->getSourceRange();
429
430
0
  case TemplateArgument::NullPtr:
431
0
    return getSourceNullPtrExpression()->getSourceRange();
432
433
117k
  case TemplateArgument::Type:
434
117k
    if (TypeSourceInfo *TSI = getTypeSourceInfo())
435
117k
      return TSI->getTypeLoc().getSourceRange();
436
0
    else
437
0
      return SourceRange();
438
439
254
  case TemplateArgument::Template:
440
254
    if (getTemplateQualifierLoc())
441
43
      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
442
43
                         getTemplateNameLoc());
443
211
    return SourceRange(getTemplateNameLoc());
444
445
2
  case TemplateArgument::TemplateExpansion:
446
2
    if (getTemplateQualifierLoc())
447
1
      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
448
1
                         getTemplateEllipsisLoc());
449
1
    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
450
451
0
  case TemplateArgument::Integral:
452
0
    return getSourceIntegralExpression()->getSourceRange();
453
454
0
  case TemplateArgument::Pack:
455
0
  case TemplateArgument::Null:
456
0
    return SourceRange();
457
0
  }
458
459
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
460
0
}
461
462
template <typename T>
463
1.05k
static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
464
1.05k
  switch (Arg.getKind()) {
465
0
  case TemplateArgument::Null:
466
    // This is bad, but not as bad as crashing because of argument
467
    // count mismatches.
468
0
    return DB << "(null template argument)";
469
470
449
  case TemplateArgument::Type:
471
449
    return DB << Arg.getAsType();
472
473
8
  case TemplateArgument::Declaration:
474
8
    return DB << Arg.getAsDecl();
475
476
0
  case TemplateArgument::NullPtr:
477
0
    return DB << "nullptr";
478
479
44
  case TemplateArgument::Integral:
480
44
    return DB << Arg.getAsIntegral().toString(10);
481
482
14
  case TemplateArgument::Template:
483
14
    return DB << Arg.getAsTemplate();
484
485
0
  case TemplateArgument::TemplateExpansion:
486
0
    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
487
488
416
  case TemplateArgument::Expression: {
489
    // This shouldn't actually ever happen, so it's okay that we're
490
    // regurgitating an expression here.
491
    // FIXME: We're guessing at LangOptions!
492
416
    SmallString<32> Str;
493
416
    llvm::raw_svector_ostream OS(Str);
494
416
    LangOptions LangOpts;
495
416
    LangOpts.CPlusPlus = true;
496
416
    PrintingPolicy Policy(LangOpts);
497
416
    Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
498
416
    return DB << OS.str();
499
0
  }
500
501
126
  case TemplateArgument::Pack: {
502
    // FIXME: We're guessing at LangOptions!
503
126
    SmallString<32> Str;
504
126
    llvm::raw_svector_ostream OS(Str);
505
126
    LangOptions LangOpts;
506
126
    LangOpts.CPlusPlus = true;
507
126
    PrintingPolicy Policy(LangOpts);
508
126
    Arg.print(Policy, OS);
509
126
    return DB << OS.str();
510
0
  }
511
0
  }
512
513
0
  llvm_unreachable("Invalid TemplateArgument Kind!");
514
0
}
515
516
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
517
1.05k
                                             const TemplateArgument &Arg) {
518
1.05k
  return DiagTemplateArg(DB, Arg);
519
1.05k
}
520
521
clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
522
    ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
523
45.5k
    SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
524
45.5k
  TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
525
45.5k
  Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
526
45.5k
  Template->QualifierLocData = QualifierLoc.getOpaqueData();
527
45.5k
  Template->TemplateNameLoc = TemplateNameLoc;
528
45.5k
  Template->EllipsisLoc = EllipsisLoc;
529
45.5k
  Pointer = Template;
530
45.5k
}
531
532
const ASTTemplateArgumentListInfo *
533
ASTTemplateArgumentListInfo::Create(const ASTContext &C,
534
192k
                                    const TemplateArgumentListInfo &List) {
535
192k
  std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
536
192k
  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
537
192k
  return new (Mem) ASTTemplateArgumentListInfo(List);
538
192k
}
539
540
ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
541
192k
    const TemplateArgumentListInfo &Info) {
542
192k
  LAngleLoc = Info.getLAngleLoc();
543
192k
  RAngleLoc = Info.getRAngleLoc();
544
192k
  NumTemplateArgs = Info.size();
545
546
192k
  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
547
604k
  for (unsigned i = 0; i != NumTemplateArgs; 
++i411k
)
548
411k
    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
549
192k
}
550
551
void ASTTemplateKWAndArgsInfo::initializeFrom(
552
    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
553
51.8k
    TemplateArgumentLoc *OutArgArray) {
554
51.8k
  this->TemplateKWLoc = TemplateKWLoc;
555
51.8k
  LAngleLoc = Info.getLAngleLoc();
556
51.8k
  RAngleLoc = Info.getRAngleLoc();
557
51.8k
  NumTemplateArgs = Info.size();
558
559
120k
  for (unsigned i = 0; i != NumTemplateArgs; 
++i68.8k
)
560
68.8k
    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
561
51.8k
}
562
563
179
void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
564
179
  assert(TemplateKWLoc.isValid());
565
179
  LAngleLoc = SourceLocation();
566
179
  RAngleLoc = SourceLocation();
567
179
  this->TemplateKWLoc = TemplateKWLoc;
568
179
  NumTemplateArgs = 0;
569
179
}
570
571
void ASTTemplateKWAndArgsInfo::initializeFrom(
572
    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
573
563k
    TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
574
563k
  this->TemplateKWLoc = TemplateKWLoc;
575
563k
  LAngleLoc = Info.getLAngleLoc();
576
563k
  RAngleLoc = Info.getRAngleLoc();
577
563k
  NumTemplateArgs = Info.size();
578
579
1.23M
  for (unsigned i = 0; i != NumTemplateArgs; 
++i671k
) {
580
671k
    Deps |= Info[i].getArgument().getDependence();
581
582
671k
    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
583
671k
  }
584
563k
}
585
586
void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
587
275k
                                        TemplateArgumentListInfo &Info) const {
588
275k
  Info.setLAngleLoc(LAngleLoc);
589
275k
  Info.setRAngleLoc(RAngleLoc);
590
581k
  for (unsigned I = 0; I != NumTemplateArgs; 
++I305k
)
591
305k
    Info.addArgument(ArgArray[I]);
592
275k
}