22 #include "llvm/ADT/SmallString.h"
23 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
41 if (
const ParenType *PT = dyn_cast<ParenType>(Ty)) {
47 dyn_cast<SubstTemplateTypeParmType>(Ty)) {
57 if (
const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) {
62 if (
const AutoType *AT = dyn_cast<AutoType>(Ty)) {
71 = dyn_cast<TemplateSpecializationType>(Ty))
72 if (!TST->isTypeAlias())
90 #define ABSTRACT_TYPE(Class, Base)
91 #define TYPE(Class, Base) \
93 const Class##Type *CTy = cast<Class##Type>(Ty); \
94 if (CTy->isSugared()) { \
96 Underlying = CTy->desugar(); \
100 #include "clang/AST/TypeNodes.def"
109 if (isa<VectorType>(Underlying))
114 if (
const TypedefType *QTT = dyn_cast<TypedefType>(QT))
115 if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl())
138 if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {
141 llvm::makeArrayRef(Ty->qual_begin(),
142 Ty->getNumProtocols()),
143 Ty->isKindOfTypeAsWritten());
147 return QC.
apply(Context, QT);
179 bool ForceAKA =
false;
184 for (
unsigned I = 0, E = QualTypeVals.size(); I != E; ++I) {
192 if (CompareCanTy == CanTy)
195 bool ShouldAKA =
false;
197 std::string CompareDesugarStr =
199 if (CompareS != S && CompareDesugarStr != S)
202 std::string CompareCanS =
205 if (CompareCanS == CanS)
214 bool Repeated =
false;
215 for (
unsigned i = 0, e = PrevArgs.size(); i != e; ++i) {
218 void *Ptr = (
void*)PrevArgs[i].second;
230 bool ShouldAKA =
false;
232 if (ShouldAKA || ForceAKA) {
233 if (DesugaredTy == Ty) {
238 S =
"'" + S +
"' (aka '" + akaStr +
"')";
248 std::string DecoratedString;
249 llvm::raw_string_ostream OS(DecoratedString);
250 const char *Values = VTy->
getNumElements() > 1 ?
"values" :
"value";
251 OS <<
"'" << S <<
"' (vector of " << VTy->
getNumElements() <<
" '"
253 <<
"' " << Values <<
")";
264 bool PrintFromType,
bool ElideType,
265 bool ShowColors, raw_ostream &OS);
278 size_t OldEnd = Output.size();
279 llvm::raw_svector_ostream OS(Output);
280 bool NeedQuotes =
true;
283 default: llvm_unreachable(
"unknown ArgumentKind");
307 Modifier = StringRef();
308 Argument = StringRef();
312 assert(Modifier.empty() && Argument.empty() &&
313 "Invalid modifier for QualType argument");
321 if (Modifier ==
"objcclass" && Argument.empty())
323 else if (Modifier ==
"objcinstance" && Argument.empty())
326 assert(Modifier.empty() && Argument.empty() &&
327 "Invalid modifier for DeclarationName argument");
334 if (Modifier ==
"q" && Argument.empty())
337 assert(Modifier.empty() && Argument.empty() &&
338 "Invalid modifier for NamedDecl* argument");
353 assert(DC &&
"Should never have a null declaration context");
359 OS <<
"the global namespace";
361 OS <<
"the global scope";
363 OS <<
"block literal";
365 OS <<
"lambda expression";
369 PrevArgs, QualTypeVals);
371 assert(isa<NamedDecl>(DC) &&
"Expected a NamedDecl");
373 if (isa<NamespaceDecl>(ND))
375 else if (isa<ObjCMethodDecl>(ND))
377 else if (isa<FunctionDecl>(ND))
387 const Attr *At =
reinterpret_cast<Attr *
>(Val);
388 assert(At &&
"Received null Attr object!");
399 Output.insert(Output.begin()+OldEnd,
'\'');
400 Output.push_back(
'\'');
480 Expr *FromExpr, *ToExpr;
483 bool FromNullPtr, ToNullPtr;
493 llvm::APSInt FromInt, ToInt;
496 bool IsValidFromInt, IsValidToInt;
503 bool FromAddressOf, ToAddressOf;
506 bool FromDefault, ToDefault;
511 DiffNode(
unsigned ParentNode = 0)
512 :
Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode),
513 FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr),
515 FromTD(nullptr), ToTD(nullptr), IsValidFromInt(
false),
516 IsValidToInt(
false), FromValueDecl(nullptr), ToValueDecl(nullptr),
525 unsigned CurrentNode;
529 unsigned NextFreeNode;
536 CurrentNode(0), NextFreeNode(1) {
537 FlatTree.push_back(DiffNode());
543 FlatTree[CurrentNode].FromTD = FromTD;
544 FlatTree[CurrentNode].ToTD = ToTD;
549 FlatTree[CurrentNode].FromType = FromType;
550 FlatTree[CurrentNode].ToType = ToType;
554 void SetNode(
Expr *FromExpr,
Expr *ToExpr) {
555 FlatTree[CurrentNode].FromExpr = FromExpr;
556 FlatTree[CurrentNode].ToExpr = ToExpr;
560 void SetNode(llvm::APSInt FromInt, llvm::APSInt ToInt,
561 bool IsValidFromInt,
bool IsValidToInt) {
562 FlatTree[CurrentNode].FromInt = FromInt;
563 FlatTree[CurrentNode].ToInt = ToInt;
564 FlatTree[CurrentNode].IsValidFromInt = IsValidFromInt;
565 FlatTree[CurrentNode].IsValidToInt = IsValidToInt;
570 FlatTree[CurrentNode].FromQual = FromQual;
571 FlatTree[CurrentNode].ToQual = ToQual;
576 bool FromAddressOf,
bool ToAddressOf) {
577 FlatTree[CurrentNode].FromValueDecl = FromValueDecl;
578 FlatTree[CurrentNode].ToValueDecl = ToValueDecl;
579 FlatTree[CurrentNode].FromAddressOf = FromAddressOf;
580 FlatTree[CurrentNode].ToAddressOf = ToAddressOf;
584 void SetSame(
bool Same) {
585 FlatTree[CurrentNode].Same = Same;
589 void SetNullPtr(
bool FromNullPtr,
bool ToNullPtr) {
590 FlatTree[CurrentNode].FromNullPtr = FromNullPtr;
591 FlatTree[CurrentNode].ToNullPtr = ToNullPtr;
595 void SetDefault(
bool FromDefault,
bool ToDefault) {
596 FlatTree[CurrentNode].FromDefault = FromDefault;
597 FlatTree[CurrentNode].ToDefault = ToDefault;
601 void SetKind(DiffKind
Kind) {
607 CurrentNode = FlatTree[CurrentNode].ParentNode;
613 FlatTree.push_back(DiffNode(CurrentNode));
614 DiffNode &
Node = FlatTree[CurrentNode];
615 if (Node.ChildNode == 0) {
617 Node.ChildNode = NextFreeNode;
622 for (i = Node.ChildNode; FlatTree[i].NextNode != 0;
623 i = FlatTree[i].NextNode) {
625 FlatTree[i].NextNode = NextFreeNode;
627 CurrentNode = NextFreeNode;
633 void StartTraverse() {
635 CurrentNode = NextFreeNode;
641 ReadNode = FlatTree[ReadNode].ParentNode;
646 FromType = FlatTree[ReadNode].FromType;
647 ToType = FlatTree[ReadNode].ToType;
651 void GetNode(
Expr *&FromExpr,
Expr *&ToExpr) {
652 FromExpr = FlatTree[ReadNode].FromExpr;
653 ToExpr = FlatTree[ReadNode].ToExpr;
658 FromTD = FlatTree[ReadNode].FromTD;
659 ToTD = FlatTree[ReadNode].ToTD;
663 void GetNode(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
664 bool &IsValidFromInt,
bool &IsValidToInt) {
665 FromInt = FlatTree[ReadNode].FromInt;
666 ToInt = FlatTree[ReadNode].ToInt;
667 IsValidFromInt = FlatTree[ReadNode].IsValidFromInt;
668 IsValidToInt = FlatTree[ReadNode].IsValidToInt;
673 FromQual = FlatTree[ReadNode].FromQual;
674 ToQual = FlatTree[ReadNode].ToQual;
679 bool &FromAddressOf,
bool &ToAddressOf) {
680 FromValueDecl = FlatTree[ReadNode].FromValueDecl;
681 ToValueDecl = FlatTree[ReadNode].ToValueDecl;
682 FromAddressOf = FlatTree[ReadNode].FromAddressOf;
683 ToAddressOf = FlatTree[ReadNode].ToAddressOf;
688 return FlatTree[ReadNode].Same;
693 return FlatTree[ReadNode].ChildNode != 0;
698 ReadNode = FlatTree[ReadNode].ChildNode;
703 bool AdvanceSibling() {
704 if (FlatTree[ReadNode].NextNode == 0)
707 ReadNode = FlatTree[ReadNode].NextNode;
712 bool HasNextSibling() {
713 return FlatTree[ReadNode].NextNode != 0;
718 return FlatTree[ReadNode].FromNullPtr;
723 return FlatTree[ReadNode].ToNullPtr;
728 return FlatTree[ReadNode].FromDefault;
733 return FlatTree[ReadNode].ToDefault;
738 return GetKind() == Invalid;
743 return FlatTree[ReadNode].
Kind;
778 DesugarTST(GetTemplateSpecializationType(Context, TST->desugar())),
779 Index(0), CurrentTA(nullptr), EndTA(nullptr) {
791 if (CurrentTA != EndTA)
return;
804 TSTiterator &operator++() {
813 if (CurrentTA != EndTA) {
815 if (CurrentTA != EndTA)
833 if (CurrentTA != EndTA)
break;
840 assert(!isEnd() &&
"Index exceeds number of arguments.");
841 if (CurrentTA == EndTA)
842 return TST->
getArg(Index);
848 pointer operator->()
const {
853 reference getDesugar()
const {
854 return DesugarTST->getArg(Index);
888 void DiffTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter,
891 QualType FromType = GetType(FromIter, FromDefaultTypeDecl);
892 QualType ToType = GetType(ToIter, ToDefaultTypeDecl);
894 Tree.SetNode(FromType, ToType);
895 Tree.SetDefault(FromIter.isEnd() && !FromType.
isNull(),
896 ToIter.isEnd() && !ToType.
isNull());
897 Tree.SetKind(DiffTree::Type);
907 GetTemplateSpecializationType(Context, FromType);
912 GetTemplateSpecializationType(Context, ToType);
916 if (!hasSameTemplate(FromArgTST, ToArgTST))
925 Tree.SetNode(FromQual, ToQual);
926 Tree.SetKind(DiffTree::Template);
927 DiffTemplate(FromArgTST, ToArgTST);
932 void DiffTemplateTemplates(
const TSTiterator &FromIter,
933 const TSTiterator &ToIter,
936 TemplateDecl *FromDecl = GetTemplateDecl(FromIter, FromDefaultTemplateDecl);
937 TemplateDecl *ToDecl = GetTemplateDecl(ToIter, ToDefaultTemplateDecl);
938 Tree.SetNode(FromDecl, ToDecl);
939 Tree.SetSame(FromDecl && ToDecl &&
941 Tree.SetDefault(FromIter.isEnd() && FromDecl, ToIter.isEnd() && ToDecl);
942 Tree.SetKind(DiffTree::TemplateTemplate);
946 static void InitializeNonTypeDiffVariables(
958 Value = Iter->getAsIntegral();
959 else if (HasValueDecl)
960 VD = Iter->getAsDecl();
962 E = GetExpr(Iter, Default);
965 IsNullPtr = CheckForNullPtr(Context, E);
993 void DiffNonTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter,
996 Expr *FromExpr =
nullptr, *ToExpr =
nullptr;
997 llvm::APSInt FromInt, ToInt;
998 ValueDecl *FromValueDecl =
nullptr, *ToValueDecl =
nullptr;
999 bool HasFromInt =
false, HasToInt =
false, HasFromValueDecl =
false,
1000 HasToValueDecl =
false, FromNullPtr =
false, ToNullPtr =
false;
1001 InitializeNonTypeDiffVariables(Context, FromIter, FromDefaultNonTypeDecl,
1002 HasFromInt, HasFromValueDecl, FromNullPtr,
1003 FromExpr, FromInt, FromValueDecl);
1004 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl,
1005 HasToInt, HasToValueDecl, ToNullPtr,
1006 ToExpr, ToInt, ToValueDecl);
1008 assert(((!HasFromInt && !HasToInt) ||
1009 (!HasFromValueDecl && !HasToValueDecl)) &&
1010 "Template argument cannot be both integer and declaration");
1012 if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {
1013 Tree.SetNode(FromExpr, ToExpr);
1014 Tree.SetDefault(FromIter.isEnd() && FromExpr, ToIter.isEnd() && ToExpr);
1017 HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt,
1018 FromDefaultNonTypeDecl->
getType());
1020 HasToInt = GetInt(Context, ToIter, ToExpr, ToInt,
1021 ToDefaultNonTypeDecl->
getType());
1023 if (HasFromInt && HasToInt) {
1024 Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
1025 Tree.SetSame(FromInt == ToInt);
1026 Tree.SetKind(DiffTree::Integer);
1027 }
else if (HasFromInt || HasToInt) {
1028 Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
1029 Tree.SetSame(
false);
1030 Tree.SetKind(DiffTree::Integer);
1032 Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr) ||
1033 (FromNullPtr && ToNullPtr));
1034 Tree.SetNullPtr(FromNullPtr, ToNullPtr);
1035 Tree.SetKind(DiffTree::Expression);
1040 if (HasFromInt || HasToInt) {
1041 if (!HasFromInt && FromExpr)
1042 HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt,
1043 FromDefaultNonTypeDecl->
getType());
1044 if (!HasToInt && ToExpr)
1045 HasToInt = GetInt(Context, ToIter, ToExpr, ToInt,
1046 ToDefaultNonTypeDecl->
getType());
1047 Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
1048 if (HasFromInt && HasToInt) {
1049 Tree.SetSame(FromInt == ToInt);
1051 Tree.SetSame(
false);
1053 Tree.SetDefault(FromIter.isEnd() && HasFromInt,
1054 ToIter.isEnd() && HasToInt);
1055 Tree.SetKind(DiffTree::Integer);
1059 if (!HasFromValueDecl && FromExpr)
1060 FromValueDecl = GetValueDecl(FromIter, FromExpr);
1061 if (!HasToValueDecl && ToExpr)
1062 ToValueDecl = GetValueDecl(ToIter, ToExpr);
1064 bool FromAddressOf =
1065 NeedsAddressOf(FromValueDecl, FromExpr, FromDefaultNonTypeDecl);
1067 NeedsAddressOf(ToValueDecl, ToExpr, ToDefaultNonTypeDecl);
1069 Tree.SetNullPtr(FromNullPtr, ToNullPtr);
1070 Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
1071 Tree.SetSame(FromValueDecl && ToValueDecl &&
1074 Tree.SetDefault(FromIter.isEnd() && FromValueDecl,
1075 ToIter.isEnd() && ToValueDecl);
1076 Tree.SetKind(DiffTree::Declaration);
1088 unsigned TotalArgs = 0;
1089 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST);
1090 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) {
1096 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->
size() - 1);
1097 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->
size() - 1);
1105 if (FromDefaultTypeDecl && ToDefaultTypeDecl)
1106 DiffTypes(FromIter, ToIter, FromDefaultTypeDecl, ToDefaultTypeDecl);
1112 if (FromDefaultTemplateDecl && ToDefaultTemplateDecl)
1113 DiffTemplateTemplates(FromIter, ToIter, FromDefaultTemplateDecl,
1114 ToDefaultTemplateDecl);
1120 if (FromDefaultNonTypeDecl && ToDefaultNonTypeDecl)
1121 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
1122 ToDefaultNonTypeDecl);
1131 static void makeTemplateList(
1135 TemplateList.push_back(TST);
1157 if (hasSameBaseTemplate(FromTST, ToTST))
1164 makeTemplateList(FromTemplateList, FromTST);
1165 makeTemplateList(ToTemplateList, ToTST);
1168 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(),
1169 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend();
1172 if (!hasSameBaseTemplate(*FromIter, *ToIter))
1178 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) {
1179 if (!hasSameBaseTemplate(*FromIter, *ToIter))
1183 FromTST = FromIter[-1];
1191 static QualType GetType(
const TSTiterator &Iter,
1196 return Iter->getAsType();
1202 return Iter.getDesugar().getAsType();
1209 static Expr *GetExpr(
const TSTiterator &Iter,
1211 Expr *ArgExpr =
nullptr;
1215 ArgExpr = Iter->getAsExpr();
1216 else if (!isVariadic)
1221 dyn_cast<SubstNonTypeTemplateParmExpr>(ArgExpr))
1222 ArgExpr = SNTTPE->getReplacement();
1231 static bool GetInt(
ASTContext &Context,
const TSTiterator &Iter,
1232 Expr *ArgExpr, llvm::APSInt &Int,
QualType IntegerType) {
1237 switch (Iter.getDesugar().getKind()) {
1239 Int = Iter.getDesugar().getAsIntegral();
1242 ArgExpr = Iter.getDesugar().getAsExpr();
1244 Int = Int.extOrTrunc(Context.
getTypeSize(IntegerType));
1247 llvm_unreachable(
"Unexpected template argument kind");
1251 Int = Int.extOrTrunc(Context.
getTypeSize(IntegerType));
1260 static ValueDecl *GetValueDecl(
const TSTiterator &Iter,
Expr *ArgExpr) {
1264 switch (Iter.getDesugar().getKind()) {
1266 return Iter.getDesugar().getAsDecl();
1268 ArgExpr = Iter.getDesugar().getAsExpr();
1269 return cast<DeclRefExpr>(ArgExpr)->getDecl();
1271 llvm_unreachable(
"Unexpected template argument kind");
1287 assert(E &&
"Expected expression");
1307 static TemplateDecl *GetTemplateDecl(
const TSTiterator &Iter,
1317 return Iter->getAsTemplate().getAsTemplateDecl();
1326 if (FromExpr == ToExpr)
1329 if (!FromExpr || !ToExpr)
1333 *ToDRE = dyn_cast<DeclRefExpr>(ToExpr->
IgnoreParens());
1335 if (FromDRE || ToDRE) {
1336 if (!FromDRE || !ToDRE)
1338 return FromDRE->
getDecl() == ToDRE->getDecl();
1344 llvm::FoldingSetNodeID FromID, ToID;
1345 FromExpr->Profile(FromID, Context,
true);
1346 ToExpr->Profile(ToID, Context,
true);
1347 return FromID == ToID;
1361 if (FromBase.isNull() && ToBase.isNull())
1363 if (FromBase.isNull() || ToBase.isNull())
1365 return FromBase.get<
const ValueDecl*>() ==
1371 llvm_unreachable(
"Unknown template argument expression.");
1380 void TreeToString(
int Indent = 1) {
1389 switch (Tree.GetKind()) {
1390 case DiffTree::Invalid:
1391 llvm_unreachable(
"Template diffing failed with bad DiffNode");
1392 case DiffTree::Type: {
1394 Tree.GetNode(FromType, ToType);
1395 PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(),
1399 case DiffTree::Expression: {
1400 Expr *FromExpr, *ToExpr;
1401 Tree.GetNode(FromExpr, ToExpr);
1402 PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(),
1403 Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
1406 case DiffTree::TemplateTemplate: {
1408 Tree.GetNode(FromTD, ToTD);
1409 PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(),
1410 Tree.ToDefault(), Tree.NodeIsSame());
1413 case DiffTree::Integer: {
1414 llvm::APSInt FromInt, ToInt;
1415 Expr *FromExpr, *ToExpr;
1416 bool IsValidFromInt, IsValidToInt;
1417 Tree.GetNode(FromExpr, ToExpr);
1418 Tree.GetNode(FromInt, ToInt, IsValidFromInt, IsValidToInt);
1419 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt,
1420 FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
1424 case DiffTree::Declaration: {
1426 bool FromAddressOf, ToAddressOf;
1427 Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
1428 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
1429 Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(),
1430 Tree.ToDefault(), Tree.NodeIsSame());
1433 case DiffTree::Template: {
1436 Tree.GetNode(FromTD, ToTD);
1438 if (!Tree.HasChildren()) {
1446 Tree.GetNode(FromQual, ToQual);
1447 PrintQualifiers(FromQual, ToQual);
1451 unsigned NumElideArgs = 0;
1454 if (Tree.NodeIsSame()) {
1458 if (NumElideArgs > 0) {
1459 PrintElideArgs(NumElideArgs,
Indent);
1465 if (Tree.HasNextSibling())
1467 }
while (Tree.AdvanceSibling());
1468 if (NumElideArgs > 0)
1469 PrintElideArgs(NumElideArgs,
Indent);
1484 assert(!IsBold &&
"Attempting to bold text that is already bold.");
1492 assert(IsBold &&
"Attempting to remove bold from unbold text.");
1504 bool FromDefault,
bool ToDefault,
bool Same) {
1506 "Only one template argument may be missing.");
1518 PrintQualifiers(FromQual, ToQual);
1523 std::string FromTypeStr = FromType.
isNull() ?
"(no argument)"
1525 std::string ToTypeStr = ToType.
isNull() ?
"(no argument)"
1529 if (FromTypeStr == ToTypeStr) {
1530 std::string FromCanTypeStr =
1533 if (FromCanTypeStr != ToCanTypeStr) {
1534 FromTypeStr = FromCanTypeStr;
1535 ToTypeStr = ToCanTypeStr;
1539 if (PrintTree) OS <<
'[';
1540 OS << (FromDefault ?
"(default) " :
"");
1545 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1556 void PrintExpr(
const Expr *FromExpr,
const Expr *ToExpr,
bool FromNullPtr,
1557 bool ToNullPtr,
bool FromDefault,
bool ToDefault,
bool Same) {
1558 assert((FromExpr || ToExpr) &&
1559 "Only one template argument may be missing.");
1561 PrintExpr(FromExpr, FromNullPtr);
1562 }
else if (!PrintTree) {
1563 OS << (FromDefault ?
"(default) " :
"");
1565 PrintExpr(FromExpr, FromNullPtr);
1568 OS << (FromDefault ?
"[(default) " :
"[");
1570 PrintExpr(FromExpr, FromNullPtr);
1572 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1574 PrintExpr(ToExpr, ToNullPtr);
1581 void PrintExpr(
const Expr *E,
bool NullPtr =
false) {
1583 E->printPretty(OS,
nullptr, Policy);
1590 OS <<
"(no argument)";
1596 bool FromDefault,
bool ToDefault,
bool Same) {
1597 assert((FromTD || ToTD) &&
"Only one template argument may be missing.");
1599 std::string FromName = FromTD ? FromTD->
getName() :
"(no argument)";
1600 std::string ToName = ToTD ? ToTD->
getName() :
"(no argument)";
1601 if (FromTD && ToTD && FromName == ToName) {
1608 }
else if (!PrintTree) {
1609 OS << (FromDefault ?
"(default) template " :
"template ");
1614 OS << (FromDefault ?
"[(default) template " :
"[template ");
1618 OS <<
" != " << (ToDefault ?
"(default) template " :
"template ");
1628 void PrintAPSInt(llvm::APSInt FromInt, llvm::APSInt ToInt,
1629 bool IsValidFromInt,
bool IsValidToInt,
Expr *FromExpr,
1630 Expr *ToExpr,
bool FromDefault,
bool ToDefault,
bool Same) {
1631 assert((IsValidFromInt || IsValidToInt) &&
1632 "Only one integral argument may be missing.");
1635 OS << FromInt.toString(10);
1636 }
else if (!PrintTree) {
1637 OS << (FromDefault ?
"(default) " :
"");
1638 PrintAPSInt(FromInt, FromExpr, IsValidFromInt);
1640 OS << (FromDefault ?
"[(default) " :
"[");
1641 PrintAPSInt(FromInt, FromExpr, IsValidFromInt);
1642 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1643 PrintAPSInt(ToInt, ToExpr, IsValidToInt);
1650 void PrintAPSInt(llvm::APSInt Val,
Expr *E,
bool Valid) {
1653 if (HasExtraInfo(E)) {
1659 OS << Val.toString(10);
1663 OS <<
"(no argument)";
1670 bool HasExtraInfo(
Expr *E) {
1671 if (!E)
return false;
1675 if (isa<IntegerLiteral>(E))
return false;
1698 OS <<
"(no argument)";
1704 bool FromAddressOf,
bool ToAddressOf,
bool FromNullPtr,
1705 bool ToNullPtr,
bool FromDefault,
bool ToDefault,
1707 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
1708 "Only one Decl argument may be NULL");
1711 PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
1712 }
else if (!PrintTree) {
1713 OS << (FromDefault ?
"(default) " :
"");
1715 PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
1718 OS << (FromDefault ?
"[(default) " :
"[");
1720 PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
1722 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1724 PrintValueDecl(ToValueDecl, ToAddressOf, ToNullPtr);
1732 void PrintElideArgs(
unsigned NumElideArgs,
unsigned Indent) {
1735 for (
unsigned i = 0; i <
Indent; ++i)
1738 if (NumElideArgs == 0)
return;
1739 if (NumElideArgs == 1)
1742 OS <<
"[" << NumElideArgs <<
" * ...]";
1752 if (FromQual == ToQual) {
1753 PrintQualifier(FromQual,
false);
1773 if (CommonQual.
empty() && FromQual.
empty()) {
1775 OS <<
"(no qualifiers) ";
1778 PrintQualifier(CommonQual,
false);
1779 PrintQualifier(FromQual,
true);
1784 OS <<
"(no qualifiers)";
1787 PrintQualifier(CommonQual,
false,
1789 PrintQualifier(ToQual,
true,
1794 PrintQualifier(CommonQual,
false);
1795 PrintQualifier(FromQual,
true);
1799 void PrintQualifier(
Qualifiers Q,
bool ApplyBold,
1800 bool AppendSpaceIfNonEmpty =
true) {
1801 if (Q.
empty())
return;
1802 if (ApplyBold) Bold();
1803 Q.
print(OS, Policy, AppendSpaceIfNonEmpty);
1804 if (ApplyBold) Unbold();
1810 QualType ToType,
bool PrintTree,
bool PrintFromType,
1811 bool ElideType,
bool ShowColor)
1813 Policy(Context.getLangOpts()),
1814 ElideType(ElideType),
1815 PrintTree(PrintTree),
1816 ShowColor(ShowColor),
1818 FromType(PrintFromType ? FromType : ToType),
1819 ToType(PrintFromType ? ToType : FromType),
1825 void DiffTemplate() {
1830 GetTemplateSpecializationType(Context, FromType);
1832 GetTemplateSpecializationType(Context, ToType);
1835 if (!FromOrigTST || !ToOrigTST)
1839 if (!hasSameTemplate(FromOrigTST, ToOrigTST)) {
1845 Tree.SetNode(FromType, ToType);
1846 Tree.SetNode(FromQual, ToQual);
1847 Tree.SetKind(DiffTree::Template);
1853 DiffTemplate(FromOrigTST, ToOrigTST);
1860 Tree.StartTraverse();
1865 assert(!IsBold &&
"Bold is applied to end of string.");
1876 bool PrintFromType,
bool ElideType,
1877 bool ShowColors, raw_ostream &OS) {
1879 PrintFromType =
true;
1880 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType,
1881 ElideType, ShowColors);
unsigned getNumElements() const
Defines the clang::ASTContext interface.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S...
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
StringRef getName() const
bool isEvaluatable(const ASTContext &Ctx) const
bool isParameterPack() const
Returns whether this is a parameter pack.
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type...
Defines the C++ template declaration subclasses.
Represents a C++11 auto or C++1y decltype(auto) type.
std::string getAsString() const
pack_iterator pack_begin() const
Iterator referencing the first argument of a template argument pack.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
const Expr * getInit() const
NamedDecl * getParam(unsigned Idx)
This file provides some common utility functions for processing Lambda related AST Constructs...
Represents an empty template argument, e.g., one that has not been deduced.
QualType getObjCClassType() const
Represents the Objective-C Class type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Describes how types, statements, expressions, and declarations should be printed. ...
Represents the result of substituting a type for a template type parameter.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
Defines the clang::Expr interface and subclasses for C++ expressions.
unsigned getNumArgs() const
Retrieve the number of template arguments.
Expr * IgnoreImpCasts() LLVM_READONLY
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...
QualType apply(const ASTContext &Context, QualType QT) const
Apply the collected qualifiers to the given type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isReferenceType() const
bool isTranslationUnit() const
unsigned size() const
Retrieve the number of template arguments in this template argument list.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
const LangOptions & getLangOpts() const
APValue Val
Val - This is the value the expression can be folded to.
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
const ValueDecl * getMemberPointerDecl() const
bool isValueDependent() const
RecordDecl * getDecl() const
std::string getNameAsString() const
QualType getDefaultArgument() const
Retrieve the default argument, if any.
Expr * IgnoreParenCasts() LLVM_READONLY
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)
Returns the common set of qualifiers while removing them from the given sets.
TypeClass getTypeClass() const
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isLambdaCallOperator(const CXXMethodDecl *MD)
QualType getAliasedType() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
QualType getTemplateSpecializationType(TemplateName T, const TemplateArgument *Args, unsigned NumArgs, QualType Canon=QualType()) const
QualType getObjCObjectType(QualType Base, ObjCProtocolDecl *const *Protocols, unsigned NumProtocols) const
Legacy interface: cannot provide type arguments or __kindof.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const
Declaration of a template type parameter.
bool isTypeAlias() const
Determine if this template specialization type is for a type alias template that has been substituted...
ArgKind getKind() const
Return the kind of stored template argument.
unsigned TemplateDiffUsed
Represents a C++ template name within the type system.
static DeclarationName getFromOpaqueInteger(uintptr_t P)
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine()) const
Expr * getSubExpr() const
bool isDependentType() const
QualType getObjCIdType() const
Represents the Objective-CC id type.
const TemplateArgument * data() const
Retrieve a pointer to the template argument list.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
QualType getElementType() const
static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA)
const clang::PrintingPolicy & getPrintingPolicy() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
const char * getSpelling() const
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
ValueKind getKind() const
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
const char ToggleHighlight
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Expr * getDefaultArgument() const
Retrieve the default argument, if any.
bool isVectorType() const
static QualType getFromOpaquePtr(const void *Ptr)
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
ast_type_traits::DynTypedNode Node
Represents a template argument.
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons...
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
Print this nested name specifier to the given output stream.
A qualifier set is used to build a set of qualifiers.
EvalResult is a struct with detailed info about an evaluated expression.
The base class of all kinds of template declarations (e.g., class, function, etc.).
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
const Type * strip(QualType type)
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
QualType getBuiltinVaListType() const
Retrieve the type of the __builtin_va_list type.
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
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.
QualType getCanonicalType() const
llvm::PointerUnion< const ValueDecl *, const Expr * > LValueBase
const TemplateArgument & getArg(unsigned Idx) const
Retrieve a specific template argument as a type.
std::string getQualifiedNameAsString() const
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
const LValueBase getLValueBase() const
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
pack_iterator pack_end() const
Iterator referencing one past the last argument of a template argument pack.
Kind
Lists the kind of concrete classes of Decl.
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
Represents a type template specialization; the template must be a class template, a type alias templa...
static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, QualType ToType, bool PrintTree, bool PrintFromType, bool ElideType, bool ShowColors, raw_ostream &OS)
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
const TemplateArgument & getArgument() const
Attr - This represents one attribute.
Expr * IgnoreParens() LLVM_READONLY
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isPointerType() const