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