Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/AST/ASTDiagnostic.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- ASTDiagnostic.cpp - Diagnostic Printing Hooks for AST Nodes ------===//
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 a diagnostic formatting hook for AST elements.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/AST/ASTDiagnostic.h"
14
#include "clang/AST/ASTContext.h"
15
#include "clang/AST/ASTLambda.h"
16
#include "clang/AST/Attr.h"
17
#include "clang/AST/DeclObjC.h"
18
#include "clang/AST/DeclTemplate.h"
19
#include "clang/AST/ExprCXX.h"
20
#include "clang/AST/TemplateBase.h"
21
#include "clang/AST/Type.h"
22
#include "llvm/ADT/StringExtras.h"
23
#include "llvm/Support/raw_ostream.h"
24
25
using namespace clang;
26
27
// Returns a desugared version of the QualType, and marks ShouldAKA as true
28
// whenever we remove significant sugar from the type. Make sure ShouldAKA
29
// is initialized before passing it in.
30
QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT,
31
0
                                     bool &ShouldAKA) {
32
0
  QualifierCollector QC;
33
34
0
  while (true) {
35
0
    const Type *Ty = QC.strip(QT);
36
37
    // Don't aka just because we saw an elaborated type...
38
0
    if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(Ty)) {
39
0
      QT = ET->desugar();
40
0
      continue;
41
0
    }
42
    // ... or a using type ...
43
0
    if (const UsingType *UT = dyn_cast<UsingType>(Ty)) {
44
0
      QT = UT->desugar();
45
0
      continue;
46
0
    }
47
    // ... or a paren type ...
48
0
    if (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
49
0
      QT = PT->desugar();
50
0
      continue;
51
0
    }
52
    // ... or a macro defined type ...
53
0
    if (const MacroQualifiedType *MDT = dyn_cast<MacroQualifiedType>(Ty)) {
54
0
      QT = MDT->desugar();
55
0
      continue;
56
0
    }
57
    // ...or a substituted template type parameter ...
58
0
    if (const SubstTemplateTypeParmType *ST =
59
0
          dyn_cast<SubstTemplateTypeParmType>(Ty)) {
60
0
      QT = ST->desugar();
61
0
      continue;
62
0
    }
63
    // ...or an attributed type...
64
0
    if (const AttributedType *AT = dyn_cast<AttributedType>(Ty)) {
65
0
      QT = AT->desugar();
66
0
      continue;
67
0
    }
68
    // ...or an adjusted type...
69
0
    if (const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) {
70
0
      QT = AT->desugar();
71
0
      continue;
72
0
    }
73
    // ... or an auto type.
74
0
    if (const AutoType *AT = dyn_cast<AutoType>(Ty)) {
75
0
      if (!AT->isSugared())
76
0
        break;
77
0
      QT = AT->desugar();
78
0
      continue;
79
0
    }
80
81
    // Desugar FunctionType if return type or any parameter type should be
82
    // desugared. Preserve nullability attribute on desugared types.
83
0
    if (const FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
84
0
      bool DesugarReturn = false;
85
0
      QualType SugarRT = FT->getReturnType();
86
0
      QualType RT = desugarForDiagnostic(Context, SugarRT, DesugarReturn);
87
0
      if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) {
88
0
        RT = Context.getAttributedType(
89
0
            AttributedType::getNullabilityAttrKind(*nullability), RT, RT);
90
0
      }
91
92
0
      bool DesugarArgument = false;
93
0
      SmallVector<QualType, 4> Args;
94
0
      const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT);
95
0
      if (FPT) {
96
0
        for (QualType SugarPT : FPT->param_types()) {
97
0
          QualType PT = desugarForDiagnostic(Context, SugarPT, DesugarArgument);
98
0
          if (auto nullability =
99
0
                  AttributedType::stripOuterNullability(SugarPT)) {
100
0
            PT = Context.getAttributedType(
101
0
                AttributedType::getNullabilityAttrKind(*nullability), PT, PT);
102
0
          }
103
0
          Args.push_back(PT);
104
0
        }
105
0
      }
106
107
0
      if (DesugarReturn || DesugarArgument) {
108
0
        ShouldAKA = true;
109
0
        QT = FPT ? Context.getFunctionType(RT, Args, FPT->getExtProtoInfo())
110
0
                 : Context.getFunctionNoProtoType(RT, FT->getExtInfo());
111
0
        break;
112
0
      }
113
0
    }
114
115
    // Desugar template specializations if any template argument should be
116
    // desugared.
117
0
    if (const TemplateSpecializationType *TST =
118
0
            dyn_cast<TemplateSpecializationType>(Ty)) {
119
0
      if (!TST->isTypeAlias()) {
120
0
        bool DesugarArgument = false;
121
0
        SmallVector<TemplateArgument, 4> Args;
122
0
        for (const TemplateArgument &Arg : TST->template_arguments()) {
123
0
          if (Arg.getKind() == TemplateArgument::Type)
124
0
            Args.push_back(desugarForDiagnostic(Context, Arg.getAsType(),
125
0
                                                DesugarArgument));
126
0
          else
127
0
            Args.push_back(Arg);
128
0
        }
129
130
0
        if (DesugarArgument) {
131
0
          ShouldAKA = true;
132
0
          QT = Context.getTemplateSpecializationType(
133
0
              TST->getTemplateName(), Args, QT);
134
0
        }
135
0
        break;
136
0
      }
137
0
    }
138
139
0
    if (const auto *AT = dyn_cast<ArrayType>(Ty)) {
140
0
      QualType ElementTy =
141
0
          desugarForDiagnostic(Context, AT->getElementType(), ShouldAKA);
142
0
      if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
143
0
        QT = Context.getConstantArrayType(
144
0
            ElementTy, CAT->getSize(), CAT->getSizeExpr(),
145
0
            CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());
146
0
      else if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
147
0
        QT = Context.getVariableArrayType(
148
0
            ElementTy, VAT->getSizeExpr(), VAT->getSizeModifier(),
149
0
            VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange());
150
0
      else if (const auto *DSAT = dyn_cast<DependentSizedArrayType>(AT))
151
0
        QT = Context.getDependentSizedArrayType(
152
0
            ElementTy, DSAT->getSizeExpr(), DSAT->getSizeModifier(),
153
0
            DSAT->getIndexTypeCVRQualifiers(), DSAT->getBracketsRange());
154
0
      else if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT))
155
0
        QT = Context.getIncompleteArrayType(ElementTy, IAT->getSizeModifier(),
156
0
                                            IAT->getIndexTypeCVRQualifiers());
157
0
      else
158
0
        llvm_unreachable("Unhandled array type");
159
0
      break;
160
0
    }
161
162
    // Don't desugar magic Objective-C types.
163
0
    if (QualType(Ty,0) == Context.getObjCIdType() ||
164
0
        QualType(Ty,0) == Context.getObjCClassType() ||
165
0
        QualType(Ty,0) == Context.getObjCSelType() ||
166
0
        QualType(Ty,0) == Context.getObjCProtoType())
167
0
      break;
168
169
    // Don't desugar va_list.
170
0
    if (QualType(Ty, 0) == Context.getBuiltinVaListType() ||
171
0
        QualType(Ty, 0) == Context.getBuiltinMSVaListType())
172
0
      break;
173
174
    // Otherwise, do a single-step desugar.
175
0
    QualType Underlying;
176
0
    bool IsSugar = false;
177
0
    switch (Ty->getTypeClass()) {
178
0
#define ABSTRACT_TYPE(Class, Base)
179
0
#define TYPE(Class, Base) \
180
0
case Type::Class: { \
181
0
const Class##Type *CTy = cast<Class##Type>(Ty); \
182
0
if (CTy->isSugared()) { \
183
0
IsSugar = true; \
184
0
Underlying = CTy->desugar(); \
185
0
} \
186
0
break; \
187
0
}
188
0
#include "clang/AST/TypeNodes.inc"
189
0
    }
190
191
    // If it wasn't sugared, we're done.
192
0
    if (!IsSugar)
193
0
      break;
194
195
    // If the desugared type is a vector type, we don't want to expand
196
    // it, it will turn into an attribute mess. People want their "vec4".
197
0
    if (isa<VectorType>(Underlying))
198
0
      break;
199
200
    // Don't desugar through the primary typedef of an anonymous type.
201
0
    if (const TagType *UTT = Underlying->getAs<TagType>())
202
0
      if (const TypedefType *QTT = dyn_cast<TypedefType>(QT))
203
0
        if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl())
204
0
          break;
205
206
    // Record that we actually looked through an opaque type here.
207
0
    ShouldAKA = true;
208
0
    QT = Underlying;
209
0
  }
210
211
  // If we have a pointer-like type, desugar the pointee as well.
212
  // FIXME: Handle other pointer-like types.
213
0
  if (const PointerType *Ty = QT->getAs<PointerType>()) {
214
0
    QT = Context.getPointerType(
215
0
        desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
216
0
  } else if (const auto *Ty = QT->getAs<ObjCObjectPointerType>()) {
217
0
    QT = Context.getObjCObjectPointerType(
218
0
        desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
219
0
  } else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) {
220
0
    QT = Context.getLValueReferenceType(
221
0
        desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
222
0
  } else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) {
223
0
    QT = Context.getRValueReferenceType(
224
0
        desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
225
0
  } else if (const auto *Ty = QT->getAs<ObjCObjectType>()) {
226
0
    if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {
227
0
      QualType BaseType =
228
0
          desugarForDiagnostic(Context, Ty->getBaseType(), ShouldAKA);
229
0
      QT = Context.getObjCObjectType(
230
0
          BaseType, Ty->getTypeArgsAsWritten(),
231
0
          llvm::ArrayRef(Ty->qual_begin(), Ty->getNumProtocols()),
232
0
          Ty->isKindOfTypeAsWritten());
233
0
    }
234
0
  }
235
236
0
  return QC.apply(Context, QT);
237
0
}
238
239
/// Convert the given type to a string suitable for printing as part of
240
/// a diagnostic.
241
///
242
/// There are four main criteria when determining whether we should have an
243
/// a.k.a. clause when pretty-printing a type:
244
///
245
/// 1) Some types provide very minimal sugar that doesn't impede the
246
///    user's understanding --- for example, elaborated type
247
///    specifiers.  If this is all the sugar we see, we don't want an
248
///    a.k.a. clause.
249
/// 2) Some types are technically sugared but are much more familiar
250
///    when seen in their sugared form --- for example, va_list,
251
///    vector types, and the magic Objective C types.  We don't
252
///    want to desugar these, even if we do produce an a.k.a. clause.
253
/// 3) Some types may have already been desugared previously in this diagnostic.
254
///    if this is the case, doing another "aka" would just be clutter.
255
/// 4) Two different types within the same diagnostic have the same output
256
///    string.  In this case, force an a.k.a with the desugared type when
257
///    doing so will provide additional information.
258
///
259
/// \param Context the context in which the type was allocated
260
/// \param Ty the type to print
261
/// \param QualTypeVals pointer values to QualTypes which are used in the
262
/// diagnostic message
263
static std::string
264
ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
265
                            ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
266
0
                            ArrayRef<intptr_t> QualTypeVals) {
267
  // FIXME: Playing with std::string is really slow.
268
0
  bool ForceAKA = false;
269
0
  QualType CanTy = Ty.getCanonicalType();
270
0
  std::string S = Ty.getAsString(Context.getPrintingPolicy());
271
0
  std::string CanS = CanTy.getAsString(Context.getPrintingPolicy());
272
273
0
  for (const intptr_t &QualTypeVal : QualTypeVals) {
274
0
    QualType CompareTy =
275
0
        QualType::getFromOpaquePtr(reinterpret_cast<void *>(QualTypeVal));
276
0
    if (CompareTy.isNull())
277
0
      continue;
278
0
    if (CompareTy == Ty)
279
0
      continue;  // Same types
280
0
    QualType CompareCanTy = CompareTy.getCanonicalType();
281
0
    if (CompareCanTy == CanTy)
282
0
      continue;  // Same canonical types
283
0
    std::string CompareS = CompareTy.getAsString(Context.getPrintingPolicy());
284
0
    bool ShouldAKA = false;
285
0
    QualType CompareDesugar =
286
0
        desugarForDiagnostic(Context, CompareTy, ShouldAKA);
287
0
    std::string CompareDesugarStr =
288
0
        CompareDesugar.getAsString(Context.getPrintingPolicy());
289
0
    if (CompareS != S && CompareDesugarStr != S)
290
0
      continue;  // The type string is different than the comparison string
291
                 // and the desugared comparison string.
292
0
    std::string CompareCanS =
293
0
        CompareCanTy.getAsString(Context.getPrintingPolicy());
294
295
0
    if (CompareCanS == CanS)
296
0
      continue;  // No new info from canonical type
297
298
0
    ForceAKA = true;
299
0
    break;
300
0
  }
301
302
  // Check to see if we already desugared this type in this
303
  // diagnostic.  If so, don't do it again.
304
0
  bool Repeated = false;
305
0
  for (const auto &PrevArg : PrevArgs) {
306
    // TODO: Handle ak_declcontext case.
307
0
    if (PrevArg.first == DiagnosticsEngine::ak_qualtype) {
308
0
      QualType PrevTy(
309
0
          QualType::getFromOpaquePtr(reinterpret_cast<void *>(PrevArg.second)));
310
0
      if (PrevTy == Ty) {
311
0
        Repeated = true;
312
0
        break;
313
0
      }
314
0
    }
315
0
  }
316
317
  // Consider producing an a.k.a. clause if removing all the direct
318
  // sugar gives us something "significantly different".
319
0
  if (!Repeated) {
320
0
    bool ShouldAKA = false;
321
0
    QualType DesugaredTy = desugarForDiagnostic(Context, Ty, ShouldAKA);
322
0
    if (ShouldAKA || ForceAKA) {
323
0
      if (DesugaredTy == Ty) {
324
0
        DesugaredTy = Ty.getCanonicalType();
325
0
      }
326
0
      std::string akaStr = DesugaredTy.getAsString(Context.getPrintingPolicy());
327
0
      if (akaStr != S) {
328
0
        S = "'" + S + "' (aka '" + akaStr + "')";
329
0
        return S;
330
0
      }
331
0
    }
332
333
    // Give some additional info on vector types. These are either not desugared
334
    // or displaying complex __attribute__ expressions so add details of the
335
    // type and element count.
336
0
    if (const auto *VTy = Ty->getAs<VectorType>()) {
337
0
      std::string DecoratedString;
338
0
      llvm::raw_string_ostream OS(DecoratedString);
339
0
      const char *Values = VTy->getNumElements() > 1 ? "values" : "value";
340
0
      OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '"
341
0
         << VTy->getElementType().getAsString(Context.getPrintingPolicy())
342
0
         << "' " << Values << ")";
343
0
      return DecoratedString;
344
0
    }
345
0
  }
346
347
0
  S = "'" + S + "'";
348
0
  return S;
349
0
}
350
351
static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType,
352
                                   QualType ToType, bool PrintTree,
353
                                   bool PrintFromType, bool ElideType,
354
                                   bool ShowColors, raw_ostream &OS);
355
356
void clang::FormatASTNodeDiagnosticArgument(
357
    DiagnosticsEngine::ArgumentKind Kind,
358
    intptr_t Val,
359
    StringRef Modifier,
360
    StringRef Argument,
361
    ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
362
    SmallVectorImpl<char> &Output,
363
    void *Cookie,
364
0
    ArrayRef<intptr_t> QualTypeVals) {
365
0
  ASTContext &Context = *static_cast<ASTContext*>(Cookie);
366
367
0
  size_t OldEnd = Output.size();
368
0
  llvm::raw_svector_ostream OS(Output);
369
0
  bool NeedQuotes = true;
370
371
0
  switch (Kind) {
372
0
    default: llvm_unreachable("unknown ArgumentKind");
373
0
    case DiagnosticsEngine::ak_addrspace: {
374
0
      assert(Modifier.empty() && Argument.empty() &&
375
0
             "Invalid modifier for Qualifiers argument");
376
377
0
      auto S = Qualifiers::getAddrSpaceAsString(static_cast<LangAS>(Val));
378
0
      if (S.empty()) {
379
0
        OS << (Context.getLangOpts().OpenCL ? "default" : "generic");
380
0
        OS << " address space";
381
0
      } else {
382
0
        OS << "address space";
383
0
        OS << " '" << S << "'";
384
0
      }
385
0
      NeedQuotes = false;
386
0
      break;
387
0
    }
388
0
    case DiagnosticsEngine::ak_qual: {
389
0
      assert(Modifier.empty() && Argument.empty() &&
390
0
             "Invalid modifier for Qualifiers argument");
391
392
0
      Qualifiers Q(Qualifiers::fromOpaqueValue(Val));
393
0
      auto S = Q.getAsString();
394
0
      if (S.empty()) {
395
0
        OS << "unqualified";
396
0
        NeedQuotes = false;
397
0
      } else {
398
0
        OS << S;
399
0
      }
400
0
      break;
401
0
    }
402
0
    case DiagnosticsEngine::ak_qualtype_pair: {
403
0
      TemplateDiffTypes &TDT = *reinterpret_cast<TemplateDiffTypes*>(Val);
404
0
      QualType FromType =
405
0
          QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.FromType));
406
0
      QualType ToType =
407
0
          QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.ToType));
408
409
0
      if (FormatTemplateTypeDiff(Context, FromType, ToType, TDT.PrintTree,
410
0
                                 TDT.PrintFromType, TDT.ElideType,
411
0
                                 TDT.ShowColors, OS)) {
412
0
        NeedQuotes = !TDT.PrintTree;
413
0
        TDT.TemplateDiffUsed = true;
414
0
        break;
415
0
      }
416
417
      // Don't fall-back during tree printing.  The caller will handle
418
      // this case.
419
0
      if (TDT.PrintTree)
420
0
        return;
421
422
      // Attempting to do a template diff on non-templates.  Set the variables
423
      // and continue with regular type printing of the appropriate type.
424
0
      Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType;
425
0
      Modifier = StringRef();
426
0
      Argument = StringRef();
427
      // Fall through
428
0
      [[fallthrough]];
429
0
    }
430
0
    case DiagnosticsEngine::ak_qualtype: {
431
0
      assert(Modifier.empty() && Argument.empty() &&
432
0
             "Invalid modifier for QualType argument");
433
434
0
      QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
435
0
      OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals);
436
0
      NeedQuotes = false;
437
0
      break;
438
0
    }
439
0
    case DiagnosticsEngine::ak_declarationname: {
440
0
      if (Modifier == "objcclass" && Argument.empty())
441
0
        OS << '+';
442
0
      else if (Modifier == "objcinstance" && Argument.empty())
443
0
        OS << '-';
444
0
      else
445
0
        assert(Modifier.empty() && Argument.empty() &&
446
0
               "Invalid modifier for DeclarationName argument");
447
448
0
      OS << DeclarationName::getFromOpaqueInteger(Val);
449
0
      break;
450
0
    }
451
0
    case DiagnosticsEngine::ak_nameddecl: {
452
0
      bool Qualified;
453
0
      if (Modifier == "q" && Argument.empty())
454
0
        Qualified = true;
455
0
      else {
456
0
        assert(Modifier.empty() && Argument.empty() &&
457
0
               "Invalid modifier for NamedDecl* argument");
458
0
        Qualified = false;
459
0
      }
460
0
      const NamedDecl *ND = reinterpret_cast<const NamedDecl*>(Val);
461
0
      ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), Qualified);
462
0
      break;
463
0
    }
464
0
    case DiagnosticsEngine::ak_nestednamespec: {
465
0
      NestedNameSpecifier *NNS = reinterpret_cast<NestedNameSpecifier*>(Val);
466
0
      NNS->print(OS, Context.getPrintingPolicy());
467
0
      NeedQuotes = false;
468
0
      break;
469
0
    }
470
0
    case DiagnosticsEngine::ak_declcontext: {
471
0
      DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
472
0
      assert(DC && "Should never have a null declaration context");
473
0
      NeedQuotes = false;
474
475
      // FIXME: Get the strings for DeclContext from some localized place
476
0
      if (DC->isTranslationUnit()) {
477
0
        if (Context.getLangOpts().CPlusPlus)
478
0
          OS << "the global namespace";
479
0
        else
480
0
          OS << "the global scope";
481
0
      } else if (DC->isClosure()) {
482
0
        OS << "block literal";
483
0
      } else if (isLambdaCallOperator(DC)) {
484
0
        OS << "lambda expression";
485
0
      } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
486
0
        OS << ConvertTypeToDiagnosticString(Context,
487
0
                                            Context.getTypeDeclType(Type),
488
0
                                            PrevArgs, QualTypeVals);
489
0
      } else {
490
0
        assert(isa<NamedDecl>(DC) && "Expected a NamedDecl");
491
0
        NamedDecl *ND = cast<NamedDecl>(DC);
492
0
        if (isa<NamespaceDecl>(ND))
493
0
          OS << "namespace ";
494
0
        else if (isa<ObjCMethodDecl>(ND))
495
0
          OS << "method ";
496
0
        else if (isa<FunctionDecl>(ND))
497
0
          OS << "function ";
498
499
0
        OS << '\'';
500
0
        ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true);
501
0
        OS << '\'';
502
0
      }
503
0
      break;
504
0
    }
505
0
    case DiagnosticsEngine::ak_attr: {
506
0
      const Attr *At = reinterpret_cast<Attr *>(Val);
507
0
      assert(At && "Received null Attr object!");
508
0
      OS << '\'' << At->getSpelling() << '\'';
509
0
      NeedQuotes = false;
510
0
      break;
511
0
    }
512
0
  }
513
514
0
  if (NeedQuotes) {
515
0
    Output.insert(Output.begin()+OldEnd, '\'');
516
0
    Output.push_back('\'');
517
0
  }
518
0
}
519
520
/// TemplateDiff - A class that constructs a pretty string for a pair of
521
/// QualTypes.  For the pair of types, a diff tree will be created containing
522
/// all the information about the templates and template arguments.  Afterwards,
523
/// the tree is transformed to a string according to the options passed in.
524
namespace {
525
class TemplateDiff {
526
  /// Context - The ASTContext which is used for comparing template arguments.
527
  ASTContext &Context;
528
529
  /// Policy - Used during expression printing.
530
  PrintingPolicy Policy;
531
532
  /// ElideType - Option to elide identical types.
533
  bool ElideType;
534
535
  /// PrintTree - Format output string as a tree.
536
  bool PrintTree;
537
538
  /// ShowColor - Diagnostics support color, so bolding will be used.
539
  bool ShowColor;
540
541
  /// FromTemplateType - When single type printing is selected, this is the
542
  /// type to be printed.  When tree printing is selected, this type will
543
  /// show up first in the tree.
544
  QualType FromTemplateType;
545
546
  /// ToTemplateType - The type that FromType is compared to.  Only in tree
547
  /// printing will this type be outputed.
548
  QualType ToTemplateType;
549
550
  /// OS - The stream used to construct the output strings.
551
  raw_ostream &OS;
552
553
  /// IsBold - Keeps track of the bold formatting for the output string.
554
  bool IsBold;
555
556
  /// DiffTree - A tree representation the differences between two types.
557
  class DiffTree {
558
  public:
559
    /// DiffKind - The difference in a DiffNode.  Fields of
560
    /// TemplateArgumentInfo needed by each difference can be found in the
561
    /// Set* and Get* functions.
562
    enum DiffKind {
563
      /// Incomplete or invalid node.
564
      Invalid,
565
      /// Another level of templates
566
      Template,
567
      /// Type difference, all type differences except those falling under
568
      /// the Template difference.
569
      Type,
570
      /// Expression difference, this is only when both arguments are
571
      /// expressions.  If one argument is an expression and the other is
572
      /// Integer or Declaration, then use that diff type instead.
573
      Expression,
574
      /// Template argument difference
575
      TemplateTemplate,
576
      /// Integer difference
577
      Integer,
578
      /// Declaration difference, nullptr arguments are included here
579
      Declaration,
580
      /// One argument being integer and the other being declaration
581
      FromIntegerAndToDeclaration,
582
      FromDeclarationAndToInteger
583
    };
584
585
  private:
586
    /// TemplateArgumentInfo - All the information needed to pretty print
587
    /// a template argument.  See the Set* and Get* functions to see which
588
    /// fields are used for each DiffKind.
589
    struct TemplateArgumentInfo {
590
      QualType ArgType;
591
      Qualifiers Qual;
592
      llvm::APSInt Val;
593
      bool IsValidInt = false;
594
      Expr *ArgExpr = nullptr;
595
      TemplateDecl *TD = nullptr;
596
      ValueDecl *VD = nullptr;
597
      bool NeedAddressOf = false;
598
      bool IsNullPtr = false;
599
      bool IsDefault = false;
600
    };
601
602
    /// DiffNode - The root node stores the original type.  Each child node
603
    /// stores template arguments of their parents.  For templated types, the
604
    /// template decl is also stored.
605
    struct DiffNode {
606
      DiffKind Kind = Invalid;
607
608
      /// NextNode - The index of the next sibling node or 0.
609
      unsigned NextNode = 0;
610
611
      /// ChildNode - The index of the first child node or 0.
612
      unsigned ChildNode = 0;
613
614
      /// ParentNode - The index of the parent node.
615
      unsigned ParentNode = 0;
616
617
      TemplateArgumentInfo FromArgInfo, ToArgInfo;
618
619
      /// Same - Whether the two arguments evaluate to the same value.
620
      bool Same = false;
621
622
0
      DiffNode(unsigned ParentNode = 0) : ParentNode(ParentNode) {}
623
    };
624
625
    /// FlatTree - A flattened tree used to store the DiffNodes.
626
    SmallVector<DiffNode, 16> FlatTree;
627
628
    /// CurrentNode - The index of the current node being used.
629
    unsigned CurrentNode;
630
631
    /// NextFreeNode - The index of the next unused node.  Used when creating
632
    /// child nodes.
633
    unsigned NextFreeNode;
634
635
    /// ReadNode - The index of the current node being read.
636
    unsigned ReadNode;
637
638
  public:
639
0
    DiffTree() : CurrentNode(0), NextFreeNode(1), ReadNode(0) {
640
0
      FlatTree.push_back(DiffNode());
641
0
    }
642
643
    // Node writing functions, one for each valid DiffKind element.
644
    void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
645
                         Qualifiers FromQual, Qualifiers ToQual,
646
0
                         bool FromDefault, bool ToDefault) {
647
0
      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
648
0
      FlatTree[CurrentNode].Kind = Template;
649
0
      FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
650
0
      FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
651
0
      FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;
652
0
      FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;
653
0
      SetDefault(FromDefault, ToDefault);
654
0
    }
655
656
    void SetTypeDiff(QualType FromType, QualType ToType, bool FromDefault,
657
0
                     bool ToDefault) {
658
0
      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
659
0
      FlatTree[CurrentNode].Kind = Type;
660
0
      FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;
661
0
      FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;
662
0
      SetDefault(FromDefault, ToDefault);
663
0
    }
664
665
    void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr, bool FromDefault,
666
0
                           bool ToDefault) {
667
0
      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
668
0
      FlatTree[CurrentNode].Kind = Expression;
669
0
      FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
670
0
      FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
671
0
      SetDefault(FromDefault, ToDefault);
672
0
    }
673
674
    void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
675
0
                                 bool FromDefault, bool ToDefault) {
676
0
      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
677
0
      FlatTree[CurrentNode].Kind = TemplateTemplate;
678
0
      FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
679
0
      FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
680
0
      SetDefault(FromDefault, ToDefault);
681
0
    }
682
683
    void SetIntegerDiff(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt,
684
                        bool IsValidFromInt, bool IsValidToInt,
685
                        QualType FromIntType, QualType ToIntType,
686
                        Expr *FromExpr, Expr *ToExpr, bool FromDefault,
687
0
                        bool ToDefault) {
688
0
      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
689
0
      FlatTree[CurrentNode].Kind = Integer;
690
0
      FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
691
0
      FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
692
0
      FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
693
0
      FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
694
0
      FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
695
0
      FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
696
0
      FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
697
0
      FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
698
0
      SetDefault(FromDefault, ToDefault);
699
0
    }
700
701
    void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
702
                            bool FromAddressOf, bool ToAddressOf,
703
                            bool FromNullPtr, bool ToNullPtr, Expr *FromExpr,
704
0
                            Expr *ToExpr, bool FromDefault, bool ToDefault) {
705
0
      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
706
0
      FlatTree[CurrentNode].Kind = Declaration;
707
0
      FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
708
0
      FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
709
0
      FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
710
0
      FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
711
0
      FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
712
0
      FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
713
0
      FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
714
0
      FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
715
0
      SetDefault(FromDefault, ToDefault);
716
0
    }
717
718
    void SetFromDeclarationAndToIntegerDiff(
719
        ValueDecl *FromValueDecl, bool FromAddressOf, bool FromNullPtr,
720
        Expr *FromExpr, const llvm::APSInt &ToInt, bool IsValidToInt,
721
0
        QualType ToIntType, Expr *ToExpr, bool FromDefault, bool ToDefault) {
722
0
      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
723
0
      FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger;
724
0
      FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
725
0
      FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
726
0
      FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
727
0
      FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
728
0
      FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
729
0
      FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
730
0
      FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
731
0
      FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
732
0
      SetDefault(FromDefault, ToDefault);
733
0
    }
734
735
    void SetFromIntegerAndToDeclarationDiff(
736
        const llvm::APSInt &FromInt, bool IsValidFromInt, QualType FromIntType,
737
        Expr *FromExpr, ValueDecl *ToValueDecl, bool ToAddressOf,
738
0
        bool ToNullPtr, Expr *ToExpr, bool FromDefault, bool ToDefault) {
739
0
      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
740
0
      FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration;
741
0
      FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
742
0
      FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
743
0
      FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
744
0
      FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
745
0
      FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
746
0
      FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
747
0
      FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
748
0
      FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
749
0
      SetDefault(FromDefault, ToDefault);
750
0
    }
751
752
    /// SetDefault - Sets FromDefault and ToDefault flags of the current node.
753
0
    void SetDefault(bool FromDefault, bool ToDefault) {
754
0
      assert((!FromDefault || !ToDefault) && "Both arguments cannot be default.");
755
0
      FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;
756
0
      FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;
757
0
    }
758
759
    /// SetSame - Sets the same flag of the current node.
760
0
    void SetSame(bool Same) {
761
0
      FlatTree[CurrentNode].Same = Same;
762
0
    }
763
764
    /// SetKind - Sets the current node's type.
765
0
    void SetKind(DiffKind Kind) {
766
0
      FlatTree[CurrentNode].Kind = Kind;
767
0
    }
768
769
    /// Up - Changes the node to the parent of the current node.
770
0
    void Up() {
771
0
      assert(FlatTree[CurrentNode].Kind != Invalid &&
772
0
             "Cannot exit node before setting node information.");
773
0
      CurrentNode = FlatTree[CurrentNode].ParentNode;
774
0
    }
775
776
    /// AddNode - Adds a child node to the current node, then sets that node
777
    /// node as the current node.
778
0
    void AddNode() {
779
0
      assert(FlatTree[CurrentNode].Kind == Template &&
780
0
             "Only Template nodes can have children nodes.");
781
0
      FlatTree.push_back(DiffNode(CurrentNode));
782
0
      DiffNode &Node = FlatTree[CurrentNode];
783
0
      if (Node.ChildNode == 0) {
784
        // If a child node doesn't exist, add one.
785
0
        Node.ChildNode = NextFreeNode;
786
0
      } else {
787
        // If a child node exists, find the last child node and add a
788
        // next node to it.
789
0
        unsigned i;
790
0
        for (i = Node.ChildNode; FlatTree[i].NextNode != 0;
791
0
             i = FlatTree[i].NextNode) {
792
0
        }
793
0
        FlatTree[i].NextNode = NextFreeNode;
794
0
      }
795
0
      CurrentNode = NextFreeNode;
796
0
      ++NextFreeNode;
797
0
    }
798
799
    // Node reading functions.
800
    /// StartTraverse - Prepares the tree for recursive traversal.
801
0
    void StartTraverse() {
802
0
      ReadNode = 0;
803
0
      CurrentNode = NextFreeNode;
804
0
      NextFreeNode = 0;
805
0
    }
806
807
    /// Parent - Move the current read node to its parent.
808
0
    void Parent() {
809
0
      ReadNode = FlatTree[ReadNode].ParentNode;
810
0
    }
811
812
    void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD,
813
0
                         Qualifiers &FromQual, Qualifiers &ToQual) {
814
0
      assert(FlatTree[ReadNode].Kind == Template && "Unexpected kind.");
815
0
      FromTD = FlatTree[ReadNode].FromArgInfo.TD;
816
0
      ToTD = FlatTree[ReadNode].ToArgInfo.TD;
817
0
      FromQual = FlatTree[ReadNode].FromArgInfo.Qual;
818
0
      ToQual = FlatTree[ReadNode].ToArgInfo.Qual;
819
0
    }
820
821
0
    void GetTypeDiff(QualType &FromType, QualType &ToType) {
822
0
      assert(FlatTree[ReadNode].Kind == Type && "Unexpected kind");
823
0
      FromType = FlatTree[ReadNode].FromArgInfo.ArgType;
824
0
      ToType = FlatTree[ReadNode].ToArgInfo.ArgType;
825
0
    }
826
827
0
    void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) {
828
0
      assert(FlatTree[ReadNode].Kind == Expression && "Unexpected kind");
829
0
      FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
830
0
      ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
831
0
    }
832
833
0
    void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {
834
0
      assert(FlatTree[ReadNode].Kind == TemplateTemplate && "Unexpected kind.");
835
0
      FromTD = FlatTree[ReadNode].FromArgInfo.TD;
836
0
      ToTD = FlatTree[ReadNode].ToArgInfo.TD;
837
0
    }
838
839
    void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
840
                        bool &IsValidFromInt, bool &IsValidToInt,
841
                        QualType &FromIntType, QualType &ToIntType,
842
0
                        Expr *&FromExpr, Expr *&ToExpr) {
843
0
      assert(FlatTree[ReadNode].Kind == Integer && "Unexpected kind.");
844
0
      FromInt = FlatTree[ReadNode].FromArgInfo.Val;
845
0
      ToInt = FlatTree[ReadNode].ToArgInfo.Val;
846
0
      IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
847
0
      IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
848
0
      FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
849
0
      ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
850
0
      FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
851
0
      ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
852
0
    }
853
854
    void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,
855
                            bool &FromAddressOf, bool &ToAddressOf,
856
                            bool &FromNullPtr, bool &ToNullPtr, Expr *&FromExpr,
857
0
                            Expr *&ToExpr) {
858
0
      assert(FlatTree[ReadNode].Kind == Declaration && "Unexpected kind.");
859
0
      FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
860
0
      ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
861
0
      FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
862
0
      ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
863
0
      FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
864
0
      ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
865
0
      FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
866
0
      ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
867
0
    }
868
869
    void GetFromDeclarationAndToIntegerDiff(
870
        ValueDecl *&FromValueDecl, bool &FromAddressOf, bool &FromNullPtr,
871
        Expr *&FromExpr, llvm::APSInt &ToInt, bool &IsValidToInt,
872
0
        QualType &ToIntType, Expr *&ToExpr) {
873
0
      assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger &&
874
0
             "Unexpected kind.");
875
0
      FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
876
0
      FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
877
0
      FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
878
0
      FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
879
0
      ToInt = FlatTree[ReadNode].ToArgInfo.Val;
880
0
      IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
881
0
      ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
882
0
      ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
883
0
    }
884
885
    void GetFromIntegerAndToDeclarationDiff(
886
        llvm::APSInt &FromInt, bool &IsValidFromInt, QualType &FromIntType,
887
        Expr *&FromExpr, ValueDecl *&ToValueDecl, bool &ToAddressOf,
888
0
        bool &ToNullPtr, Expr *&ToExpr) {
889
0
      assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration &&
890
0
             "Unexpected kind.");
891
0
      FromInt = FlatTree[ReadNode].FromArgInfo.Val;
892
0
      IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
893
0
      FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
894
0
      FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
895
0
      ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
896
0
      ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
897
0
      ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
898
0
      ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
899
0
    }
900
901
    /// FromDefault - Return true if the from argument is the default.
902
0
    bool FromDefault() {
903
0
      return FlatTree[ReadNode].FromArgInfo.IsDefault;
904
0
    }
905
906
    /// ToDefault - Return true if the to argument is the default.
907
0
    bool ToDefault() {
908
0
      return FlatTree[ReadNode].ToArgInfo.IsDefault;
909
0
    }
910
911
    /// NodeIsSame - Returns true the arguments are the same.
912
0
    bool NodeIsSame() {
913
0
      return FlatTree[ReadNode].Same;
914
0
    }
915
916
    /// HasChildrend - Returns true if the node has children.
917
0
    bool HasChildren() {
918
0
      return FlatTree[ReadNode].ChildNode != 0;
919
0
    }
920
921
    /// MoveToChild - Moves from the current node to its child.
922
0
    void MoveToChild() {
923
0
      ReadNode = FlatTree[ReadNode].ChildNode;
924
0
    }
925
926
    /// AdvanceSibling - If there is a next sibling, advance to it and return
927
    /// true.  Otherwise, return false.
928
0
    bool AdvanceSibling() {
929
0
      if (FlatTree[ReadNode].NextNode == 0)
930
0
        return false;
931
932
0
      ReadNode = FlatTree[ReadNode].NextNode;
933
0
      return true;
934
0
    }
935
936
    /// HasNextSibling - Return true if the node has a next sibling.
937
0
    bool HasNextSibling() {
938
0
      return FlatTree[ReadNode].NextNode != 0;
939
0
    }
940
941
    /// Empty - Returns true if the tree has no information.
942
0
    bool Empty() {
943
0
      return GetKind() == Invalid;
944
0
    }
945
946
    /// GetKind - Returns the current node's type.
947
0
    DiffKind GetKind() {
948
0
      return FlatTree[ReadNode].Kind;
949
0
    }
950
  };
951
952
  DiffTree Tree;
953
954
  /// TSTiterator - a pair of iterators that walks the
955
  /// TemplateSpecializationType and the desugared TemplateSpecializationType.
956
  /// The deseguared TemplateArgument should provide the canonical argument
957
  /// for comparisons.
958
  class TSTiterator {
959
    typedef const TemplateArgument& reference;
960
    typedef const TemplateArgument* pointer;
961
962
    /// InternalIterator - an iterator that is used to enter a
963
    /// TemplateSpecializationType and read TemplateArguments inside template
964
    /// parameter packs in order with the rest of the TemplateArguments.
965
    struct InternalIterator {
966
      /// TST - the template specialization whose arguments this iterator
967
      /// traverse over.
968
      const TemplateSpecializationType *TST;
969
970
      /// Index - the index of the template argument in TST.
971
      unsigned Index;
972
973
      /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA
974
      /// points to a TemplateArgument within a parameter pack.
975
      TemplateArgument::pack_iterator CurrentTA;
976
977
      /// EndTA - the end iterator of a parameter pack
978
      TemplateArgument::pack_iterator EndTA;
979
980
      /// InternalIterator - Constructs an iterator and sets it to the first
981
      /// template argument.
982
      InternalIterator(const TemplateSpecializationType *TST)
983
0
          : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
984
0
        if (!TST) return;
985
986
0
        if (isEnd()) return;
987
988
        // Set to first template argument.  If not a parameter pack, done.
989
0
        TemplateArgument TA = TST->template_arguments()[0];
990
0
        if (TA.getKind() != TemplateArgument::Pack) return;
991
992
        // Start looking into the parameter pack.
993
0
        CurrentTA = TA.pack_begin();
994
0
        EndTA = TA.pack_end();
995
996
        // Found a valid template argument.
997
0
        if (CurrentTA != EndTA) return;
998
999
        // Parameter pack is empty, use the increment to get to a valid
1000
        // template argument.
1001
0
        ++(*this);
1002
0
      }
1003
1004
      /// Return true if the iterator is non-singular.
1005
0
      bool isValid() const { return TST; }
1006
1007
      /// isEnd - Returns true if the iterator is one past the end.
1008
0
      bool isEnd() const {
1009
0
        assert(TST && "InternalIterator is invalid with a null TST.");
1010
0
        return Index >= TST->template_arguments().size();
1011
0
      }
1012
1013
      /// &operator++ - Increment the iterator to the next template argument.
1014
0
      InternalIterator &operator++() {
1015
0
        assert(TST && "InternalIterator is invalid with a null TST.");
1016
0
        if (isEnd()) {
1017
0
          return *this;
1018
0
        }
1019
1020
        // If in a parameter pack, advance in the parameter pack.
1021
0
        if (CurrentTA != EndTA) {
1022
0
          ++CurrentTA;
1023
0
          if (CurrentTA != EndTA)
1024
0
            return *this;
1025
0
        }
1026
1027
        // Loop until a template argument is found, or the end is reached.
1028
0
        while (true) {
1029
          // Advance to the next template argument.  Break if reached the end.
1030
0
          if (++Index == TST->template_arguments().size())
1031
0
            break;
1032
1033
          // If the TemplateArgument is not a parameter pack, done.
1034
0
          TemplateArgument TA = TST->template_arguments()[Index];
1035
0
          if (TA.getKind() != TemplateArgument::Pack)
1036
0
            break;
1037
1038
          // Handle parameter packs.
1039
0
          CurrentTA = TA.pack_begin();
1040
0
          EndTA = TA.pack_end();
1041
1042
          // If the parameter pack is empty, try to advance again.
1043
0
          if (CurrentTA != EndTA)
1044
0
            break;
1045
0
        }
1046
0
        return *this;
1047
0
      }
1048
1049
      /// operator* - Returns the appropriate TemplateArgument.
1050
0
      reference operator*() const {
1051
0
        assert(TST && "InternalIterator is invalid with a null TST.");
1052
0
        assert(!isEnd() && "Index exceeds number of arguments.");
1053
0
        if (CurrentTA == EndTA)
1054
0
          return TST->template_arguments()[Index];
1055
0
        else
1056
0
          return *CurrentTA;
1057
0
      }
1058
1059
      /// operator-> - Allow access to the underlying TemplateArgument.
1060
0
      pointer operator->() const {
1061
0
        assert(TST && "InternalIterator is invalid with a null TST.");
1062
0
        return &operator*();
1063
0
      }
1064
    };
1065
1066
    InternalIterator SugaredIterator;
1067
    InternalIterator DesugaredIterator;
1068
1069
  public:
1070
    TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
1071
        : SugaredIterator(TST),
1072
          DesugaredIterator(
1073
              (TST->isSugared() && !TST->isTypeAlias())
1074
                  ? GetTemplateSpecializationType(Context, TST->desugar())
1075
0
                  : nullptr) {}
1076
1077
    /// &operator++ - Increment the iterator to the next template argument.
1078
0
    TSTiterator &operator++() {
1079
0
      ++SugaredIterator;
1080
0
      if (DesugaredIterator.isValid())
1081
0
        ++DesugaredIterator;
1082
0
      return *this;
1083
0
    }
1084
1085
    /// operator* - Returns the appropriate TemplateArgument.
1086
0
    reference operator*() const {
1087
0
      return *SugaredIterator;
1088
0
    }
1089
1090
    /// operator-> - Allow access to the underlying TemplateArgument.
1091
0
    pointer operator->() const {
1092
0
      return &operator*();
1093
0
    }
1094
1095
    /// isEnd - Returns true if no more TemplateArguments are available.
1096
0
    bool isEnd() const {
1097
0
      return SugaredIterator.isEnd();
1098
0
    }
1099
1100
    /// hasDesugaredTA - Returns true if there is another TemplateArgument
1101
    /// available.
1102
0
    bool hasDesugaredTA() const {
1103
0
      return DesugaredIterator.isValid() && !DesugaredIterator.isEnd();
1104
0
    }
1105
1106
    /// getDesugaredTA - Returns the desugared TemplateArgument.
1107
0
    reference getDesugaredTA() const {
1108
0
      assert(DesugaredIterator.isValid() &&
1109
0
             "Desugared TemplateArgument should not be used.");
1110
0
      return *DesugaredIterator;
1111
0
    }
1112
  };
1113
1114
  // These functions build up the template diff tree, including functions to
1115
  // retrieve and compare template arguments.
1116
1117
  static const TemplateSpecializationType *GetTemplateSpecializationType(
1118
0
      ASTContext &Context, QualType Ty) {
1119
0
    if (const TemplateSpecializationType *TST =
1120
0
            Ty->getAs<TemplateSpecializationType>())
1121
0
      return TST;
1122
1123
0
    if (const auto* SubstType = Ty->getAs<SubstTemplateTypeParmType>())
1124
0
      Ty = SubstType->getReplacementType();
1125
1126
0
    const RecordType *RT = Ty->getAs<RecordType>();
1127
1128
0
    if (!RT)
1129
0
      return nullptr;
1130
1131
0
    const ClassTemplateSpecializationDecl *CTSD =
1132
0
        dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
1133
1134
0
    if (!CTSD)
1135
0
      return nullptr;
1136
1137
0
    Ty = Context.getTemplateSpecializationType(
1138
0
             TemplateName(CTSD->getSpecializedTemplate()),
1139
0
             CTSD->getTemplateArgs().asArray(),
1140
0
             Ty.getLocalUnqualifiedType().getCanonicalType());
1141
1142
0
    return Ty->getAs<TemplateSpecializationType>();
1143
0
  }
1144
1145
  /// Returns true if the DiffType is Type and false for Template.
1146
  static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType,
1147
                                  QualType ToType,
1148
                                  const TemplateSpecializationType *&FromArgTST,
1149
0
                                  const TemplateSpecializationType *&ToArgTST) {
1150
0
    if (FromType.isNull() || ToType.isNull())
1151
0
      return true;
1152
1153
0
    if (Context.hasSameType(FromType, ToType))
1154
0
      return true;
1155
1156
0
    FromArgTST = GetTemplateSpecializationType(Context, FromType);
1157
0
    ToArgTST = GetTemplateSpecializationType(Context, ToType);
1158
1159
0
    if (!FromArgTST || !ToArgTST)
1160
0
      return true;
1161
1162
0
    if (!hasSameTemplate(FromArgTST, ToArgTST))
1163
0
      return true;
1164
1165
0
    return false;
1166
0
  }
1167
1168
  /// DiffTypes - Fills a DiffNode with information about a type difference.
1169
0
  void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter) {
1170
0
    QualType FromType = GetType(FromIter);
1171
0
    QualType ToType = GetType(ToIter);
1172
1173
0
    bool FromDefault = FromIter.isEnd() && !FromType.isNull();
1174
0
    bool ToDefault = ToIter.isEnd() && !ToType.isNull();
1175
1176
0
    const TemplateSpecializationType *FromArgTST = nullptr;
1177
0
    const TemplateSpecializationType *ToArgTST = nullptr;
1178
0
    if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {
1179
0
      Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);
1180
0
      Tree.SetSame(!FromType.isNull() && !ToType.isNull() &&
1181
0
                   Context.hasSameType(FromType, ToType));
1182
0
    } else {
1183
0
      assert(FromArgTST && ToArgTST &&
1184
0
             "Both template specializations need to be valid.");
1185
0
      Qualifiers FromQual = FromType.getQualifiers(),
1186
0
                 ToQual = ToType.getQualifiers();
1187
0
      FromQual -= QualType(FromArgTST, 0).getQualifiers();
1188
0
      ToQual -= QualType(ToArgTST, 0).getQualifiers();
1189
0
      Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(),
1190
0
                           ToArgTST->getTemplateName().getAsTemplateDecl(),
1191
0
                           FromQual, ToQual, FromDefault, ToDefault);
1192
0
      DiffTemplate(FromArgTST, ToArgTST);
1193
0
    }
1194
0
  }
1195
1196
  /// DiffTemplateTemplates - Fills a DiffNode with information about a
1197
  /// template template difference.
1198
  void DiffTemplateTemplates(const TSTiterator &FromIter,
1199
0
                             const TSTiterator &ToIter) {
1200
0
    TemplateDecl *FromDecl = GetTemplateDecl(FromIter);
1201
0
    TemplateDecl *ToDecl = GetTemplateDecl(ToIter);
1202
0
    Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl,
1203
0
                                 ToIter.isEnd() && ToDecl);
1204
0
    Tree.SetSame(FromDecl && ToDecl &&
1205
0
                 FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl());
1206
0
  }
1207
1208
  /// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes
1209
  static void InitializeNonTypeDiffVariables(ASTContext &Context,
1210
                                             const TSTiterator &Iter,
1211
                                             NonTypeTemplateParmDecl *Default,
1212
                                             llvm::APSInt &Value, bool &HasInt,
1213
                                             QualType &IntType, bool &IsNullPtr,
1214
                                             Expr *&E, ValueDecl *&VD,
1215
0
                                             bool &NeedAddressOf) {
1216
0
    if (!Iter.isEnd()) {
1217
0
      switch (Iter->getKind()) {
1218
0
        default:
1219
0
          llvm_unreachable("unknown ArgumentKind");
1220
0
        case TemplateArgument::Integral:
1221
0
          Value = Iter->getAsIntegral();
1222
0
          HasInt = true;
1223
0
          IntType = Iter->getIntegralType();
1224
0
          return;
1225
0
        case TemplateArgument::Declaration: {
1226
0
          VD = Iter->getAsDecl();
1227
0
          QualType ArgType = Iter->getParamTypeForDecl();
1228
0
          QualType VDType = VD->getType();
1229
0
          if (ArgType->isPointerType() &&
1230
0
              Context.hasSameType(ArgType->getPointeeType(), VDType))
1231
0
            NeedAddressOf = true;
1232
0
          return;
1233
0
        }
1234
0
        case TemplateArgument::NullPtr:
1235
0
          IsNullPtr = true;
1236
0
          return;
1237
0
        case TemplateArgument::Expression:
1238
0
          E = Iter->getAsExpr();
1239
0
      }
1240
0
    } else if (!Default->isParameterPack()) {
1241
0
      E = Default->getDefaultArgument();
1242
0
    }
1243
1244
0
    if (!Iter.hasDesugaredTA()) return;
1245
1246
0
    const TemplateArgument& TA = Iter.getDesugaredTA();
1247
0
    switch (TA.getKind()) {
1248
0
      default:
1249
0
        llvm_unreachable("unknown ArgumentKind");
1250
0
      case TemplateArgument::Integral:
1251
0
        Value = TA.getAsIntegral();
1252
0
        HasInt = true;
1253
0
        IntType = TA.getIntegralType();
1254
0
        return;
1255
0
      case TemplateArgument::Declaration: {
1256
0
        VD = TA.getAsDecl();
1257
0
        QualType ArgType = TA.getParamTypeForDecl();
1258
0
        QualType VDType = VD->getType();
1259
0
        if (ArgType->isPointerType() &&
1260
0
            Context.hasSameType(ArgType->getPointeeType(), VDType))
1261
0
          NeedAddressOf = true;
1262
0
        return;
1263
0
      }
1264
0
      case TemplateArgument::NullPtr:
1265
0
        IsNullPtr = true;
1266
0
        return;
1267
0
      case TemplateArgument::Expression:
1268
        // TODO: Sometimes, the desugared template argument Expr differs from
1269
        // the sugared template argument Expr.  It may be useful in the future
1270
        // but for now, it is just discarded.
1271
0
        if (!E)
1272
0
          E = TA.getAsExpr();
1273
0
        return;
1274
0
    }
1275
0
  }
1276
1277
  /// DiffNonTypes - Handles any template parameters not handled by DiffTypes
1278
  /// of DiffTemplatesTemplates, such as integer and declaration parameters.
1279
  void DiffNonTypes(const TSTiterator &FromIter, const TSTiterator &ToIter,
1280
                    NonTypeTemplateParmDecl *FromDefaultNonTypeDecl,
1281
0
                    NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) {
1282
0
    Expr *FromExpr = nullptr, *ToExpr = nullptr;
1283
0
    llvm::APSInt FromInt, ToInt;
1284
0
    QualType FromIntType, ToIntType;
1285
0
    ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr;
1286
0
    bool HasFromInt = false, HasToInt = false, FromNullPtr = false,
1287
0
         ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false;
1288
0
    InitializeNonTypeDiffVariables(
1289
0
        Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt,
1290
0
        FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf);
1291
0
    InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt,
1292
0
                                   HasToInt, ToIntType, ToNullPtr, ToExpr,
1293
0
                                   ToValueDecl, NeedToAddressOf);
1294
1295
0
    bool FromDefault = FromIter.isEnd() &&
1296
0
                       (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);
1297
0
    bool ToDefault = ToIter.isEnd() &&
1298
0
                     (ToExpr || ToValueDecl || HasToInt || ToNullPtr);
1299
1300
0
    bool FromDeclaration = FromValueDecl || FromNullPtr;
1301
0
    bool ToDeclaration = ToValueDecl || ToNullPtr;
1302
1303
0
    if (FromDeclaration && HasToInt) {
1304
0
      Tree.SetFromDeclarationAndToIntegerDiff(
1305
0
          FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt,
1306
0
          HasToInt, ToIntType, ToExpr, FromDefault, ToDefault);
1307
0
      Tree.SetSame(false);
1308
0
      return;
1309
1310
0
    }
1311
1312
0
    if (HasFromInt && ToDeclaration) {
1313
0
      Tree.SetFromIntegerAndToDeclarationDiff(
1314
0
          FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl,
1315
0
          NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault);
1316
0
      Tree.SetSame(false);
1317
0
      return;
1318
0
    }
1319
1320
0
    if (HasFromInt || HasToInt) {
1321
0
      Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType,
1322
0
                          ToIntType, FromExpr, ToExpr, FromDefault, ToDefault);
1323
0
      if (HasFromInt && HasToInt) {
1324
0
        Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) &&
1325
0
                     FromInt == ToInt);
1326
0
      }
1327
0
      return;
1328
0
    }
1329
1330
0
    if (FromDeclaration || ToDeclaration) {
1331
0
      Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf,
1332
0
                              NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1333
0
                              ToExpr, FromDefault, ToDefault);
1334
0
      bool BothNull = FromNullPtr && ToNullPtr;
1335
0
      bool SameValueDecl =
1336
0
          FromValueDecl && ToValueDecl &&
1337
0
          NeedFromAddressOf == NeedToAddressOf &&
1338
0
          FromValueDecl->getCanonicalDecl() == ToValueDecl->getCanonicalDecl();
1339
0
      Tree.SetSame(BothNull || SameValueDecl);
1340
0
      return;
1341
0
    }
1342
1343
0
    assert((FromExpr || ToExpr) && "Both template arguments cannot be empty.");
1344
0
    Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault);
1345
0
    Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));
1346
0
  }
1347
1348
  /// DiffTemplate - recursively visits template arguments and stores the
1349
  /// argument info into a tree.
1350
  void DiffTemplate(const TemplateSpecializationType *FromTST,
1351
0
                    const TemplateSpecializationType *ToTST) {
1352
    // Begin descent into diffing template tree.
1353
0
    TemplateParameterList *ParamsFrom =
1354
0
        FromTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters();
1355
0
    TemplateParameterList *ParamsTo =
1356
0
        ToTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters();
1357
0
    unsigned TotalArgs = 0;
1358
0
    for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST);
1359
0
         !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) {
1360
0
      Tree.AddNode();
1361
1362
      // Get the parameter at index TotalArgs.  If index is larger
1363
      // than the total number of parameters, then there is an
1364
      // argument pack, so re-use the last parameter.
1365
0
      unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->size() - 1);
1366
0
      unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->size() - 1);
1367
0
      NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex);
1368
0
      NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex);
1369
1370
0
      assert(FromParamND->getKind() == ToParamND->getKind() &&
1371
0
             "Parameter Decl are not the same kind.");
1372
1373
0
      if (isa<TemplateTypeParmDecl>(FromParamND)) {
1374
0
        DiffTypes(FromIter, ToIter);
1375
0
      } else if (isa<TemplateTemplateParmDecl>(FromParamND)) {
1376
0
        DiffTemplateTemplates(FromIter, ToIter);
1377
0
      } else if (isa<NonTypeTemplateParmDecl>(FromParamND)) {
1378
0
        NonTypeTemplateParmDecl *FromDefaultNonTypeDecl =
1379
0
            cast<NonTypeTemplateParmDecl>(FromParamND);
1380
0
        NonTypeTemplateParmDecl *ToDefaultNonTypeDecl =
1381
0
            cast<NonTypeTemplateParmDecl>(ToParamND);
1382
0
        DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
1383
0
                     ToDefaultNonTypeDecl);
1384
0
      } else {
1385
0
        llvm_unreachable("Unexpected Decl type.");
1386
0
      }
1387
1388
0
      ++FromIter;
1389
0
      ++ToIter;
1390
0
      Tree.Up();
1391
0
    }
1392
0
  }
1393
1394
  /// makeTemplateList - Dump every template alias into the vector.
1395
  static void makeTemplateList(
1396
      SmallVectorImpl<const TemplateSpecializationType *> &TemplateList,
1397
0
      const TemplateSpecializationType *TST) {
1398
0
    while (TST) {
1399
0
      TemplateList.push_back(TST);
1400
0
      if (!TST->isTypeAlias())
1401
0
        return;
1402
0
      TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1403
0
    }
1404
0
  }
1405
1406
  /// hasSameBaseTemplate - Returns true when the base templates are the same,
1407
  /// even if the template arguments are not.
1408
  static bool hasSameBaseTemplate(const TemplateSpecializationType *FromTST,
1409
0
                                  const TemplateSpecializationType *ToTST) {
1410
0
    return FromTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl() ==
1411
0
           ToTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl();
1412
0
  }
1413
1414
  /// hasSameTemplate - Returns true if both types are specialized from the
1415
  /// same template declaration.  If they come from different template aliases,
1416
  /// do a parallel ascension search to determine the highest template alias in
1417
  /// common and set the arguments to them.
1418
  static bool hasSameTemplate(const TemplateSpecializationType *&FromTST,
1419
0
                              const TemplateSpecializationType *&ToTST) {
1420
    // Check the top templates if they are the same.
1421
0
    if (hasSameBaseTemplate(FromTST, ToTST))
1422
0
      return true;
1423
1424
    // Create vectors of template aliases.
1425
0
    SmallVector<const TemplateSpecializationType*, 1> FromTemplateList,
1426
0
                                                      ToTemplateList;
1427
1428
0
    makeTemplateList(FromTemplateList, FromTST);
1429
0
    makeTemplateList(ToTemplateList, ToTST);
1430
1431
0
    SmallVectorImpl<const TemplateSpecializationType *>::reverse_iterator
1432
0
        FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(),
1433
0
        ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend();
1434
1435
    // Check if the lowest template types are the same.  If not, return.
1436
0
    if (!hasSameBaseTemplate(*FromIter, *ToIter))
1437
0
      return false;
1438
1439
    // Begin searching up the template aliases.  The bottom most template
1440
    // matches so move up until one pair does not match.  Use the template
1441
    // right before that one.
1442
0
    for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) {
1443
0
      if (!hasSameBaseTemplate(*FromIter, *ToIter))
1444
0
        break;
1445
0
    }
1446
1447
0
    FromTST = FromIter[-1];
1448
0
    ToTST = ToIter[-1];
1449
1450
0
    return true;
1451
0
  }
1452
1453
  /// GetType - Retrieves the template type arguments, including default
1454
  /// arguments.
1455
0
  static QualType GetType(const TSTiterator &Iter) {
1456
0
    if (!Iter.isEnd())
1457
0
      return Iter->getAsType();
1458
0
    if (Iter.hasDesugaredTA())
1459
0
      return Iter.getDesugaredTA().getAsType();
1460
0
    return QualType();
1461
0
  }
1462
1463
  /// GetTemplateDecl - Retrieves the template template arguments, including
1464
  /// default arguments.
1465
0
  static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter) {
1466
0
    if (!Iter.isEnd())
1467
0
      return Iter->getAsTemplate().getAsTemplateDecl();
1468
0
    if (Iter.hasDesugaredTA())
1469
0
      return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();
1470
0
    return nullptr;
1471
0
  }
1472
1473
  /// IsEqualExpr - Returns true if the expressions are the same in regards to
1474
  /// template arguments.  These expressions are dependent, so profile them
1475
  /// instead of trying to evaluate them.
1476
0
  static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) {
1477
0
    if (FromExpr == ToExpr)
1478
0
      return true;
1479
1480
0
    if (!FromExpr || !ToExpr)
1481
0
      return false;
1482
1483
0
    llvm::FoldingSetNodeID FromID, ToID;
1484
0
    FromExpr->Profile(FromID, Context, true);
1485
0
    ToExpr->Profile(ToID, Context, true);
1486
0
    return FromID == ToID;
1487
0
  }
1488
1489
  // These functions converts the tree representation of the template
1490
  // differences into the internal character vector.
1491
1492
  /// TreeToString - Converts the Tree object into a character stream which
1493
  /// will later be turned into the output string.
1494
0
  void TreeToString(int Indent = 1) {
1495
0
    if (PrintTree) {
1496
0
      OS << '\n';
1497
0
      OS.indent(2 * Indent);
1498
0
      ++Indent;
1499
0
    }
1500
1501
    // Handle cases where the difference is not templates with different
1502
    // arguments.
1503
0
    switch (Tree.GetKind()) {
1504
0
      case DiffTree::Invalid:
1505
0
        llvm_unreachable("Template diffing failed with bad DiffNode");
1506
0
      case DiffTree::Type: {
1507
0
        QualType FromType, ToType;
1508
0
        Tree.GetTypeDiff(FromType, ToType);
1509
0
        PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(),
1510
0
                       Tree.NodeIsSame());
1511
0
        return;
1512
0
      }
1513
0
      case DiffTree::Expression: {
1514
0
        Expr *FromExpr, *ToExpr;
1515
0
        Tree.GetExpressionDiff(FromExpr, ToExpr);
1516
0
        PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
1517
0
                  Tree.NodeIsSame());
1518
0
        return;
1519
0
      }
1520
0
      case DiffTree::TemplateTemplate: {
1521
0
        TemplateDecl *FromTD, *ToTD;
1522
0
        Tree.GetTemplateTemplateDiff(FromTD, ToTD);
1523
0
        PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(),
1524
0
                              Tree.ToDefault(), Tree.NodeIsSame());
1525
0
        return;
1526
0
      }
1527
0
      case DiffTree::Integer: {
1528
0
        llvm::APSInt FromInt, ToInt;
1529
0
        Expr *FromExpr, *ToExpr;
1530
0
        bool IsValidFromInt, IsValidToInt;
1531
0
        QualType FromIntType, ToIntType;
1532
0
        Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,
1533
0
                            FromIntType, ToIntType, FromExpr, ToExpr);
1534
0
        PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType,
1535
0
                    ToIntType, FromExpr, ToExpr, Tree.FromDefault(),
1536
0
                    Tree.ToDefault(), Tree.NodeIsSame());
1537
0
        return;
1538
0
      }
1539
0
      case DiffTree::Declaration: {
1540
0
        ValueDecl *FromValueDecl, *ToValueDecl;
1541
0
        bool FromAddressOf, ToAddressOf;
1542
0
        bool FromNullPtr, ToNullPtr;
1543
0
        Expr *FromExpr, *ToExpr;
1544
0
        Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,
1545
0
                                ToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1546
0
                                ToExpr);
1547
0
        PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
1548
0
                       FromNullPtr, ToNullPtr, FromExpr, ToExpr,
1549
0
                       Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
1550
0
        return;
1551
0
      }
1552
0
      case DiffTree::FromDeclarationAndToInteger: {
1553
0
        ValueDecl *FromValueDecl;
1554
0
        bool FromAddressOf;
1555
0
        bool FromNullPtr;
1556
0
        Expr *FromExpr;
1557
0
        llvm::APSInt ToInt;
1558
0
        bool IsValidToInt;
1559
0
        QualType ToIntType;
1560
0
        Expr *ToExpr;
1561
0
        Tree.GetFromDeclarationAndToIntegerDiff(
1562
0
            FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt,
1563
0
            IsValidToInt, ToIntType, ToExpr);
1564
0
        assert((FromValueDecl || FromNullPtr) && IsValidToInt);
1565
0
        PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr,
1566
0
                                 FromExpr, Tree.FromDefault(), ToInt, ToIntType,
1567
0
                                 ToExpr, Tree.ToDefault());
1568
0
        return;
1569
0
      }
1570
0
      case DiffTree::FromIntegerAndToDeclaration: {
1571
0
        llvm::APSInt FromInt;
1572
0
        bool IsValidFromInt;
1573
0
        QualType FromIntType;
1574
0
        Expr *FromExpr;
1575
0
        ValueDecl *ToValueDecl;
1576
0
        bool ToAddressOf;
1577
0
        bool ToNullPtr;
1578
0
        Expr *ToExpr;
1579
0
        Tree.GetFromIntegerAndToDeclarationDiff(
1580
0
            FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl,
1581
0
            ToAddressOf, ToNullPtr, ToExpr);
1582
0
        assert(IsValidFromInt && (ToValueDecl || ToNullPtr));
1583
0
        PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr,
1584
0
                                 Tree.FromDefault(), ToValueDecl, ToAddressOf,
1585
0
                                 ToNullPtr, ToExpr, Tree.ToDefault());
1586
0
        return;
1587
0
      }
1588
0
      case DiffTree::Template: {
1589
        // Node is root of template.  Recurse on children.
1590
0
        TemplateDecl *FromTD, *ToTD;
1591
0
        Qualifiers FromQual, ToQual;
1592
0
        Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);
1593
1594
0
        PrintQualifiers(FromQual, ToQual);
1595
1596
0
        if (!Tree.HasChildren()) {
1597
          // If we're dealing with a template specialization with zero
1598
          // arguments, there are no children; special-case this.
1599
0
          OS << FromTD->getDeclName() << "<>";
1600
0
          return;
1601
0
        }
1602
1603
0
        OS << FromTD->getDeclName() << '<';
1604
0
        Tree.MoveToChild();
1605
0
        unsigned NumElideArgs = 0;
1606
0
        bool AllArgsElided = true;
1607
0
        do {
1608
0
          if (ElideType) {
1609
0
            if (Tree.NodeIsSame()) {
1610
0
              ++NumElideArgs;
1611
0
              continue;
1612
0
            }
1613
0
            AllArgsElided = false;
1614
0
            if (NumElideArgs > 0) {
1615
0
              PrintElideArgs(NumElideArgs, Indent);
1616
0
              NumElideArgs = 0;
1617
0
              OS << ", ";
1618
0
            }
1619
0
          }
1620
0
          TreeToString(Indent);
1621
0
          if (Tree.HasNextSibling())
1622
0
            OS << ", ";
1623
0
        } while (Tree.AdvanceSibling());
1624
0
        if (NumElideArgs > 0) {
1625
0
          if (AllArgsElided)
1626
0
            OS << "...";
1627
0
          else
1628
0
            PrintElideArgs(NumElideArgs, Indent);
1629
0
        }
1630
1631
0
        Tree.Parent();
1632
0
        OS << ">";
1633
0
        return;
1634
0
      }
1635
0
    }
1636
0
  }
1637
1638
  // To signal to the text printer that a certain text needs to be bolded,
1639
  // a special character is injected into the character stream which the
1640
  // text printer will later strip out.
1641
1642
  /// Bold - Start bolding text.
1643
0
  void Bold() {
1644
0
    assert(!IsBold && "Attempting to bold text that is already bold.");
1645
0
    IsBold = true;
1646
0
    if (ShowColor)
1647
0
      OS << ToggleHighlight;
1648
0
  }
1649
1650
  /// Unbold - Stop bolding text.
1651
0
  void Unbold() {
1652
0
    assert(IsBold && "Attempting to remove bold from unbold text.");
1653
0
    IsBold = false;
1654
0
    if (ShowColor)
1655
0
      OS << ToggleHighlight;
1656
0
  }
1657
1658
  // Functions to print out the arguments and highlighting the difference.
1659
1660
  /// PrintTypeNames - prints the typenames, bolding differences.  Will detect
1661
  /// typenames that are the same and attempt to disambiguate them by using
1662
  /// canonical typenames.
1663
  void PrintTypeNames(QualType FromType, QualType ToType,
1664
0
                      bool FromDefault, bool ToDefault, bool Same) {
1665
0
    assert((!FromType.isNull() || !ToType.isNull()) &&
1666
0
           "Only one template argument may be missing.");
1667
1668
0
    if (Same) {
1669
0
      OS << FromType.getAsString(Policy);
1670
0
      return;
1671
0
    }
1672
1673
0
    if (!FromType.isNull() && !ToType.isNull() &&
1674
0
        FromType.getLocalUnqualifiedType() ==
1675
0
        ToType.getLocalUnqualifiedType()) {
1676
0
      Qualifiers FromQual = FromType.getLocalQualifiers(),
1677
0
                 ToQual = ToType.getLocalQualifiers();
1678
0
      PrintQualifiers(FromQual, ToQual);
1679
0
      FromType.getLocalUnqualifiedType().print(OS, Policy);
1680
0
      return;
1681
0
    }
1682
1683
0
    std::string FromTypeStr = FromType.isNull() ? "(no argument)"
1684
0
                                                : FromType.getAsString(Policy);
1685
0
    std::string ToTypeStr = ToType.isNull() ? "(no argument)"
1686
0
                                            : ToType.getAsString(Policy);
1687
    // Print without ElaboratedType sugar if it is better.
1688
    // TODO: merge this with other aka printing above.
1689
0
    if (FromTypeStr == ToTypeStr) {
1690
0
      const auto *FromElTy = dyn_cast<ElaboratedType>(FromType),
1691
0
                 *ToElTy = dyn_cast<ElaboratedType>(ToType);
1692
0
      if (FromElTy || ToElTy) {
1693
0
        std::string FromNamedTypeStr =
1694
0
            FromElTy ? FromElTy->getNamedType().getAsString(Policy)
1695
0
                     : FromTypeStr;
1696
0
        std::string ToNamedTypeStr =
1697
0
            ToElTy ? ToElTy->getNamedType().getAsString(Policy) : ToTypeStr;
1698
0
        if (FromNamedTypeStr != ToNamedTypeStr) {
1699
0
          FromTypeStr = FromNamedTypeStr;
1700
0
          ToTypeStr = ToNamedTypeStr;
1701
0
          goto PrintTypes;
1702
0
        }
1703
0
      }
1704
      // Switch to canonical typename if it is better.
1705
0
      std::string FromCanTypeStr =
1706
0
          FromType.getCanonicalType().getAsString(Policy);
1707
0
      std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(Policy);
1708
0
      if (FromCanTypeStr != ToCanTypeStr) {
1709
0
        FromTypeStr = FromCanTypeStr;
1710
0
        ToTypeStr = ToCanTypeStr;
1711
0
      }
1712
0
    }
1713
1714
0
  PrintTypes:
1715
0
    if (PrintTree) OS << '[';
1716
0
    OS << (FromDefault ? "(default) " : "");
1717
0
    Bold();
1718
0
    OS << FromTypeStr;
1719
0
    Unbold();
1720
0
    if (PrintTree) {
1721
0
      OS << " != " << (ToDefault ? "(default) " : "");
1722
0
      Bold();
1723
0
      OS << ToTypeStr;
1724
0
      Unbold();
1725
0
      OS << "]";
1726
0
    }
1727
0
  }
1728
1729
  /// PrintExpr - Prints out the expr template arguments, highlighting argument
1730
  /// differences.
1731
  void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault,
1732
0
                 bool ToDefault, bool Same) {
1733
0
    assert((FromExpr || ToExpr) &&
1734
0
            "Only one template argument may be missing.");
1735
0
    if (Same) {
1736
0
      PrintExpr(FromExpr);
1737
0
    } else if (!PrintTree) {
1738
0
      OS << (FromDefault ? "(default) " : "");
1739
0
      Bold();
1740
0
      PrintExpr(FromExpr);
1741
0
      Unbold();
1742
0
    } else {
1743
0
      OS << (FromDefault ? "[(default) " : "[");
1744
0
      Bold();
1745
0
      PrintExpr(FromExpr);
1746
0
      Unbold();
1747
0
      OS << " != " << (ToDefault ? "(default) " : "");
1748
0
      Bold();
1749
0
      PrintExpr(ToExpr);
1750
0
      Unbold();
1751
0
      OS << ']';
1752
0
    }
1753
0
  }
1754
1755
  /// PrintExpr - Actual formatting and printing of expressions.
1756
0
  void PrintExpr(const Expr *E) {
1757
0
    if (E) {
1758
0
      E->printPretty(OS, nullptr, Policy);
1759
0
      return;
1760
0
    }
1761
0
    OS << "(no argument)";
1762
0
  }
1763
1764
  /// PrintTemplateTemplate - Handles printing of template template arguments,
1765
  /// highlighting argument differences.
1766
  void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD,
1767
0
                             bool FromDefault, bool ToDefault, bool Same) {
1768
0
    assert((FromTD || ToTD) && "Only one template argument may be missing.");
1769
1770
0
    std::string FromName =
1771
0
        std::string(FromTD ? FromTD->getName() : "(no argument)");
1772
0
    std::string ToName = std::string(ToTD ? ToTD->getName() : "(no argument)");
1773
0
    if (FromTD && ToTD && FromName == ToName) {
1774
0
      FromName = FromTD->getQualifiedNameAsString();
1775
0
      ToName = ToTD->getQualifiedNameAsString();
1776
0
    }
1777
1778
0
    if (Same) {
1779
0
      OS << "template " << FromTD->getDeclName();
1780
0
    } else if (!PrintTree) {
1781
0
      OS << (FromDefault ? "(default) template " : "template ");
1782
0
      Bold();
1783
0
      OS << FromName;
1784
0
      Unbold();
1785
0
    } else {
1786
0
      OS << (FromDefault ? "[(default) template " : "[template ");
1787
0
      Bold();
1788
0
      OS << FromName;
1789
0
      Unbold();
1790
0
      OS << " != " << (ToDefault ? "(default) template " : "template ");
1791
0
      Bold();
1792
0
      OS << ToName;
1793
0
      Unbold();
1794
0
      OS << ']';
1795
0
    }
1796
0
  }
1797
1798
  /// PrintAPSInt - Handles printing of integral arguments, highlighting
1799
  /// argument differences.
1800
  void PrintAPSInt(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt,
1801
                   bool IsValidFromInt, bool IsValidToInt, QualType FromIntType,
1802
                   QualType ToIntType, Expr *FromExpr, Expr *ToExpr,
1803
0
                   bool FromDefault, bool ToDefault, bool Same) {
1804
0
    assert((IsValidFromInt || IsValidToInt) &&
1805
0
           "Only one integral argument may be missing.");
1806
1807
0
    if (Same) {
1808
0
      if (FromIntType->isBooleanType()) {
1809
0
        OS << ((FromInt == 0) ? "false" : "true");
1810
0
      } else {
1811
0
        OS << toString(FromInt, 10);
1812
0
      }
1813
0
      return;
1814
0
    }
1815
1816
0
    bool PrintType = IsValidFromInt && IsValidToInt &&
1817
0
                     !Context.hasSameType(FromIntType, ToIntType);
1818
1819
0
    if (!PrintTree) {
1820
0
      OS << (FromDefault ? "(default) " : "");
1821
0
      PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1822
0
    } else {
1823
0
      OS << (FromDefault ? "[(default) " : "[");
1824
0
      PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1825
0
      OS << " != " << (ToDefault ? "(default) " : "");
1826
0
      PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType);
1827
0
      OS << ']';
1828
0
    }
1829
0
  }
1830
1831
  /// PrintAPSInt - If valid, print the APSInt.  If the expression is
1832
  /// gives more information, print it too.
1833
  void PrintAPSInt(const llvm::APSInt &Val, Expr *E, bool Valid,
1834
0
                   QualType IntType, bool PrintType) {
1835
0
    Bold();
1836
0
    if (Valid) {
1837
0
      if (HasExtraInfo(E)) {
1838
0
        PrintExpr(E);
1839
0
        Unbold();
1840
0
        OS << " aka ";
1841
0
        Bold();
1842
0
      }
1843
0
      if (PrintType) {
1844
0
        Unbold();
1845
0
        OS << "(";
1846
0
        Bold();
1847
0
        IntType.print(OS, Context.getPrintingPolicy());
1848
0
        Unbold();
1849
0
        OS << ") ";
1850
0
        Bold();
1851
0
      }
1852
0
      if (IntType->isBooleanType()) {
1853
0
        OS << ((Val == 0) ? "false" : "true");
1854
0
      } else {
1855
0
        OS << toString(Val, 10);
1856
0
      }
1857
0
    } else if (E) {
1858
0
      PrintExpr(E);
1859
0
    } else {
1860
0
      OS << "(no argument)";
1861
0
    }
1862
0
    Unbold();
1863
0
  }
1864
1865
  /// HasExtraInfo - Returns true if E is not an integer literal, the
1866
  /// negation of an integer literal, or a boolean literal.
1867
0
  bool HasExtraInfo(Expr *E) {
1868
0
    if (!E) return false;
1869
1870
0
    E = E->IgnoreImpCasts();
1871
1872
0
    if (isa<IntegerLiteral>(E)) return false;
1873
1874
0
    if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E))
1875
0
      if (UO->getOpcode() == UO_Minus)
1876
0
        if (isa<IntegerLiteral>(UO->getSubExpr()))
1877
0
          return false;
1878
1879
0
    if (isa<CXXBoolLiteralExpr>(E))
1880
0
      return false;
1881
1882
0
    return true;
1883
0
  }
1884
1885
0
  void PrintValueDecl(ValueDecl *VD, bool AddressOf, Expr *E, bool NullPtr) {
1886
0
    if (VD) {
1887
0
      if (AddressOf)
1888
0
        OS << "&";
1889
0
      else if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
1890
        // FIXME: Diffing the APValue would be neat.
1891
        // FIXME: Suppress this and use the full name of the declaration if the
1892
        // parameter is a pointer or reference.
1893
0
        TPO->getType().getUnqualifiedType().print(OS, Policy);
1894
0
        TPO->printAsInit(OS, Policy);
1895
0
        return;
1896
0
      }
1897
0
      VD->printName(OS, Policy);
1898
0
      return;
1899
0
    }
1900
1901
0
    if (NullPtr) {
1902
0
      if (E && !isa<CXXNullPtrLiteralExpr>(E)) {
1903
0
        PrintExpr(E);
1904
0
        if (IsBold) {
1905
0
          Unbold();
1906
0
          OS << " aka ";
1907
0
          Bold();
1908
0
        } else {
1909
0
          OS << " aka ";
1910
0
        }
1911
0
      }
1912
1913
0
      OS << "nullptr";
1914
0
      return;
1915
0
    }
1916
1917
0
    OS << "(no argument)";
1918
0
  }
1919
1920
  /// PrintDecl - Handles printing of Decl arguments, highlighting
1921
  /// argument differences.
1922
  void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
1923
                      bool FromAddressOf, bool ToAddressOf, bool FromNullPtr,
1924
                      bool ToNullPtr, Expr *FromExpr, Expr *ToExpr,
1925
0
                      bool FromDefault, bool ToDefault, bool Same) {
1926
0
    assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
1927
0
           "Only one Decl argument may be NULL");
1928
1929
0
    if (Same) {
1930
0
      PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1931
0
    } else if (!PrintTree) {
1932
0
      OS << (FromDefault ? "(default) " : "");
1933
0
      Bold();
1934
0
      PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1935
0
      Unbold();
1936
0
    } else {
1937
0
      OS << (FromDefault ? "[(default) " : "[");
1938
0
      Bold();
1939
0
      PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1940
0
      Unbold();
1941
0
      OS << " != " << (ToDefault ? "(default) " : "");
1942
0
      Bold();
1943
0
      PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr);
1944
0
      Unbold();
1945
0
      OS << ']';
1946
0
    }
1947
0
  }
1948
1949
  /// PrintValueDeclAndInteger - Uses the print functions for ValueDecl and
1950
  /// APSInt to print a mixed difference.
1951
  void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf,
1952
                                bool IsNullPtr, Expr *VDExpr, bool DefaultDecl,
1953
                                const llvm::APSInt &Val, QualType IntType,
1954
0
                                Expr *IntExpr, bool DefaultInt) {
1955
0
    if (!PrintTree) {
1956
0
      OS << (DefaultDecl ? "(default) " : "");
1957
0
      Bold();
1958
0
      PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
1959
0
      Unbold();
1960
0
    } else {
1961
0
      OS << (DefaultDecl ? "[(default) " : "[");
1962
0
      Bold();
1963
0
      PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
1964
0
      Unbold();
1965
0
      OS << " != " << (DefaultInt ? "(default) " : "");
1966
0
      PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
1967
0
      OS << ']';
1968
0
    }
1969
0
  }
1970
1971
  /// PrintIntegerAndValueDecl - Uses the print functions for APSInt and
1972
  /// ValueDecl to print a mixed difference.
1973
  void PrintIntegerAndValueDecl(const llvm::APSInt &Val, QualType IntType,
1974
                                Expr *IntExpr, bool DefaultInt, ValueDecl *VD,
1975
                                bool NeedAddressOf, bool IsNullPtr,
1976
0
                                Expr *VDExpr, bool DefaultDecl) {
1977
0
    if (!PrintTree) {
1978
0
      OS << (DefaultInt ? "(default) " : "");
1979
0
      PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
1980
0
    } else {
1981
0
      OS << (DefaultInt ? "[(default) " : "[");
1982
0
      PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
1983
0
      OS << " != " << (DefaultDecl ? "(default) " : "");
1984
0
      Bold();
1985
0
      PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
1986
0
      Unbold();
1987
0
      OS << ']';
1988
0
    }
1989
0
  }
1990
1991
  // Prints the appropriate placeholder for elided template arguments.
1992
0
  void PrintElideArgs(unsigned NumElideArgs, unsigned Indent) {
1993
0
    if (PrintTree) {
1994
0
      OS << '\n';
1995
0
      for (unsigned i = 0; i < Indent; ++i)
1996
0
        OS << "  ";
1997
0
    }
1998
0
    if (NumElideArgs == 0) return;
1999
0
    if (NumElideArgs == 1)
2000
0
      OS << "[...]";
2001
0
    else
2002
0
      OS << "[" << NumElideArgs << " * ...]";
2003
0
  }
2004
2005
  // Prints and highlights differences in Qualifiers.
2006
0
  void PrintQualifiers(Qualifiers FromQual, Qualifiers ToQual) {
2007
    // Both types have no qualifiers
2008
0
    if (FromQual.empty() && ToQual.empty())
2009
0
      return;
2010
2011
    // Both types have same qualifiers
2012
0
    if (FromQual == ToQual) {
2013
0
      PrintQualifier(FromQual, /*ApplyBold*/false);
2014
0
      return;
2015
0
    }
2016
2017
    // Find common qualifiers and strip them from FromQual and ToQual.
2018
0
    Qualifiers CommonQual = Qualifiers::removeCommonQualifiers(FromQual,
2019
0
                                                               ToQual);
2020
2021
    // The qualifiers are printed before the template name.
2022
    // Inline printing:
2023
    // The common qualifiers are printed.  Then, qualifiers only in this type
2024
    // are printed and highlighted.  Finally, qualifiers only in the other
2025
    // type are printed and highlighted inside parentheses after "missing".
2026
    // Tree printing:
2027
    // Qualifiers are printed next to each other, inside brackets, and
2028
    // separated by "!=".  The printing order is:
2029
    // common qualifiers, highlighted from qualifiers, "!=",
2030
    // common qualifiers, highlighted to qualifiers
2031
0
    if (PrintTree) {
2032
0
      OS << "[";
2033
0
      if (CommonQual.empty() && FromQual.empty()) {
2034
0
        Bold();
2035
0
        OS << "(no qualifiers) ";
2036
0
        Unbold();
2037
0
      } else {
2038
0
        PrintQualifier(CommonQual, /*ApplyBold*/false);
2039
0
        PrintQualifier(FromQual, /*ApplyBold*/true);
2040
0
      }
2041
0
      OS << "!= ";
2042
0
      if (CommonQual.empty() && ToQual.empty()) {
2043
0
        Bold();
2044
0
        OS << "(no qualifiers)";
2045
0
        Unbold();
2046
0
      } else {
2047
0
        PrintQualifier(CommonQual, /*ApplyBold*/false,
2048
0
                       /*appendSpaceIfNonEmpty*/!ToQual.empty());
2049
0
        PrintQualifier(ToQual, /*ApplyBold*/true,
2050
0
                       /*appendSpaceIfNonEmpty*/false);
2051
0
      }
2052
0
      OS << "] ";
2053
0
    } else {
2054
0
      PrintQualifier(CommonQual, /*ApplyBold*/false);
2055
0
      PrintQualifier(FromQual, /*ApplyBold*/true);
2056
0
    }
2057
0
  }
2058
2059
  void PrintQualifier(Qualifiers Q, bool ApplyBold,
2060
0
                      bool AppendSpaceIfNonEmpty = true) {
2061
0
    if (Q.empty()) return;
2062
0
    if (ApplyBold) Bold();
2063
0
    Q.print(OS, Policy, AppendSpaceIfNonEmpty);
2064
0
    if (ApplyBold) Unbold();
2065
0
  }
2066
2067
public:
2068
2069
  TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType,
2070
               QualType ToType, bool PrintTree, bool PrintFromType,
2071
               bool ElideType, bool ShowColor)
2072
    : Context(Context),
2073
      Policy(Context.getLangOpts()),
2074
      ElideType(ElideType),
2075
      PrintTree(PrintTree),
2076
      ShowColor(ShowColor),
2077
      // When printing a single type, the FromType is the one printed.
2078
      FromTemplateType(PrintFromType ? FromType : ToType),
2079
      ToTemplateType(PrintFromType ? ToType : FromType),
2080
      OS(OS),
2081
0
      IsBold(false) {
2082
0
  }
2083
2084
  /// DiffTemplate - Start the template type diffing.
2085
0
  void DiffTemplate() {
2086
0
    Qualifiers FromQual = FromTemplateType.getQualifiers(),
2087
0
               ToQual = ToTemplateType.getQualifiers();
2088
2089
0
    const TemplateSpecializationType *FromOrigTST =
2090
0
        GetTemplateSpecializationType(Context, FromTemplateType);
2091
0
    const TemplateSpecializationType *ToOrigTST =
2092
0
        GetTemplateSpecializationType(Context, ToTemplateType);
2093
2094
    // Only checking templates.
2095
0
    if (!FromOrigTST || !ToOrigTST)
2096
0
      return;
2097
2098
    // Different base templates.
2099
0
    if (!hasSameTemplate(FromOrigTST, ToOrigTST)) {
2100
0
      return;
2101
0
    }
2102
2103
0
    FromQual -= QualType(FromOrigTST, 0).getQualifiers();
2104
0
    ToQual -= QualType(ToOrigTST, 0).getQualifiers();
2105
2106
    // Same base template, but different arguments.
2107
0
    Tree.SetTemplateDiff(FromOrigTST->getTemplateName().getAsTemplateDecl(),
2108
0
                         ToOrigTST->getTemplateName().getAsTemplateDecl(),
2109
0
                         FromQual, ToQual, false /*FromDefault*/,
2110
0
                         false /*ToDefault*/);
2111
2112
0
    DiffTemplate(FromOrigTST, ToOrigTST);
2113
0
  }
2114
2115
  /// Emit - When the two types given are templated types with the same
2116
  /// base template, a string representation of the type difference will be
2117
  /// emitted to the stream and return true.  Otherwise, return false.
2118
0
  bool Emit() {
2119
0
    Tree.StartTraverse();
2120
0
    if (Tree.Empty())
2121
0
      return false;
2122
2123
0
    TreeToString();
2124
0
    assert(!IsBold && "Bold is applied to end of string.");
2125
0
    return true;
2126
0
  }
2127
}; // end class TemplateDiff
2128
}  // end anonymous namespace
2129
2130
/// FormatTemplateTypeDiff - A helper static function to start the template
2131
/// diff and return the properly formatted string.  Returns true if the diff
2132
/// is successful.
2133
static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType,
2134
                                   QualType ToType, bool PrintTree,
2135
                                   bool PrintFromType, bool ElideType,
2136
0
                                   bool ShowColors, raw_ostream &OS) {
2137
0
  if (PrintTree)
2138
0
    PrintFromType = true;
2139
0
  TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType,
2140
0
                  ElideType, ShowColors);
2141
0
  TD.DiffTemplate();
2142
0
  return TD.Emit();
2143
0
}