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