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