clang  10.0.0svn
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 (Ty->isVectorType()) {
304  const VectorType *VTy = Ty->getAs<VectorType>();
305  std::string DecoratedString;
306  llvm::raw_string_ostream OS(DecoratedString);
307  const char *Values = VTy->getNumElements() > 1 ? "values" : "value";
308  OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '"
309  << VTy->getElementType().getAsString(Context.getPrintingPolicy())
310  << "' " << Values << ")";
311  return OS.str();
312  }
313  }
314 
315  S = "'" + S + "'";
316  return S;
317 }
318 
319 static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType,
320  QualType ToType, bool PrintTree,
321  bool PrintFromType, bool ElideType,
322  bool ShowColors, raw_ostream &OS);
323 
326  intptr_t Val,
327  StringRef Modifier,
328  StringRef Argument,
330  SmallVectorImpl<char> &Output,
331  void *Cookie,
332  ArrayRef<intptr_t> QualTypeVals) {
333  ASTContext &Context = *static_cast<ASTContext*>(Cookie);
334 
335  size_t OldEnd = Output.size();
336  llvm::raw_svector_ostream OS(Output);
337  bool NeedQuotes = true;
338 
339  switch (Kind) {
340  default: llvm_unreachable("unknown ArgumentKind");
342  assert(Modifier.empty() && Argument.empty() &&
343  "Invalid modifier for Qualfiers argument");
344 
346  auto S = Q.getAsString();
347  if (S.empty()) {
348  OS << "unqualified";
349  NeedQuotes = false;
350  } else {
351  OS << Q.getAsString();
352  }
353  break;
354  }
356  TemplateDiffTypes &TDT = *reinterpret_cast<TemplateDiffTypes*>(Val);
357  QualType FromType =
358  QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.FromType));
359  QualType ToType =
360  QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.ToType));
361 
362  if (FormatTemplateTypeDiff(Context, FromType, ToType, TDT.PrintTree,
363  TDT.PrintFromType, TDT.ElideType,
364  TDT.ShowColors, OS)) {
365  NeedQuotes = !TDT.PrintTree;
366  TDT.TemplateDiffUsed = true;
367  break;
368  }
369 
370  // Don't fall-back during tree printing. The caller will handle
371  // this case.
372  if (TDT.PrintTree)
373  return;
374 
375  // Attempting to do a template diff on non-templates. Set the variables
376  // and continue with regular type printing of the appropriate type.
377  Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType;
378  Modifier = StringRef();
379  Argument = StringRef();
380  // Fall through
381  LLVM_FALLTHROUGH;
382  }
384  assert(Modifier.empty() && Argument.empty() &&
385  "Invalid modifier for QualType argument");
386 
387  QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
388  OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals);
389  NeedQuotes = false;
390  break;
391  }
393  if (Modifier == "objcclass" && Argument.empty())
394  OS << '+';
395  else if (Modifier == "objcinstance" && Argument.empty())
396  OS << '-';
397  else
398  assert(Modifier.empty() && Argument.empty() &&
399  "Invalid modifier for DeclarationName argument");
400 
402  break;
403  }
405  bool Qualified;
406  if (Modifier == "q" && Argument.empty())
407  Qualified = true;
408  else {
409  assert(Modifier.empty() && Argument.empty() &&
410  "Invalid modifier for NamedDecl* argument");
411  Qualified = false;
412  }
413  const NamedDecl *ND = reinterpret_cast<const NamedDecl*>(Val);
414  ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), Qualified);
415  break;
416  }
418  NestedNameSpecifier *NNS = reinterpret_cast<NestedNameSpecifier*>(Val);
419  NNS->print(OS, Context.getPrintingPolicy());
420  NeedQuotes = false;
421  break;
422  }
424  DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
425  assert(DC && "Should never have a null declaration context");
426  NeedQuotes = false;
427 
428  // FIXME: Get the strings for DeclContext from some localized place
429  if (DC->isTranslationUnit()) {
430  if (Context.getLangOpts().CPlusPlus)
431  OS << "the global namespace";
432  else
433  OS << "the global scope";
434  } else if (DC->isClosure()) {
435  OS << "block literal";
436  } else if (isLambdaCallOperator(DC)) {
437  OS << "lambda expression";
438  } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
439  OS << ConvertTypeToDiagnosticString(Context,
440  Context.getTypeDeclType(Type),
441  PrevArgs, QualTypeVals);
442  } else {
443  assert(isa<NamedDecl>(DC) && "Expected a NamedDecl");
444  NamedDecl *ND = cast<NamedDecl>(DC);
445  if (isa<NamespaceDecl>(ND))
446  OS << "namespace ";
447  else if (isa<ObjCMethodDecl>(ND))
448  OS << "method ";
449  else if (isa<FunctionDecl>(ND))
450  OS << "function ";
451 
452  OS << '\'';
453  ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true);
454  OS << '\'';
455  }
456  break;
457  }
459  const Attr *At = reinterpret_cast<Attr *>(Val);
460  assert(At && "Received null Attr object!");
461  OS << '\'' << At->getSpelling() << '\'';
462  NeedQuotes = false;
463  break;
464  }
465  }
466 
467  if (NeedQuotes) {
468  Output.insert(Output.begin()+OldEnd, '\'');
469  Output.push_back('\'');
470  }
471 }
472 
473 /// TemplateDiff - A class that constructs a pretty string for a pair of
474 /// QualTypes. For the pair of types, a diff tree will be created containing
475 /// all the information about the templates and template arguments. Afterwards,
476 /// the tree is transformed to a string according to the options passed in.
477 namespace {
478 class TemplateDiff {
479  /// Context - The ASTContext which is used for comparing template arguments.
480  ASTContext &Context;
481 
482  /// Policy - Used during expression printing.
483  PrintingPolicy Policy;
484 
485  /// ElideType - Option to elide identical types.
486  bool ElideType;
487 
488  /// PrintTree - Format output string as a tree.
489  bool PrintTree;
490 
491  /// ShowColor - Diagnostics support color, so bolding will be used.
492  bool ShowColor;
493 
494  /// FromTemplateType - When single type printing is selected, this is the
495  /// type to be be printed. When tree printing is selected, this type will
496  /// show up first in the tree.
497  QualType FromTemplateType;
498 
499  /// ToTemplateType - The type that FromType is compared to. Only in tree
500  /// printing will this type be outputed.
501  QualType ToTemplateType;
502 
503  /// OS - The stream used to construct the output strings.
504  raw_ostream &OS;
505 
506  /// IsBold - Keeps track of the bold formatting for the output string.
507  bool IsBold;
508 
509  /// DiffTree - A tree representation the differences between two types.
510  class DiffTree {
511  public:
512  /// DiffKind - The difference in a DiffNode. Fields of
513  /// TemplateArgumentInfo needed by each difference can be found in the
514  /// Set* and Get* functions.
515  enum DiffKind {
516  /// Incomplete or invalid node.
517  Invalid,
518  /// Another level of templates
519  Template,
520  /// Type difference, all type differences except those falling under
521  /// the Template difference.
522  Type,
523  /// Expression difference, this is only when both arguments are
524  /// expressions. If one argument is an expression and the other is
525  /// Integer or Declaration, then use that diff type instead.
526  Expression,
527  /// Template argument difference
528  TemplateTemplate,
529  /// Integer difference
530  Integer,
531  /// Declaration difference, nullptr arguments are included here
532  Declaration,
533  /// One argument being integer and the other being declaration
534  FromIntegerAndToDeclaration,
535  FromDeclarationAndToInteger
536  };
537 
538  private:
539  /// TemplateArgumentInfo - All the information needed to pretty print
540  /// a template argument. See the Set* and Get* functions to see which
541  /// fields are used for each DiffKind.
542  struct TemplateArgumentInfo {
543  QualType ArgType;
544  Qualifiers Qual;
545  llvm::APSInt Val;
546  bool IsValidInt = false;
547  Expr *ArgExpr = nullptr;
548  TemplateDecl *TD = nullptr;
549  ValueDecl *VD = nullptr;
550  bool NeedAddressOf = false;
551  bool IsNullPtr = false;
552  bool IsDefault = false;
553  };
554 
555  /// DiffNode - The root node stores the original type. Each child node
556  /// stores template arguments of their parents. For templated types, the
557  /// template decl is also stored.
558  struct DiffNode {
559  DiffKind Kind = Invalid;
560 
561  /// NextNode - The index of the next sibling node or 0.
562  unsigned NextNode = 0;
563 
564  /// ChildNode - The index of the first child node or 0.
565  unsigned ChildNode = 0;
566 
567  /// ParentNode - The index of the parent node.
568  unsigned ParentNode = 0;
569 
570  TemplateArgumentInfo FromArgInfo, ToArgInfo;
571 
572  /// Same - Whether the two arguments evaluate to the same value.
573  bool Same = false;
574 
575  DiffNode(unsigned ParentNode = 0) : ParentNode(ParentNode) {}
576  };
577 
578  /// FlatTree - A flattened tree used to store the DiffNodes.
579  SmallVector<DiffNode, 16> FlatTree;
580 
581  /// CurrentNode - The index of the current node being used.
582  unsigned CurrentNode;
583 
584  /// NextFreeNode - The index of the next unused node. Used when creating
585  /// child nodes.
586  unsigned NextFreeNode;
587 
588  /// ReadNode - The index of the current node being read.
589  unsigned ReadNode;
590 
591  public:
592  DiffTree() :
593  CurrentNode(0), NextFreeNode(1) {
594  FlatTree.push_back(DiffNode());
595  }
596 
597  // Node writing functions, one for each valid DiffKind element.
598  void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
599  Qualifiers FromQual, Qualifiers ToQual,
600  bool FromDefault, bool ToDefault) {
601  assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
602  FlatTree[CurrentNode].Kind = Template;
603  FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
604  FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
605  FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;
606  FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;
607  SetDefault(FromDefault, ToDefault);
608  }
609 
610  void SetTypeDiff(QualType FromType, QualType ToType, bool FromDefault,
611  bool ToDefault) {
612  assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
613  FlatTree[CurrentNode].Kind = Type;
614  FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;
615  FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;
616  SetDefault(FromDefault, ToDefault);
617  }
618 
619  void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr, bool FromDefault,
620  bool ToDefault) {
621  assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
622  FlatTree[CurrentNode].Kind = Expression;
623  FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
624  FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
625  SetDefault(FromDefault, ToDefault);
626  }
627 
628  void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
629  bool FromDefault, bool ToDefault) {
630  assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
631  FlatTree[CurrentNode].Kind = TemplateTemplate;
632  FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
633  FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
634  SetDefault(FromDefault, ToDefault);
635  }
636 
637  void SetIntegerDiff(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt,
638  bool IsValidFromInt, bool IsValidToInt,
639  QualType FromIntType, QualType ToIntType,
640  Expr *FromExpr, Expr *ToExpr, bool FromDefault,
641  bool ToDefault) {
642  assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
643  FlatTree[CurrentNode].Kind = Integer;
644  FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
645  FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
646  FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
647  FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
648  FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
649  FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
650  FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
651  FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
652  SetDefault(FromDefault, ToDefault);
653  }
654 
655  void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
656  bool FromAddressOf, bool ToAddressOf,
657  bool FromNullPtr, bool ToNullPtr, Expr *FromExpr,
658  Expr *ToExpr, bool FromDefault, bool ToDefault) {
659  assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
660  FlatTree[CurrentNode].Kind = Declaration;
661  FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
662  FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
663  FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
664  FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
665  FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
666  FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
667  FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
668  FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
669  SetDefault(FromDefault, ToDefault);
670  }
671 
672  void SetFromDeclarationAndToIntegerDiff(
673  ValueDecl *FromValueDecl, bool FromAddressOf, bool FromNullPtr,
674  Expr *FromExpr, const llvm::APSInt &ToInt, bool IsValidToInt,
675  QualType ToIntType, Expr *ToExpr, bool FromDefault, bool ToDefault) {
676  assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
677  FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger;
678  FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
679  FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
680  FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
681  FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
682  FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
683  FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
684  FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
685  FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
686  SetDefault(FromDefault, ToDefault);
687  }
688 
689  void SetFromIntegerAndToDeclarationDiff(
690  const llvm::APSInt &FromInt, bool IsValidFromInt, QualType FromIntType,
691  Expr *FromExpr, ValueDecl *ToValueDecl, bool ToAddressOf,
692  bool ToNullPtr, Expr *ToExpr, bool FromDefault, bool ToDefault) {
693  assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
694  FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration;
695  FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
696  FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
697  FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
698  FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
699  FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
700  FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
701  FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
702  FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
703  SetDefault(FromDefault, ToDefault);
704  }
705 
706  /// SetDefault - Sets FromDefault and ToDefault flags of the current node.
707  void SetDefault(bool FromDefault, bool ToDefault) {
708  assert((!FromDefault || !ToDefault) && "Both arguments cannot be default.");
709  FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;
710  FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;
711  }
712 
713  /// SetSame - Sets the same flag of the current node.
714  void SetSame(bool Same) {
715  FlatTree[CurrentNode].Same = Same;
716  }
717 
718  /// SetKind - Sets the current node's type.
719  void SetKind(DiffKind Kind) {
720  FlatTree[CurrentNode].Kind = Kind;
721  }
722 
723  /// Up - Changes the node to the parent of the current node.
724  void Up() {
725  assert(FlatTree[CurrentNode].Kind != Invalid &&
726  "Cannot exit node before setting node information.");
727  CurrentNode = FlatTree[CurrentNode].ParentNode;
728  }
729 
730  /// AddNode - Adds a child node to the current node, then sets that node
731  /// node as the current node.
732  void AddNode() {
733  assert(FlatTree[CurrentNode].Kind == Template &&
734  "Only Template nodes can have children nodes.");
735  FlatTree.push_back(DiffNode(CurrentNode));
736  DiffNode &Node = FlatTree[CurrentNode];
737  if (Node.ChildNode == 0) {
738  // If a child node doesn't exist, add one.
739  Node.ChildNode = NextFreeNode;
740  } else {
741  // If a child node exists, find the last child node and add a
742  // next node to it.
743  unsigned i;
744  for (i = Node.ChildNode; FlatTree[i].NextNode != 0;
745  i = FlatTree[i].NextNode) {
746  }
747  FlatTree[i].NextNode = NextFreeNode;
748  }
749  CurrentNode = NextFreeNode;
750  ++NextFreeNode;
751  }
752 
753  // Node reading functions.
754  /// StartTraverse - Prepares the tree for recursive traversal.
755  void StartTraverse() {
756  ReadNode = 0;
757  CurrentNode = NextFreeNode;
758  NextFreeNode = 0;
759  }
760 
761  /// Parent - Move the current read node to its parent.
762  void Parent() {
763  ReadNode = FlatTree[ReadNode].ParentNode;
764  }
765 
766  void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD,
767  Qualifiers &FromQual, Qualifiers &ToQual) {
768  assert(FlatTree[ReadNode].Kind == Template && "Unexpected kind.");
769  FromTD = FlatTree[ReadNode].FromArgInfo.TD;
770  ToTD = FlatTree[ReadNode].ToArgInfo.TD;
771  FromQual = FlatTree[ReadNode].FromArgInfo.Qual;
772  ToQual = FlatTree[ReadNode].ToArgInfo.Qual;
773  }
774 
775  void GetTypeDiff(QualType &FromType, QualType &ToType) {
776  assert(FlatTree[ReadNode].Kind == Type && "Unexpected kind");
777  FromType = FlatTree[ReadNode].FromArgInfo.ArgType;
778  ToType = FlatTree[ReadNode].ToArgInfo.ArgType;
779  }
780 
781  void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) {
782  assert(FlatTree[ReadNode].Kind == Expression && "Unexpected kind");
783  FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
784  ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
785  }
786 
787  void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {
788  assert(FlatTree[ReadNode].Kind == TemplateTemplate && "Unexpected kind.");
789  FromTD = FlatTree[ReadNode].FromArgInfo.TD;
790  ToTD = FlatTree[ReadNode].ToArgInfo.TD;
791  }
792 
793  void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
794  bool &IsValidFromInt, bool &IsValidToInt,
795  QualType &FromIntType, QualType &ToIntType,
796  Expr *&FromExpr, Expr *&ToExpr) {
797  assert(FlatTree[ReadNode].Kind == Integer && "Unexpected kind.");
798  FromInt = FlatTree[ReadNode].FromArgInfo.Val;
799  ToInt = FlatTree[ReadNode].ToArgInfo.Val;
800  IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
801  IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
802  FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
803  ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
804  FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
805  ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
806  }
807 
808  void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,
809  bool &FromAddressOf, bool &ToAddressOf,
810  bool &FromNullPtr, bool &ToNullPtr, Expr *&FromExpr,
811  Expr *&ToExpr) {
812  assert(FlatTree[ReadNode].Kind == Declaration && "Unexpected kind.");
813  FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
814  ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
815  FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
816  ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
817  FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
818  ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
819  FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
820  ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
821  }
822 
823  void GetFromDeclarationAndToIntegerDiff(
824  ValueDecl *&FromValueDecl, bool &FromAddressOf, bool &FromNullPtr,
825  Expr *&FromExpr, llvm::APSInt &ToInt, bool &IsValidToInt,
826  QualType &ToIntType, Expr *&ToExpr) {
827  assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger &&
828  "Unexpected kind.");
829  FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
830  FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
831  FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
832  FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
833  ToInt = FlatTree[ReadNode].ToArgInfo.Val;
834  IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
835  ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
836  ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
837  }
838 
839  void GetFromIntegerAndToDeclarationDiff(
840  llvm::APSInt &FromInt, bool &IsValidFromInt, QualType &FromIntType,
841  Expr *&FromExpr, ValueDecl *&ToValueDecl, bool &ToAddressOf,
842  bool &ToNullPtr, Expr *&ToExpr) {
843  assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration &&
844  "Unexpected kind.");
845  FromInt = FlatTree[ReadNode].FromArgInfo.Val;
846  IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
847  FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
848  FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
849  ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
850  ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
851  ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
852  ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
853  }
854 
855  /// FromDefault - Return true if the from argument is the default.
856  bool FromDefault() {
857  return FlatTree[ReadNode].FromArgInfo.IsDefault;
858  }
859 
860  /// ToDefault - Return true if the to argument is the default.
861  bool ToDefault() {
862  return FlatTree[ReadNode].ToArgInfo.IsDefault;
863  }
864 
865  /// NodeIsSame - Returns true the arguments are the same.
866  bool NodeIsSame() {
867  return FlatTree[ReadNode].Same;
868  }
869 
870  /// HasChildrend - Returns true if the node has children.
871  bool HasChildren() {
872  return FlatTree[ReadNode].ChildNode != 0;
873  }
874 
875  /// MoveToChild - Moves from the current node to its child.
876  void MoveToChild() {
877  ReadNode = FlatTree[ReadNode].ChildNode;
878  }
879 
880  /// AdvanceSibling - If there is a next sibling, advance to it and return
881  /// true. Otherwise, return false.
882  bool AdvanceSibling() {
883  if (FlatTree[ReadNode].NextNode == 0)
884  return false;
885 
886  ReadNode = FlatTree[ReadNode].NextNode;
887  return true;
888  }
889 
890  /// HasNextSibling - Return true if the node has a next sibling.
891  bool HasNextSibling() {
892  return FlatTree[ReadNode].NextNode != 0;
893  }
894 
895  /// Empty - Returns true if the tree has no information.
896  bool Empty() {
897  return GetKind() == Invalid;
898  }
899 
900  /// GetKind - Returns the current node's type.
901  DiffKind GetKind() {
902  return FlatTree[ReadNode].Kind;
903  }
904  };
905 
906  DiffTree Tree;
907 
908  /// TSTiterator - a pair of iterators that walks the
909  /// TemplateSpecializationType and the desugared TemplateSpecializationType.
910  /// The deseguared TemplateArgument should provide the canonical argument
911  /// for comparisons.
912  class TSTiterator {
913  typedef const TemplateArgument& reference;
914  typedef const TemplateArgument* pointer;
915 
916  /// InternalIterator - an iterator that is used to enter a
917  /// TemplateSpecializationType and read TemplateArguments inside template
918  /// parameter packs in order with the rest of the TemplateArguments.
919  struct InternalIterator {
920  /// TST - the template specialization whose arguments this iterator
921  /// traverse over.
922  const TemplateSpecializationType *TST;
923 
924  /// Index - the index of the template argument in TST.
925  unsigned Index;
926 
927  /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA
928  /// points to a TemplateArgument within a parameter pack.
930 
931  /// EndTA - the end iterator of a parameter pack
933 
934  /// InternalIterator - Constructs an iterator and sets it to the first
935  /// template argument.
936  InternalIterator(const TemplateSpecializationType *TST)
937  : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
938  if (!TST) return;
939 
940  if (isEnd()) return;
941 
942  // Set to first template argument. If not a parameter pack, done.
943  TemplateArgument TA = TST->getArg(0);
944  if (TA.getKind() != TemplateArgument::Pack) return;
945 
946  // Start looking into the parameter pack.
947  CurrentTA = TA.pack_begin();
948  EndTA = TA.pack_end();
949 
950  // Found a valid template argument.
951  if (CurrentTA != EndTA) return;
952 
953  // Parameter pack is empty, use the increment to get to a valid
954  // template argument.
955  ++(*this);
956  }
957 
958  /// Return true if the iterator is non-singular.
959  bool isValid() const { return TST; }
960 
961  /// isEnd - Returns true if the iterator is one past the end.
962  bool isEnd() const {
963  assert(TST && "InternalIterator is invalid with a null TST.");
964  return Index >= TST->getNumArgs();
965  }
966 
967  /// &operator++ - Increment the iterator to the next template argument.
968  InternalIterator &operator++() {
969  assert(TST && "InternalIterator is invalid with a null TST.");
970  if (isEnd()) {
971  return *this;
972  }
973 
974  // If in a parameter pack, advance in the parameter pack.
975  if (CurrentTA != EndTA) {
976  ++CurrentTA;
977  if (CurrentTA != EndTA)
978  return *this;
979  }
980 
981  // Loop until a template argument is found, or the end is reached.
982  while (true) {
983  // Advance to the next template argument. Break if reached the end.
984  if (++Index == TST->getNumArgs())
985  break;
986 
987  // If the TemplateArgument is not a parameter pack, done.
988  TemplateArgument TA = TST->getArg(Index);
989  if (TA.getKind() != TemplateArgument::Pack)
990  break;
991 
992  // Handle parameter packs.
993  CurrentTA = TA.pack_begin();
994  EndTA = TA.pack_end();
995 
996  // If the parameter pack is empty, try to advance again.
997  if (CurrentTA != EndTA)
998  break;
999  }
1000  return *this;
1001  }
1002 
1003  /// operator* - Returns the appropriate TemplateArgument.
1004  reference operator*() const {
1005  assert(TST && "InternalIterator is invalid with a null TST.");
1006  assert(!isEnd() && "Index exceeds number of arguments.");
1007  if (CurrentTA == EndTA)
1008  return TST->getArg(Index);
1009  else
1010  return *CurrentTA;
1011  }
1012 
1013  /// operator-> - Allow access to the underlying TemplateArgument.
1014  pointer operator->() const {
1015  assert(TST && "InternalIterator is invalid with a null TST.");
1016  return &operator*();
1017  }
1018  };
1019 
1020  InternalIterator SugaredIterator;
1021  InternalIterator DesugaredIterator;
1022 
1023  public:
1024  TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
1025  : SugaredIterator(TST),
1026  DesugaredIterator(
1027  (TST->isSugared() && !TST->isTypeAlias())
1028  ? GetTemplateSpecializationType(Context, TST->desugar())
1029  : nullptr) {}
1030 
1031  /// &operator++ - Increment the iterator to the next template argument.
1032  TSTiterator &operator++() {
1033  ++SugaredIterator;
1034  if (DesugaredIterator.isValid())
1035  ++DesugaredIterator;
1036  return *this;
1037  }
1038 
1039  /// operator* - Returns the appropriate TemplateArgument.
1040  reference operator*() const {
1041  return *SugaredIterator;
1042  }
1043 
1044  /// operator-> - Allow access to the underlying TemplateArgument.
1045  pointer operator->() const {
1046  return &operator*();
1047  }
1048 
1049  /// isEnd - Returns true if no more TemplateArguments are available.
1050  bool isEnd() const {
1051  return SugaredIterator.isEnd();
1052  }
1053 
1054  /// hasDesugaredTA - Returns true if there is another TemplateArgument
1055  /// available.
1056  bool hasDesugaredTA() const {
1057  return DesugaredIterator.isValid() && !DesugaredIterator.isEnd();
1058  }
1059 
1060  /// getDesugaredTA - Returns the desugared TemplateArgument.
1061  reference getDesugaredTA() const {
1062  assert(DesugaredIterator.isValid() &&
1063  "Desugared TemplateArgument should not be used.");
1064  return *DesugaredIterator;
1065  }
1066  };
1067 
1068  // These functions build up the template diff tree, including functions to
1069  // retrieve and compare template arguments.
1070 
1071  static const TemplateSpecializationType *GetTemplateSpecializationType(
1072  ASTContext &Context, QualType Ty) {
1073  if (const TemplateSpecializationType *TST =
1075  return TST;
1076 
1077  const RecordType *RT = Ty->getAs<RecordType>();
1078 
1079  if (!RT)
1080  return nullptr;
1081 
1082  const ClassTemplateSpecializationDecl *CTSD =
1083  dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
1084 
1085  if (!CTSD)
1086  return nullptr;
1087 
1088  Ty = Context.getTemplateSpecializationType(
1090  CTSD->getTemplateArgs().asArray(),
1092 
1093  return Ty->getAs<TemplateSpecializationType>();
1094  }
1095 
1096  /// Returns true if the DiffType is Type and false for Template.
1097  static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType,
1098  QualType ToType,
1099  const TemplateSpecializationType *&FromArgTST,
1100  const TemplateSpecializationType *&ToArgTST) {
1101  if (FromType.isNull() || ToType.isNull())
1102  return true;
1103 
1104  if (Context.hasSameType(FromType, ToType))
1105  return true;
1106 
1107  FromArgTST = GetTemplateSpecializationType(Context, FromType);
1108  ToArgTST = GetTemplateSpecializationType(Context, ToType);
1109 
1110  if (!FromArgTST || !ToArgTST)
1111  return true;
1112 
1113  if (!hasSameTemplate(FromArgTST, ToArgTST))
1114  return true;
1115 
1116  return false;
1117  }
1118 
1119  /// DiffTypes - Fills a DiffNode with information about a type difference.
1120  void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter) {
1121  QualType FromType = GetType(FromIter);
1122  QualType ToType = GetType(ToIter);
1123 
1124  bool FromDefault = FromIter.isEnd() && !FromType.isNull();
1125  bool ToDefault = ToIter.isEnd() && !ToType.isNull();
1126 
1127  const TemplateSpecializationType *FromArgTST = nullptr;
1128  const TemplateSpecializationType *ToArgTST = nullptr;
1129  if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {
1130  Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);
1131  Tree.SetSame(!FromType.isNull() && !ToType.isNull() &&
1132  Context.hasSameType(FromType, ToType));
1133  } else {
1134  assert(FromArgTST && ToArgTST &&
1135  "Both template specializations need to be valid.");
1136  Qualifiers FromQual = FromType.getQualifiers(),
1137  ToQual = ToType.getQualifiers();
1138  FromQual -= QualType(FromArgTST, 0).getQualifiers();
1139  ToQual -= QualType(ToArgTST, 0).getQualifiers();
1140  Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(),
1141  ToArgTST->getTemplateName().getAsTemplateDecl(),
1142  FromQual, ToQual, FromDefault, ToDefault);
1143  DiffTemplate(FromArgTST, ToArgTST);
1144  }
1145  }
1146 
1147  /// DiffTemplateTemplates - Fills a DiffNode with information about a
1148  /// template template difference.
1149  void DiffTemplateTemplates(const TSTiterator &FromIter,
1150  const TSTiterator &ToIter) {
1151  TemplateDecl *FromDecl = GetTemplateDecl(FromIter);
1152  TemplateDecl *ToDecl = GetTemplateDecl(ToIter);
1153  Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl,
1154  ToIter.isEnd() && ToDecl);
1155  Tree.SetSame(FromDecl && ToDecl &&
1156  FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl());
1157  }
1158 
1159  /// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes
1160  static void InitializeNonTypeDiffVariables(ASTContext &Context,
1161  const TSTiterator &Iter,
1163  llvm::APSInt &Value, bool &HasInt,
1164  QualType &IntType, bool &IsNullPtr,
1165  Expr *&E, ValueDecl *&VD,
1166  bool &NeedAddressOf) {
1167  if (!Iter.isEnd()) {
1168  switch (Iter->getKind()) {
1169  default:
1170  llvm_unreachable("unknown ArgumentKind");
1172  Value = Iter->getAsIntegral();
1173  HasInt = true;
1174  IntType = Iter->getIntegralType();
1175  return;
1177  VD = Iter->getAsDecl();
1178  QualType ArgType = Iter->getParamTypeForDecl();
1179  QualType VDType = VD->getType();
1180  if (ArgType->isPointerType() &&
1181  Context.hasSameType(ArgType->getPointeeType(), VDType))
1182  NeedAddressOf = true;
1183  return;
1184  }
1186  IsNullPtr = true;
1187  return;
1189  E = Iter->getAsExpr();
1190  }
1191  } else if (!Default->isParameterPack()) {
1192  E = Default->getDefaultArgument();
1193  }
1194 
1195  if (!Iter.hasDesugaredTA()) return;
1196 
1197  const TemplateArgument& TA = Iter.getDesugaredTA();
1198  switch (TA.getKind()) {
1199  default:
1200  llvm_unreachable("unknown ArgumentKind");
1202  Value = TA.getAsIntegral();
1203  HasInt = true;
1204  IntType = TA.getIntegralType();
1205  return;
1207  VD = TA.getAsDecl();
1208  QualType ArgType = TA.getParamTypeForDecl();
1209  QualType VDType = VD->getType();
1210  if (ArgType->isPointerType() &&
1211  Context.hasSameType(ArgType->getPointeeType(), VDType))
1212  NeedAddressOf = true;
1213  return;
1214  }
1216  IsNullPtr = true;
1217  return;
1219  // TODO: Sometimes, the desugared template argument Expr differs from
1220  // the sugared template argument Expr. It may be useful in the future
1221  // but for now, it is just discarded.
1222  if (!E)
1223  E = TA.getAsExpr();
1224  return;
1225  }
1226  }
1227 
1228  /// DiffNonTypes - Handles any template parameters not handled by DiffTypes
1229  /// of DiffTemplatesTemplates, such as integer and declaration parameters.
1230  void DiffNonTypes(const TSTiterator &FromIter, const TSTiterator &ToIter,
1231  NonTypeTemplateParmDecl *FromDefaultNonTypeDecl,
1232  NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) {
1233  Expr *FromExpr = nullptr, *ToExpr = nullptr;
1234  llvm::APSInt FromInt, ToInt;
1235  QualType FromIntType, ToIntType;
1236  ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr;
1237  bool HasFromInt = false, HasToInt = false, FromNullPtr = false,
1238  ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false;
1239  InitializeNonTypeDiffVariables(
1240  Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt,
1241  FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf);
1242  InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt,
1243  HasToInt, ToIntType, ToNullPtr, ToExpr,
1244  ToValueDecl, NeedToAddressOf);
1245 
1246  bool FromDefault = FromIter.isEnd() &&
1247  (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);
1248  bool ToDefault = ToIter.isEnd() &&
1249  (ToExpr || ToValueDecl || HasToInt || ToNullPtr);
1250 
1251  bool FromDeclaration = FromValueDecl || FromNullPtr;
1252  bool ToDeclaration = ToValueDecl || ToNullPtr;
1253 
1254  if (FromDeclaration && HasToInt) {
1255  Tree.SetFromDeclarationAndToIntegerDiff(
1256  FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt,
1257  HasToInt, ToIntType, ToExpr, FromDefault, ToDefault);
1258  Tree.SetSame(false);
1259  return;
1260 
1261  }
1262 
1263  if (HasFromInt && ToDeclaration) {
1264  Tree.SetFromIntegerAndToDeclarationDiff(
1265  FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl,
1266  NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault);
1267  Tree.SetSame(false);
1268  return;
1269  }
1270 
1271  if (HasFromInt || HasToInt) {
1272  Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType,
1273  ToIntType, FromExpr, ToExpr, FromDefault, ToDefault);
1274  if (HasFromInt && HasToInt) {
1275  Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) &&
1276  FromInt == ToInt);
1277  }
1278  return;
1279  }
1280 
1281  if (FromDeclaration || ToDeclaration) {
1282  Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf,
1283  NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1284  ToExpr, FromDefault, ToDefault);
1285  bool BothNull = FromNullPtr && ToNullPtr;
1286  bool SameValueDecl =
1287  FromValueDecl && ToValueDecl &&
1288  NeedFromAddressOf == NeedToAddressOf &&
1289  FromValueDecl->getCanonicalDecl() == ToValueDecl->getCanonicalDecl();
1290  Tree.SetSame(BothNull || SameValueDecl);
1291  return;
1292  }
1293 
1294  assert((FromExpr || ToExpr) && "Both template arguments cannot be empty.");
1295  Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault);
1296  Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));
1297  }
1298 
1299  /// DiffTemplate - recursively visits template arguments and stores the
1300  /// argument info into a tree.
1301  void DiffTemplate(const TemplateSpecializationType *FromTST,
1302  const TemplateSpecializationType *ToTST) {
1303  // Begin descent into diffing template tree.
1304  TemplateParameterList *ParamsFrom =
1306  TemplateParameterList *ParamsTo =
1308  unsigned TotalArgs = 0;
1309  for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST);
1310  !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) {
1311  Tree.AddNode();
1312 
1313  // Get the parameter at index TotalArgs. If index is larger
1314  // than the total number of parameters, then there is an
1315  // argument pack, so re-use the last parameter.
1316  unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->size() - 1);
1317  unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->size() - 1);
1318  NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex);
1319  NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex);
1320 
1321  assert(FromParamND->getKind() == ToParamND->getKind() &&
1322  "Parameter Decl are not the same kind.");
1323 
1324  if (isa<TemplateTypeParmDecl>(FromParamND)) {
1325  DiffTypes(FromIter, ToIter);
1326  } else if (isa<TemplateTemplateParmDecl>(FromParamND)) {
1327  DiffTemplateTemplates(FromIter, ToIter);
1328  } else if (isa<NonTypeTemplateParmDecl>(FromParamND)) {
1329  NonTypeTemplateParmDecl *FromDefaultNonTypeDecl =
1330  cast<NonTypeTemplateParmDecl>(FromParamND);
1331  NonTypeTemplateParmDecl *ToDefaultNonTypeDecl =
1332  cast<NonTypeTemplateParmDecl>(ToParamND);
1333  DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
1334  ToDefaultNonTypeDecl);
1335  } else {
1336  llvm_unreachable("Unexpected Decl type.");
1337  }
1338 
1339  ++FromIter;
1340  ++ToIter;
1341  Tree.Up();
1342  }
1343  }
1344 
1345  /// makeTemplateList - Dump every template alias into the vector.
1346  static void makeTemplateList(
1348  const TemplateSpecializationType *TST) {
1349  while (TST) {
1350  TemplateList.push_back(TST);
1351  if (!TST->isTypeAlias())
1352  return;
1354  }
1355  }
1356 
1357  /// hasSameBaseTemplate - Returns true when the base templates are the same,
1358  /// even if the template arguments are not.
1359  static bool hasSameBaseTemplate(const TemplateSpecializationType *FromTST,
1360  const TemplateSpecializationType *ToTST) {
1361  return FromTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl() ==
1363  }
1364 
1365  /// hasSameTemplate - Returns true if both types are specialized from the
1366  /// same template declaration. If they come from different template aliases,
1367  /// do a parallel ascension search to determine the highest template alias in
1368  /// common and set the arguments to them.
1369  static bool hasSameTemplate(const TemplateSpecializationType *&FromTST,
1370  const TemplateSpecializationType *&ToTST) {
1371  // Check the top templates if they are the same.
1372  if (hasSameBaseTemplate(FromTST, ToTST))
1373  return true;
1374 
1375  // Create vectors of template aliases.
1377  ToTemplateList;
1378 
1379  makeTemplateList(FromTemplateList, FromTST);
1380  makeTemplateList(ToTemplateList, ToTST);
1381 
1383  FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(),
1384  ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend();
1385 
1386  // Check if the lowest template types are the same. If not, return.
1387  if (!hasSameBaseTemplate(*FromIter, *ToIter))
1388  return false;
1389 
1390  // Begin searching up the template aliases. The bottom most template
1391  // matches so move up until one pair does not match. Use the template
1392  // right before that one.
1393  for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) {
1394  if (!hasSameBaseTemplate(*FromIter, *ToIter))
1395  break;
1396  }
1397 
1398  FromTST = FromIter[-1];
1399  ToTST = ToIter[-1];
1400 
1401  return true;
1402  }
1403 
1404  /// GetType - Retrieves the template type arguments, including default
1405  /// arguments.
1406  static QualType GetType(const TSTiterator &Iter) {
1407  if (!Iter.isEnd())
1408  return Iter->getAsType();
1409  if (Iter.hasDesugaredTA())
1410  return Iter.getDesugaredTA().getAsType();
1411  return QualType();
1412  }
1413 
1414  /// GetTemplateDecl - Retrieves the template template arguments, including
1415  /// default arguments.
1416  static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter) {
1417  if (!Iter.isEnd())
1418  return Iter->getAsTemplate().getAsTemplateDecl();
1419  if (Iter.hasDesugaredTA())
1420  return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();
1421  return nullptr;
1422  }
1423 
1424  /// IsEqualExpr - Returns true if the expressions are the same in regards to
1425  /// template arguments. These expressions are dependent, so profile them
1426  /// instead of trying to evaluate them.
1427  static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) {
1428  if (FromExpr == ToExpr)
1429  return true;
1430 
1431  if (!FromExpr || !ToExpr)
1432  return false;
1433 
1434  llvm::FoldingSetNodeID FromID, ToID;
1435  FromExpr->Profile(FromID, Context, true);
1436  ToExpr->Profile(ToID, Context, true);
1437  return FromID == ToID;
1438  }
1439 
1440  // These functions converts the tree representation of the template
1441  // differences into the internal character vector.
1442 
1443  /// TreeToString - Converts the Tree object into a character stream which
1444  /// will later be turned into the output string.
1445  void TreeToString(int Indent = 1) {
1446  if (PrintTree) {
1447  OS << '\n';
1448  OS.indent(2 * Indent);
1449  ++Indent;
1450  }
1451 
1452  // Handle cases where the difference is not templates with different
1453  // arguments.
1454  switch (Tree.GetKind()) {
1455  case DiffTree::Invalid:
1456  llvm_unreachable("Template diffing failed with bad DiffNode");
1457  case DiffTree::Type: {
1458  QualType FromType, ToType;
1459  Tree.GetTypeDiff(FromType, ToType);
1460  PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(),
1461  Tree.NodeIsSame());
1462  return;
1463  }
1464  case DiffTree::Expression: {
1465  Expr *FromExpr, *ToExpr;
1466  Tree.GetExpressionDiff(FromExpr, ToExpr);
1467  PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
1468  Tree.NodeIsSame());
1469  return;
1470  }
1471  case DiffTree::TemplateTemplate: {
1472  TemplateDecl *FromTD, *ToTD;
1473  Tree.GetTemplateTemplateDiff(FromTD, ToTD);
1474  PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(),
1475  Tree.ToDefault(), Tree.NodeIsSame());
1476  return;
1477  }
1478  case DiffTree::Integer: {
1479  llvm::APSInt FromInt, ToInt;
1480  Expr *FromExpr, *ToExpr;
1481  bool IsValidFromInt, IsValidToInt;
1482  QualType FromIntType, ToIntType;
1483  Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,
1484  FromIntType, ToIntType, FromExpr, ToExpr);
1485  PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType,
1486  ToIntType, FromExpr, ToExpr, Tree.FromDefault(),
1487  Tree.ToDefault(), Tree.NodeIsSame());
1488  return;
1489  }
1490  case DiffTree::Declaration: {
1491  ValueDecl *FromValueDecl, *ToValueDecl;
1492  bool FromAddressOf, ToAddressOf;
1493  bool FromNullPtr, ToNullPtr;
1494  Expr *FromExpr, *ToExpr;
1495  Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,
1496  ToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1497  ToExpr);
1498  PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
1499  FromNullPtr, ToNullPtr, FromExpr, ToExpr,
1500  Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
1501  return;
1502  }
1503  case DiffTree::FromDeclarationAndToInteger: {
1504  ValueDecl *FromValueDecl;
1505  bool FromAddressOf;
1506  bool FromNullPtr;
1507  Expr *FromExpr;
1508  llvm::APSInt ToInt;
1509  bool IsValidToInt;
1510  QualType ToIntType;
1511  Expr *ToExpr;
1512  Tree.GetFromDeclarationAndToIntegerDiff(
1513  FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt,
1514  IsValidToInt, ToIntType, ToExpr);
1515  assert((FromValueDecl || FromNullPtr) && IsValidToInt);
1516  PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr,
1517  FromExpr, Tree.FromDefault(), ToInt, ToIntType,
1518  ToExpr, Tree.ToDefault());
1519  return;
1520  }
1521  case DiffTree::FromIntegerAndToDeclaration: {
1522  llvm::APSInt FromInt;
1523  bool IsValidFromInt;
1524  QualType FromIntType;
1525  Expr *FromExpr;
1526  ValueDecl *ToValueDecl;
1527  bool ToAddressOf;
1528  bool ToNullPtr;
1529  Expr *ToExpr;
1530  Tree.GetFromIntegerAndToDeclarationDiff(
1531  FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl,
1532  ToAddressOf, ToNullPtr, ToExpr);
1533  assert(IsValidFromInt && (ToValueDecl || ToNullPtr));
1534  PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr,
1535  Tree.FromDefault(), ToValueDecl, ToAddressOf,
1536  ToNullPtr, ToExpr, Tree.ToDefault());
1537  return;
1538  }
1539  case DiffTree::Template: {
1540  // Node is root of template. Recurse on children.
1541  TemplateDecl *FromTD, *ToTD;
1542  Qualifiers FromQual, ToQual;
1543  Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);
1544 
1545  PrintQualifiers(FromQual, ToQual);
1546 
1547  if (!Tree.HasChildren()) {
1548  // If we're dealing with a template specialization with zero
1549  // arguments, there are no children; special-case this.
1550  OS << FromTD->getNameAsString() << "<>";
1551  return;
1552  }
1553 
1554  OS << FromTD->getNameAsString() << '<';
1555  Tree.MoveToChild();
1556  unsigned NumElideArgs = 0;
1557  bool AllArgsElided = true;
1558  do {
1559  if (ElideType) {
1560  if (Tree.NodeIsSame()) {
1561  ++NumElideArgs;
1562  continue;
1563  }
1564  AllArgsElided = false;
1565  if (NumElideArgs > 0) {
1566  PrintElideArgs(NumElideArgs, Indent);
1567  NumElideArgs = 0;
1568  OS << ", ";
1569  }
1570  }
1571  TreeToString(Indent);
1572  if (Tree.HasNextSibling())
1573  OS << ", ";
1574  } while (Tree.AdvanceSibling());
1575  if (NumElideArgs > 0) {
1576  if (AllArgsElided)
1577  OS << "...";
1578  else
1579  PrintElideArgs(NumElideArgs, Indent);
1580  }
1581 
1582  Tree.Parent();
1583  OS << ">";
1584  return;
1585  }
1586  }
1587  }
1588 
1589  // To signal to the text printer that a certain text needs to be bolded,
1590  // a special character is injected into the character stream which the
1591  // text printer will later strip out.
1592 
1593  /// Bold - Start bolding text.
1594  void Bold() {
1595  assert(!IsBold && "Attempting to bold text that is already bold.");
1596  IsBold = true;
1597  if (ShowColor)
1598  OS << ToggleHighlight;
1599  }
1600 
1601  /// Unbold - Stop bolding text.
1602  void Unbold() {
1603  assert(IsBold && "Attempting to remove bold from unbold text.");
1604  IsBold = false;
1605  if (ShowColor)
1606  OS << ToggleHighlight;
1607  }
1608 
1609  // Functions to print out the arguments and highlighting the difference.
1610 
1611  /// PrintTypeNames - prints the typenames, bolding differences. Will detect
1612  /// typenames that are the same and attempt to disambiguate them by using
1613  /// canonical typenames.
1614  void PrintTypeNames(QualType FromType, QualType ToType,
1615  bool FromDefault, bool ToDefault, bool Same) {
1616  assert((!FromType.isNull() || !ToType.isNull()) &&
1617  "Only one template argument may be missing.");
1618 
1619  if (Same) {
1620  OS << FromType.getAsString(Policy);
1621  return;
1622  }
1623 
1624  if (!FromType.isNull() && !ToType.isNull() &&
1625  FromType.getLocalUnqualifiedType() ==
1626  ToType.getLocalUnqualifiedType()) {
1627  Qualifiers FromQual = FromType.getLocalQualifiers(),
1628  ToQual = ToType.getLocalQualifiers();
1629  PrintQualifiers(FromQual, ToQual);
1630  FromType.getLocalUnqualifiedType().print(OS, Policy);
1631  return;
1632  }
1633 
1634  std::string FromTypeStr = FromType.isNull() ? "(no argument)"
1635  : FromType.getAsString(Policy);
1636  std::string ToTypeStr = ToType.isNull() ? "(no argument)"
1637  : ToType.getAsString(Policy);
1638  // Switch to canonical typename if it is better.
1639  // TODO: merge this with other aka printing above.
1640  if (FromTypeStr == ToTypeStr) {
1641  std::string FromCanTypeStr =
1642  FromType.getCanonicalType().getAsString(Policy);
1643  std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(Policy);
1644  if (FromCanTypeStr != ToCanTypeStr) {
1645  FromTypeStr = FromCanTypeStr;
1646  ToTypeStr = ToCanTypeStr;
1647  }
1648  }
1649 
1650  if (PrintTree) OS << '[';
1651  OS << (FromDefault ? "(default) " : "");
1652  Bold();
1653  OS << FromTypeStr;
1654  Unbold();
1655  if (PrintTree) {
1656  OS << " != " << (ToDefault ? "(default) " : "");
1657  Bold();
1658  OS << ToTypeStr;
1659  Unbold();
1660  OS << "]";
1661  }
1662  }
1663 
1664  /// PrintExpr - Prints out the expr template arguments, highlighting argument
1665  /// differences.
1666  void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault,
1667  bool ToDefault, bool Same) {
1668  assert((FromExpr || ToExpr) &&
1669  "Only one template argument may be missing.");
1670  if (Same) {
1671  PrintExpr(FromExpr);
1672  } else if (!PrintTree) {
1673  OS << (FromDefault ? "(default) " : "");
1674  Bold();
1675  PrintExpr(FromExpr);
1676  Unbold();
1677  } else {
1678  OS << (FromDefault ? "[(default) " : "[");
1679  Bold();
1680  PrintExpr(FromExpr);
1681  Unbold();
1682  OS << " != " << (ToDefault ? "(default) " : "");
1683  Bold();
1684  PrintExpr(ToExpr);
1685  Unbold();
1686  OS << ']';
1687  }
1688  }
1689 
1690  /// PrintExpr - Actual formatting and printing of expressions.
1691  void PrintExpr(const Expr *E) {
1692  if (E) {
1693  E->printPretty(OS, nullptr, Policy);
1694  return;
1695  }
1696  OS << "(no argument)";
1697  }
1698 
1699  /// PrintTemplateTemplate - Handles printing of template template arguments,
1700  /// highlighting argument differences.
1701  void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD,
1702  bool FromDefault, bool ToDefault, bool Same) {
1703  assert((FromTD || ToTD) && "Only one template argument may be missing.");
1704 
1705  std::string FromName = FromTD ? FromTD->getName() : "(no argument)";
1706  std::string ToName = ToTD ? ToTD->getName() : "(no argument)";
1707  if (FromTD && ToTD && FromName == ToName) {
1708  FromName = FromTD->getQualifiedNameAsString();
1709  ToName = ToTD->getQualifiedNameAsString();
1710  }
1711 
1712  if (Same) {
1713  OS << "template " << FromTD->getNameAsString();
1714  } else if (!PrintTree) {
1715  OS << (FromDefault ? "(default) template " : "template ");
1716  Bold();
1717  OS << FromName;
1718  Unbold();
1719  } else {
1720  OS << (FromDefault ? "[(default) template " : "[template ");
1721  Bold();
1722  OS << FromName;
1723  Unbold();
1724  OS << " != " << (ToDefault ? "(default) template " : "template ");
1725  Bold();
1726  OS << ToName;
1727  Unbold();
1728  OS << ']';
1729  }
1730  }
1731 
1732  /// PrintAPSInt - Handles printing of integral arguments, highlighting
1733  /// argument differences.
1734  void PrintAPSInt(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt,
1735  bool IsValidFromInt, bool IsValidToInt, QualType FromIntType,
1736  QualType ToIntType, Expr *FromExpr, Expr *ToExpr,
1737  bool FromDefault, bool ToDefault, bool Same) {
1738  assert((IsValidFromInt || IsValidToInt) &&
1739  "Only one integral argument may be missing.");
1740 
1741  if (Same) {
1742  if (FromIntType->isBooleanType()) {
1743  OS << ((FromInt == 0) ? "false" : "true");
1744  } else {
1745  OS << FromInt.toString(10);
1746  }
1747  return;
1748  }
1749 
1750  bool PrintType = IsValidFromInt && IsValidToInt &&
1751  !Context.hasSameType(FromIntType, ToIntType);
1752 
1753  if (!PrintTree) {
1754  OS << (FromDefault ? "(default) " : "");
1755  PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1756  } else {
1757  OS << (FromDefault ? "[(default) " : "[");
1758  PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1759  OS << " != " << (ToDefault ? "(default) " : "");
1760  PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType);
1761  OS << ']';
1762  }
1763  }
1764 
1765  /// PrintAPSInt - If valid, print the APSInt. If the expression is
1766  /// gives more information, print it too.
1767  void PrintAPSInt(const llvm::APSInt &Val, Expr *E, bool Valid,
1768  QualType IntType, bool PrintType) {
1769  Bold();
1770  if (Valid) {
1771  if (HasExtraInfo(E)) {
1772  PrintExpr(E);
1773  Unbold();
1774  OS << " aka ";
1775  Bold();
1776  }
1777  if (PrintType) {
1778  Unbold();
1779  OS << "(";
1780  Bold();
1781  IntType.print(OS, Context.getPrintingPolicy());
1782  Unbold();
1783  OS << ") ";
1784  Bold();
1785  }
1786  if (IntType->isBooleanType()) {
1787  OS << ((Val == 0) ? "false" : "true");
1788  } else {
1789  OS << Val.toString(10);
1790  }
1791  } else if (E) {
1792  PrintExpr(E);
1793  } else {
1794  OS << "(no argument)";
1795  }
1796  Unbold();
1797  }
1798 
1799  /// HasExtraInfo - Returns true if E is not an integer literal, the
1800  /// negation of an integer literal, or a boolean literal.
1801  bool HasExtraInfo(Expr *E) {
1802  if (!E) return false;
1803 
1804  E = E->IgnoreImpCasts();
1805 
1806  if (isa<IntegerLiteral>(E)) return false;
1807 
1808  if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E))
1809  if (UO->getOpcode() == UO_Minus)
1810  if (isa<IntegerLiteral>(UO->getSubExpr()))
1811  return false;
1812 
1813  if (isa<CXXBoolLiteralExpr>(E))
1814  return false;
1815 
1816  return true;
1817  }
1818 
1819  void PrintValueDecl(ValueDecl *VD, bool AddressOf, Expr *E, bool NullPtr) {
1820  if (VD) {
1821  if (AddressOf)
1822  OS << "&";
1823  OS << VD->getName();
1824  return;
1825  }
1826 
1827  if (NullPtr) {
1828  if (E && !isa<CXXNullPtrLiteralExpr>(E)) {
1829  PrintExpr(E);
1830  if (IsBold) {
1831  Unbold();
1832  OS << " aka ";
1833  Bold();
1834  } else {
1835  OS << " aka ";
1836  }
1837  }
1838 
1839  OS << "nullptr";
1840  return;
1841  }
1842 
1843  OS << "(no argument)";
1844  }
1845 
1846  /// PrintDecl - Handles printing of Decl arguments, highlighting
1847  /// argument differences.
1848  void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
1849  bool FromAddressOf, bool ToAddressOf, bool FromNullPtr,
1850  bool ToNullPtr, Expr *FromExpr, Expr *ToExpr,
1851  bool FromDefault, bool ToDefault, bool Same) {
1852  assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
1853  "Only one Decl argument may be NULL");
1854 
1855  if (Same) {
1856  PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1857  } else if (!PrintTree) {
1858  OS << (FromDefault ? "(default) " : "");
1859  Bold();
1860  PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1861  Unbold();
1862  } else {
1863  OS << (FromDefault ? "[(default) " : "[");
1864  Bold();
1865  PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1866  Unbold();
1867  OS << " != " << (ToDefault ? "(default) " : "");
1868  Bold();
1869  PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr);
1870  Unbold();
1871  OS << ']';
1872  }
1873  }
1874 
1875  /// PrintValueDeclAndInteger - Uses the print functions for ValueDecl and
1876  /// APSInt to print a mixed difference.
1877  void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf,
1878  bool IsNullPtr, Expr *VDExpr, bool DefaultDecl,
1879  const llvm::APSInt &Val, QualType IntType,
1880  Expr *IntExpr, bool DefaultInt) {
1881  if (!PrintTree) {
1882  OS << (DefaultDecl ? "(default) " : "");
1883  Bold();
1884  PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
1885  Unbold();
1886  } else {
1887  OS << (DefaultDecl ? "[(default) " : "[");
1888  Bold();
1889  PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
1890  Unbold();
1891  OS << " != " << (DefaultInt ? "(default) " : "");
1892  PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
1893  OS << ']';
1894  }
1895  }
1896 
1897  /// PrintIntegerAndValueDecl - Uses the print functions for APSInt and
1898  /// ValueDecl to print a mixed difference.
1899  void PrintIntegerAndValueDecl(const llvm::APSInt &Val, QualType IntType,
1900  Expr *IntExpr, bool DefaultInt, ValueDecl *VD,
1901  bool NeedAddressOf, bool IsNullPtr,
1902  Expr *VDExpr, bool DefaultDecl) {
1903  if (!PrintTree) {
1904  OS << (DefaultInt ? "(default) " : "");
1905  PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
1906  } else {
1907  OS << (DefaultInt ? "[(default) " : "[");
1908  PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
1909  OS << " != " << (DefaultDecl ? "(default) " : "");
1910  Bold();
1911  PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
1912  Unbold();
1913  OS << ']';
1914  }
1915  }
1916 
1917  // Prints the appropriate placeholder for elided template arguments.
1918  void PrintElideArgs(unsigned NumElideArgs, unsigned Indent) {
1919  if (PrintTree) {
1920  OS << '\n';
1921  for (unsigned i = 0; i < Indent; ++i)
1922  OS << " ";
1923  }
1924  if (NumElideArgs == 0) return;
1925  if (NumElideArgs == 1)
1926  OS << "[...]";
1927  else
1928  OS << "[" << NumElideArgs << " * ...]";
1929  }
1930 
1931  // Prints and highlights differences in Qualifiers.
1932  void PrintQualifiers(Qualifiers FromQual, Qualifiers ToQual) {
1933  // Both types have no qualifiers
1934  if (FromQual.empty() && ToQual.empty())
1935  return;
1936 
1937  // Both types have same qualifiers
1938  if (FromQual == ToQual) {
1939  PrintQualifier(FromQual, /*ApplyBold*/false);
1940  return;
1941  }
1942 
1943  // Find common qualifiers and strip them from FromQual and ToQual.
1944  Qualifiers CommonQual = Qualifiers::removeCommonQualifiers(FromQual,
1945  ToQual);
1946 
1947  // The qualifiers are printed before the template name.
1948  // Inline printing:
1949  // The common qualifiers are printed. Then, qualifiers only in this type
1950  // are printed and highlighted. Finally, qualifiers only in the other
1951  // type are printed and highlighted inside parentheses after "missing".
1952  // Tree printing:
1953  // Qualifiers are printed next to each other, inside brackets, and
1954  // separated by "!=". The printing order is:
1955  // common qualifiers, highlighted from qualifiers, "!=",
1956  // common qualifiers, highlighted to qualifiers
1957  if (PrintTree) {
1958  OS << "[";
1959  if (CommonQual.empty() && FromQual.empty()) {
1960  Bold();
1961  OS << "(no qualifiers) ";
1962  Unbold();
1963  } else {
1964  PrintQualifier(CommonQual, /*ApplyBold*/false);
1965  PrintQualifier(FromQual, /*ApplyBold*/true);
1966  }
1967  OS << "!= ";
1968  if (CommonQual.empty() && ToQual.empty()) {
1969  Bold();
1970  OS << "(no qualifiers)";
1971  Unbold();
1972  } else {
1973  PrintQualifier(CommonQual, /*ApplyBold*/false,
1974  /*appendSpaceIfNonEmpty*/!ToQual.empty());
1975  PrintQualifier(ToQual, /*ApplyBold*/true,
1976  /*appendSpaceIfNonEmpty*/false);
1977  }
1978  OS << "] ";
1979  } else {
1980  PrintQualifier(CommonQual, /*ApplyBold*/false);
1981  PrintQualifier(FromQual, /*ApplyBold*/true);
1982  }
1983  }
1984 
1985  void PrintQualifier(Qualifiers Q, bool ApplyBold,
1986  bool AppendSpaceIfNonEmpty = true) {
1987  if (Q.empty()) return;
1988  if (ApplyBold) Bold();
1989  Q.print(OS, Policy, AppendSpaceIfNonEmpty);
1990  if (ApplyBold) Unbold();
1991  }
1992 
1993 public:
1994 
1995  TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType,
1996  QualType ToType, bool PrintTree, bool PrintFromType,
1997  bool ElideType, bool ShowColor)
1998  : Context(Context),
1999  Policy(Context.getLangOpts()),
2000  ElideType(ElideType),
2001  PrintTree(PrintTree),
2002  ShowColor(ShowColor),
2003  // When printing a single type, the FromType is the one printed.
2004  FromTemplateType(PrintFromType ? FromType : ToType),
2005  ToTemplateType(PrintFromType ? ToType : FromType),
2006  OS(OS),
2007  IsBold(false) {
2008  }
2009 
2010  /// DiffTemplate - Start the template type diffing.
2011  void DiffTemplate() {
2012  Qualifiers FromQual = FromTemplateType.getQualifiers(),
2013  ToQual = ToTemplateType.getQualifiers();
2014 
2015  const TemplateSpecializationType *FromOrigTST =
2016  GetTemplateSpecializationType(Context, FromTemplateType);
2017  const TemplateSpecializationType *ToOrigTST =
2018  GetTemplateSpecializationType(Context, ToTemplateType);
2019 
2020  // Only checking templates.
2021  if (!FromOrigTST || !ToOrigTST)
2022  return;
2023 
2024  // Different base templates.
2025  if (!hasSameTemplate(FromOrigTST, ToOrigTST)) {
2026  return;
2027  }
2028 
2029  FromQual -= QualType(FromOrigTST, 0).getQualifiers();
2030  ToQual -= QualType(ToOrigTST, 0).getQualifiers();
2031 
2032  // Same base template, but different arguments.
2033  Tree.SetTemplateDiff(FromOrigTST->getTemplateName().getAsTemplateDecl(),
2034  ToOrigTST->getTemplateName().getAsTemplateDecl(),
2035  FromQual, ToQual, false /*FromDefault*/,
2036  false /*ToDefault*/);
2037 
2038  DiffTemplate(FromOrigTST, ToOrigTST);
2039  }
2040 
2041  /// Emit - When the two types given are templated types with the same
2042  /// base template, a string representation of the type difference will be
2043  /// emitted to the stream and return true. Otherwise, return false.
2044  bool Emit() {
2045  Tree.StartTraverse();
2046  if (Tree.Empty())
2047  return false;
2048 
2049  TreeToString();
2050  assert(!IsBold && "Bold is applied to end of string.");
2051  return true;
2052  }
2053 }; // end class TemplateDiff
2054 } // end anonymous namespace
2055 
2056 /// FormatTemplateTypeDiff - A helper static function to start the template
2057 /// diff and return the properly formatted string. Returns true if the diff
2058 /// is successful.
2059 static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType,
2060  QualType ToType, bool PrintTree,
2061  bool PrintFromType, bool ElideType,
2062  bool ShowColors, raw_ostream &OS) {
2063  if (PrintTree)
2064  PrintFromType = true;
2065  TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType,
2066  ElideType, ShowColors);
2067  TD.DiffTemplate();
2068  return TD.Emit();
2069 }
Defines the clang::ASTContext interface.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S...
Definition: Type.h:5205
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:1858
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2585
A (possibly-)qualified type.
Definition: Type.h:643
QualType getBuiltinVaListType() const
Retrieve the type of the __builtin_va_list type.
Definition: ASTContext.h:1913
bool isClosure() const
Definition: DeclBase.h:1812
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:3393
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.
Definition: Type.h:4823
The base class of the type hierarchy.
Definition: Type.h:1436
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:132
This file provides some common utility functions for processing Lambda related AST Constructs...
static Qualifiers fromOpaqueValue(unsigned opaque)
Definition: Type.h:243
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6858
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:1880
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:67
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:37
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:4677
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
Definition: Type.h:882
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:137
QualType desugar() const
Definition: Type.h:5004
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:5614
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:160
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:4980
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:6167
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:2786
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:4965
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation...
Definition: Type.h:4216
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:670
Represents a declaration of a type.
Definition: Decl.h:2943
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)
Returns the common set of qualifiers while removing them from the given sets.
Definition: Type.h:188
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:1904
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:2950
NodeId Parent
Definition: ASTDiff.cpp:191
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3725
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:406
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:644
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:4555
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:278
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents a C++ template name within the type system.
Definition: TemplateName.h:187
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:3965
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:2021
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:1387
Represents a GCC generic vector type.
Definition: Type.h:3206
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:2768
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:1403
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:708
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType)
const NamedDecl * FromDecl
RecordDecl * getDecl() const
Definition: Type.h:4454
QualType getBuiltinMSVaListType() const
Retrieve the type of the __builtin_ms_va_list type.
Definition: ASTContext.h:1927
__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:6187
param_type_range param_types() const
Definition: Type.h:4069
ExtProtoInfo getExtProtoInfo() const
Definition: Type.h:3938
Sugar for parentheses used when specifying types.
Definition: Type.h:2555
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:291
QualType getElementType() const
Definition: Type.h:3241
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C &#39;SEL&#39; type.
Definition: ASTContext.h:1868
const char ToggleHighlight
Special character that the diagnostic printer will use to toggle the bold attribute.
Definition: Diagnostic.h:1585
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:1851
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:300
bool isVectorType() const
Definition: Type.h:6483
static QualType getFromOpaquePtr(const void *Ptr)
Definition: Type.h:690
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:2633
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:1667
A qualifier set is used to build a set of qualifiers.
Definition: Type.h:6115
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:387
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:979
bool isBooleanType() const
Definition: Type.h:6767
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:6122
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:3497
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:5870
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4444
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:4988
bool empty() const
Definition: Type.h:415
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:2305
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:4499
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:4969
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:6175
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:275
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1550
unsigned getNumElements() const
Definition: Type.h:3242
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:4917
bool isPointerType() const
Definition: Type.h:6391
QualType getType() const
Definition: Decl.h:655
This represents a decl that may have a name.
Definition: Decl.h:248
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool isTranslationUnit() const
Definition: DeclBase.h:1854
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:723
Attr - This represents one attribute.
Definition: Attr.h:45