Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/lib/AST/TemplateBase.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- TemplateBase.cpp - Common template AST class implementation ------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file implements common classes used throughout C++ template
11
// representations.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "clang/AST/TemplateBase.h"
16
#include "clang/AST/ASTContext.h"
17
#include "clang/AST/DeclBase.h"
18
#include "clang/AST/DeclTemplate.h"
19
#include "clang/AST/Expr.h"
20
#include "clang/AST/ExprCXX.h"
21
#include "clang/AST/Type.h"
22
#include "clang/AST/TypeLoc.h"
23
#include "clang/Basic/Diagnostic.h"
24
#include "llvm/ADT/FoldingSet.h"
25
#include "llvm/ADT/SmallString.h"
26
#include "llvm/Support/raw_ostream.h"
27
#include <algorithm>
28
29
using namespace clang;
30
31
/// \brief Print a template integral argument value.
32
///
33
/// \param TemplArg the TemplateArgument instance to print.
34
///
35
/// \param Out the raw_ostream instance to use for printing.
36
///
37
/// \param Policy the printing policy for EnumConstantDecl printing.
38
static void printIntegral(const TemplateArgument &TemplArg,
39
3.56k
                          raw_ostream &Out, const PrintingPolicy& Policy) {
40
3.56k
  const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
41
3.56k
  const llvm::APSInt &Val = TemplArg.getAsIntegral();
42
3.56k
43
3.56k
  if (const EnumType *
ET3.56k
= T->getAs<EnumType>()) {
44
36
    for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
45
36
      // In Sema::CheckTemplateArugment, enum template arguments value are
46
36
      // extended to the size of the integer underlying the enum type.  This
47
36
      // may create a size difference between the enum value and template
48
36
      // argument value, requiring isSameValue here instead of operator==.
49
36
      if (
llvm::APSInt::isSameValue(ECD->getInitVal(), Val)36
) {
50
31
        ECD->printQualifiedName(Out, Policy);
51
31
        return;
52
31
      }
53
3.53k
    }
54
32
  }
55
3.53k
56
3.53k
  
if (3.53k
T->isBooleanType() && 3.53k
!Policy.MSVCFormatting122
) {
57
122
    Out << (Val.getBoolValue() ? 
"true"67
:
"false"55
);
58
3.53k
  } else 
if (3.41k
T->isCharType()3.41k
) {
59
94
    const char Ch = Val.getZExtValue();
60
94
    Out << ((Ch == '\'') ? 
"'\\"6
:
"'"88
);
61
94
    Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
62
94
    Out << "'";
63
3.41k
  } else {
64
3.32k
    Out << Val;
65
3.32k
  }
66
3.56k
}
67
68
//===----------------------------------------------------------------------===//
69
// TemplateArgument Implementation
70
//===----------------------------------------------------------------------===//
71
72
TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
73
32.6k
                                   QualType Type) {
74
32.6k
  Integer.Kind = Integral;
75
32.6k
  // Copy the APSInt value into our decomposed form.
76
32.6k
  Integer.BitWidth = Value.getBitWidth();
77
32.6k
  Integer.IsUnsigned = Value.isUnsigned();
78
32.6k
  // If the value is large, we have to get additional memory from the ASTContext
79
32.6k
  unsigned NumWords = Value.getNumWords();
80
32.6k
  if (
NumWords > 132.6k
) {
81
0
    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
82
0
    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
83
0
    Integer.pVal = static_cast<uint64_t *>(Mem);
84
32.6k
  } else {
85
32.6k
    Integer.VAL = Value.getZExtValue();
86
32.6k
  }
87
32.6k
88
32.6k
  Integer.Type = Type.getAsOpaquePtr();
89
32.6k
}
90
91
TemplateArgument
92
TemplateArgument::CreatePackCopy(ASTContext &Context,
93
5.82k
                                 ArrayRef<TemplateArgument> Args) {
94
5.82k
  if (Args.empty())
95
747
    return getEmptyPack();
96
5.07k
97
5.07k
  return TemplateArgument(Args.copy(Context));
98
5.07k
}
99
100
188k
bool TemplateArgument::isDependent() const {
101
188k
  switch (getKind()) {
102
0
  case Null:
103
0
    llvm_unreachable("Should not have a NULL template argument");
104
188k
105
140k
  case Type:
106
140k
    return getAsType()->isDependentType() ||
107
83.4k
           isa<PackExpansionType>(getAsType());
108
188k
109
714
  case Template:
110
714
    return getAsTemplate().isDependent();
111
188k
112
14
  case TemplateExpansion:
113
14
    return true;
114
188k
115
0
  case Declaration:
116
0
    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
117
0
      return DC->isDependentContext();
118
0
    return getAsDecl()->getDeclContext()->isDependentContext();
119
0
120
0
  case NullPtr:
121
0
    return false;
122
0
123
0
  case Integral:
124
0
    // Never dependent
125
0
    return false;
126
0
127
47.1k
  case Expression:
128
45.1k
    return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() ||
129
47.1k
            isa<PackExpansionExpr>(getAsExpr()));
130
0
131
5
  case Pack:
132
5
    for (const auto &P : pack_elements())
133
5
      
if (5
P.isDependent()5
)
134
5
        return true;
135
0
    return false;
136
0
  }
137
0
138
0
  
llvm_unreachable0
("Invalid TemplateArgument Kind!");
139
0
}
140
141
536k
bool TemplateArgument::isInstantiationDependent() const {
142
536k
  switch (getKind()) {
143
0
  case Null:
144
0
    llvm_unreachable("Should not have a NULL template argument");
145
536k
    
146
423k
  case Type:
147
423k
    return getAsType()->isInstantiationDependentType();
148
536k
    
149
4.86k
  case Template:
150
4.86k
    return getAsTemplate().isInstantiationDependent();
151
536k
    
152
136
  case TemplateExpansion:
153
136
    return true;
154
536k
    
155
1.27k
  case Declaration:
156
1.27k
    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
157
49
      return DC->isDependentContext();
158
1.22k
    return getAsDecl()->getDeclContext()->isDependentContext();
159
1.22k
160
233
  case NullPtr:
161
233
    return false;
162
1.22k
      
163
8.12k
  case Integral:
164
8.12k
    // Never dependent
165
8.12k
    return false;
166
1.22k
    
167
96.3k
  case Expression:
168
96.3k
    return getAsExpr()->isInstantiationDependent();
169
1.22k
    
170
2.41k
  case Pack:
171
2.41k
    for (const auto &P : pack_elements())
172
7.08k
      
if (7.08k
P.isInstantiationDependent()7.08k
)
173
1.50k
        return true;
174
904
    return false;
175
0
  }
176
0
177
0
  
llvm_unreachable0
("Invalid TemplateArgument Kind!");
178
0
}
179
180
443k
bool TemplateArgument::isPackExpansion() const {
181
443k
  switch (getKind()) {
182
19.2k
  case Null:
183
19.2k
  case Declaration:
184
19.2k
  case Integral:
185
19.2k
  case Pack:    
186
19.2k
  case Template:
187
19.2k
  case NullPtr:
188
19.2k
    return false;
189
19.2k
      
190
87
  case TemplateExpansion:
191
87
    return true;
192
19.2k
      
193
339k
  case Type:
194
339k
    return isa<PackExpansionType>(getAsType());
195
19.2k
          
196
83.9k
  case Expression:
197
83.9k
    return isa<PackExpansionExpr>(getAsExpr());
198
0
  }
199
0
200
0
  
llvm_unreachable0
("Invalid TemplateArgument Kind!");
201
0
}
202
203
393k
bool TemplateArgument::containsUnexpandedParameterPack() const {
204
393k
  switch (getKind()) {
205
4.33k
  case Null:
206
4.33k
  case Declaration:
207
4.33k
  case Integral:
208
4.33k
  case TemplateExpansion:
209
4.33k
  case NullPtr:
210
4.33k
    break;
211
4.33k
212
305k
  case Type:
213
305k
    if (getAsType()->containsUnexpandedParameterPack())
214
418
      return true;
215
304k
    break;
216
304k
217
4.26k
  case Template:
218
4.26k
    if (getAsTemplate().containsUnexpandedParameterPack())
219
3
      return true;
220
4.26k
    break;
221
4.26k
        
222
78.0k
  case Expression:
223
78.0k
    if (getAsExpr()->containsUnexpandedParameterPack())
224
55
      return true;
225
78.0k
    break;
226
78.0k
227
2.11k
  case Pack:
228
2.11k
    for (const auto &P : pack_elements())
229
4.84k
      
if (4.84k
P.containsUnexpandedParameterPack()4.84k
)
230
7
        return true;
231
2.10k
232
2.10k
    break;
233
393k
  }
234
393k
235
393k
  return false;
236
393k
}
237
238
107
Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
239
107
  assert(getKind() == TemplateExpansion);
240
107
  if (TemplateArg.NumExpansions)
241
3
    return TemplateArg.NumExpansions - 1;
242
104
  
243
104
  return None; 
244
104
}
245
246
10.7k
QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
247
10.7k
  switch (getKind()) {
248
10.5k
  case TemplateArgument::Null:
249
10.5k
  case TemplateArgument::Type:
250
10.5k
  case TemplateArgument::Template:
251
10.5k
  case TemplateArgument::TemplateExpansion:
252
10.5k
  case TemplateArgument::Pack:
253
10.5k
    return QualType();
254
10.5k
255
110
  case TemplateArgument::Integral:
256
110
    return getIntegralType();
257
10.5k
258
72
  case TemplateArgument::Expression:
259
72
    return getAsExpr()->getType();
260
10.5k
261
8
  case TemplateArgument::Declaration:
262
8
    return getParamTypeForDecl();
263
10.5k
264
0
  case TemplateArgument::NullPtr:
265
0
    return getNullPtrType();
266
0
  }
267
0
268
0
  
llvm_unreachable0
("Invalid TemplateArgument Kind!");
269
0
}
270
271
void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
272
690k
                               const ASTContext &Context) const {
273
690k
  ID.AddInteger(getKind());
274
690k
  switch (getKind()) {
275
0
  case Null:
276
0
    break;
277
690k
278
535k
  case Type:
279
535k
    getAsType().Profile(ID);
280
535k
    break;
281
690k
282
490
  case NullPtr:
283
490
    getNullPtrType().Profile(ID);
284
490
    break;
285
690k
286
1.61k
  case Declaration:
287
1.61k
    ID.AddPointer(getAsDecl()? 
getAsDecl()->getCanonicalDecl()1.61k
:
nullptr0
);
288
1.61k
    break;
289
690k
290
2.09k
  case Template:
291
2.09k
  case TemplateExpansion: {
292
2.09k
    TemplateName Template = getAsTemplateOrTemplatePattern();
293
2.09k
    if (TemplateTemplateParmDecl *TTP
294
2.09k
          = dyn_cast_or_null<TemplateTemplateParmDecl>(
295
916
                                                Template.getAsTemplateDecl())) {
296
916
      ID.AddBoolean(true);
297
916
      ID.AddInteger(TTP->getDepth());
298
916
      ID.AddInteger(TTP->getPosition());
299
916
      ID.AddBoolean(TTP->isParameterPack());
300
2.09k
    } else {
301
1.18k
      ID.AddBoolean(false);
302
1.18k
      ID.AddPointer(Context.getCanonicalTemplateName(Template)
303
1.18k
                                                          .getAsVoidPointer());
304
1.18k
    }
305
2.09k
    break;
306
2.09k
  }
307
2.09k
      
308
64.0k
  case Integral:
309
64.0k
    getAsIntegral().Profile(ID);
310
64.0k
    getIntegralType().Profile(ID);
311
64.0k
    break;
312
2.09k
313
78.4k
  case Expression:
314
78.4k
    getAsExpr()->Profile(ID, Context, true);
315
78.4k
    break;
316
2.09k
317
7.99k
  case Pack:
318
7.99k
    ID.AddInteger(Args.NumArgs);
319
26.6k
    for (unsigned I = 0; 
I != Args.NumArgs26.6k
;
++I18.6k
)
320
18.6k
      Args.Args[I].Profile(ID, Context);
321
690k
  }
322
690k
}
323
324
584
bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
325
584
  if (
getKind() != Other.getKind()584
)
return false0
;
326
584
327
584
  switch (getKind()) {
328
584
  case Null:
329
584
  case Type:
330
584
  case Expression:      
331
584
  case Template:
332
584
  case TemplateExpansion:
333
584
  case NullPtr:
334
584
    return TypeOrValue.V == Other.TypeOrValue.V;
335
584
336
0
  case Declaration:
337
0
    return getAsDecl() == Other.getAsDecl();
338
584
339
0
  case Integral:
340
0
    return getIntegralType() == Other.getIntegralType() &&
341
0
           getAsIntegral() == Other.getAsIntegral();
342
584
343
0
  case Pack:
344
0
    if (
Args.NumArgs != Other.Args.NumArgs0
)
return false0
;
345
0
    
for (unsigned I = 0, E = Args.NumArgs; 0
I != E0
;
++I0
)
346
0
      
if (0
!Args.Args[I].structurallyEquals(Other.Args.Args[I])0
)
347
0
        return false;
348
0
    return true;
349
0
  }
350
0
351
0
  
llvm_unreachable0
("Invalid TemplateArgument Kind!");
352
0
}
353
354
1.02k
TemplateArgument TemplateArgument::getPackExpansionPattern() const {
355
1.02k
  assert(isPackExpansion());
356
1.02k
  
357
1.02k
  switch (getKind()) {
358
826
  case Type:
359
826
    return getAsType()->getAs<PackExpansionType>()->getPattern();
360
1.02k
    
361
155
  case Expression:
362
155
    return cast<PackExpansionExpr>(getAsExpr())->getPattern();
363
1.02k
    
364
43
  case TemplateExpansion:
365
43
    return TemplateArgument(getAsTemplateOrTemplatePattern());
366
1.02k
367
0
  case Declaration:
368
0
  case Integral:
369
0
  case Pack:
370
0
  case Null:
371
0
  case Template:
372
0
  case NullPtr:
373
0
    return TemplateArgument();
374
0
  }
375
0
376
0
  
llvm_unreachable0
("Invalid TemplateArgument Kind!");
377
0
}
378
379
void TemplateArgument::print(const PrintingPolicy &Policy, 
380
36.8k
                             raw_ostream &Out) const {
381
36.8k
  switch (getKind()) {
382
53
  case Null:
383
53
    Out << "(no value)";
384
53
    break;
385
36.8k
    
386
28.1k
  case Type: {
387
28.1k
    PrintingPolicy SubPolicy(Policy);
388
28.1k
    SubPolicy.SuppressStrongLifetime = true;
389
28.1k
    getAsType().print(Out, SubPolicy);
390
28.1k
    break;
391
36.8k
  }
392
36.8k
    
393
1.66k
  case Declaration: {
394
1.66k
    NamedDecl *ND = cast<NamedDecl>(getAsDecl());
395
1.66k
    Out << '&';
396
1.66k
    if (
ND->getDeclName()1.66k
) {
397
1.66k
      // FIXME: distinguish between pointer and reference args?
398
1.66k
      ND->printQualifiedName(Out);
399
1.66k
    } else {
400
0
      Out << "(anonymous)";
401
0
    }
402
1.66k
    break;
403
36.8k
  }
404
36.8k
405
807
  case NullPtr:
406
807
    Out << "nullptr";
407
807
    break;
408
36.8k
409
933
  case Template:
410
933
    getAsTemplate().print(Out, Policy);
411
933
    break;
412
36.8k
413
2
  case TemplateExpansion:
414
2
    getAsTemplateOrTemplatePattern().print(Out, Policy);
415
2
    Out << "...";
416
2
    break;
417
36.8k
      
418
3.56k
  case Integral: {
419
3.56k
    printIntegral(*this, Out, Policy);
420
3.56k
    break;
421
36.8k
  }
422
36.8k
    
423
1.50k
  case Expression:
424
1.50k
    getAsExpr()->printPretty(Out, nullptr, Policy);
425
1.50k
    break;
426
36.8k
    
427
151
  case Pack:
428
151
    Out << "<";
429
151
    bool First = true;
430
216
    for (const auto &P : pack_elements()) {
431
216
      if (First)
432
101
        First = false;
433
216
      else
434
115
        Out << ", ";
435
216
      
436
216
      P.print(Policy, Out);
437
216
    }
438
151
    Out << ">";
439
151
    break;        
440
36.8k
  }
441
36.8k
}
442
443
0
void TemplateArgument::dump(raw_ostream &Out) const {
444
0
  LangOptions LO; // FIXME! see also TemplateName::dump().
445
0
  LO.CPlusPlus = true;
446
0
  LO.Bool = true;
447
0
  print(PrintingPolicy(LO), Out);
448
0
}
449
450
0
LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
451
452
//===----------------------------------------------------------------------===//
453
// TemplateArgumentLoc Implementation
454
//===----------------------------------------------------------------------===//
455
456
1.81k
SourceRange TemplateArgumentLoc::getSourceRange() const {
457
1.81k
  switch (Argument.getKind()) {
458
454
  case TemplateArgument::Expression:
459
454
    return getSourceExpression()->getSourceRange();
460
1.81k
461
0
  case TemplateArgument::Declaration:
462
0
    return getSourceDeclExpression()->getSourceRange();
463
1.81k
464
0
  case TemplateArgument::NullPtr:
465
0
    return getSourceNullPtrExpression()->getSourceRange();
466
1.81k
467
1.18k
  case TemplateArgument::Type:
468
1.18k
    if (TypeSourceInfo *TSI = getTypeSourceInfo())
469
1.18k
      return TSI->getTypeLoc().getSourceRange();
470
1.18k
    else
471
0
      return SourceRange();
472
0
473
173
  case TemplateArgument::Template:
474
173
    if (getTemplateQualifierLoc())
475
36
      return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 
476
36
                         getTemplateNameLoc());
477
137
    return SourceRange(getTemplateNameLoc());
478
137
479
0
  case TemplateArgument::TemplateExpansion:
480
0
    if (getTemplateQualifierLoc())
481
0
      return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 
482
0
                         getTemplateEllipsisLoc());
483
0
    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
484
0
485
0
  case TemplateArgument::Integral:
486
0
    return getSourceIntegralExpression()->getSourceRange();
487
0
488
0
  case TemplateArgument::Pack:
489
0
  case TemplateArgument::Null:
490
0
    return SourceRange();
491
0
  }
492
0
493
0
  
llvm_unreachable0
("Invalid TemplateArgument Kind!");
494
0
}
495
496
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
497
1.22k
                                           const TemplateArgument &Arg) {
498
1.22k
  switch (Arg.getKind()) {
499
0
  case TemplateArgument::Null:
500
0
    // This is bad, but not as bad as crashing because of argument
501
0
    // count mismatches.
502
0
    return DB << "(null template argument)";
503
1.22k
      
504
1.04k
  case TemplateArgument::Type:
505
1.04k
    return DB << Arg.getAsType();
506
1.22k
      
507
4
  case TemplateArgument::Declaration:
508
4
    return DB << Arg.getAsDecl();
509
1.22k
510
0
  case TemplateArgument::NullPtr:
511
0
    return DB << "nullptr";
512
1.22k
      
513
44
  case TemplateArgument::Integral:
514
44
    return DB << Arg.getAsIntegral().toString(10);
515
1.22k
      
516
6
  case TemplateArgument::Template:
517
6
    return DB << Arg.getAsTemplate();
518
1.22k
519
0
  case TemplateArgument::TemplateExpansion:
520
0
    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
521
1.22k
522
44
  case TemplateArgument::Expression: {
523
44
    // This shouldn't actually ever happen, so it's okay that we're
524
44
    // regurgitating an expression here.
525
44
    // FIXME: We're guessing at LangOptions!
526
44
    SmallString<32> Str;
527
44
    llvm::raw_svector_ostream OS(Str);
528
44
    LangOptions LangOpts;
529
44
    LangOpts.CPlusPlus = true;
530
44
    PrintingPolicy Policy(LangOpts);
531
44
    Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
532
44
    return DB << OS.str();
533
1.22k
  }
534
1.22k
      
535
86
  case TemplateArgument::Pack: {
536
86
    // FIXME: We're guessing at LangOptions!
537
86
    SmallString<32> Str;
538
86
    llvm::raw_svector_ostream OS(Str);
539
86
    LangOptions LangOpts;
540
86
    LangOpts.CPlusPlus = true;
541
86
    PrintingPolicy Policy(LangOpts);
542
86
    Arg.print(Policy, OS);
543
86
    return DB << OS.str();
544
0
  }
545
0
  }
546
0
547
0
  
llvm_unreachable0
("Invalid TemplateArgument Kind!");
548
0
}
549
550
const ASTTemplateArgumentListInfo *
551
ASTTemplateArgumentListInfo::Create(ASTContext &C,
552
5.31k
                                    const TemplateArgumentListInfo &List) {
553
5.31k
  std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
554
5.31k
  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
555
5.31k
  return new (Mem) ASTTemplateArgumentListInfo(List);
556
5.31k
}
557
558
ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
559
5.31k
    const TemplateArgumentListInfo &Info) {
560
5.31k
  LAngleLoc = Info.getLAngleLoc();
561
5.31k
  RAngleLoc = Info.getRAngleLoc();
562
5.31k
  NumTemplateArgs = Info.size();
563
5.31k
564
5.31k
  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
565
15.2k
  for (unsigned i = 0; 
i != NumTemplateArgs15.2k
;
++i9.91k
)
566
9.91k
    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
567
5.31k
}
568
569
void ASTTemplateKWAndArgsInfo::initializeFrom(
570
    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
571
283
    TemplateArgumentLoc *OutArgArray) {
572
283
  this->TemplateKWLoc = TemplateKWLoc;
573
283
  LAngleLoc = Info.getLAngleLoc();
574
283
  RAngleLoc = Info.getRAngleLoc();
575
283
  NumTemplateArgs = Info.size();
576
283
577
642
  for (unsigned i = 0; 
i != NumTemplateArgs642
;
++i359
)
578
359
    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
579
283
}
580
581
39
void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
582
39
  assert(TemplateKWLoc.isValid());
583
39
  LAngleLoc = SourceLocation();
584
39
  RAngleLoc = SourceLocation();
585
39
  this->TemplateKWLoc = TemplateKWLoc;
586
39
  NumTemplateArgs = 0;
587
39
}
588
589
void ASTTemplateKWAndArgsInfo::initializeFrom(
590
    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
591
    TemplateArgumentLoc *OutArgArray, bool &Dependent,
592
22.8k
    bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) {
593
22.8k
  this->TemplateKWLoc = TemplateKWLoc;
594
22.8k
  LAngleLoc = Info.getLAngleLoc();
595
22.8k
  RAngleLoc = Info.getRAngleLoc();
596
22.8k
  NumTemplateArgs = Info.size();
597
22.8k
598
52.0k
  for (unsigned i = 0; 
i != NumTemplateArgs52.0k
;
++i29.1k
) {
599
28.7k
    Dependent = Dependent || Info[i].getArgument().isDependent();
600
29.1k
    InstantiationDependent = InstantiationDependent ||
601
28.7k
                             Info[i].getArgument().isInstantiationDependent();
602
29.1k
    ContainsUnexpandedParameterPack =
603
29.1k
        ContainsUnexpandedParameterPack ||
604
29.1k
        Info[i].getArgument().containsUnexpandedParameterPack();
605
29.1k
606
29.1k
    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
607
29.1k
  }
608
22.8k
}
609
610
void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
611
25.1k
                                        TemplateArgumentListInfo &Info) const {
612
25.1k
  Info.setLAngleLoc(LAngleLoc);
613
25.1k
  Info.setRAngleLoc(RAngleLoc);
614
57.3k
  for (unsigned I = 0; 
I != NumTemplateArgs57.3k
;
++I32.2k
)
615
32.2k
    Info.addArgument(ArgArray[I]);
616
25.1k
}