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->getOriginalDecl()->getTypedefNameForAnonDecl() ==
211 QT = Context.getPointerType(
214 QT = Context.getObjCObjectPointerType(
217 QT = Context.getLValueReferenceType(
220 QT = Context.getRValueReferenceType(
223 if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {
226 QT = Context.getObjCObjectType(
227 BaseType, Ty->getTypeArgsAsWritten(),
228 ArrayRef(Ty->qual_begin(), Ty->getNumProtocols()),
229 Ty->isKindOfTypeAsWritten());
233 return QC.
apply(Context, QT);
265 bool ForceAKA =
false;
267 std::string S = Ty.
getAsString(Context.getPrintingPolicy());
268 std::string CanS = CanTy.
getAsString(Context.getPrintingPolicy());
270 for (
const intptr_t &QualTypeVal : QualTypeVals) {
278 if (CompareCanTy == CanTy)
280 std::string CompareS = CompareTy.
getAsString(Context.getPrintingPolicy());
281 bool ShouldAKA =
false;
284 std::string CompareDesugarStr =
285 CompareDesugar.
getAsString(Context.getPrintingPolicy());
286 if (CompareS != S && CompareDesugarStr != S)
289 std::string CompareCanS =
290 CompareCanTy.
getAsString(Context.getPrintingPolicy());
292 if (CompareCanS == CanS)
301 bool Repeated =
false;
302 for (
const auto &PrevArg : PrevArgs) {
317 bool ShouldAKA =
false;
319 if (ShouldAKA || ForceAKA) {
320 if (DesugaredTy == Ty) {
323 std::string akaStr = DesugaredTy.
getAsString(Context.getPrintingPolicy());
325 S =
"'" + S +
"' (aka '" + akaStr +
"')";
334 std::string DecoratedString;
335 llvm::raw_string_ostream OS(DecoratedString);
336 const char *Values = VTy->getNumElements() > 1 ?
"values" :
"value";
337 OS <<
"'" << S <<
"' (vector of " << VTy->getNumElements() <<
" '"
338 << VTy->getElementType().getAsString(Context.getPrintingPolicy())
339 <<
"' " << Values <<
")";
340 return DecoratedString;
350 bool PrintFromType,
bool ElideType,
351 bool ShowColors, raw_ostream &OS);
364 size_t OldEnd = Output.size();
365 llvm::raw_svector_ostream OS(Output);
366 bool NeedQuotes =
true;
369 default: llvm_unreachable(
"unknown ArgumentKind");
371 assert(Modifier.empty() && Argument.empty() &&
372 "Invalid modifier for Qualifiers argument");
376 OS << (Context.getLangOpts().
OpenCL ?
"default" :
"generic");
377 OS <<
" address space";
379 OS <<
"address space";
380 OS <<
" '" << S <<
"'";
386 assert(Modifier.empty() && Argument.empty() &&
387 "Invalid modifier for Qualifiers argument");
422 Modifier = StringRef();
423 Argument = StringRef();
428 assert(Modifier.empty() && Argument.empty() &&
429 "Invalid modifier for QualType argument");
437 if (Modifier ==
"objcclass" && Argument.empty())
439 else if (Modifier ==
"objcinstance" && Argument.empty())
442 assert(Modifier.empty() && Argument.empty() &&
443 "Invalid modifier for DeclarationName argument");
450 if (Modifier ==
"q" && Argument.empty())
453 assert(Modifier.empty() && Argument.empty() &&
454 "Invalid modifier for NamedDecl* argument");
463 .
print(OS, Context.getPrintingPolicy(),
469 assert(DC &&
"Should never have a null declaration context");
474 if (Context.getLangOpts().CPlusPlus)
475 OS <<
"the global namespace";
477 OS <<
"the global scope";
479 OS <<
"block literal";
481 OS <<
"lambda expression";
484 Context, Context.getTypeDeclType(
Type), PrevArgs, QualTypeVals);
502 const Attr *At =
reinterpret_cast<Attr *
>(Val);
503 assert(At &&
"Received null Attr object!");
517 const Expr *E =
reinterpret_cast<Expr *
>(Val);
518 assert(E &&
"Received null Expr!");
519 E->
printPretty(OS,
nullptr, Context.getPrintingPolicy());
524 assert(AT &&
"Received null AttributeCommonInfo object!");
539 Output.insert(Output.begin()+OldEnd,
'\'');
540 Output.push_back(
'\'');
605 FromIntegerAndToDeclaration,
606 FromDeclarationAndToInteger
613 struct TemplateArgumentInfo {
617 bool IsValidInt =
false;
618 Expr *ArgExpr =
nullptr;
619 TemplateDecl *TD =
nullptr;
620 ValueDecl *VD =
nullptr;
621 bool NeedAddressOf =
false;
622 bool IsNullPtr =
false;
623 bool IsDefault =
false;
633 unsigned NextNode = 0;
636 unsigned ChildNode = 0;
639 unsigned ParentNode = 0;
641 TemplateArgumentInfo FromArgInfo, ToArgInfo;
646 DiffNode(
unsigned ParentNode = 0) : ParentNode(ParentNode) {}
650 SmallVector<DiffNode, 16> FlatTree;
653 unsigned CurrentNode;
657 unsigned NextFreeNode;
663 DiffTree() : CurrentNode(0), NextFreeNode(1), ReadNode(0) {
664 FlatTree.push_back(DiffNode());
668 void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
669 Qualifiers FromQual, Qualifiers ToQual,
670 bool FromDefault,
bool ToDefault) {
671 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
672 FlatTree[CurrentNode].Kind = Template;
673 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
674 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
675 FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;
676 FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;
677 SetDefault(FromDefault, ToDefault);
680 void SetTypeDiff(QualType FromType, QualType ToType,
bool FromDefault,
682 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
683 FlatTree[CurrentNode].Kind = Type;
684 FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;
685 FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;
686 SetDefault(FromDefault, ToDefault);
689 void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr,
bool FromDefault,
691 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
692 FlatTree[CurrentNode].Kind = Expression;
693 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
694 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
695 SetDefault(FromDefault, ToDefault);
698 void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
699 bool FromDefault,
bool ToDefault) {
700 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
701 FlatTree[CurrentNode].Kind = TemplateTemplate;
702 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
703 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
704 SetDefault(FromDefault, ToDefault);
707 void SetIntegerDiff(
const llvm::APSInt &FromInt,
const llvm::APSInt &ToInt,
708 bool IsValidFromInt,
bool IsValidToInt,
709 QualType FromIntType, QualType ToIntType,
710 Expr *FromExpr, Expr *ToExpr,
bool FromDefault,
712 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
713 FlatTree[CurrentNode].Kind = Integer;
714 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
715 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
716 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
717 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
718 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
719 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
720 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
721 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
722 SetDefault(FromDefault, ToDefault);
725 void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
726 bool FromAddressOf,
bool ToAddressOf,
727 bool FromNullPtr,
bool ToNullPtr, Expr *FromExpr,
728 Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
729 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
730 FlatTree[CurrentNode].Kind = Declaration;
731 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
732 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
733 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
734 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
735 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
736 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
737 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
738 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
739 SetDefault(FromDefault, ToDefault);
742 void SetFromDeclarationAndToIntegerDiff(
743 ValueDecl *FromValueDecl,
bool FromAddressOf,
bool FromNullPtr,
744 Expr *FromExpr,
const llvm::APSInt &ToInt,
bool IsValidToInt,
745 QualType ToIntType, Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
746 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
747 FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger;
748 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
749 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
750 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
751 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
752 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
753 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
754 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
755 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
756 SetDefault(FromDefault, ToDefault);
759 void SetFromIntegerAndToDeclarationDiff(
760 const llvm::APSInt &FromInt,
bool IsValidFromInt, QualType FromIntType,
761 Expr *FromExpr, ValueDecl *ToValueDecl,
bool ToAddressOf,
762 bool ToNullPtr, Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
763 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
764 FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration;
765 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
766 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
767 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
768 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
769 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
770 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
771 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
772 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
773 SetDefault(FromDefault, ToDefault);
777 void SetDefault(
bool FromDefault,
bool ToDefault) {
778 assert((!FromDefault || !ToDefault) &&
"Both arguments cannot be default.");
779 FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;
780 FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;
784 void SetSame(
bool Same) {
785 FlatTree[CurrentNode].Same =
Same;
789 void SetKind(DiffKind Kind) {
790 FlatTree[CurrentNode].Kind =
Kind;
795 assert(FlatTree[CurrentNode].Kind != Invalid &&
796 "Cannot exit node before setting node information.");
797 CurrentNode = FlatTree[CurrentNode].ParentNode;
803 assert(FlatTree[CurrentNode].Kind == Template &&
804 "Only Template nodes can have children nodes.");
805 FlatTree.push_back(DiffNode(CurrentNode));
806 DiffNode &Node = FlatTree[CurrentNode];
807 if (Node.ChildNode == 0) {
809 Node.ChildNode = NextFreeNode;
814 for (i = Node.ChildNode; FlatTree[i].NextNode != 0;
815 i = FlatTree[i].NextNode) {
817 FlatTree[i].NextNode = NextFreeNode;
819 CurrentNode = NextFreeNode;
825 void StartTraverse() {
827 CurrentNode = NextFreeNode;
833 ReadNode = FlatTree[ReadNode].ParentNode;
836 void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD,
837 Qualifiers &FromQual, Qualifiers &ToQual) {
838 assert(FlatTree[ReadNode].Kind == Template &&
"Unexpected kind.");
839 FromTD = FlatTree[ReadNode].FromArgInfo.TD;
840 ToTD = FlatTree[ReadNode].ToArgInfo.TD;
841 FromQual = FlatTree[ReadNode].FromArgInfo.Qual;
842 ToQual = FlatTree[ReadNode].ToArgInfo.Qual;
845 void GetTypeDiff(QualType &FromType, QualType &ToType) {
846 assert(FlatTree[ReadNode].Kind == Type &&
"Unexpected kind");
847 FromType = FlatTree[ReadNode].FromArgInfo.ArgType;
848 ToType = FlatTree[ReadNode].ToArgInfo.ArgType;
851 void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) {
852 assert(FlatTree[ReadNode].Kind == Expression &&
"Unexpected kind");
853 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
854 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
857 void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {
858 assert(FlatTree[ReadNode].Kind == TemplateTemplate &&
"Unexpected kind.");
859 FromTD = FlatTree[ReadNode].FromArgInfo.TD;
860 ToTD = FlatTree[ReadNode].ToArgInfo.TD;
863 void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
864 bool &IsValidFromInt,
bool &IsValidToInt,
865 QualType &FromIntType, QualType &ToIntType,
866 Expr *&FromExpr, Expr *&ToExpr) {
867 assert(FlatTree[ReadNode].Kind == Integer &&
"Unexpected kind.");
868 FromInt = FlatTree[ReadNode].FromArgInfo.Val;
869 ToInt = FlatTree[ReadNode].ToArgInfo.Val;
870 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
871 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
872 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
873 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
874 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
875 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
878 void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,
879 bool &FromAddressOf,
bool &ToAddressOf,
880 bool &FromNullPtr,
bool &ToNullPtr, Expr *&FromExpr,
882 assert(FlatTree[ReadNode].Kind == Declaration &&
"Unexpected kind.");
883 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
884 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
885 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
886 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
887 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
888 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
889 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
890 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
893 void GetFromDeclarationAndToIntegerDiff(
894 ValueDecl *&FromValueDecl,
bool &FromAddressOf,
bool &FromNullPtr,
895 Expr *&FromExpr, llvm::APSInt &ToInt,
bool &IsValidToInt,
896 QualType &ToIntType, Expr *&ToExpr) {
897 assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger &&
899 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
900 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
901 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
902 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
903 ToInt = FlatTree[ReadNode].ToArgInfo.Val;
904 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
905 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
906 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
909 void GetFromIntegerAndToDeclarationDiff(
910 llvm::APSInt &FromInt,
bool &IsValidFromInt, QualType &FromIntType,
911 Expr *&FromExpr, ValueDecl *&ToValueDecl,
bool &ToAddressOf,
912 bool &ToNullPtr, Expr *&ToExpr) {
913 assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration &&
915 FromInt = FlatTree[ReadNode].FromArgInfo.Val;
916 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
917 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
918 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
919 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
920 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
921 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
922 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
927 return FlatTree[ReadNode].FromArgInfo.IsDefault;
932 return FlatTree[ReadNode].ToArgInfo.IsDefault;
937 return FlatTree[ReadNode].Same;
942 return FlatTree[ReadNode].ChildNode != 0;
947 ReadNode = FlatTree[ReadNode].ChildNode;
952 bool AdvanceSibling() {
953 if (FlatTree[ReadNode].NextNode == 0)
956 ReadNode = FlatTree[ReadNode].NextNode;
961 bool HasNextSibling() {
962 return FlatTree[ReadNode].NextNode != 0;
967 return GetKind() == Invalid;
972 return FlatTree[ReadNode].Kind;
983 typedef const TemplateArgument& reference;
984 typedef const TemplateArgument* pointer;
989 struct InternalIterator {
992 const TemplateSpecializationType *TST;
1006 InternalIterator(
const TemplateSpecializationType *TST)
1010 if (isEnd())
return;
1013 TemplateArgument TA = TST->template_arguments()[0];
1021 if (CurrentTA != EndTA)
return;
1029 bool isValid()
const {
return TST; }
1032 bool isEnd()
const {
1033 assert(TST &&
"InternalIterator is invalid with a null TST.");
1034 return Index >= TST->template_arguments().size();
1038 InternalIterator &operator++() {
1039 assert(TST &&
"InternalIterator is invalid with a null TST.");
1045 if (CurrentTA != EndTA) {
1047 if (CurrentTA != EndTA)
1054 if (++Index == TST->template_arguments().size())
1058 TemplateArgument TA = TST->template_arguments()[Index];
1067 if (CurrentTA != EndTA)
1075 assert(TST &&
"InternalIterator is invalid with a null TST.");
1076 assert(!isEnd() &&
"Index exceeds number of arguments.");
1077 if (CurrentTA == EndTA)
1078 return TST->template_arguments()[Index];
1084 pointer operator->()
const {
1085 assert(TST &&
"InternalIterator is invalid with a null TST.");
1090 InternalIterator SugaredIterator;
1091 InternalIterator DesugaredIterator;
1094 TSTiterator(ASTContext &Context,
const TemplateSpecializationType *TST)
1095 : SugaredIterator(TST),
1097 (TST->isSugared() && !TST->isTypeAlias())
1098 ? GetTemplateSpecializationType(Context, TST->desugar())
1102 TSTiterator &operator++() {
1104 if (DesugaredIterator.isValid())
1105 ++DesugaredIterator;
1111 return *SugaredIterator;
1115 pointer operator->()
const {
1120 bool isEnd()
const {
1121 return SugaredIterator.isEnd();
1126 bool hasDesugaredTA()
const {
1127 return DesugaredIterator.isValid() && !DesugaredIterator.isEnd();
1131 reference getDesugaredTA()
const {
1132 assert(DesugaredIterator.isValid() &&
1133 "Desugared TemplateArgument should not be used.");
1134 return *DesugaredIterator;
1141 static const TemplateSpecializationType *
1142 GetTemplateSpecializationType(ASTContext &Context, QualType Ty) {
1143 if (
const TemplateSpecializationType *TST =
1144 Ty->
getAs<TemplateSpecializationType>())
1147 if (
const auto* SubstType = Ty->
getAs<SubstTemplateTypeParmType>())
1148 Ty = SubstType->getReplacementType();
1150 const RecordType *RT = Ty->
getAs<RecordType>();
1155 const ClassTemplateSpecializationDecl *CTSD =
1156 dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl());
1161 Ty = Context.getTemplateSpecializationType(
1162 ElaboratedTypeKeyword::None,
1167 return Ty->
getAs<TemplateSpecializationType>();
1171 static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType,
1173 const TemplateSpecializationType *&FromArgTST,
1174 const TemplateSpecializationType *&ToArgTST) {
1178 if (Context.hasSameType(FromType, ToType))
1181 FromArgTST = GetTemplateSpecializationType(Context, FromType);
1182 ToArgTST = GetTemplateSpecializationType(Context, ToType);
1184 if (!FromArgTST || !ToArgTST)
1187 if (!hasSameTemplate(Context, FromArgTST, ToArgTST))
1194 void DiffTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter) {
1195 QualType FromType = GetType(FromIter);
1196 QualType ToType = GetType(ToIter);
1198 bool FromDefault = FromIter.isEnd() && !FromType.
isNull();
1199 bool ToDefault = ToIter.isEnd() && !ToType.
isNull();
1201 const TemplateSpecializationType *FromArgTST =
nullptr;
1202 const TemplateSpecializationType *ToArgTST =
nullptr;
1203 if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {
1204 Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);
1206 Context.hasSameType(FromType, ToType));
1208 assert(FromArgTST && ToArgTST &&
1209 "Both template specializations need to be valid.");
1212 FromQual -= QualType(FromArgTST, 0).getQualifiers();
1213 ToQual -= QualType(ToArgTST, 0).getQualifiers();
1214 Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(),
1215 ToArgTST->getTemplateName().getAsTemplateDecl(),
1216 FromQual, ToQual, FromDefault, ToDefault);
1217 DiffTemplate(FromArgTST, ToArgTST);
1223 void DiffTemplateTemplates(
const TSTiterator &FromIter,
1224 const TSTiterator &ToIter) {
1225 TemplateDecl *FromDecl = GetTemplateDecl(FromIter);
1226 TemplateDecl *ToDecl = GetTemplateDecl(ToIter);
1227 Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl,
1228 ToIter.isEnd() && ToDecl);
1229 Tree.SetSame(FromDecl && ToDecl &&
1234 static void InitializeNonTypeDiffVariables(ASTContext &Context,
1235 const TSTiterator &Iter,
1236 NonTypeTemplateParmDecl *
Default,
1237 llvm::APSInt &
Value,
bool &HasInt,
1238 QualType &IntType,
bool &IsNullPtr,
1239 Expr *&E, ValueDecl *&VD,
1240 bool &NeedAddressOf) {
1241 if (!Iter.isEnd()) {
1242 switch (Iter->getKind()) {
1249 Value = Iter->getAsIntegral();
1251 IntType = Iter->getIntegralType();
1254 VD = Iter->getAsDecl();
1255 QualType ArgType = Iter->getParamTypeForDecl();
1256 QualType VDType = VD->
getType();
1259 NeedAddressOf =
true;
1266 E = Iter->getAsExpr();
1272 llvm_unreachable(
"TemplateArgument kind is not expected for NTTP");
1274 llvm_unreachable(
"TemplateArgument kind should be handled elsewhere");
1276 }
else if (!
Default->isParameterPack()) {
1277 E =
Default->getDefaultArgument().getArgument().getAsExpr();
1280 if (!Iter.hasDesugaredTA())
1283 const TemplateArgument &TA = Iter.getDesugaredTA();
1297 QualType VDType = VD->
getType();
1300 NeedAddressOf =
true;
1317 llvm_unreachable(
"TemplateArgument kind is not expected for NTTP");
1319 llvm_unreachable(
"TemplateArgument kind should be handled elsewhere");
1321 llvm_unreachable(
"Unexpected TemplateArgument kind");
1326 void DiffNonTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter,
1327 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl,
1328 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) {
1329 Expr *FromExpr =
nullptr, *ToExpr =
nullptr;
1330 llvm::APSInt FromInt, ToInt;
1331 QualType FromIntType, ToIntType;
1332 ValueDecl *FromValueDecl =
nullptr, *ToValueDecl =
nullptr;
1333 bool HasFromInt =
false, HasToInt =
false, FromNullPtr =
false,
1334 ToNullPtr =
false, NeedFromAddressOf =
false, NeedToAddressOf =
false;
1335 InitializeNonTypeDiffVariables(
1336 Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt,
1337 FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf);
1338 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt,
1339 HasToInt, ToIntType, ToNullPtr, ToExpr,
1340 ToValueDecl, NeedToAddressOf);
1342 bool FromDefault = FromIter.isEnd() &&
1343 (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);
1344 bool ToDefault = ToIter.isEnd() &&
1345 (ToExpr || ToValueDecl || HasToInt || ToNullPtr);
1347 bool FromDeclaration = FromValueDecl || FromNullPtr;
1348 bool ToDeclaration = ToValueDecl || ToNullPtr;
1350 if (FromDeclaration && HasToInt) {
1351 Tree.SetFromDeclarationAndToIntegerDiff(
1352 FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt,
1353 HasToInt, ToIntType, ToExpr, FromDefault, ToDefault);
1354 Tree.SetSame(
false);
1359 if (HasFromInt && ToDeclaration) {
1360 Tree.SetFromIntegerAndToDeclarationDiff(
1361 FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl,
1362 NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault);
1363 Tree.SetSame(
false);
1367 if (HasFromInt || HasToInt) {
1368 Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType,
1369 ToIntType, FromExpr, ToExpr, FromDefault, ToDefault);
1370 if (HasFromInt && HasToInt) {
1371 Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) &&
1377 if (FromDeclaration || ToDeclaration) {
1378 Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf,
1379 NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1380 ToExpr, FromDefault, ToDefault);
1381 bool BothNull = FromNullPtr && ToNullPtr;
1382 bool SameValueDecl =
1383 FromValueDecl && ToValueDecl &&
1384 NeedFromAddressOf == NeedToAddressOf &&
1386 Tree.SetSame(BothNull || SameValueDecl);
1390 assert((FromExpr || ToExpr) &&
"Both template arguments cannot be empty.");
1391 Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault);
1392 Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));
1397 void DiffTemplate(
const TemplateSpecializationType *FromTST,
1398 const TemplateSpecializationType *ToTST) {
1402 TemplateParameterList *ParamsFrom =
1403 FromTST->getTemplateName()
1404 .getAsTemplateDecl(
true)
1405 ->getTemplateParameters();
1406 TemplateParameterList *ParamsTo =
1407 ToTST->getTemplateName()
1408 .getAsTemplateDecl(
true)
1409 ->getTemplateParameters();
1410 unsigned TotalArgs = 0;
1411 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST);
1412 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) {
1418 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->
size() - 1);
1419 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->
size() - 1);
1420 NamedDecl *FromParamND = ParamsFrom->
getParam(FromParamIndex);
1421 NamedDecl *ToParamND = ParamsTo->
getParam(ToParamIndex);
1424 "Parameter Decl are not the same kind.");
1427 DiffTypes(FromIter, ToIter);
1429 DiffTemplateTemplates(FromIter, ToIter);
1431 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl =
1433 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl =
1435 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
1436 ToDefaultNonTypeDecl);
1438 llvm_unreachable(
"Unexpected Decl type.");
1448 static void makeTemplateList(
1449 SmallVectorImpl<const TemplateSpecializationType *> &TemplateList,
1450 const TemplateSpecializationType *TST) {
1452 TemplateList.push_back(TST);
1453 if (!TST->isTypeAlias())
1455 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1461 static bool hasSameBaseTemplate(ASTContext &Context,
1462 const TemplateSpecializationType *FromTST,
1463 const TemplateSpecializationType *ToTST) {
1464 return Context.getCanonicalTemplateName(FromTST->getTemplateName(),
1466 Context.getCanonicalTemplateName(ToTST->getTemplateName(),
1474 static bool hasSameTemplate(ASTContext &Context,
1475 const TemplateSpecializationType *&FromTST,
1476 const TemplateSpecializationType *&ToTST) {
1478 if (hasSameBaseTemplate(Context, FromTST, ToTST))
1482 SmallVector<const TemplateSpecializationType*, 1> FromTemplateList,
1485 makeTemplateList(FromTemplateList, FromTST);
1486 makeTemplateList(ToTemplateList, ToTST);
1488 SmallVectorImpl<const TemplateSpecializationType *>::reverse_iterator
1489 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(),
1490 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend();
1493 if (!hasSameBaseTemplate(Context, *FromIter, *ToIter))
1499 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) {
1500 if (!hasSameBaseTemplate(Context, *FromIter, *ToIter))
1504 FromTST = FromIter[-1];
1512 static QualType GetType(
const TSTiterator &Iter) {
1514 return Iter->getAsType();
1515 if (Iter.hasDesugaredTA())
1516 return Iter.getDesugaredTA().getAsType();
1522 static TemplateDecl *GetTemplateDecl(
const TSTiterator &Iter) {
1524 return Iter->getAsTemplate().getAsTemplateDecl();
1525 if (Iter.hasDesugaredTA())
1526 return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();
1533 static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) {
1534 if (FromExpr == ToExpr)
1537 if (!FromExpr || !ToExpr)
1540 llvm::FoldingSetNodeID FromID, ToID;
1541 FromExpr->
Profile(FromID, Context,
true);
1542 ToExpr->
Profile(ToID, Context,
true);
1543 return FromID == ToID;
1551 void TreeToString(
int Indent = 1) {
1560 switch (Tree.GetKind()) {
1561 case DiffTree::Invalid:
1562 llvm_unreachable(
"Template diffing failed with bad DiffNode");
1563 case DiffTree::Type: {
1564 QualType FromType, ToType;
1565 Tree.GetTypeDiff(FromType, ToType);
1566 PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(),
1570 case DiffTree::Expression: {
1571 Expr *FromExpr, *ToExpr;
1572 Tree.GetExpressionDiff(FromExpr, ToExpr);
1573 PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
1577 case DiffTree::TemplateTemplate: {
1578 TemplateDecl *FromTD, *ToTD;
1579 Tree.GetTemplateTemplateDiff(FromTD, ToTD);
1580 PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(),
1581 Tree.ToDefault(), Tree.NodeIsSame());
1584 case DiffTree::Integer: {
1585 llvm::APSInt FromInt, ToInt;
1586 Expr *FromExpr, *ToExpr;
1587 bool IsValidFromInt, IsValidToInt;
1588 QualType FromIntType, ToIntType;
1589 Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,
1590 FromIntType, ToIntType, FromExpr, ToExpr);
1591 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType,
1592 ToIntType, FromExpr, ToExpr, Tree.FromDefault(),
1593 Tree.ToDefault(), Tree.NodeIsSame());
1596 case DiffTree::Declaration: {
1597 ValueDecl *FromValueDecl, *ToValueDecl;
1598 bool FromAddressOf, ToAddressOf;
1599 bool FromNullPtr, ToNullPtr;
1600 Expr *FromExpr, *ToExpr;
1601 Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,
1602 ToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1604 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
1605 FromNullPtr, ToNullPtr, FromExpr, ToExpr,
1606 Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
1609 case DiffTree::FromDeclarationAndToInteger: {
1610 ValueDecl *FromValueDecl;
1618 Tree.GetFromDeclarationAndToIntegerDiff(
1619 FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt,
1620 IsValidToInt, ToIntType, ToExpr);
1621 assert((FromValueDecl || FromNullPtr) && IsValidToInt);
1622 PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr,
1623 FromExpr, Tree.FromDefault(), ToInt, ToIntType,
1624 ToExpr, Tree.ToDefault());
1627 case DiffTree::FromIntegerAndToDeclaration: {
1628 llvm::APSInt FromInt;
1629 bool IsValidFromInt;
1630 QualType FromIntType;
1632 ValueDecl *ToValueDecl;
1636 Tree.GetFromIntegerAndToDeclarationDiff(
1637 FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl,
1638 ToAddressOf, ToNullPtr, ToExpr);
1639 assert(IsValidFromInt && (ToValueDecl || ToNullPtr));
1640 PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr,
1641 Tree.FromDefault(), ToValueDecl, ToAddressOf,
1642 ToNullPtr, ToExpr, Tree.ToDefault());
1645 case DiffTree::Template: {
1647 TemplateDecl *FromTD, *ToTD;
1648 Qualifiers FromQual, ToQual;
1649 Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);
1651 PrintQualifiers(FromQual, ToQual);
1653 if (!Tree.HasChildren()) {
1662 unsigned NumElideArgs = 0;
1663 bool AllArgsElided =
true;
1666 if (Tree.NodeIsSame()) {
1670 AllArgsElided =
false;
1671 if (NumElideArgs > 0) {
1672 PrintElideArgs(NumElideArgs,
Indent);
1678 if (Tree.HasNextSibling())
1680 }
while (Tree.AdvanceSibling());
1681 if (NumElideArgs > 0) {
1685 PrintElideArgs(NumElideArgs,
Indent);
1701 assert(!IsBold &&
"Attempting to bold text that is already bold.");
1709 assert(IsBold &&
"Attempting to remove bold from unbold text.");
1720 void PrintTypeNames(QualType FromType, QualType ToType,
1721 bool FromDefault,
bool ToDefault,
bool Same) {
1723 "Only one template argument may be missing.");
1735 PrintQualifiers(FromQual, ToQual);
1740 std::string FromTypeStr = FromType.
isNull() ?
"(no argument)"
1742 std::string ToTypeStr =
1745 if (FromTypeStr == ToTypeStr) {
1747 std::string FromCanTypeStr =
1750 if (FromCanTypeStr != ToCanTypeStr) {
1751 FromTypeStr = FromCanTypeStr;
1752 ToTypeStr = ToCanTypeStr;
1758 OS << (FromDefault ?
"(default) " :
"");
1763 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1773 void PrintExpr(
const Expr *FromExpr,
const Expr *ToExpr,
bool FromDefault,
1774 bool ToDefault,
bool Same) {
1775 assert((FromExpr || ToExpr) &&
1776 "Only one template argument may be missing.");
1778 PrintExpr(FromExpr);
1779 }
else if (!PrintTree) {
1780 OS << (FromDefault ?
"(default) " :
"");
1782 PrintExpr(FromExpr);
1785 OS << (FromDefault ?
"[(default) " :
"[");
1787 PrintExpr(FromExpr);
1789 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1798 void PrintExpr(
const Expr *E) {
1803 OS <<
"(no argument)";
1808 void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD,
1809 bool FromDefault,
bool ToDefault,
bool Same) {
1810 assert((FromTD || ToTD) &&
"Only one template argument may be missing.");
1812 std::string FromName =
1813 std::string(FromTD ? FromTD->
getName() :
"(no argument)");
1814 std::string ToName = std::string(ToTD ? ToTD->
getName() :
"(no argument)");
1815 if (FromTD && ToTD && FromName == ToName) {
1822 }
else if (!PrintTree) {
1823 OS << (FromDefault ?
"(default) template " :
"template ");
1828 OS << (FromDefault ?
"[(default) template " :
"[template ");
1832 OS <<
" != " << (ToDefault ?
"(default) template " :
"template ");
1842 void PrintAPSInt(
const llvm::APSInt &FromInt,
const llvm::APSInt &ToInt,
1843 bool IsValidFromInt,
bool IsValidToInt, QualType FromIntType,
1844 QualType ToIntType, Expr *FromExpr, Expr *ToExpr,
1845 bool FromDefault,
bool ToDefault,
bool Same) {
1846 assert((IsValidFromInt || IsValidToInt) &&
1847 "Only one integral argument may be missing.");
1851 OS << ((FromInt == 0) ?
"false" :
"true");
1858 bool PrintType = IsValidFromInt && IsValidToInt &&
1859 !Context.hasSameType(FromIntType, ToIntType);
1862 OS << (FromDefault ?
"(default) " :
"");
1863 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1865 OS << (FromDefault ?
"[(default) " :
"[");
1866 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1867 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1868 PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType);
1875 void PrintAPSInt(
const llvm::APSInt &Val, Expr *E,
bool Valid,
1876 QualType IntType,
bool PrintType) {
1879 if (HasExtraInfo(E)) {
1889 IntType.
print(OS, Context.getPrintingPolicy());
1895 OS << ((Val == 0) ?
"false" :
"true");
1902 OS <<
"(no argument)";
1909 bool HasExtraInfo(Expr *E) {
1910 if (!E)
return false;
1914 auto CheckIntegerLiteral = [](Expr *E) {
1915 if (
auto *TemplateExpr = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
1916 E = TemplateExpr->getReplacement();
1920 if (CheckIntegerLiteral(E))
return false;
1922 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E))
1923 if (UO->getOpcode() == UO_Minus)
1924 if (CheckIntegerLiteral(UO->getSubExpr()))
1933 void PrintValueDecl(ValueDecl *VD,
bool AddressOf, Expr *E,
bool NullPtr) {
1937 else if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
1941 TPO->getType().getUnqualifiedType().print(OS, Policy);
1942 TPO->printAsInit(OS, Policy);
1970 OS <<
"(no argument)";
1975 void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
1976 bool FromAddressOf,
bool ToAddressOf,
bool FromNullPtr,
1977 bool ToNullPtr, Expr *FromExpr, Expr *ToExpr,
1978 bool FromDefault,
bool ToDefault,
bool Same) {
1979 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
1980 "Only one Decl argument may be NULL");
1983 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1984 }
else if (!PrintTree) {
1985 OS << (FromDefault ?
"(default) " :
"");
1987 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1990 OS << (FromDefault ?
"[(default) " :
"[");
1992 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1994 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1996 PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr);
2004 void PrintValueDeclAndInteger(ValueDecl *VD,
bool NeedAddressOf,
2005 bool IsNullPtr, Expr *VDExpr,
bool DefaultDecl,
2006 const llvm::APSInt &Val, QualType IntType,
2007 Expr *IntExpr,
bool DefaultInt) {
2009 OS << (DefaultDecl ?
"(default) " :
"");
2011 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
2014 OS << (DefaultDecl ?
"[(default) " :
"[");
2016 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
2018 OS <<
" != " << (DefaultInt ?
"(default) " :
"");
2019 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
2026 void PrintIntegerAndValueDecl(
const llvm::APSInt &Val, QualType IntType,
2027 Expr *IntExpr,
bool DefaultInt, ValueDecl *VD,
2028 bool NeedAddressOf,
bool IsNullPtr,
2029 Expr *VDExpr,
bool DefaultDecl) {
2031 OS << (DefaultInt ?
"(default) " :
"");
2032 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
2034 OS << (DefaultInt ?
"[(default) " :
"[");
2035 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
2036 OS <<
" != " << (DefaultDecl ?
"(default) " :
"");
2038 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
2045 void PrintElideArgs(
unsigned NumElideArgs,
unsigned Indent) {
2048 for (
unsigned i = 0; i <
Indent; ++i)
2051 if (NumElideArgs == 0)
return;
2052 if (NumElideArgs == 1)
2055 OS <<
"[" << NumElideArgs <<
" * ...]";
2059 void PrintQualifiers(Qualifiers FromQual, Qualifiers ToQual) {
2065 if (FromQual == ToQual) {
2066 PrintQualifier(FromQual,
false);
2086 if (CommonQual.
empty() && FromQual.
empty()) {
2088 OS <<
"(no qualifiers) ";
2091 PrintQualifier(CommonQual,
false);
2092 PrintQualifier(FromQual,
true);
2097 OS <<
"(no qualifiers)";
2100 PrintQualifier(CommonQual,
false,
2102 PrintQualifier(ToQual,
true,
2107 PrintQualifier(CommonQual,
false);
2108 PrintQualifier(FromQual,
true);
2112 void PrintQualifier(Qualifiers Q,
bool ApplyBold,
2113 bool AppendSpaceIfNonEmpty =
true) {
2114 if (Q.
empty())
return;
2115 if (ApplyBold)
Bold();
2116 Q.
print(OS, Policy, AppendSpaceIfNonEmpty);
2117 if (ApplyBold) Unbold();
2122 TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType,
2123 QualType ToType,
bool PrintTree,
bool PrintFromType,
2124 bool ElideType,
bool ShowColor)
2126 Policy(Context.getLangOpts()),
2127 ElideType(ElideType),
2128 PrintTree(PrintTree),
2129 ShowColor(ShowColor),
2131 FromTemplateType(PrintFromType ? FromType : ToType),
2132 ToTemplateType(PrintFromType ? ToType : FromType),
2138 void DiffTemplate() {
2139 Qualifiers FromQual = FromTemplateType.getQualifiers(),
2140 ToQual = ToTemplateType.getQualifiers();
2142 const TemplateSpecializationType *FromOrigTST =
2143 GetTemplateSpecializationType(Context, FromTemplateType);
2144 const TemplateSpecializationType *ToOrigTST =
2145 GetTemplateSpecializationType(Context, ToTemplateType);
2148 if (!FromOrigTST || !ToOrigTST)
2152 if (!hasSameTemplate(Context, FromOrigTST, ToOrigTST)) {
2156 FromQual -= QualType(FromOrigTST, 0).getQualifiers();
2157 ToQual -= QualType(ToOrigTST, 0).getQualifiers();
2160 Tree.SetTemplateDiff(
2161 FromOrigTST->getTemplateName().getAsTemplateDecl(
2163 ToOrigTST->getTemplateName().getAsTemplateDecl(
true),
2164 FromQual, ToQual,
false ,
false );
2166 DiffTemplate(FromOrigTST, ToOrigTST);
2173 Tree.StartTraverse();
2178 assert(!IsBold &&
"Bold is applied to end of string.");
2189 bool PrintFromType,
bool ElideType,
2190 bool ShowColors, raw_ostream &OS) {
2192 PrintFromType =
true;
2193 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType,
2194 ElideType, ShowColors);
2201 if (
T->isChar8Type()) {
2202 assert(
Value <= 0xFF &&
"not a valid UTF-8 code unit");
2203 return Value <= 0x7F;
2205 if (
T->isChar16Type()) {
2206 assert(
Value <= 0xFFFF &&
"not a valid UTF-16 code unit");
2207 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value);
2209 assert(
T->isChar32Type());
2210 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value);
2213 if (!IsSingleCodeUnitCP(
Value,
T)) {
2214 llvm::raw_svector_ostream OS(Str);
2215 OS <<
"<" << llvm::format_hex(
Value, 1,
true) <<
">";
2216 return std::string(Str.begin(), Str.end());
2219 char Buffer[UNI_MAX_UTF8_BYTES_PER_CODE_POINT];
2221 [[maybe_unused]]
bool Converted = llvm::ConvertCodePointToUTF8(
Value, Ptr);
2222 assert(Converted &&
"trying to encode invalid code unit");
2224 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...
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
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.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
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