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)) {
56 dyn_cast<SubstTemplateTypeParmType>(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();
88 bool DesugarArgument =
false;
94 if (
auto nullability =
102 if (DesugarReturn || DesugarArgument) {
113 dyn_cast<TemplateSpecializationType>(Ty)) {
114 if (!TST->isTypeAlias()) {
115 bool DesugarArgument =
false;
125 if (DesugarArgument) {
128 TST->getKeyword(), TST->getTemplateName(), Args,
135 if (
const auto *AT = dyn_cast<ArrayType>(Ty)) {
138 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
140 ElementTy, CAT->getSize(), CAT->getSizeExpr(),
141 CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());
142 else if (
const auto *VAT = dyn_cast<VariableArrayType>(AT))
144 VAT->getSizeModifier(),
145 VAT->getIndexTypeCVRQualifiers());
146 else if (
const auto *DSAT = dyn_cast<DependentSizedArrayType>(AT))
148 ElementTy, DSAT->getSizeExpr(), DSAT->getSizeModifier(),
149 DSAT->getIndexTypeCVRQualifiers());
150 else if (
const auto *IAT = dyn_cast<IncompleteArrayType>(AT))
152 IAT->getIndexTypeCVRQualifiers());
154 llvm_unreachable(
"Unhandled array type");
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"
193 if (isa<VectorType>(Underlying))
198 if (
const TypedefType *QTT = dyn_cast<TypedefType>(QT))
199 if (UTT->getOriginalDecl()->getTypedefNameForAnonDecl() ==
223 if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {
227 BaseType, Ty->getTypeArgsAsWritten(),
228 ArrayRef(Ty->qual_begin(), Ty->getNumProtocols()),
229 Ty->isKindOfTypeAsWritten());
233 return QC.
apply(Context, QT);
265 bool ForceAKA =
false;
270 for (
const intptr_t &QualTypeVal : QualTypeVals) {
278 if (CompareCanTy == CanTy)
281 bool ShouldAKA =
false;
284 std::string CompareDesugarStr =
286 if (CompareS != S && CompareDesugarStr != S)
289 std::string CompareCanS =
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) {
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() <<
" '"
339 <<
"' " << Values <<
")";
340 return DecoratedString;
350 bool PrintFromType,
bool ElideType,
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");
469 assert(DC &&
"Should never have a null declaration context");
475 OS <<
"the global namespace";
477 OS <<
"the global scope";
479 OS <<
"block literal";
481 OS <<
"lambda expression";
486 assert(isa<NamedDecl>(DC) &&
"Expected a NamedDecl");
488 if (isa<NamespaceDecl>(ND))
490 else if (isa<ObjCMethodDecl>(ND))
492 else if (isa<FunctionDecl>(ND))
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!");
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;
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) {}
653 unsigned CurrentNode;
657 unsigned NextFreeNode;
663 DiffTree() : CurrentNode(0), NextFreeNode(1), ReadNode(0) {
664 FlatTree.push_back(DiffNode());
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);
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.");
693 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
694 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
695 SetDefault(FromDefault, ToDefault);
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,
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);
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.");
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,
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;
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;
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;
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,
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;
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,
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,
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;
972 return FlatTree[ReadNode].Kind;
989 struct InternalIterator {
1007 : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
1010 if (isEnd())
return;
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.");
1038 InternalIterator &operator++() {
1039 assert(TST &&
"InternalIterator is invalid with a null TST.");
1045 if (CurrentTA != EndTA) {
1047 if (CurrentTA != EndTA)
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)
1084 pointer operator->()
const {
1085 assert(TST &&
"InternalIterator is invalid with a null TST.");
1090 InternalIterator SugaredIterator;
1091 InternalIterator DesugaredIterator;
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;
1148 Ty = SubstType->getReplacementType();
1162 ElaboratedTypeKeyword::None,
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);
1198 bool FromDefault = FromIter.isEnd() && !FromType.
isNull();
1199 bool ToDefault = ToIter.isEnd() && !ToType.
isNull();
1203 if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {
1204 Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);
1208 assert(FromArgTST && ToArgTST &&
1209 "Both template specializations need to be valid.");
1216 FromQual, ToQual, FromDefault, ToDefault);
1217 DiffTemplate(FromArgTST, ToArgTST);
1223 void DiffTemplateTemplates(
const TSTiterator &FromIter,
1224 const TSTiterator &ToIter) {
1228 ToIter.isEnd() && ToDecl);
1234 static void InitializeNonTypeDiffVariables(
ASTContext &Context,
1235 const TSTiterator &
Iter,
1237 llvm::APSInt &
Value,
bool &HasInt,
1238 QualType &IntType,
bool &IsNullPtr,
1240 bool &NeedAddressOf) {
1241 if (!
Iter.isEnd()) {
1242 switch (
Iter->getKind()) {
1251 IntType =
Iter->getIntegralType();
1254 VD =
Iter->getAsDecl();
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())
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,
1329 Expr *FromExpr =
nullptr, *ToExpr =
nullptr;
1330 llvm::APSInt FromInt, ToInt;
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) {
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));
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);
1424 "Parameter Decl are not the same kind.");
1426 if (isa<TemplateTypeParmDecl>(FromParamND)) {
1427 DiffTypes(FromIter, ToIter);
1428 }
else if (isa<TemplateTemplateParmDecl>(FromParamND)) {
1429 DiffTemplateTemplates(FromIter, ToIter);
1430 }
else if (isa<NonTypeTemplateParmDecl>(FromParamND)) {
1432 cast<NonTypeTemplateParmDecl>(FromParamND);
1434 cast<NonTypeTemplateParmDecl>(ToParamND);
1435 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
1436 ToDefaultNonTypeDecl);
1438 llvm_unreachable(
"Unexpected Decl type.");
1448 static void makeTemplateList(
1452 TemplateList.push_back(TST);
1461 static bool hasSameBaseTemplate(
ASTContext &Context,
1474 static bool hasSameTemplate(
ASTContext &Context,
1478 if (hasSameBaseTemplate(Context, FromTST, ToTST))
1485 makeTemplateList(FromTemplateList, FromTST);
1486 makeTemplateList(ToTemplateList, ToTST);
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];
1514 return Iter->getAsType();
1515 if (
Iter.hasDesugaredTA())
1516 return Iter.getDesugaredTA().getAsType();
1524 return Iter->getAsTemplate().getAsTemplateDecl();
1525 if (
Iter.hasDesugaredTA())
1526 return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();
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) {
1554 OS.indent(2 * Indent);
1560 switch (
Tree.GetKind()) {
1561 case DiffTree::Invalid:
1562 llvm_unreachable(
"Template diffing failed with bad DiffNode");
1563 case DiffTree::Type: {
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: {
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;
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: {
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: {
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;
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: {
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);
1677 TreeToString(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.");
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)";
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,
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 &&
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)) {
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();
1917 return isa<IntegerLiteral>(
E);
1920 if (CheckIntegerLiteral(
E))
return false;
1923 if (UO->getOpcode() == UO_Minus)
1924 if (CheckIntegerLiteral(UO->getSubExpr()))
1927 if (isa<CXXBoolLiteralExpr>(
E))
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);
1950 if (
E && !isa<CXXNullPtrLiteralExpr>(
E)) {
1970 OS <<
"(no argument)";
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,
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 <<
" * ...]";
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();
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() {
2143 GetTemplateSpecializationType(Context, FromTemplateType);
2145 GetTemplateSpecializationType(Context, ToTemplateType);
2148 if (!FromOrigTST || !ToOrigTST)
2152 if (!hasSameTemplate(Context, FromOrigTST, ToOrigTST)) {
2160 Tree.SetTemplateDiff(
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,
2192 PrintFromType =
true;
2193 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType,
2202 assert(
Value <= 0xFF &&
"not a valid UTF-8 code unit");
2203 return Value <= 0x7F;
2206 assert(
Value <= 0xFFFF &&
"not a valid UTF-16 code unit");
2207 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value);
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.
const NamedDecl * FromDecl
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
QualType getBuiltinVaListType() const
Retrieve the type of the __builtin_va_list type.
QualType getObjCClassType() const
Represents the Objective-C Class type.
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType, const Attr *attr=nullptr) const
QualType getBuiltinMSVaListType() const
Retrieve the type of the __builtin_ms_va_list type.
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
TemplateName getCanonicalTemplateName(TemplateName Name, bool IgnoreDeduced=false) const
Retrieves the "canonical" template name that refers to a given template.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
const LangOptions & getLangOpts() const
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
QualType getObjCObjectType(QualType Base, ObjCProtocolDecl *const *Protocols, unsigned NumProtocols) const
Legacy interface: cannot provide type arguments or __kindof.
const clang::PrintingPolicy & getPrintingPolicy() const
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return a non-unique reference to the type for a variable array of the specified element type.
QualType getObjCIdType() const
Represents the Objective-CC id type.
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
QualType getTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T, ArrayRef< TemplateArgument > SpecifiedArgs, ArrayRef< TemplateArgument > CanonicalArgs, QualType Underlying=QualType()) const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return a non-unique reference to the type for a dependently-sized array of the specified element type...
QualType getIncompleteArrayType(QualType EltTy, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return a unique reference to the type for an incomplete array of the specified element type.
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...
An attributed type is a type to which a type attribute has been applied.
static std::optional< NullabilityKind > stripOuterNullability(QualType &T)
Strip off the top-level nullability annotation on the given type, if it's there.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Represents a class template specialization, which refers to a class template with a given set of temp...
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)
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents a pointer to an Objective C object.
Represents a class type in Objective C.
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].
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
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 the result of substituting a type for a template type parameter.
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.
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.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
Represents a type template specialization; the template must be a class template, a type alias templa...
QualType getAliasedType() const
Get the aliased type, if this is a specialization of a type alias template.
ArrayRef< TemplateArgument > template_arguments() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
bool isTypeAlias() const
Determine if this template specialization type is for a type alias template that has been substituted...
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.
bool isChar16Type() const
bool isChar32Type() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a GCC generic vector type.
The JSON file list parser is used to communicate input to InstallAPI.
QualType desugarForDiagnostic(ASTContext &Context, QualType QT, bool &ShouldAKA)
Returns a desugared version of the QualType, and marks ShouldAKA as true whenever we remove significa...
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ 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.
const FunctionProtoType * T
__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