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