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