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