llvm-project

Форк
0
/
TemplateBase.cpp 
791 строка · 24.1 Кб
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
                          const PrintingPolicy &Policy, bool IncludeType) {
59
  const Type *T = TemplArg.getIntegralType().getTypePtr();
60
  const llvm::APSInt &Val = TemplArg.getAsIntegral();
61

62
  if (Policy.UseEnumerators) {
63
    if (const EnumType *ET = T->getAs<EnumType>()) {
64
      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
        if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
70
          ECD->printQualifiedName(Out, Policy);
71
          return;
72
        }
73
      }
74
    }
75
  }
76

77
  if (Policy.MSVCFormatting)
78
    IncludeType = false;
79

80
  if (T->isBooleanType()) {
81
    if (!Policy.MSVCFormatting)
82
      Out << (Val.getBoolValue() ? "true" : "false");
83
    else
84
      Out << Val;
85
  } else if (T->isCharType()) {
86
    if (IncludeType) {
87
      if (T->isSpecificBuiltinType(BuiltinType::SChar))
88
        Out << "(signed char)";
89
      else if (T->isSpecificBuiltinType(BuiltinType::UChar))
90
        Out << "(unsigned char)";
91
    }
92
    CharacterLiteral::print(Val.getZExtValue(), CharacterLiteralKind::Ascii,
93
                            Out);
94
  } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
95
    CharacterLiteralKind Kind;
96
    if (T->isWideCharType())
97
      Kind = CharacterLiteralKind::Wide;
98
    else if (T->isChar8Type())
99
      Kind = CharacterLiteralKind::UTF8;
100
    else if (T->isChar16Type())
101
      Kind = CharacterLiteralKind::UTF16;
102
    else if (T->isChar32Type())
103
      Kind = CharacterLiteralKind::UTF32;
104
    else
105
      Kind = CharacterLiteralKind::Ascii;
106
    CharacterLiteral::print(Val.getExtValue(), Kind, Out);
107
  } else if (IncludeType) {
108
    if (const auto *BT = T->getAs<BuiltinType>()) {
109
      switch (BT->getKind()) {
110
      case BuiltinType::ULongLong:
111
        Out << Val << "ULL";
112
        break;
113
      case BuiltinType::LongLong:
114
        Out << Val << "LL";
115
        break;
116
      case BuiltinType::ULong:
117
        Out << Val << "UL";
118
        break;
119
      case BuiltinType::Long:
120
        Out << Val << "L";
121
        break;
122
      case BuiltinType::UInt:
123
        Out << Val << "U";
124
        break;
125
      case BuiltinType::Int:
126
        Out << Val;
127
        break;
128
      default:
129
        Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
130
            << Val;
131
        break;
132
      }
133
    } else
134
      Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
135
          << Val;
136
  } else
137
    Out << Val;
138
}
139

140
static unsigned getArrayDepth(QualType type) {
141
  unsigned count = 0;
142
  while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
143
    count++;
144
    type = arrayType->getElementType();
145
  }
146
  return count;
147
}
148

149
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
  if (!paramType->isPointerType())
154
    return paramType->isMemberPointerType();
155
  if (argType->isArrayType())
156
    return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType());
157
  return true;
158
}
159

160
//===----------------------------------------------------------------------===//
161
// TemplateArgument Implementation
162
//===----------------------------------------------------------------------===//
163

164
void TemplateArgument::initFromType(QualType T, bool IsNullPtr,
165
                                    bool IsDefaulted) {
166
  TypeOrValue.Kind = IsNullPtr ? NullPtr : Type;
167
  TypeOrValue.IsDefaulted = IsDefaulted;
168
  TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
169
}
170

171
void TemplateArgument::initFromDeclaration(ValueDecl *D, QualType QT,
172
                                           bool IsDefaulted) {
173
  assert(D && "Expected decl");
174
  DeclArg.Kind = Declaration;
175
  DeclArg.IsDefaulted = IsDefaulted;
176
  DeclArg.QT = QT.getAsOpaquePtr();
177
  DeclArg.D = D;
178
}
179

180
void TemplateArgument::initFromIntegral(const ASTContext &Ctx,
181
                                        const llvm::APSInt &Value,
182
                                        QualType Type, bool IsDefaulted) {
183
  Integer.Kind = Integral;
184
  Integer.IsDefaulted = IsDefaulted;
185
  // Copy the APSInt value into our decomposed form.
186
  Integer.BitWidth = Value.getBitWidth();
187
  Integer.IsUnsigned = Value.isUnsigned();
188
  // If the value is large, we have to get additional memory from the ASTContext
189
  unsigned NumWords = Value.getNumWords();
190
  if (NumWords > 1) {
191
    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
192
    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
193
    Integer.pVal = static_cast<uint64_t *>(Mem);
194
  } else {
195
    Integer.VAL = Value.getZExtValue();
196
  }
197

198
  Integer.Type = Type.getAsOpaquePtr();
199
}
200

201
void TemplateArgument::initFromStructural(const ASTContext &Ctx, QualType Type,
202
                                          const APValue &V, bool IsDefaulted) {
203
  Value.Kind = StructuralValue;
204
  Value.IsDefaulted = IsDefaulted;
205
  Value.Value = new (Ctx) APValue(V);
206
  Ctx.addDestruction(Value.Value);
207
  Value.Type = Type.getAsOpaquePtr();
208
}
209

210
TemplateArgument::TemplateArgument(const ASTContext &Ctx,
211
                                   const llvm::APSInt &Value, QualType Type,
212
                                   bool IsDefaulted) {
213
  initFromIntegral(Ctx, Value, Type, IsDefaulted);
214
}
215

216
static const ValueDecl *getAsSimpleValueDeclRef(const ASTContext &Ctx,
217
                                                QualType T, const APValue &V) {
218
  // Pointers to members are relatively easy.
219
  if (V.isMemberPointer() && V.getMemberPointerPath().empty())
220
    return V.getMemberPointerDecl();
221

222
  // We model class non-type template parameters as their template parameter
223
  // object declaration.
224
  if (V.isStruct() || V.isUnion()) {
225
    // Dependent types are not supposed to be described as
226
    // TemplateParamObjectDecls.
227
    if (T->isDependentType() || T->isInstantiationDependentType())
228
      return nullptr;
229
    return Ctx.getTemplateParamObjectDecl(T, V);
230
  }
231

232
  // Pointers and references with an empty path use the special 'Declaration'
233
  // representation.
234
  if (V.isLValue() && V.hasLValuePath() && V.getLValuePath().empty() &&
235
      !V.isLValueOnePastTheEnd())
236
    return V.getLValueBase().dyn_cast<const ValueDecl *>();
237

238
  // Everything else uses the 'structural' representation.
239
  return nullptr;
240
}
241

242
TemplateArgument::TemplateArgument(const ASTContext &Ctx, QualType Type,
243
                                   const APValue &V, bool IsDefaulted) {
244
  if (Type->isIntegralOrEnumerationType() && V.isInt())
245
    initFromIntegral(Ctx, V.getInt(), Type, IsDefaulted);
246
  else if ((V.isLValue() && V.isNullPointer()) ||
247
           (V.isMemberPointer() && !V.getMemberPointerDecl()))
248
    initFromType(Type, /*isNullPtr=*/true, IsDefaulted);
249
  else if (const ValueDecl *VD = getAsSimpleValueDeclRef(Ctx, Type, V))
250
    // FIXME: The Declaration form should expose a const ValueDecl*.
251
    initFromDeclaration(const_cast<ValueDecl *>(VD), Type, IsDefaulted);
252
  else
253
    initFromStructural(Ctx, Type, V, IsDefaulted);
254
}
255

256
TemplateArgument
257
TemplateArgument::CreatePackCopy(ASTContext &Context,
258
                                 ArrayRef<TemplateArgument> Args) {
259
  if (Args.empty())
260
    return getEmptyPack();
261

262
  return TemplateArgument(Args.copy(Context));
263
}
264

265
TemplateArgumentDependence TemplateArgument::getDependence() const {
266
  auto Deps = TemplateArgumentDependence::None;
267
  switch (getKind()) {
268
  case Null:
269
    llvm_unreachable("Should not have a NULL template argument");
270

271
  case Type:
272
    Deps = toTemplateArgumentDependence(getAsType()->getDependence());
273
    if (isa<PackExpansionType>(getAsType()))
274
      Deps |= TemplateArgumentDependence::Dependent;
275
    return Deps;
276

277
  case Template:
278
    return toTemplateArgumentDependence(getAsTemplate().getDependence());
279

280
  case TemplateExpansion:
281
    return TemplateArgumentDependence::Dependent |
282
           TemplateArgumentDependence::Instantiation;
283

284
  case Declaration: {
285
    auto *DC = dyn_cast<DeclContext>(getAsDecl());
286
    if (!DC)
287
      DC = getAsDecl()->getDeclContext();
288
    if (DC->isDependentContext())
289
      Deps = TemplateArgumentDependence::Dependent |
290
             TemplateArgumentDependence::Instantiation;
291
    return Deps;
292
  }
293

294
  case NullPtr:
295
  case Integral:
296
  case StructuralValue:
297
    return TemplateArgumentDependence::None;
298

299
  case Expression:
300
    Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
301
    if (isa<PackExpansionExpr>(getAsExpr()))
302
      Deps |= TemplateArgumentDependence::Dependent |
303
              TemplateArgumentDependence::Instantiation;
304
    return Deps;
305

306
  case Pack:
307
    for (const auto &P : pack_elements())
308
      Deps |= P.getDependence();
309
    return Deps;
310
  }
311
  llvm_unreachable("unhandled ArgKind");
312
}
313

314
bool TemplateArgument::isDependent() const {
315
  return getDependence() & TemplateArgumentDependence::Dependent;
316
}
317

318
bool TemplateArgument::isInstantiationDependent() const {
319
  return getDependence() & TemplateArgumentDependence::Instantiation;
320
}
321

322
bool TemplateArgument::isPackExpansion() const {
323
  switch (getKind()) {
324
  case Null:
325
  case Declaration:
326
  case Integral:
327
  case StructuralValue:
328
  case Pack:
329
  case Template:
330
  case NullPtr:
331
    return false;
332

333
  case TemplateExpansion:
334
    return true;
335

336
  case Type:
337
    return isa<PackExpansionType>(getAsType());
338

339
  case Expression:
340
    return isa<PackExpansionExpr>(getAsExpr());
341
  }
342

343
  llvm_unreachable("Invalid TemplateArgument Kind!");
344
}
345

346
bool TemplateArgument::containsUnexpandedParameterPack() const {
347
  return getDependence() & TemplateArgumentDependence::UnexpandedPack;
348
}
349

350
std::optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
351
  assert(getKind() == TemplateExpansion);
352
  if (TemplateArg.NumExpansions)
353
    return TemplateArg.NumExpansions - 1;
354

355
  return std::nullopt;
356
}
357

358
QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
359
  switch (getKind()) {
360
  case TemplateArgument::Null:
361
  case TemplateArgument::Type:
362
  case TemplateArgument::Template:
363
  case TemplateArgument::TemplateExpansion:
364
  case TemplateArgument::Pack:
365
    return QualType();
366

367
  case TemplateArgument::Integral:
368
    return getIntegralType();
369

370
  case TemplateArgument::Expression:
371
    return getAsExpr()->getType();
372

373
  case TemplateArgument::Declaration:
374
    return getParamTypeForDecl();
375

376
  case TemplateArgument::NullPtr:
377
    return getNullPtrType();
378

379
  case TemplateArgument::StructuralValue:
380
    return getStructuralValueType();
381
  }
382

383
  llvm_unreachable("Invalid TemplateArgument Kind!");
384
}
385

386
void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
387
                               const ASTContext &Context) const {
388
  ID.AddInteger(getKind());
389
  switch (getKind()) {
390
  case Null:
391
    break;
392

393
  case Type:
394
    getAsType().Profile(ID);
395
    break;
396

397
  case NullPtr:
398
    getNullPtrType().Profile(ID);
399
    break;
400

401
  case Declaration:
402
    getParamTypeForDecl().Profile(ID);
403
    ID.AddPointer(getAsDecl());
404
    break;
405

406
  case TemplateExpansion:
407
    ID.AddInteger(TemplateArg.NumExpansions);
408
    [[fallthrough]];
409
  case Template:
410
    ID.AddPointer(TemplateArg.Name);
411
    break;
412

413
  case Integral:
414
    getIntegralType().Profile(ID);
415
    getAsIntegral().Profile(ID);
416
    break;
417

418
  case StructuralValue:
419
    getStructuralValueType().Profile(ID);
420
    getAsStructuralValue().Profile(ID);
421
    break;
422

423
  case Expression:
424
    getAsExpr()->Profile(ID, Context, true);
425
    break;
426

427
  case Pack:
428
    ID.AddInteger(Args.NumArgs);
429
    for (unsigned I = 0; I != Args.NumArgs; ++I)
430
      Args.Args[I].Profile(ID, Context);
431
  }
432
}
433

434
bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
435
  if (getKind() != Other.getKind()) return false;
436

437
  switch (getKind()) {
438
  case Null:
439
  case Type:
440
  case Expression:
441
  case NullPtr:
442
    return TypeOrValue.V == Other.TypeOrValue.V;
443

444
  case Template:
445
  case TemplateExpansion:
446
    return TemplateArg.Name == Other.TemplateArg.Name &&
447
           TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
448

449
  case Declaration:
450
    return getAsDecl() == Other.getAsDecl() &&
451
           getParamTypeForDecl() == Other.getParamTypeForDecl();
452

453
  case Integral:
454
    return getIntegralType() == Other.getIntegralType() &&
455
           getAsIntegral() == Other.getAsIntegral();
456

457
  case StructuralValue: {
458
    if (getStructuralValueType().getCanonicalType() !=
459
        Other.getStructuralValueType().getCanonicalType())
460
      return false;
461

462
    llvm::FoldingSetNodeID A, B;
463
    getAsStructuralValue().Profile(A);
464
    Other.getAsStructuralValue().Profile(B);
465
    return A == B;
466
  }
467

468
  case Pack:
469
    if (Args.NumArgs != Other.Args.NumArgs) return false;
470
    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
471
      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
472
        return false;
473
    return true;
474
  }
475

476
  llvm_unreachable("Invalid TemplateArgument Kind!");
477
}
478

479
TemplateArgument TemplateArgument::getPackExpansionPattern() const {
480
  assert(isPackExpansion());
481

482
  switch (getKind()) {
483
  case Type:
484
    return getAsType()->castAs<PackExpansionType>()->getPattern();
485

486
  case Expression:
487
    return cast<PackExpansionExpr>(getAsExpr())->getPattern();
488

489
  case TemplateExpansion:
490
    return TemplateArgument(getAsTemplateOrTemplatePattern());
491

492
  case Declaration:
493
  case Integral:
494
  case StructuralValue:
495
  case Pack:
496
  case Null:
497
  case Template:
498
  case NullPtr:
499
    return TemplateArgument();
500
  }
501

502
  llvm_unreachable("Invalid TemplateArgument Kind!");
503
}
504

505
void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
506
                             bool IncludeType) const {
507

508
  switch (getKind()) {
509
  case Null:
510
    Out << "(no value)";
511
    break;
512

513
  case Type: {
514
    PrintingPolicy SubPolicy(Policy);
515
    SubPolicy.SuppressStrongLifetime = true;
516
    getAsType().print(Out, SubPolicy);
517
    break;
518
  }
519

520
  case Declaration: {
521
    NamedDecl *ND = getAsDecl();
522
    if (getParamTypeForDecl()->isRecordType()) {
523
      if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
524
        TPO->getType().getUnqualifiedType().print(Out, Policy);
525
        TPO->printAsInit(Out, Policy);
526
        break;
527
      }
528
    }
529
    if (auto *VD = dyn_cast<ValueDecl>(ND)) {
530
      if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType()))
531
        Out << "&";
532
    }
533
    ND->printQualifiedName(Out);
534
    break;
535
  }
536

537
  case StructuralValue:
538
    getAsStructuralValue().printPretty(Out, Policy, getStructuralValueType());
539
    break;
540

541
  case NullPtr:
542
    // FIXME: Include the type if it's not obvious from the context.
543
    Out << "nullptr";
544
    break;
545

546
  case Template: {
547
    getAsTemplate().print(Out, Policy);
548
    break;
549
  }
550

551
  case TemplateExpansion:
552
    getAsTemplateOrTemplatePattern().print(Out, Policy);
553
    Out << "...";
554
    break;
555

556
  case Integral:
557
    printIntegral(*this, Out, Policy, IncludeType);
558
    break;
559

560
  case Expression:
561
    getAsExpr()->printPretty(Out, nullptr, Policy);
562
    break;
563

564
  case Pack:
565
    Out << "<";
566
    bool First = true;
567
    for (const auto &P : pack_elements()) {
568
      if (First)
569
        First = false;
570
      else
571
        Out << ", ";
572

573
      P.print(Policy, Out, IncludeType);
574
    }
575
    Out << ">";
576
    break;
577
  }
578
}
579

580
//===----------------------------------------------------------------------===//
581
// TemplateArgumentLoc Implementation
582
//===----------------------------------------------------------------------===//
583

584
SourceRange TemplateArgumentLoc::getSourceRange() const {
585
  switch (Argument.getKind()) {
586
  case TemplateArgument::Expression:
587
    return getSourceExpression()->getSourceRange();
588

589
  case TemplateArgument::Declaration:
590
    return getSourceDeclExpression()->getSourceRange();
591

592
  case TemplateArgument::NullPtr:
593
    return getSourceNullPtrExpression()->getSourceRange();
594

595
  case TemplateArgument::Type:
596
    if (TypeSourceInfo *TSI = getTypeSourceInfo())
597
      return TSI->getTypeLoc().getSourceRange();
598
    else
599
      return SourceRange();
600

601
  case TemplateArgument::Template:
602
    if (getTemplateQualifierLoc())
603
      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
604
                         getTemplateNameLoc());
605
    return SourceRange(getTemplateNameLoc());
606

607
  case TemplateArgument::TemplateExpansion:
608
    if (getTemplateQualifierLoc())
609
      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
610
                         getTemplateEllipsisLoc());
611
    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
612

613
  case TemplateArgument::Integral:
614
    return getSourceIntegralExpression()->getSourceRange();
615

616
  case TemplateArgument::StructuralValue:
617
    return getSourceStructuralValueExpression()->getSourceRange();
618

619
  case TemplateArgument::Pack:
620
  case TemplateArgument::Null:
621
    return SourceRange();
622
  }
623

624
  llvm_unreachable("Invalid TemplateArgument Kind!");
625
}
626

627
template <typename T>
628
static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
629
  switch (Arg.getKind()) {
630
  case TemplateArgument::Null:
631
    // This is bad, but not as bad as crashing because of argument
632
    // count mismatches.
633
    return DB << "(null template argument)";
634

635
  case TemplateArgument::Type:
636
    return DB << Arg.getAsType();
637

638
  case TemplateArgument::Declaration:
639
    return DB << Arg.getAsDecl();
640

641
  case TemplateArgument::NullPtr:
642
    return DB << "nullptr";
643

644
  case TemplateArgument::Integral:
645
    return DB << toString(Arg.getAsIntegral(), 10);
646

647
  case TemplateArgument::StructuralValue: {
648
    // FIXME: We're guessing at LangOptions!
649
    SmallString<32> Str;
650
    llvm::raw_svector_ostream OS(Str);
651
    LangOptions LangOpts;
652
    LangOpts.CPlusPlus = true;
653
    PrintingPolicy Policy(LangOpts);
654
    Arg.getAsStructuralValue().printPretty(OS, Policy,
655
                                           Arg.getStructuralValueType());
656
    return DB << OS.str();
657
  }
658

659
  case TemplateArgument::Template:
660
    return DB << Arg.getAsTemplate();
661

662
  case TemplateArgument::TemplateExpansion:
663
    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
664

665
  case TemplateArgument::Expression: {
666
    // This shouldn't actually ever happen, so it's okay that we're
667
    // regurgitating an expression here.
668
    // FIXME: We're guessing at LangOptions!
669
    SmallString<32> Str;
670
    llvm::raw_svector_ostream OS(Str);
671
    LangOptions LangOpts;
672
    LangOpts.CPlusPlus = true;
673
    PrintingPolicy Policy(LangOpts);
674
    Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
675
    return DB << OS.str();
676
  }
677

678
  case TemplateArgument::Pack: {
679
    // FIXME: We're guessing at LangOptions!
680
    SmallString<32> Str;
681
    llvm::raw_svector_ostream OS(Str);
682
    LangOptions LangOpts;
683
    LangOpts.CPlusPlus = true;
684
    PrintingPolicy Policy(LangOpts);
685
    Arg.print(Policy, OS, /*IncludeType*/ true);
686
    return DB << OS.str();
687
  }
688
  }
689

690
  llvm_unreachable("Invalid TemplateArgument Kind!");
691
}
692

693
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
694
                                             const TemplateArgument &Arg) {
695
  return DiagTemplateArg(DB, Arg);
696
}
697

698
clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
699
    ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
700
    SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
701
  TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
702
  Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
703
  Template->QualifierLocData = QualifierLoc.getOpaqueData();
704
  Template->TemplateNameLoc = TemplateNameLoc;
705
  Template->EllipsisLoc = EllipsisLoc;
706
  Pointer = Template;
707
}
708

709
const ASTTemplateArgumentListInfo *
710
ASTTemplateArgumentListInfo::Create(const ASTContext &C,
711
                                    const TemplateArgumentListInfo &List) {
712
  std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
713
  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
714
  return new (Mem) ASTTemplateArgumentListInfo(List);
715
}
716

717
const ASTTemplateArgumentListInfo *
718
ASTTemplateArgumentListInfo::Create(const ASTContext &C,
719
                                    const ASTTemplateArgumentListInfo *List) {
720
  if (!List)
721
    return nullptr;
722
  std::size_t size =
723
      totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
724
  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
725
  return new (Mem) ASTTemplateArgumentListInfo(List);
726
}
727

728
ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
729
    const TemplateArgumentListInfo &Info) {
730
  LAngleLoc = Info.getLAngleLoc();
731
  RAngleLoc = Info.getRAngleLoc();
732
  NumTemplateArgs = Info.size();
733

734
  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
735
  for (unsigned i = 0; i != NumTemplateArgs; ++i)
736
    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
737
}
738

739
ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
740
    const ASTTemplateArgumentListInfo *Info) {
741
  LAngleLoc = Info->getLAngleLoc();
742
  RAngleLoc = Info->getRAngleLoc();
743
  NumTemplateArgs = Info->getNumTemplateArgs();
744

745
  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
746
  for (unsigned i = 0; i != NumTemplateArgs; ++i)
747
    new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
748
}
749

750
void ASTTemplateKWAndArgsInfo::initializeFrom(
751
    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
752
    TemplateArgumentLoc *OutArgArray) {
753
  this->TemplateKWLoc = TemplateKWLoc;
754
  LAngleLoc = Info.getLAngleLoc();
755
  RAngleLoc = Info.getRAngleLoc();
756
  NumTemplateArgs = Info.size();
757

758
  for (unsigned i = 0; i != NumTemplateArgs; ++i)
759
    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
760
}
761

762
void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
763
  assert(TemplateKWLoc.isValid());
764
  LAngleLoc = SourceLocation();
765
  RAngleLoc = SourceLocation();
766
  this->TemplateKWLoc = TemplateKWLoc;
767
  NumTemplateArgs = 0;
768
}
769

770
void ASTTemplateKWAndArgsInfo::initializeFrom(
771
    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
772
    TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
773
  this->TemplateKWLoc = TemplateKWLoc;
774
  LAngleLoc = Info.getLAngleLoc();
775
  RAngleLoc = Info.getRAngleLoc();
776
  NumTemplateArgs = Info.size();
777

778
  for (unsigned i = 0; i != NumTemplateArgs; ++i) {
779
    Deps |= Info[i].getArgument().getDependence();
780

781
    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
782
  }
783
}
784

785
void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
786
                                        TemplateArgumentListInfo &Info) const {
787
  Info.setLAngleLoc(LAngleLoc);
788
  Info.setRAngleLoc(RAngleLoc);
789
  for (unsigned I = 0; I != NumTemplateArgs; ++I)
790
    Info.addArgument(ArgArray[I]);
791
}
792

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.