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