22#include "llvm/ADT/StringExtras.h"
23#include "llvm/Support/raw_ostream.h"
43 if (
const UsingType *UT = dyn_cast<UsingType>(Ty)) {
48 if (
const ParenType *PT = dyn_cast<ParenType>(Ty)) {
59 dyn_cast<SubstTemplateTypeParmType>(Ty)) {
69 if (
const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) {
74 if (
const AutoType *AT = dyn_cast<AutoType>(Ty)) {
83 if (
const FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
84 bool DesugarReturn =
false;
85 QualType SugarRT = FT->getReturnType();
91 bool DesugarArgument =
false;
97 if (
auto nullability =
105 if (DesugarReturn || DesugarArgument) {
116 dyn_cast<TemplateSpecializationType>(Ty)) {
117 if (!TST->isTypeAlias()) {
118 bool DesugarArgument =
false;
128 if (DesugarArgument) {
131 TST->getTemplateName(), Args, QT);
137 if (
const auto *AT = dyn_cast<ArrayType>(Ty)) {
140 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
142 ElementTy, CAT->getSize(), CAT->getSizeExpr(),
143 CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());
144 else if (
const auto *VAT = dyn_cast<VariableArrayType>(AT))
146 ElementTy, VAT->getSizeExpr(), VAT->getSizeModifier(),
147 VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange());
148 else if (
const auto *DSAT = dyn_cast<DependentSizedArrayType>(AT))
150 ElementTy, DSAT->getSizeExpr(), DSAT->getSizeModifier(),
151 DSAT->getIndexTypeCVRQualifiers(), DSAT->getBracketsRange());
152 else if (
const auto *IAT = dyn_cast<IncompleteArrayType>(AT))
154 IAT->getIndexTypeCVRQualifiers());
156 llvm_unreachable(
"Unhandled array type");
174 bool IsSugar =
false;
176#define ABSTRACT_TYPE(Class, Base)
177#define TYPE(Class, Base) \
179const Class##Type *CTy = cast<Class##Type>(Ty); \
180if (CTy->isSugared()) { \
182Underlying = CTy->desugar(); \
186#include "clang/AST/TypeNodes.inc"
195 if (isa<VectorType>(Underlying))
200 if (
const TypedefType *QTT = dyn_cast<TypedefType>(QT))
201 if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl())
224 if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {
228 BaseType, Ty->getTypeArgsAsWritten(),
230 Ty->isKindOfTypeAsWritten());
234 return QC.
apply(Context, QT);
266 bool ForceAKA =
false;
271 for (
const intptr_t &QualTypeVal : QualTypeVals) {
279 if (CompareCanTy == CanTy)
282 bool ShouldAKA =
false;
285 std::string CompareDesugarStr =
287 if (CompareS != S && CompareDesugarStr != S)
290 std::string CompareCanS =
293 if (CompareCanS == CanS)
302 bool Repeated =
false;
303 for (
const auto &PrevArg : PrevArgs) {
318 bool ShouldAKA =
false;
320 if (ShouldAKA || ForceAKA) {
321 if (DesugaredTy == Ty) {
326 S =
"'" + S +
"' (aka '" + akaStr +
"')";
335 std::string DecoratedString;
336 llvm::raw_string_ostream OS(DecoratedString);
337 const char *Values = VTy->getNumElements() > 1 ?
"values" :
"value";
338 OS <<
"'" << S <<
"' (vector of " << VTy->getNumElements() <<
" '"
340 <<
"' " << Values <<
")";
341 return DecoratedString;
351 bool PrintFromType,
bool ElideType,
365 size_t OldEnd = Output.size();
366 llvm::raw_svector_ostream OS(Output);
367 bool NeedQuotes =
true;
370 default: llvm_unreachable(
"unknown ArgumentKind");
372 assert(Modifier.empty() && Argument.empty() &&
373 "Invalid modifier for Qualifiers argument");
377 OS << (Context.
getLangOpts().OpenCL ?
"default" :
"generic");
378 OS <<
" address space";
380 OS <<
"address space";
381 OS <<
" '" << S <<
"'";
387 assert(Modifier.empty() && Argument.empty() &&
388 "Invalid modifier for Qualifiers argument");
423 Modifier = StringRef();
424 Argument = StringRef();
429 assert(Modifier.empty() && Argument.empty() &&
430 "Invalid modifier for QualType argument");
438 if (Modifier ==
"objcclass" && Argument.empty())
440 else if (Modifier ==
"objcinstance" && Argument.empty())
443 assert(Modifier.empty() && Argument.empty() &&
444 "Invalid modifier for DeclarationName argument");
451 if (Modifier ==
"q" && Argument.empty())
454 assert(Modifier.empty() && Argument.empty() &&
455 "Invalid modifier for NamedDecl* argument");
470 assert(DC &&
"Should never have a null declaration context");
476 OS <<
"the global namespace";
478 OS <<
"the global scope";
480 OS <<
"block literal";
482 OS <<
"lambda expression";
486 PrevArgs, QualTypeVals);
488 assert(isa<NamedDecl>(DC) &&
"Expected a NamedDecl");
490 if (isa<NamespaceDecl>(ND))
492 else if (isa<ObjCMethodDecl>(ND))
494 else if (isa<FunctionDecl>(ND))
504 const Attr *At =
reinterpret_cast<Attr *
>(Val);
505 assert(At &&
"Received null Attr object!");
513 Output.insert(Output.begin()+OldEnd,
'\'');
514 Output.push_back(
'\'');
579 FromIntegerAndToDeclaration,
580 FromDeclarationAndToInteger
587 struct TemplateArgumentInfo {
591 bool IsValidInt =
false;
592 Expr *ArgExpr =
nullptr;
595 bool NeedAddressOf =
false;
596 bool IsNullPtr =
false;
597 bool IsDefault =
false;
607 unsigned NextNode = 0;
610 unsigned ChildNode = 0;
613 unsigned ParentNode = 0;
615 TemplateArgumentInfo FromArgInfo, ToArgInfo;
620 DiffNode(
unsigned ParentNode = 0) : ParentNode(ParentNode) {}
627 unsigned CurrentNode;
631 unsigned NextFreeNode;
637 DiffTree() : CurrentNode(0), NextFreeNode(1), ReadNode(0) {
638 FlatTree.push_back(DiffNode());
644 bool FromDefault,
bool ToDefault) {
645 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
646 FlatTree[CurrentNode].Kind = Template;
647 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
648 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
649 FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;
650 FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;
651 SetDefault(FromDefault, ToDefault);
656 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
657 FlatTree[CurrentNode].Kind =
Type;
658 FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;
659 FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;
660 SetDefault(FromDefault, ToDefault);
663 void SetExpressionDiff(
Expr *FromExpr,
Expr *ToExpr,
bool FromDefault,
665 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
667 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
668 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
669 SetDefault(FromDefault, ToDefault);
673 bool FromDefault,
bool ToDefault) {
674 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
675 FlatTree[CurrentNode].Kind = TemplateTemplate;
676 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
677 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
678 SetDefault(FromDefault, ToDefault);
681 void SetIntegerDiff(
const llvm::APSInt &FromInt,
const llvm::APSInt &ToInt,
682 bool IsValidFromInt,
bool IsValidToInt,
684 Expr *FromExpr,
Expr *ToExpr,
bool FromDefault,
686 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
687 FlatTree[CurrentNode].Kind =
Integer;
688 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
689 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
690 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
691 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
692 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
693 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
694 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
695 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
696 SetDefault(FromDefault, ToDefault);
700 bool FromAddressOf,
bool ToAddressOf,
701 bool FromNullPtr,
bool ToNullPtr,
Expr *FromExpr,
702 Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
703 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
705 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
706 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
707 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
708 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
709 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
710 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
711 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
712 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
713 SetDefault(FromDefault, ToDefault);
716 void SetFromDeclarationAndToIntegerDiff(
717 ValueDecl *FromValueDecl,
bool FromAddressOf,
bool FromNullPtr,
718 Expr *FromExpr,
const llvm::APSInt &ToInt,
bool IsValidToInt,
719 QualType ToIntType,
Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
720 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
721 FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger;
722 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
723 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
724 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
725 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
726 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
727 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
728 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
729 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
730 SetDefault(FromDefault, ToDefault);
733 void SetFromIntegerAndToDeclarationDiff(
734 const llvm::APSInt &FromInt,
bool IsValidFromInt,
QualType FromIntType,
736 bool ToNullPtr,
Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
737 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
738 FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration;
739 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
740 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
741 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
742 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
743 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
744 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
745 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
746 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
747 SetDefault(FromDefault, ToDefault);
751 void SetDefault(
bool FromDefault,
bool ToDefault) {
752 assert((!FromDefault || !ToDefault) &&
"Both arguments cannot be default.");
753 FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;
754 FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;
758 void SetSame(
bool Same) {
759 FlatTree[CurrentNode].Same =
Same;
763 void SetKind(DiffKind Kind) {
764 FlatTree[CurrentNode].Kind =
Kind;
769 assert(FlatTree[CurrentNode].Kind != Invalid &&
770 "Cannot exit node before setting node information.");
771 CurrentNode = FlatTree[CurrentNode].ParentNode;
777 assert(FlatTree[CurrentNode].Kind == Template &&
778 "Only Template nodes can have children nodes.");
779 FlatTree.push_back(DiffNode(CurrentNode));
780 DiffNode &
Node = FlatTree[CurrentNode];
781 if (
Node.ChildNode == 0) {
783 Node.ChildNode = NextFreeNode;
788 for (i =
Node.ChildNode; FlatTree[i].NextNode != 0;
789 i = FlatTree[i].NextNode) {
791 FlatTree[i].NextNode = NextFreeNode;
793 CurrentNode = NextFreeNode;
799 void StartTraverse() {
801 CurrentNode = NextFreeNode;
807 ReadNode = FlatTree[ReadNode].ParentNode;
812 assert(FlatTree[ReadNode].Kind == Template &&
"Unexpected kind.");
813 FromTD = FlatTree[ReadNode].FromArgInfo.TD;
814 ToTD = FlatTree[ReadNode].ToArgInfo.TD;
815 FromQual = FlatTree[ReadNode].FromArgInfo.Qual;
816 ToQual = FlatTree[ReadNode].ToArgInfo.Qual;
820 assert(FlatTree[ReadNode].Kind ==
Type &&
"Unexpected kind");
821 FromType = FlatTree[ReadNode].FromArgInfo.ArgType;
822 ToType = FlatTree[ReadNode].ToArgInfo.ArgType;
825 void GetExpressionDiff(
Expr *&FromExpr,
Expr *&ToExpr) {
826 assert(FlatTree[ReadNode].Kind ==
Expression &&
"Unexpected kind");
827 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
828 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
832 assert(FlatTree[ReadNode].Kind == TemplateTemplate &&
"Unexpected kind.");
833 FromTD = FlatTree[ReadNode].FromArgInfo.TD;
834 ToTD = FlatTree[ReadNode].ToArgInfo.TD;
837 void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
838 bool &IsValidFromInt,
bool &IsValidToInt,
841 assert(FlatTree[ReadNode].Kind == Integer &&
"Unexpected kind.");
842 FromInt = FlatTree[ReadNode].FromArgInfo.Val;
843 ToInt = FlatTree[ReadNode].ToArgInfo.Val;
844 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
845 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
846 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
847 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
848 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
849 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
853 bool &FromAddressOf,
bool &ToAddressOf,
854 bool &FromNullPtr,
bool &ToNullPtr,
Expr *&FromExpr,
856 assert(FlatTree[ReadNode].Kind == Declaration &&
"Unexpected kind.");
857 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
858 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
859 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
860 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
861 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
862 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
863 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
864 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
867 void GetFromDeclarationAndToIntegerDiff(
868 ValueDecl *&FromValueDecl,
bool &FromAddressOf,
bool &FromNullPtr,
869 Expr *&FromExpr, llvm::APSInt &ToInt,
bool &IsValidToInt,
871 assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger &&
873 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
874 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
875 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
876 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
877 ToInt = FlatTree[ReadNode].ToArgInfo.Val;
878 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
879 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
880 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
883 void GetFromIntegerAndToDeclarationDiff(
884 llvm::APSInt &FromInt,
bool &IsValidFromInt,
QualType &FromIntType,
886 bool &ToNullPtr,
Expr *&ToExpr) {
887 assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration &&
889 FromInt = FlatTree[ReadNode].FromArgInfo.Val;
890 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
891 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
892 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
893 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
894 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
895 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
896 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
901 return FlatTree[ReadNode].FromArgInfo.IsDefault;
906 return FlatTree[ReadNode].ToArgInfo.IsDefault;
911 return FlatTree[ReadNode].Same;
916 return FlatTree[ReadNode].ChildNode != 0;
921 ReadNode = FlatTree[ReadNode].ChildNode;
926 bool AdvanceSibling() {
927 if (FlatTree[ReadNode].NextNode == 0)
930 ReadNode = FlatTree[ReadNode].NextNode;
935 bool HasNextSibling() {
936 return FlatTree[ReadNode].NextNode != 0;
946 return FlatTree[ReadNode].Kind;
963 struct InternalIterator {
981 : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
995 if (CurrentTA != EndTA)
return;
1003 bool isValid()
const {
return TST; }
1006 bool isEnd()
const {
1007 assert(TST &&
"InternalIterator is invalid with a null TST.");
1012 InternalIterator &operator++() {
1013 assert(TST &&
"InternalIterator is invalid with a null TST.");
1019 if (CurrentTA != EndTA) {
1021 if (CurrentTA != EndTA)
1041 if (CurrentTA != EndTA)
1049 assert(TST &&
"InternalIterator is invalid with a null TST.");
1050 assert(!isEnd() &&
"Index exceeds number of arguments.");
1051 if (CurrentTA == EndTA)
1058 pointer operator->()
const {
1059 assert(TST &&
"InternalIterator is invalid with a null TST.");
1064 InternalIterator SugaredIterator;
1065 InternalIterator DesugaredIterator;
1069 : SugaredIterator(TST),
1071 (TST->isSugared() && !TST->isTypeAlias())
1072 ? GetTemplateSpecializationType(Context, TST->desugar())
1076 TSTiterator &operator++() {
1078 if (DesugaredIterator.isValid())
1079 ++DesugaredIterator;
1085 return *SugaredIterator;
1089 pointer operator->()
const {
1094 bool isEnd()
const {
1095 return SugaredIterator.isEnd();
1100 bool hasDesugaredTA()
const {
1101 return DesugaredIterator.isValid() && !DesugaredIterator.isEnd();
1105 reference getDesugaredTA()
const {
1106 assert(DesugaredIterator.isValid() &&
1107 "Desugared TemplateArgument should not be used.");
1108 return *DesugaredIterator;
1122 Ty = SubstType->getReplacementType();
1130 dyn_cast<ClassTemplateSpecializationDecl>(RT->
getDecl());
1154 FromArgTST = GetTemplateSpecializationType(Context, FromType);
1155 ToArgTST = GetTemplateSpecializationType(Context, ToType);
1157 if (!FromArgTST || !ToArgTST)
1160 if (!hasSameTemplate(Context, FromArgTST, ToArgTST))
1167 void DiffTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter) {
1168 QualType FromType = GetType(FromIter);
1171 bool FromDefault = FromIter.isEnd() && !FromType.
isNull();
1172 bool ToDefault = ToIter.isEnd() && !ToType.
isNull();
1176 if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {
1177 Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);
1181 assert(FromArgTST && ToArgTST &&
1182 "Both template specializations need to be valid.");
1189 FromQual, ToQual, FromDefault, ToDefault);
1190 DiffTemplate(FromArgTST, ToArgTST);
1196 void DiffTemplateTemplates(
const TSTiterator &FromIter,
1197 const TSTiterator &ToIter) {
1201 ToIter.isEnd() && ToDecl);
1207 static void InitializeNonTypeDiffVariables(
ASTContext &Context,
1208 const TSTiterator &
Iter,
1210 llvm::APSInt &
Value,
bool &HasInt,
1211 QualType &IntType,
bool &IsNullPtr,
1213 bool &NeedAddressOf) {
1214 if (!
Iter.isEnd()) {
1215 switch (
Iter->getKind()) {
1224 IntType =
Iter->getIntegralType();
1227 VD =
Iter->getAsDecl();
1232 NeedAddressOf =
true;
1239 E =
Iter->getAsExpr();
1245 llvm_unreachable(
"TemplateArgument kind is not expected for NTTP");
1247 llvm_unreachable(
"TemplateArgument kind should be handled elsewhere");
1249 }
else if (!
Default->isParameterPack()) {
1250 E =
Default->getDefaultArgument().getArgument().getAsExpr();
1253 if (!
Iter.hasDesugaredTA())
1273 NeedAddressOf =
true;
1290 llvm_unreachable(
"TemplateArgument kind is not expected for NTTP");
1292 llvm_unreachable(
"TemplateArgument kind should be handled elsewhere");
1294 llvm_unreachable(
"Unexpected TemplateArgument kind");
1299 void DiffNonTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter,
1302 Expr *FromExpr =
nullptr, *ToExpr =
nullptr;
1303 llvm::APSInt FromInt, ToInt;
1305 ValueDecl *FromValueDecl =
nullptr, *ToValueDecl =
nullptr;
1306 bool HasFromInt =
false, HasToInt =
false, FromNullPtr =
false,
1307 ToNullPtr =
false, NeedFromAddressOf =
false, NeedToAddressOf =
false;
1308 InitializeNonTypeDiffVariables(
1309 Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt,
1310 FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf);
1311 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt,
1312 HasToInt, ToIntType, ToNullPtr, ToExpr,
1313 ToValueDecl, NeedToAddressOf);
1315 bool FromDefault = FromIter.isEnd() &&
1316 (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);
1317 bool ToDefault = ToIter.isEnd() &&
1318 (ToExpr || ToValueDecl || HasToInt || ToNullPtr);
1320 bool FromDeclaration = FromValueDecl || FromNullPtr;
1321 bool ToDeclaration = ToValueDecl || ToNullPtr;
1323 if (FromDeclaration && HasToInt) {
1324 Tree.SetFromDeclarationAndToIntegerDiff(
1325 FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt,
1326 HasToInt, ToIntType, ToExpr, FromDefault, ToDefault);
1327 Tree.SetSame(
false);
1332 if (HasFromInt && ToDeclaration) {
1333 Tree.SetFromIntegerAndToDeclarationDiff(
1334 FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl,
1335 NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault);
1336 Tree.SetSame(
false);
1340 if (HasFromInt || HasToInt) {
1341 Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType,
1342 ToIntType, FromExpr, ToExpr, FromDefault, ToDefault);
1343 if (HasFromInt && HasToInt) {
1350 if (FromDeclaration || ToDeclaration) {
1351 Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf,
1352 NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1353 ToExpr, FromDefault, ToDefault);
1354 bool BothNull = FromNullPtr && ToNullPtr;
1355 bool SameValueDecl =
1356 FromValueDecl && ToValueDecl &&
1357 NeedFromAddressOf == NeedToAddressOf &&
1359 Tree.SetSame(BothNull || SameValueDecl);
1363 assert((FromExpr || ToExpr) &&
"Both template arguments cannot be empty.");
1364 Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault);
1365 Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));
1383 unsigned TotalArgs = 0;
1384 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST);
1385 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) {
1391 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->
size() - 1);
1392 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->
size() - 1);
1397 "Parameter Decl are not the same kind.");
1399 if (isa<TemplateTypeParmDecl>(FromParamND)) {
1400 DiffTypes(FromIter, ToIter);
1401 }
else if (isa<TemplateTemplateParmDecl>(FromParamND)) {
1402 DiffTemplateTemplates(FromIter, ToIter);
1403 }
else if (isa<NonTypeTemplateParmDecl>(FromParamND)) {
1405 cast<NonTypeTemplateParmDecl>(FromParamND);
1407 cast<NonTypeTemplateParmDecl>(ToParamND);
1408 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
1409 ToDefaultNonTypeDecl);
1411 llvm_unreachable(
"Unexpected Decl type.");
1421 static void makeTemplateList(
1425 TemplateList.push_back(TST);
1434 static bool hasSameBaseTemplate(
ASTContext &Context,
1447 static bool hasSameTemplate(
ASTContext &Context,
1451 if (hasSameBaseTemplate(Context, FromTST, ToTST))
1458 makeTemplateList(FromTemplateList, FromTST);
1459 makeTemplateList(ToTemplateList, ToTST);
1462 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(),
1463 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend();
1466 if (!hasSameBaseTemplate(Context, *FromIter, *ToIter))
1472 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) {
1473 if (!hasSameBaseTemplate(Context, *FromIter, *ToIter))
1477 FromTST = FromIter[-1];
1487 return Iter->getAsType();
1488 if (
Iter.hasDesugaredTA())
1489 return Iter.getDesugaredTA().getAsType();
1497 return Iter->getAsTemplate().getAsTemplateDecl();
1498 if (
Iter.hasDesugaredTA())
1499 return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();
1507 if (FromExpr == ToExpr)
1510 if (!FromExpr || !ToExpr)
1513 llvm::FoldingSetNodeID FromID, ToID;
1514 FromExpr->
Profile(FromID, Context,
true);
1515 ToExpr->
Profile(ToID, Context,
true);
1516 return FromID == ToID;
1524 void TreeToString(
int Indent = 1) {
1527 OS.indent(2 * Indent);
1533 switch (
Tree.GetKind()) {
1534 case DiffTree::Invalid:
1535 llvm_unreachable(
"Template diffing failed with bad DiffNode");
1536 case DiffTree::Type: {
1538 Tree.GetTypeDiff(FromType, ToType);
1539 PrintTypeNames(FromType, ToType,
Tree.FromDefault(),
Tree.ToDefault(),
1543 case DiffTree::Expression: {
1544 Expr *FromExpr, *ToExpr;
1545 Tree.GetExpressionDiff(FromExpr, ToExpr);
1546 PrintExpr(FromExpr, ToExpr,
Tree.FromDefault(),
Tree.ToDefault(),
1550 case DiffTree::TemplateTemplate: {
1552 Tree.GetTemplateTemplateDiff(FromTD, ToTD);
1553 PrintTemplateTemplate(FromTD, ToTD,
Tree.FromDefault(),
1554 Tree.ToDefault(),
Tree.NodeIsSame());
1557 case DiffTree::Integer: {
1558 llvm::APSInt FromInt, ToInt;
1559 Expr *FromExpr, *ToExpr;
1560 bool IsValidFromInt, IsValidToInt;
1562 Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,
1563 FromIntType, ToIntType, FromExpr, ToExpr);
1564 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType,
1565 ToIntType, FromExpr, ToExpr,
Tree.FromDefault(),
1566 Tree.ToDefault(),
Tree.NodeIsSame());
1569 case DiffTree::Declaration: {
1571 bool FromAddressOf, ToAddressOf;
1572 bool FromNullPtr, ToNullPtr;
1573 Expr *FromExpr, *ToExpr;
1574 Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,
1575 ToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1577 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
1578 FromNullPtr, ToNullPtr, FromExpr, ToExpr,
1579 Tree.FromDefault(),
Tree.ToDefault(),
Tree.NodeIsSame());
1582 case DiffTree::FromDeclarationAndToInteger: {
1591 Tree.GetFromDeclarationAndToIntegerDiff(
1592 FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt,
1593 IsValidToInt, ToIntType, ToExpr);
1594 assert((FromValueDecl || FromNullPtr) && IsValidToInt);
1595 PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr,
1596 FromExpr,
Tree.FromDefault(), ToInt, ToIntType,
1597 ToExpr,
Tree.ToDefault());
1600 case DiffTree::FromIntegerAndToDeclaration: {
1601 llvm::APSInt FromInt;
1602 bool IsValidFromInt;
1609 Tree.GetFromIntegerAndToDeclarationDiff(
1610 FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl,
1611 ToAddressOf, ToNullPtr, ToExpr);
1612 assert(IsValidFromInt && (ToValueDecl || ToNullPtr));
1613 PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr,
1614 Tree.FromDefault(), ToValueDecl, ToAddressOf,
1615 ToNullPtr, ToExpr,
Tree.ToDefault());
1618 case DiffTree::Template: {
1622 Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);
1624 PrintQualifiers(FromQual, ToQual);
1626 if (!
Tree.HasChildren()) {
1635 unsigned NumElideArgs = 0;
1636 bool AllArgsElided =
true;
1639 if (
Tree.NodeIsSame()) {
1643 AllArgsElided =
false;
1644 if (NumElideArgs > 0) {
1645 PrintElideArgs(NumElideArgs, Indent);
1650 TreeToString(Indent);
1651 if (
Tree.HasNextSibling())
1653 }
while (
Tree.AdvanceSibling());
1654 if (NumElideArgs > 0) {
1658 PrintElideArgs(NumElideArgs, Indent);
1674 assert(!IsBold &&
"Attempting to bold text that is already bold.");
1682 assert(IsBold &&
"Attempting to remove bold from unbold text.");
1694 bool FromDefault,
bool ToDefault,
bool Same) {
1696 "Only one template argument may be missing.");
1708 PrintQualifiers(FromQual, ToQual);
1713 std::string FromTypeStr = FromType.
isNull() ?
"(no argument)"
1715 std::string ToTypeStr = ToType.
isNull() ?
"(no argument)"
1719 if (FromTypeStr == ToTypeStr) {
1720 const auto *FromElTy = dyn_cast<ElaboratedType>(FromType),
1721 *ToElTy = dyn_cast<ElaboratedType>(ToType);
1722 if (FromElTy || ToElTy) {
1723 std::string FromNamedTypeStr =
1724 FromElTy ? FromElTy->getNamedType().getAsString(Policy)
1726 std::string ToNamedTypeStr =
1727 ToElTy ? ToElTy->getNamedType().getAsString(Policy) : ToTypeStr;
1728 if (FromNamedTypeStr != ToNamedTypeStr) {
1729 FromTypeStr = FromNamedTypeStr;
1730 ToTypeStr = ToNamedTypeStr;
1735 std::string FromCanTypeStr =
1738 if (FromCanTypeStr != ToCanTypeStr) {
1739 FromTypeStr = FromCanTypeStr;
1740 ToTypeStr = ToCanTypeStr;
1745 if (PrintTree) OS <<
'[';
1746 OS << (FromDefault ?
"(default) " :
"");
1751 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1761 void PrintExpr(
const Expr *FromExpr,
const Expr *ToExpr,
bool FromDefault,
1762 bool ToDefault,
bool Same) {
1763 assert((FromExpr || ToExpr) &&
1764 "Only one template argument may be missing.");
1766 PrintExpr(FromExpr);
1767 }
else if (!PrintTree) {
1768 OS << (FromDefault ?
"(default) " :
"");
1770 PrintExpr(FromExpr);
1773 OS << (FromDefault ?
"[(default) " :
"[");
1775 PrintExpr(FromExpr);
1777 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1786 void PrintExpr(
const Expr *
E) {
1791 OS <<
"(no argument)";
1797 bool FromDefault,
bool ToDefault,
bool Same) {
1798 assert((FromTD || ToTD) &&
"Only one template argument may be missing.");
1800 std::string FromName =
1801 std::string(FromTD ? FromTD->
getName() :
"(no argument)");
1802 std::string ToName = std::string(ToTD ? ToTD->
getName() :
"(no argument)");
1803 if (FromTD && ToTD && FromName == ToName) {
1810 }
else if (!PrintTree) {
1811 OS << (FromDefault ?
"(default) template " :
"template ");
1816 OS << (FromDefault ?
"[(default) template " :
"[template ");
1820 OS <<
" != " << (ToDefault ?
"(default) template " :
"template ");
1830 void PrintAPSInt(
const llvm::APSInt &FromInt,
const llvm::APSInt &ToInt,
1831 bool IsValidFromInt,
bool IsValidToInt,
QualType FromIntType,
1833 bool FromDefault,
bool ToDefault,
bool Same) {
1834 assert((IsValidFromInt || IsValidToInt) &&
1835 "Only one integral argument may be missing.");
1839 OS << ((FromInt == 0) ?
"false" :
"true");
1846 bool PrintType = IsValidFromInt && IsValidToInt &&
1850 OS << (FromDefault ?
"(default) " :
"");
1851 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1853 OS << (FromDefault ?
"[(default) " :
"[");
1854 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1855 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1856 PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType);
1863 void PrintAPSInt(
const llvm::APSInt &Val,
Expr *
E,
bool Valid,
1864 QualType IntType,
bool PrintType) {
1867 if (HasExtraInfo(
E)) {
1883 OS << ((Val == 0) ?
"false" :
"true");
1890 OS <<
"(no argument)";
1897 bool HasExtraInfo(
Expr *
E) {
1898 if (!
E)
return false;
1902 auto CheckIntegerLiteral = [](
Expr *
E) {
1903 if (
auto *TemplateExpr = dyn_cast<SubstNonTypeTemplateParmExpr>(
E))
1904 E = TemplateExpr->getReplacement();
1905 return isa<IntegerLiteral>(
E);
1908 if (CheckIntegerLiteral(
E))
return false;
1911 if (UO->getOpcode() == UO_Minus)
1912 if (CheckIntegerLiteral(UO->getSubExpr()))
1915 if (isa<CXXBoolLiteralExpr>(
E))
1921 void PrintValueDecl(
ValueDecl *VD,
bool AddressOf,
Expr *
E,
bool NullPtr) {
1925 else if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
1929 TPO->getType().getUnqualifiedType().print(OS, Policy);
1930 TPO->printAsInit(OS, Policy);
1938 if (
E && !isa<CXXNullPtrLiteralExpr>(
E)) {
1958 OS <<
"(no argument)";
1964 bool FromAddressOf,
bool ToAddressOf,
bool FromNullPtr,
1965 bool ToNullPtr,
Expr *FromExpr,
Expr *ToExpr,
1966 bool FromDefault,
bool ToDefault,
bool Same) {
1967 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
1968 "Only one Decl argument may be NULL");
1971 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1972 }
else if (!PrintTree) {
1973 OS << (FromDefault ?
"(default) " :
"");
1975 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1978 OS << (FromDefault ?
"[(default) " :
"[");
1980 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1982 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1984 PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr);
1992 void PrintValueDeclAndInteger(
ValueDecl *VD,
bool NeedAddressOf,
1993 bool IsNullPtr,
Expr *VDExpr,
bool DefaultDecl,
1994 const llvm::APSInt &Val,
QualType IntType,
1995 Expr *IntExpr,
bool DefaultInt) {
1997 OS << (DefaultDecl ?
"(default) " :
"");
1999 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
2002 OS << (DefaultDecl ?
"[(default) " :
"[");
2004 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
2006 OS <<
" != " << (DefaultInt ?
"(default) " :
"");
2007 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
2014 void PrintIntegerAndValueDecl(
const llvm::APSInt &Val,
QualType IntType,
2016 bool NeedAddressOf,
bool IsNullPtr,
2017 Expr *VDExpr,
bool DefaultDecl) {
2019 OS << (DefaultInt ?
"(default) " :
"");
2020 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
2022 OS << (DefaultInt ?
"[(default) " :
"[");
2023 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
2024 OS <<
" != " << (DefaultDecl ?
"(default) " :
"");
2026 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
2033 void PrintElideArgs(
unsigned NumElideArgs,
unsigned Indent) {
2036 for (
unsigned i = 0; i < Indent; ++i)
2039 if (NumElideArgs == 0)
return;
2040 if (NumElideArgs == 1)
2043 OS <<
"[" << NumElideArgs <<
" * ...]";
2053 if (FromQual == ToQual) {
2054 PrintQualifier(FromQual,
false);
2074 if (CommonQual.
empty() && FromQual.
empty()) {
2076 OS <<
"(no qualifiers) ";
2079 PrintQualifier(CommonQual,
false);
2080 PrintQualifier(FromQual,
true);
2085 OS <<
"(no qualifiers)";
2088 PrintQualifier(CommonQual,
false,
2090 PrintQualifier(ToQual,
true,
2095 PrintQualifier(CommonQual,
false);
2096 PrintQualifier(FromQual,
true);
2100 void PrintQualifier(
Qualifiers Q,
bool ApplyBold,
2101 bool AppendSpaceIfNonEmpty =
true) {
2102 if (Q.
empty())
return;
2103 if (ApplyBold)
Bold();
2104 Q.
print(OS, Policy, AppendSpaceIfNonEmpty);
2105 if (ApplyBold) Unbold();
2111 QualType ToType,
bool PrintTree,
bool PrintFromType,
2112 bool ElideType,
bool ShowColor)
2114 Policy(Context.getLangOpts()),
2115 ElideType(ElideType),
2116 PrintTree(PrintTree),
2117 ShowColor(ShowColor),
2119 FromTemplateType(PrintFromType ? FromType : ToType),
2120 ToTemplateType(PrintFromType ? ToType : FromType),
2126 void DiffTemplate() {
2131 GetTemplateSpecializationType(Context, FromTemplateType);
2133 GetTemplateSpecializationType(Context, ToTemplateType);
2136 if (!FromOrigTST || !ToOrigTST)
2140 if (!hasSameTemplate(Context, FromOrigTST, ToOrigTST)) {
2148 Tree.SetTemplateDiff(
2152 FromQual, ToQual,
false ,
false );
2154 DiffTemplate(FromOrigTST, ToOrigTST);
2161 Tree.StartTraverse();
2166 assert(!IsBold &&
"Bold is applied to end of string.");
2177 bool PrintFromType,
bool ElideType,
2180 PrintFromType =
true;
2181 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType,
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 getTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon=QualType()) const
QualType getBuiltinMSVaListType() const
Retrieve the type of the __builtin_ms_va_list type.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element 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 getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
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 getDependentSizedArrayType(QualType EltTy, Expr *NumElts, ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a dependently-sized array of the specified element type...
QualType getObjCIdType() const
Represents the Objective-CC id type.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
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
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_declarationname
DeclarationName.
@ ak_nestednamespec
NestedNameSpecifier *.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
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.
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.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
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 * getDecl() 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.
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...
bool isLambdaCallOperator(const CXXMethodDecl *MD)
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.
__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