22#include "llvm/ADT/StringExtras.h"
23#include "llvm/Support/ConvertUTF.h"
24#include "llvm/Support/Format.h"
25#include "llvm/Support/raw_ostream.h"
40 if (
const UsingType *UT = dyn_cast<UsingType>(Ty)) {
45 if (
const ParenType *PT = dyn_cast<ParenType>(Ty)) {
55 if (
const SubstTemplateTypeParmType *ST =
56 dyn_cast<SubstTemplateTypeParmType>(Ty)) {
61 if (
const AttributedType *AT = dyn_cast<AttributedType>(Ty)) {
66 if (
const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) {
71 if (
const AutoType *AT = dyn_cast<AutoType>(Ty)) {
80 if (
const FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
81 bool DesugarReturn =
false;
82 QualType SugarRT = FT->getReturnType();
84 if (
auto nullability = AttributedType::stripOuterNullability(SugarRT)) {
85 RT = Context.getAttributedType(*nullability, RT, RT);
88 bool DesugarArgument =
false;
94 if (
auto nullability =
95 AttributedType::stripOuterNullability(SugarPT)) {
96 PT = Context.getAttributedType(*nullability, PT, PT);
102 if (DesugarReturn || DesugarArgument) {
105 : Context.getFunctionNoProtoType(RT, FT->getExtInfo());
112 if (
const TemplateSpecializationType *TST =
113 dyn_cast<TemplateSpecializationType>(Ty)) {
114 if (!TST->isTypeAlias()) {
115 bool DesugarArgument =
false;
125 if (DesugarArgument) {
127 QT = Context.getTemplateSpecializationType(
128 TST->getKeyword(), TST->getTemplateName(), Args,
135 if (
const auto *AT = dyn_cast<ArrayType>(Ty)) {
138 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
139 QT = Context.getConstantArrayType(
140 ElementTy, CAT->getSize(), CAT->getSizeExpr(),
141 CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());
142 else if (
const auto *VAT = dyn_cast<VariableArrayType>(AT))
143 QT = Context.getVariableArrayType(ElementTy, VAT->getSizeExpr(),
144 VAT->getSizeModifier(),
145 VAT->getIndexTypeCVRQualifiers());
146 else if (
const auto *DSAT = dyn_cast<DependentSizedArrayType>(AT))
147 QT = Context.getDependentSizedArrayType(
148 ElementTy, DSAT->getSizeExpr(), DSAT->getSizeModifier(),
149 DSAT->getIndexTypeCVRQualifiers());
150 else if (
const auto *IAT = dyn_cast<IncompleteArrayType>(AT))
151 QT = Context.getIncompleteArrayType(ElementTy, IAT->getSizeModifier(),
152 IAT->getIndexTypeCVRQualifiers());
154 llvm_unreachable(
"Unhandled array type");
159 if (
QualType(Ty,0) == Context.getObjCIdType() ||
160 QualType(Ty,0) == Context.getObjCClassType() ||
161 QualType(Ty,0) == Context.getObjCSelType() ||
162 QualType(Ty,0) == Context.getObjCProtoType())
166 if (
QualType(Ty, 0) == Context.getBuiltinVaListType() ||
167 QualType(Ty, 0) == Context.getBuiltinMSVaListType())
172 bool IsSugar =
false;
174#define ABSTRACT_TYPE(Class, Base)
175#define TYPE(Class, Base) \
177const Class##Type *CTy = cast<Class##Type>(Ty); \
178if (CTy->isSugared()) { \
180Underlying = CTy->desugar(); \
184#include "clang/AST/TypeNodes.inc"
197 if (
const TagType *UTT = Underlying->
getAs<TagType>())
198 if (
const TypedefType *QTT = dyn_cast<TypedefType>(QT))
199 if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl())
210 QT = Context.getPointerType(
213 QT = Context.getObjCObjectPointerType(
216 QT = Context.getLValueReferenceType(
219 QT = Context.getRValueReferenceType(
222 if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {
225 QT = Context.getObjCObjectType(
226 BaseType, Ty->getTypeArgsAsWritten(),
227 ArrayRef(Ty->qual_begin(), Ty->getNumProtocols()),
228 Ty->isKindOfTypeAsWritten());
232 return QC.
apply(Context, QT);
264 bool ForceAKA =
false;
266 std::string S = Ty.
getAsString(Context.getPrintingPolicy());
267 std::string CanS = CanTy.
getAsString(Context.getPrintingPolicy());
269 for (
const intptr_t &QualTypeVal : QualTypeVals) {
277 if (CompareCanTy == CanTy)
279 std::string CompareS = CompareTy.
getAsString(Context.getPrintingPolicy());
280 bool ShouldAKA =
false;
283 std::string CompareDesugarStr =
284 CompareDesugar.
getAsString(Context.getPrintingPolicy());
285 if (CompareS != S && CompareDesugarStr != S)
288 std::string CompareCanS =
289 CompareCanTy.
getAsString(Context.getPrintingPolicy());
291 if (CompareCanS == CanS)
300 bool Repeated =
false;
301 for (
const auto &PrevArg : PrevArgs) {
316 bool ShouldAKA =
false;
318 if (ShouldAKA || ForceAKA) {
319 if (DesugaredTy == Ty) {
322 std::string akaStr = DesugaredTy.
getAsString(Context.getPrintingPolicy());
324 S =
"'" + S +
"' (aka '" + akaStr +
"')";
333 std::string DecoratedString;
334 llvm::raw_string_ostream OS(DecoratedString);
335 const char *Values = VTy->getNumElements() > 1 ?
"values" :
"value";
336 OS <<
"'" << S <<
"' (vector of " << VTy->getNumElements() <<
" '"
337 << VTy->getElementType().getAsString(Context.getPrintingPolicy())
338 <<
"' " << Values <<
")";
339 return DecoratedString;
349 bool PrintFromType,
bool ElideType,
350 bool ShowColors, raw_ostream &OS);
363 size_t OldEnd = Output.size();
364 llvm::raw_svector_ostream OS(Output);
365 bool NeedQuotes =
true;
368 default: llvm_unreachable(
"unknown ArgumentKind");
370 assert(Modifier.empty() && Argument.empty() &&
371 "Invalid modifier for Qualifiers argument");
375 OS << (Context.getLangOpts().
OpenCL ?
"default" :
"generic");
376 OS <<
" address space";
378 OS <<
"address space";
379 OS <<
" '" << S <<
"'";
385 assert(Modifier.empty() && Argument.empty() &&
386 "Invalid modifier for Qualifiers argument");
421 Modifier = StringRef();
422 Argument = StringRef();
427 assert(Modifier.empty() && Argument.empty() &&
428 "Invalid modifier for QualType argument");
436 if (Modifier ==
"objcclass" && Argument.empty())
438 else if (Modifier ==
"objcinstance" && Argument.empty())
441 assert(Modifier.empty() && Argument.empty() &&
442 "Invalid modifier for DeclarationName argument");
449 if (Modifier ==
"q" && Argument.empty())
452 assert(Modifier.empty() && Argument.empty() &&
453 "Invalid modifier for NamedDecl* argument");
462 .
print(OS, Context.getPrintingPolicy(),
468 assert(DC &&
"Should never have a null declaration context");
473 if (Context.getLangOpts().CPlusPlus)
474 OS <<
"the global namespace";
476 OS <<
"the global scope";
478 OS <<
"block literal";
480 OS <<
"lambda expression";
483 Context, Context.getTypeDeclType(
Type), PrevArgs, QualTypeVals);
501 const Attr *At =
reinterpret_cast<Attr *
>(Val);
502 assert(At &&
"Received null Attr object!");
516 const Expr *E =
reinterpret_cast<Expr *
>(Val);
517 assert(E &&
"Received null Expr!");
518 E->
printPretty(OS,
nullptr, Context.getPrintingPolicy());
523 assert(AT &&
"Received null AttributeCommonInfo object!");
538 Output.insert(Output.begin()+OldEnd,
'\'');
539 Output.push_back(
'\'');
604 FromIntegerAndToDeclaration,
605 FromDeclarationAndToInteger
612 struct TemplateArgumentInfo {
616 bool IsValidInt =
false;
617 Expr *ArgExpr =
nullptr;
618 TemplateDecl *TD =
nullptr;
619 ValueDecl *VD =
nullptr;
620 bool NeedAddressOf =
false;
621 bool IsNullPtr =
false;
622 bool IsDefault =
false;
632 unsigned NextNode = 0;
635 unsigned ChildNode = 0;
638 unsigned ParentNode = 0;
640 TemplateArgumentInfo FromArgInfo, ToArgInfo;
645 DiffNode(
unsigned ParentNode = 0) : ParentNode(ParentNode) {}
649 SmallVector<DiffNode, 16> FlatTree;
652 unsigned CurrentNode;
656 unsigned NextFreeNode;
662 DiffTree() : CurrentNode(0), NextFreeNode(1), ReadNode(0) {
663 FlatTree.push_back(DiffNode());
667 void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
668 Qualifiers FromQual, Qualifiers ToQual,
669 bool FromDefault,
bool ToDefault) {
670 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
671 FlatTree[CurrentNode].Kind = Template;
672 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
673 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
674 FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;
675 FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;
676 SetDefault(FromDefault, ToDefault);
679 void SetTypeDiff(QualType FromType, QualType ToType,
bool FromDefault,
681 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
682 FlatTree[CurrentNode].Kind = Type;
683 FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;
684 FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;
685 SetDefault(FromDefault, ToDefault);
688 void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr,
bool FromDefault,
690 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
691 FlatTree[CurrentNode].Kind = Expression;
692 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
693 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
694 SetDefault(FromDefault, ToDefault);
697 void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
698 bool FromDefault,
bool ToDefault) {
699 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
700 FlatTree[CurrentNode].Kind = TemplateTemplate;
701 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
702 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
703 SetDefault(FromDefault, ToDefault);
706 void SetIntegerDiff(
const llvm::APSInt &FromInt,
const llvm::APSInt &ToInt,
707 bool IsValidFromInt,
bool IsValidToInt,
708 QualType FromIntType, QualType ToIntType,
709 Expr *FromExpr, Expr *ToExpr,
bool FromDefault,
711 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
712 FlatTree[CurrentNode].Kind = Integer;
713 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
714 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
715 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
716 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
717 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
718 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
719 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
720 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
721 SetDefault(FromDefault, ToDefault);
724 void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
725 bool FromAddressOf,
bool ToAddressOf,
726 bool FromNullPtr,
bool ToNullPtr, Expr *FromExpr,
727 Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
728 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
729 FlatTree[CurrentNode].Kind = Declaration;
730 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
731 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
732 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
733 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
734 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
735 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
736 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
737 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
738 SetDefault(FromDefault, ToDefault);
741 void SetFromDeclarationAndToIntegerDiff(
742 ValueDecl *FromValueDecl,
bool FromAddressOf,
bool FromNullPtr,
743 Expr *FromExpr,
const llvm::APSInt &ToInt,
bool IsValidToInt,
744 QualType ToIntType, Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
745 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
746 FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger;
747 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
748 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
749 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
750 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
751 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
752 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
753 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
754 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
755 SetDefault(FromDefault, ToDefault);
758 void SetFromIntegerAndToDeclarationDiff(
759 const llvm::APSInt &FromInt,
bool IsValidFromInt, QualType FromIntType,
760 Expr *FromExpr, ValueDecl *ToValueDecl,
bool ToAddressOf,
761 bool ToNullPtr, Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
762 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
763 FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration;
764 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
765 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
766 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
767 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
768 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
769 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
770 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
771 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
772 SetDefault(FromDefault, ToDefault);
776 void SetDefault(
bool FromDefault,
bool ToDefault) {
777 assert((!FromDefault || !ToDefault) &&
"Both arguments cannot be default.");
778 FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;
779 FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;
783 void SetSame(
bool Same) {
784 FlatTree[CurrentNode].Same =
Same;
788 void SetKind(DiffKind Kind) {
789 FlatTree[CurrentNode].Kind =
Kind;
794 assert(FlatTree[CurrentNode].Kind != Invalid &&
795 "Cannot exit node before setting node information.");
796 CurrentNode = FlatTree[CurrentNode].ParentNode;
802 assert(FlatTree[CurrentNode].Kind == Template &&
803 "Only Template nodes can have children nodes.");
804 FlatTree.push_back(DiffNode(CurrentNode));
805 DiffNode &Node = FlatTree[CurrentNode];
806 if (Node.ChildNode == 0) {
808 Node.ChildNode = NextFreeNode;
813 for (i = Node.ChildNode; FlatTree[i].NextNode != 0;
814 i = FlatTree[i].NextNode) {
816 FlatTree[i].NextNode = NextFreeNode;
818 CurrentNode = NextFreeNode;
824 void StartTraverse() {
826 CurrentNode = NextFreeNode;
832 ReadNode = FlatTree[ReadNode].ParentNode;
835 void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD,
836 Qualifiers &FromQual, Qualifiers &ToQual) {
837 assert(FlatTree[ReadNode].Kind == Template &&
"Unexpected kind.");
838 FromTD = FlatTree[ReadNode].FromArgInfo.TD;
839 ToTD = FlatTree[ReadNode].ToArgInfo.TD;
840 FromQual = FlatTree[ReadNode].FromArgInfo.Qual;
841 ToQual = FlatTree[ReadNode].ToArgInfo.Qual;
844 void GetTypeDiff(QualType &FromType, QualType &ToType) {
845 assert(FlatTree[ReadNode].Kind == Type &&
"Unexpected kind");
846 FromType = FlatTree[ReadNode].FromArgInfo.ArgType;
847 ToType = FlatTree[ReadNode].ToArgInfo.ArgType;
850 void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) {
851 assert(FlatTree[ReadNode].Kind == Expression &&
"Unexpected kind");
852 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
853 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
856 void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {
857 assert(FlatTree[ReadNode].Kind == TemplateTemplate &&
"Unexpected kind.");
858 FromTD = FlatTree[ReadNode].FromArgInfo.TD;
859 ToTD = FlatTree[ReadNode].ToArgInfo.TD;
862 void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
863 bool &IsValidFromInt,
bool &IsValidToInt,
864 QualType &FromIntType, QualType &ToIntType,
865 Expr *&FromExpr, Expr *&ToExpr) {
866 assert(FlatTree[ReadNode].Kind == Integer &&
"Unexpected kind.");
867 FromInt = FlatTree[ReadNode].FromArgInfo.Val;
868 ToInt = FlatTree[ReadNode].ToArgInfo.Val;
869 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
870 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
871 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
872 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
873 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
874 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
877 void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,
878 bool &FromAddressOf,
bool &ToAddressOf,
879 bool &FromNullPtr,
bool &ToNullPtr, Expr *&FromExpr,
881 assert(FlatTree[ReadNode].Kind == Declaration &&
"Unexpected kind.");
882 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
883 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
884 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
885 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
886 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
887 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
888 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
889 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
892 void GetFromDeclarationAndToIntegerDiff(
893 ValueDecl *&FromValueDecl,
bool &FromAddressOf,
bool &FromNullPtr,
894 Expr *&FromExpr, llvm::APSInt &ToInt,
bool &IsValidToInt,
895 QualType &ToIntType, Expr *&ToExpr) {
896 assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger &&
898 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
899 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
900 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
901 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
902 ToInt = FlatTree[ReadNode].ToArgInfo.Val;
903 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
904 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
905 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
908 void GetFromIntegerAndToDeclarationDiff(
909 llvm::APSInt &FromInt,
bool &IsValidFromInt, QualType &FromIntType,
910 Expr *&FromExpr, ValueDecl *&ToValueDecl,
bool &ToAddressOf,
911 bool &ToNullPtr, Expr *&ToExpr) {
912 assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration &&
914 FromInt = FlatTree[ReadNode].FromArgInfo.Val;
915 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
916 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
917 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
918 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
919 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
920 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
921 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
926 return FlatTree[ReadNode].FromArgInfo.IsDefault;
931 return FlatTree[ReadNode].ToArgInfo.IsDefault;
936 return FlatTree[ReadNode].Same;
941 return FlatTree[ReadNode].ChildNode != 0;
946 ReadNode = FlatTree[ReadNode].ChildNode;
951 bool AdvanceSibling() {
952 if (FlatTree[ReadNode].NextNode == 0)
955 ReadNode = FlatTree[ReadNode].NextNode;
960 bool HasNextSibling() {
961 return FlatTree[ReadNode].NextNode != 0;
966 return GetKind() == Invalid;
971 return FlatTree[ReadNode].Kind;
982 typedef const TemplateArgument& reference;
983 typedef const TemplateArgument* pointer;
988 struct InternalIterator {
991 const TemplateSpecializationType *TST;
1005 InternalIterator(
const TemplateSpecializationType *TST)
1009 if (isEnd())
return;
1012 TemplateArgument TA = TST->template_arguments()[0];
1020 if (CurrentTA != EndTA)
return;
1028 bool isValid()
const {
return TST; }
1031 bool isEnd()
const {
1032 assert(TST &&
"InternalIterator is invalid with a null TST.");
1033 return Index >= TST->template_arguments().size();
1037 InternalIterator &operator++() {
1038 assert(TST &&
"InternalIterator is invalid with a null TST.");
1044 if (CurrentTA != EndTA) {
1046 if (CurrentTA != EndTA)
1053 if (++Index == TST->template_arguments().size())
1057 TemplateArgument TA = TST->template_arguments()[Index];
1066 if (CurrentTA != EndTA)
1074 assert(TST &&
"InternalIterator is invalid with a null TST.");
1075 assert(!isEnd() &&
"Index exceeds number of arguments.");
1076 if (CurrentTA == EndTA)
1077 return TST->template_arguments()[Index];
1083 pointer operator->()
const {
1084 assert(TST &&
"InternalIterator is invalid with a null TST.");
1089 InternalIterator SugaredIterator;
1090 InternalIterator DesugaredIterator;
1093 TSTiterator(ASTContext &Context,
const TemplateSpecializationType *TST)
1094 : SugaredIterator(TST),
1096 (TST->isSugared() && !TST->isTypeAlias())
1097 ? GetTemplateSpecializationType(Context, TST->desugar())
1101 TSTiterator &operator++() {
1103 if (DesugaredIterator.isValid())
1104 ++DesugaredIterator;
1110 return *SugaredIterator;
1114 pointer operator->()
const {
1119 bool isEnd()
const {
1120 return SugaredIterator.isEnd();
1125 bool hasDesugaredTA()
const {
1126 return DesugaredIterator.isValid() && !DesugaredIterator.isEnd();
1130 reference getDesugaredTA()
const {
1131 assert(DesugaredIterator.isValid() &&
1132 "Desugared TemplateArgument should not be used.");
1133 return *DesugaredIterator;
1140 static const TemplateSpecializationType *
1141 GetTemplateSpecializationType(ASTContext &Context, QualType Ty) {
1142 if (
const TemplateSpecializationType *TST =
1143 Ty->
getAs<TemplateSpecializationType>())
1146 if (
const auto* SubstType = Ty->
getAs<SubstTemplateTypeParmType>())
1147 Ty = SubstType->getReplacementType();
1149 const auto *RT = Ty->
getAs<RecordType>();
1153 const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
1157 Ty = Context.getTemplateSpecializationType(
1158 ElaboratedTypeKeyword::None,
1160 CTSD->getTemplateArgs().asArray(), {},
1163 return Ty->
getAs<TemplateSpecializationType>();
1167 static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType,
1169 const TemplateSpecializationType *&FromArgTST,
1170 const TemplateSpecializationType *&ToArgTST) {
1174 if (Context.hasSameType(FromType, ToType))
1177 FromArgTST = GetTemplateSpecializationType(Context, FromType);
1178 ToArgTST = GetTemplateSpecializationType(Context, ToType);
1180 if (!FromArgTST || !ToArgTST)
1183 if (!hasSameTemplate(Context, FromArgTST, ToArgTST))
1190 void DiffTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter) {
1191 QualType FromType = GetType(FromIter);
1192 QualType ToType = GetType(ToIter);
1194 bool FromDefault = FromIter.isEnd() && !FromType.
isNull();
1195 bool ToDefault = ToIter.isEnd() && !ToType.
isNull();
1197 const TemplateSpecializationType *FromArgTST =
nullptr;
1198 const TemplateSpecializationType *ToArgTST =
nullptr;
1199 if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {
1200 Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);
1202 Context.hasSameType(FromType, ToType));
1204 assert(FromArgTST && ToArgTST &&
1205 "Both template specializations need to be valid.");
1208 FromQual -= QualType(FromArgTST, 0).getQualifiers();
1209 ToQual -= QualType(ToArgTST, 0).getQualifiers();
1210 Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(),
1211 ToArgTST->getTemplateName().getAsTemplateDecl(),
1212 FromQual, ToQual, FromDefault, ToDefault);
1213 DiffTemplate(FromArgTST, ToArgTST);
1219 void DiffTemplateTemplates(
const TSTiterator &FromIter,
1220 const TSTiterator &ToIter) {
1221 TemplateDecl *FromDecl = GetTemplateDecl(FromIter);
1222 TemplateDecl *ToDecl = GetTemplateDecl(ToIter);
1223 Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl,
1224 ToIter.isEnd() && ToDecl);
1225 Tree.SetSame(FromDecl && ToDecl &&
1230 static void InitializeNonTypeDiffVariables(ASTContext &Context,
1231 const TSTiterator &Iter,
1232 NonTypeTemplateParmDecl *
Default,
1233 llvm::APSInt &
Value,
bool &HasInt,
1234 QualType &IntType,
bool &IsNullPtr,
1235 Expr *&E, ValueDecl *&VD,
1236 bool &NeedAddressOf) {
1237 if (!Iter.isEnd()) {
1238 switch (Iter->getKind()) {
1245 Value = Iter->getAsIntegral();
1247 IntType = Iter->getIntegralType();
1250 VD = Iter->getAsDecl();
1251 QualType ArgType = Iter->getParamTypeForDecl();
1252 QualType VDType = VD->
getType();
1255 NeedAddressOf =
true;
1262 E = Iter->getAsExpr();
1268 llvm_unreachable(
"TemplateArgument kind is not expected for NTTP");
1270 llvm_unreachable(
"TemplateArgument kind should be handled elsewhere");
1272 }
else if (!
Default->isParameterPack()) {
1273 E =
Default->getDefaultArgument().getArgument().getAsExpr();
1276 if (!Iter.hasDesugaredTA())
1279 const TemplateArgument &TA = Iter.getDesugaredTA();
1293 QualType VDType = VD->
getType();
1296 NeedAddressOf =
true;
1313 llvm_unreachable(
"TemplateArgument kind is not expected for NTTP");
1315 llvm_unreachable(
"TemplateArgument kind should be handled elsewhere");
1317 llvm_unreachable(
"Unexpected TemplateArgument kind");
1322 void DiffNonTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter,
1323 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl,
1324 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) {
1325 Expr *FromExpr =
nullptr, *ToExpr =
nullptr;
1326 llvm::APSInt FromInt, ToInt;
1327 QualType FromIntType, ToIntType;
1328 ValueDecl *FromValueDecl =
nullptr, *ToValueDecl =
nullptr;
1329 bool HasFromInt =
false, HasToInt =
false, FromNullPtr =
false,
1330 ToNullPtr =
false, NeedFromAddressOf =
false, NeedToAddressOf =
false;
1331 InitializeNonTypeDiffVariables(
1332 Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt,
1333 FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf);
1334 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt,
1335 HasToInt, ToIntType, ToNullPtr, ToExpr,
1336 ToValueDecl, NeedToAddressOf);
1338 bool FromDefault = FromIter.isEnd() &&
1339 (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);
1340 bool ToDefault = ToIter.isEnd() &&
1341 (ToExpr || ToValueDecl || HasToInt || ToNullPtr);
1343 bool FromDeclaration = FromValueDecl || FromNullPtr;
1344 bool ToDeclaration = ToValueDecl || ToNullPtr;
1346 if (FromDeclaration && HasToInt) {
1347 Tree.SetFromDeclarationAndToIntegerDiff(
1348 FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt,
1349 HasToInt, ToIntType, ToExpr, FromDefault, ToDefault);
1350 Tree.SetSame(
false);
1355 if (HasFromInt && ToDeclaration) {
1356 Tree.SetFromIntegerAndToDeclarationDiff(
1357 FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl,
1358 NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault);
1359 Tree.SetSame(
false);
1363 if (HasFromInt || HasToInt) {
1364 Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType,
1365 ToIntType, FromExpr, ToExpr, FromDefault, ToDefault);
1366 if (HasFromInt && HasToInt) {
1367 Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) &&
1373 if (FromDeclaration || ToDeclaration) {
1374 Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf,
1375 NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1376 ToExpr, FromDefault, ToDefault);
1377 bool BothNull = FromNullPtr && ToNullPtr;
1378 bool SameValueDecl =
1379 FromValueDecl && ToValueDecl &&
1380 NeedFromAddressOf == NeedToAddressOf &&
1382 Tree.SetSame(BothNull || SameValueDecl);
1386 assert((FromExpr || ToExpr) &&
"Both template arguments cannot be empty.");
1387 Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault);
1388 Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));
1393 void DiffTemplate(
const TemplateSpecializationType *FromTST,
1394 const TemplateSpecializationType *ToTST) {
1398 TemplateParameterList *ParamsFrom =
1399 FromTST->getTemplateName()
1400 .getAsTemplateDecl(
true)
1401 ->getTemplateParameters();
1402 TemplateParameterList *ParamsTo =
1403 ToTST->getTemplateName()
1404 .getAsTemplateDecl(
true)
1405 ->getTemplateParameters();
1406 unsigned TotalArgs = 0;
1407 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST);
1408 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) {
1414 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->
size() - 1);
1415 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->
size() - 1);
1416 NamedDecl *FromParamND = ParamsFrom->
getParam(FromParamIndex);
1417 NamedDecl *ToParamND = ParamsTo->
getParam(ToParamIndex);
1420 "Parameter Decl are not the same kind.");
1423 DiffTypes(FromIter, ToIter);
1425 DiffTemplateTemplates(FromIter, ToIter);
1427 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl =
1429 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl =
1431 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
1432 ToDefaultNonTypeDecl);
1434 llvm_unreachable(
"Unexpected Decl type.");
1444 static void makeTemplateList(
1445 SmallVectorImpl<const TemplateSpecializationType *> &TemplateList,
1446 const TemplateSpecializationType *TST) {
1448 TemplateList.push_back(TST);
1449 if (!TST->isTypeAlias())
1451 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1457 static bool hasSameBaseTemplate(ASTContext &Context,
1458 const TemplateSpecializationType *FromTST,
1459 const TemplateSpecializationType *ToTST) {
1460 return Context.getCanonicalTemplateName(FromTST->getTemplateName(),
1462 Context.getCanonicalTemplateName(ToTST->getTemplateName(),
1470 static bool hasSameTemplate(ASTContext &Context,
1471 const TemplateSpecializationType *&FromTST,
1472 const TemplateSpecializationType *&ToTST) {
1474 if (hasSameBaseTemplate(Context, FromTST, ToTST))
1478 SmallVector<const TemplateSpecializationType*, 1> FromTemplateList,
1481 makeTemplateList(FromTemplateList, FromTST);
1482 makeTemplateList(ToTemplateList, ToTST);
1484 SmallVectorImpl<const TemplateSpecializationType *>::reverse_iterator
1485 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(),
1486 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend();
1489 if (!hasSameBaseTemplate(Context, *FromIter, *ToIter))
1495 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) {
1496 if (!hasSameBaseTemplate(Context, *FromIter, *ToIter))
1500 FromTST = FromIter[-1];
1508 static QualType GetType(
const TSTiterator &Iter) {
1510 return Iter->getAsType();
1511 if (Iter.hasDesugaredTA())
1512 return Iter.getDesugaredTA().getAsType();
1518 static TemplateDecl *GetTemplateDecl(
const TSTiterator &Iter) {
1520 return Iter->getAsTemplate().getAsTemplateDecl();
1521 if (Iter.hasDesugaredTA())
1522 return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();
1529 static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) {
1530 if (FromExpr == ToExpr)
1533 if (!FromExpr || !ToExpr)
1536 llvm::FoldingSetNodeID FromID, ToID;
1537 FromExpr->
Profile(FromID, Context,
true);
1538 ToExpr->
Profile(ToID, Context,
true);
1539 return FromID == ToID;
1547 void TreeToString(
int Indent = 1) {
1556 switch (Tree.GetKind()) {
1557 case DiffTree::Invalid:
1558 llvm_unreachable(
"Template diffing failed with bad DiffNode");
1559 case DiffTree::Type: {
1560 QualType FromType, ToType;
1561 Tree.GetTypeDiff(FromType, ToType);
1562 PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(),
1566 case DiffTree::Expression: {
1567 Expr *FromExpr, *ToExpr;
1568 Tree.GetExpressionDiff(FromExpr, ToExpr);
1569 PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
1573 case DiffTree::TemplateTemplate: {
1574 TemplateDecl *FromTD, *ToTD;
1575 Tree.GetTemplateTemplateDiff(FromTD, ToTD);
1576 PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(),
1577 Tree.ToDefault(), Tree.NodeIsSame());
1580 case DiffTree::Integer: {
1581 llvm::APSInt FromInt, ToInt;
1582 Expr *FromExpr, *ToExpr;
1583 bool IsValidFromInt, IsValidToInt;
1584 QualType FromIntType, ToIntType;
1585 Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,
1586 FromIntType, ToIntType, FromExpr, ToExpr);
1587 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType,
1588 ToIntType, FromExpr, ToExpr, Tree.FromDefault(),
1589 Tree.ToDefault(), Tree.NodeIsSame());
1592 case DiffTree::Declaration: {
1593 ValueDecl *FromValueDecl, *ToValueDecl;
1594 bool FromAddressOf, ToAddressOf;
1595 bool FromNullPtr, ToNullPtr;
1596 Expr *FromExpr, *ToExpr;
1597 Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,
1598 ToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1600 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
1601 FromNullPtr, ToNullPtr, FromExpr, ToExpr,
1602 Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
1605 case DiffTree::FromDeclarationAndToInteger: {
1606 ValueDecl *FromValueDecl;
1614 Tree.GetFromDeclarationAndToIntegerDiff(
1615 FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt,
1616 IsValidToInt, ToIntType, ToExpr);
1617 assert((FromValueDecl || FromNullPtr) && IsValidToInt);
1618 PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr,
1619 FromExpr, Tree.FromDefault(), ToInt, ToIntType,
1620 ToExpr, Tree.ToDefault());
1623 case DiffTree::FromIntegerAndToDeclaration: {
1624 llvm::APSInt FromInt;
1625 bool IsValidFromInt;
1626 QualType FromIntType;
1628 ValueDecl *ToValueDecl;
1632 Tree.GetFromIntegerAndToDeclarationDiff(
1633 FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl,
1634 ToAddressOf, ToNullPtr, ToExpr);
1635 assert(IsValidFromInt && (ToValueDecl || ToNullPtr));
1636 PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr,
1637 Tree.FromDefault(), ToValueDecl, ToAddressOf,
1638 ToNullPtr, ToExpr, Tree.ToDefault());
1641 case DiffTree::Template: {
1643 TemplateDecl *FromTD, *ToTD;
1644 Qualifiers FromQual, ToQual;
1645 Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);
1647 PrintQualifiers(FromQual, ToQual);
1649 if (!Tree.HasChildren()) {
1658 unsigned NumElideArgs = 0;
1659 bool AllArgsElided =
true;
1662 if (Tree.NodeIsSame()) {
1666 AllArgsElided =
false;
1667 if (NumElideArgs > 0) {
1668 PrintElideArgs(NumElideArgs,
Indent);
1674 if (Tree.HasNextSibling())
1676 }
while (Tree.AdvanceSibling());
1677 if (NumElideArgs > 0) {
1681 PrintElideArgs(NumElideArgs,
Indent);
1697 assert(!IsBold &&
"Attempting to bold text that is already bold.");
1705 assert(IsBold &&
"Attempting to remove bold from unbold text.");
1716 void PrintTypeNames(QualType FromType, QualType ToType,
1717 bool FromDefault,
bool ToDefault,
bool Same) {
1719 "Only one template argument may be missing.");
1731 PrintQualifiers(FromQual, ToQual);
1736 std::string FromTypeStr = FromType.
isNull() ?
"(no argument)"
1738 std::string ToTypeStr =
1741 if (FromTypeStr == ToTypeStr) {
1743 std::string FromCanTypeStr =
1746 if (FromCanTypeStr != ToCanTypeStr) {
1747 FromTypeStr = FromCanTypeStr;
1748 ToTypeStr = ToCanTypeStr;
1754 OS << (FromDefault ?
"(default) " :
"");
1759 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1769 void PrintExpr(
const Expr *FromExpr,
const Expr *ToExpr,
bool FromDefault,
1770 bool ToDefault,
bool Same) {
1771 assert((FromExpr || ToExpr) &&
1772 "Only one template argument may be missing.");
1774 PrintExpr(FromExpr);
1775 }
else if (!PrintTree) {
1776 OS << (FromDefault ?
"(default) " :
"");
1778 PrintExpr(FromExpr);
1781 OS << (FromDefault ?
"[(default) " :
"[");
1783 PrintExpr(FromExpr);
1785 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1794 void PrintExpr(
const Expr *E) {
1799 OS <<
"(no argument)";
1804 void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD,
1805 bool FromDefault,
bool ToDefault,
bool Same) {
1806 assert((FromTD || ToTD) &&
"Only one template argument may be missing.");
1808 std::string FromName =
1809 std::string(FromTD ? FromTD->
getName() :
"(no argument)");
1810 std::string ToName = std::string(ToTD ? ToTD->
getName() :
"(no argument)");
1811 if (FromTD && ToTD && FromName == ToName) {
1818 }
else if (!PrintTree) {
1819 OS << (FromDefault ?
"(default) template " :
"template ");
1824 OS << (FromDefault ?
"[(default) template " :
"[template ");
1828 OS <<
" != " << (ToDefault ?
"(default) template " :
"template ");
1838 void PrintAPSInt(
const llvm::APSInt &FromInt,
const llvm::APSInt &ToInt,
1839 bool IsValidFromInt,
bool IsValidToInt, QualType FromIntType,
1840 QualType ToIntType, Expr *FromExpr, Expr *ToExpr,
1841 bool FromDefault,
bool ToDefault,
bool Same) {
1842 assert((IsValidFromInt || IsValidToInt) &&
1843 "Only one integral argument may be missing.");
1847 OS << ((FromInt == 0) ?
"false" :
"true");
1854 bool PrintType = IsValidFromInt && IsValidToInt &&
1855 !Context.hasSameType(FromIntType, ToIntType);
1858 OS << (FromDefault ?
"(default) " :
"");
1859 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1861 OS << (FromDefault ?
"[(default) " :
"[");
1862 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1863 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1864 PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType);
1871 void PrintAPSInt(
const llvm::APSInt &Val, Expr *E,
bool Valid,
1872 QualType IntType,
bool PrintType) {
1875 if (HasExtraInfo(E)) {
1885 IntType.
print(OS, Context.getPrintingPolicy());
1891 OS << ((Val == 0) ?
"false" :
"true");
1898 OS <<
"(no argument)";
1905 bool HasExtraInfo(Expr *E) {
1906 if (!E)
return false;
1910 auto CheckIntegerLiteral = [](Expr *E) {
1911 if (
auto *TemplateExpr = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
1912 E = TemplateExpr->getReplacement();
1916 if (CheckIntegerLiteral(E))
return false;
1918 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E))
1919 if (UO->getOpcode() == UO_Minus)
1920 if (CheckIntegerLiteral(UO->getSubExpr()))
1929 void PrintValueDecl(ValueDecl *VD,
bool AddressOf, Expr *E,
bool NullPtr) {
1933 else if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
1937 TPO->getType().getUnqualifiedType().print(OS, Policy);
1938 TPO->printAsInit(OS, Policy);
1966 OS <<
"(no argument)";
1971 void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
1972 bool FromAddressOf,
bool ToAddressOf,
bool FromNullPtr,
1973 bool ToNullPtr, Expr *FromExpr, Expr *ToExpr,
1974 bool FromDefault,
bool ToDefault,
bool Same) {
1975 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
1976 "Only one Decl argument may be NULL");
1979 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1980 }
else if (!PrintTree) {
1981 OS << (FromDefault ?
"(default) " :
"");
1983 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1986 OS << (FromDefault ?
"[(default) " :
"[");
1988 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1990 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1992 PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr);
2000 void PrintValueDeclAndInteger(ValueDecl *VD,
bool NeedAddressOf,
2001 bool IsNullPtr, Expr *VDExpr,
bool DefaultDecl,
2002 const llvm::APSInt &Val, QualType IntType,
2003 Expr *IntExpr,
bool DefaultInt) {
2005 OS << (DefaultDecl ?
"(default) " :
"");
2007 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
2010 OS << (DefaultDecl ?
"[(default) " :
"[");
2012 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
2014 OS <<
" != " << (DefaultInt ?
"(default) " :
"");
2015 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
2022 void PrintIntegerAndValueDecl(
const llvm::APSInt &Val, QualType IntType,
2023 Expr *IntExpr,
bool DefaultInt, ValueDecl *VD,
2024 bool NeedAddressOf,
bool IsNullPtr,
2025 Expr *VDExpr,
bool DefaultDecl) {
2027 OS << (DefaultInt ?
"(default) " :
"");
2028 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
2030 OS << (DefaultInt ?
"[(default) " :
"[");
2031 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
2032 OS <<
" != " << (DefaultDecl ?
"(default) " :
"");
2034 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
2041 void PrintElideArgs(
unsigned NumElideArgs,
unsigned Indent) {
2044 for (
unsigned i = 0; i <
Indent; ++i)
2047 if (NumElideArgs == 0)
return;
2048 if (NumElideArgs == 1)
2051 OS <<
"[" << NumElideArgs <<
" * ...]";
2055 void PrintQualifiers(Qualifiers FromQual, Qualifiers ToQual) {
2061 if (FromQual == ToQual) {
2062 PrintQualifier(FromQual,
false);
2082 if (CommonQual.
empty() && FromQual.
empty()) {
2084 OS <<
"(no qualifiers) ";
2087 PrintQualifier(CommonQual,
false);
2088 PrintQualifier(FromQual,
true);
2093 OS <<
"(no qualifiers)";
2096 PrintQualifier(CommonQual,
false,
2098 PrintQualifier(ToQual,
true,
2103 PrintQualifier(CommonQual,
false);
2104 PrintQualifier(FromQual,
true);
2108 void PrintQualifier(Qualifiers Q,
bool ApplyBold,
2109 bool AppendSpaceIfNonEmpty =
true) {
2110 if (Q.
empty())
return;
2111 if (ApplyBold)
Bold();
2112 Q.
print(OS, Policy, AppendSpaceIfNonEmpty);
2113 if (ApplyBold) Unbold();
2118 TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType,
2119 QualType ToType,
bool PrintTree,
bool PrintFromType,
2120 bool ElideType,
bool ShowColor)
2122 Policy(Context.getLangOpts()),
2123 ElideType(ElideType),
2124 PrintTree(PrintTree),
2125 ShowColor(ShowColor),
2127 FromTemplateType(PrintFromType ? FromType : ToType),
2128 ToTemplateType(PrintFromType ? ToType : FromType),
2134 void DiffTemplate() {
2135 Qualifiers FromQual = FromTemplateType.getQualifiers(),
2136 ToQual = ToTemplateType.getQualifiers();
2138 const TemplateSpecializationType *FromOrigTST =
2139 GetTemplateSpecializationType(Context, FromTemplateType);
2140 const TemplateSpecializationType *ToOrigTST =
2141 GetTemplateSpecializationType(Context, ToTemplateType);
2144 if (!FromOrigTST || !ToOrigTST)
2148 if (!hasSameTemplate(Context, FromOrigTST, ToOrigTST)) {
2152 FromQual -= QualType(FromOrigTST, 0).getQualifiers();
2153 ToQual -= QualType(ToOrigTST, 0).getQualifiers();
2156 Tree.SetTemplateDiff(
2157 FromOrigTST->getTemplateName().getAsTemplateDecl(
2159 ToOrigTST->getTemplateName().getAsTemplateDecl(
true),
2160 FromQual, ToQual,
false ,
false );
2162 DiffTemplate(FromOrigTST, ToOrigTST);
2169 Tree.StartTraverse();
2174 assert(!IsBold &&
"Bold is applied to end of string.");
2185 bool PrintFromType,
bool ElideType,
2186 bool ShowColors, raw_ostream &OS) {
2188 PrintFromType =
true;
2189 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType,
2190 ElideType, ShowColors);
2197 if (
T->isChar8Type()) {
2198 assert(
Value <= 0xFF &&
"not a valid UTF-8 code unit");
2199 return Value <= 0x7F;
2201 if (
T->isChar16Type()) {
2202 assert(
Value <= 0xFFFF &&
"not a valid UTF-16 code unit");
2203 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value);
2205 assert(
T->isChar32Type());
2206 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value);
2209 if (!IsSingleCodeUnitCP(
Value,
T)) {
2210 llvm::raw_svector_ostream OS(Str);
2211 OS <<
"<" << llvm::format_hex(
Value, 1,
true) <<
">";
2212 return std::string(Str.begin(), Str.end());
2215 char Buffer[UNI_MAX_UTF8_BYTES_PER_CODE_POINT];
2217 [[maybe_unused]]
bool Converted = llvm::ConvertCodePointToUTF8(
Value, Ptr);
2218 assert(Converted &&
"trying to encode invalid code unit");
2220 return std::string(Str.begin(), Str.end());
Defines the clang::ASTContext interface.
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 ...
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.
This file provides some common utility functions for processing Lambda related AST Constructs.
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Attr - This represents one attribute.
const char * getSpelling() const
std::string getNormalizedFullName() const
Gets the normalized full name, which consists of both scope and name and with surrounding underscores...
const IdentifierInfo * getScopeName() const
const IdentifierInfo * getAttrName() const
bool isStandardAttributeSyntax() const
The attribute is spelled [[]] in either C or C++ mode, including standard attributes spelled with a k...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
bool isTranslationUnit() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
static DeclarationName getFromOpaqueInteger(uintptr_t P)
Get a declaration name from an opaque integer returned by getAsOpaqueInteger.
@ ak_nameddecl
NamedDecl *.
@ ak_declcontext
DeclContext *.
@ ak_addrspace
address space
@ ak_qualtype_pair
pair<QualType, QualType>
@ ak_attr_info
AttributeCommonInfo *.
@ ak_declarationname
DeclarationName.
@ ak_nestednamespec
NestedNameSpecifier *.
This represents one expression.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Represents a prototype with parameter type info, e.g.
ExtProtoInfo getExtProtoInfo() const
ArrayRef< QualType > param_types() const
FunctionType - C99 6.7.5.3 - Function Declarators.
StringRef getName() const
Return the actual identifier string.
An lvalue reference type, per C++11 [dcl.ref].
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getQualifiedNameAsString() const
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const
Pretty-print the unqualified name of this declaration.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
static NestedNameSpecifier getFromVoidPointer(const void *Ptr)
Represents a pointer to an Objective C object.
Sugar for parentheses used when specifying types.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
static QualType getFromOpaquePtr(const void *Ptr)
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
A qualifier set is used to build a set of qualifiers.
const Type * strip(QualType type)
Collect any qualifiers on the given type and return an unqualified type.
QualType apply(const ASTContext &Context, QualType QT) const
Apply the collected qualifiers to the given type.
The collection of all-type qualifiers we support.
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)
Returns the common set of qualifiers while removing them from the given sets.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
std::string getAsString() const
static Qualifiers fromOpaqueValue(uint64_t opaque)
static std::string getAddrSpaceAsString(LangAS AS)
An rvalue reference type, per C++11 [dcl.ref].
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
Represents a template argument.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
pack_iterator pack_end() const
Iterator referencing one past the last argument of a template argument pack.
const TemplateArgument * pack_iterator
Iterator that traverses the elements of a template argument pack.
pack_iterator pack_begin() const
Iterator referencing the first argument of a template argument pack.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getIntegralType() const
Retrieve the type of the integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
NamedDecl * getParam(unsigned Idx)
Represents a declaration of a type.
The base class of the type hierarchy.
bool isBooleanType() const
bool isPointerType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector type.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
QualType desugarForDiagnostic(ASTContext &Context, QualType QT, bool &ShouldAKA)
Returns a desugared version of the QualType, and marks ShouldAKA as true whenever we remove significa...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
void EscapeStringForDiagnostic(StringRef Str, SmallVectorImpl< char > &OutStr)
EscapeStringForDiagnostic - Append Str to the diagnostic buffer, escaping non-printable characters an...
LangAS
Defines the address space values used by the address space qualifier of QualType.
const char ToggleHighlight
Special character that the diagnostic printer will use to toggle the bold attribute.
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.
U cast(CodeGen::Address addr)
__INTPTR_TYPE__ intptr_t
A signed integer type with the property that any valid pointer to void can be converted to this type,...
Describes how types, statements, expressions, and declarations should be printed.
unsigned TemplateDiffUsed