22#include "llvm/ADT/StringExtras.h"
23#include "llvm/Support/raw_ostream.h"
42 if (
const UsingType *UT = dyn_cast<UsingType>(Ty)) {
47 if (
const ParenType *PT = dyn_cast<ParenType>(Ty)) {
58 dyn_cast<SubstTemplateTypeParmType>(Ty)) {
68 if (
const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) {
73 if (
const AutoType *AT = dyn_cast<AutoType>(Ty)) {
82 if (
const FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
83 bool DesugarReturn =
false;
84 QualType SugarRT = FT->getReturnType();
91 bool DesugarArgument =
false;
97 if (
auto nullability =
106 if (DesugarReturn || DesugarArgument) {
117 dyn_cast<TemplateSpecializationType>(Ty)) {
118 if (!TST->isTypeAlias()) {
119 bool DesugarArgument =
false;
129 if (DesugarArgument) {
132 TST->getTemplateName(), Args, QT);
138 if (
const auto *AT = dyn_cast<ArrayType>(Ty)) {
141 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
143 ElementTy, CAT->getSize(), CAT->getSizeExpr(),
144 CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());
145 else if (
const auto *VAT = dyn_cast<VariableArrayType>(AT))
147 ElementTy, VAT->getSizeExpr(), VAT->getSizeModifier(),
148 VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange());
149 else if (
const auto *DSAT = dyn_cast<DependentSizedArrayType>(AT))
151 ElementTy, DSAT->getSizeExpr(), DSAT->getSizeModifier(),
152 DSAT->getIndexTypeCVRQualifiers(), DSAT->getBracketsRange());
153 else if (
const auto *IAT = dyn_cast<IncompleteArrayType>(AT))
155 IAT->getIndexTypeCVRQualifiers());
157 llvm_unreachable(
"Unhandled array type");
175 bool IsSugar =
false;
177#define ABSTRACT_TYPE(Class, Base)
178#define TYPE(Class, Base) \
180const Class##Type *CTy = cast<Class##Type>(Ty); \
181if (CTy->isSugared()) { \
183Underlying = CTy->desugar(); \
187#include "clang/AST/TypeNodes.inc"
196 if (isa<VectorType>(Underlying))
201 if (
const TypedefType *QTT = dyn_cast<TypedefType>(QT))
202 if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl())
225 if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {
229 BaseType, Ty->getTypeArgsAsWritten(),
231 Ty->isKindOfTypeAsWritten());
235 return QC.
apply(Context, QT);
267 bool ForceAKA =
false;
272 for (
const intptr_t &QualTypeVal : QualTypeVals) {
280 if (CompareCanTy == CanTy)
283 bool ShouldAKA =
false;
286 std::string CompareDesugarStr =
288 if (CompareS != S && CompareDesugarStr != S)
291 std::string CompareCanS =
294 if (CompareCanS == CanS)
303 bool Repeated =
false;
304 for (
const auto &PrevArg : PrevArgs) {
319 bool ShouldAKA =
false;
321 if (ShouldAKA || ForceAKA) {
322 if (DesugaredTy == Ty) {
327 S =
"'" + S +
"' (aka '" + akaStr +
"')";
336 std::string DecoratedString;
337 llvm::raw_string_ostream
OS(DecoratedString);
338 const char *Values = VTy->getNumElements() > 1 ?
"values" :
"value";
339 OS <<
"'" << S <<
"' (vector of " << VTy->getNumElements() <<
" '"
341 <<
"' " << Values <<
")";
342 return DecoratedString;
352 bool PrintFromType,
bool ElideType,
366 size_t OldEnd = Output.size();
367 llvm::raw_svector_ostream
OS(Output);
368 bool NeedQuotes =
true;
371 default: llvm_unreachable(
"unknown ArgumentKind");
373 assert(Modifier.empty() && Argument.empty() &&
374 "Invalid modifier for Qualifiers argument");
378 OS << (Context.
getLangOpts().OpenCL ?
"default" :
"generic");
379 OS <<
" address space";
381 OS <<
"address space";
382 OS <<
" '" << S <<
"'";
388 assert(Modifier.empty() && Argument.empty() &&
389 "Invalid modifier for Qualifiers argument");
424 Modifier = StringRef();
425 Argument = StringRef();
430 assert(Modifier.empty() && Argument.empty() &&
431 "Invalid modifier for QualType argument");
439 if (Modifier ==
"objcclass" && Argument.empty())
441 else if (Modifier ==
"objcinstance" && Argument.empty())
444 assert(Modifier.empty() && Argument.empty() &&
445 "Invalid modifier for DeclarationName argument");
452 if (Modifier ==
"q" && Argument.empty())
455 assert(Modifier.empty() && Argument.empty() &&
456 "Invalid modifier for NamedDecl* argument");
471 assert(DC &&
"Should never have a null declaration context");
477 OS <<
"the global namespace";
479 OS <<
"the global scope";
481 OS <<
"block literal";
483 OS <<
"lambda expression";
487 PrevArgs, QualTypeVals);
489 assert(isa<NamedDecl>(DC) &&
"Expected a NamedDecl");
491 if (isa<NamespaceDecl>(ND))
493 else if (isa<ObjCMethodDecl>(ND))
495 else if (isa<FunctionDecl>(ND))
505 const Attr *At =
reinterpret_cast<Attr *
>(Val);
506 assert(At &&
"Received null Attr object!");
514 Output.insert(Output.begin()+OldEnd,
'\'');
515 Output.push_back(
'\'');
580 FromIntegerAndToDeclaration,
581 FromDeclarationAndToInteger
588 struct TemplateArgumentInfo {
592 bool IsValidInt =
false;
593 Expr *ArgExpr =
nullptr;
596 bool NeedAddressOf =
false;
597 bool IsNullPtr =
false;
598 bool IsDefault =
false;
608 unsigned NextNode = 0;
611 unsigned ChildNode = 0;
614 unsigned ParentNode = 0;
616 TemplateArgumentInfo FromArgInfo, ToArgInfo;
621 DiffNode(
unsigned ParentNode = 0) : ParentNode(ParentNode) {}
628 unsigned CurrentNode;
632 unsigned NextFreeNode;
638 DiffTree() : CurrentNode(0), NextFreeNode(1), ReadNode(0) {
639 FlatTree.push_back(DiffNode());
645 bool FromDefault,
bool ToDefault) {
646 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
647 FlatTree[CurrentNode].Kind = Template;
648 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
649 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
650 FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;
651 FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;
652 SetDefault(FromDefault, ToDefault);
657 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
658 FlatTree[CurrentNode].Kind =
Type;
659 FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;
660 FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;
661 SetDefault(FromDefault, ToDefault);
664 void SetExpressionDiff(
Expr *FromExpr,
Expr *ToExpr,
bool FromDefault,
666 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
668 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
669 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
670 SetDefault(FromDefault, ToDefault);
674 bool FromDefault,
bool ToDefault) {
675 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
676 FlatTree[CurrentNode].Kind = TemplateTemplate;
677 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
678 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
679 SetDefault(FromDefault, ToDefault);
682 void SetIntegerDiff(
const llvm::APSInt &FromInt,
const llvm::APSInt &ToInt,
683 bool IsValidFromInt,
bool IsValidToInt,
685 Expr *FromExpr,
Expr *ToExpr,
bool FromDefault,
687 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
688 FlatTree[CurrentNode].Kind =
Integer;
689 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
690 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
691 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
692 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
693 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
694 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
695 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
696 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
697 SetDefault(FromDefault, ToDefault);
701 bool FromAddressOf,
bool ToAddressOf,
702 bool FromNullPtr,
bool ToNullPtr,
Expr *FromExpr,
703 Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
704 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
706 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
707 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
708 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
709 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
710 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
711 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
712 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
713 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
714 SetDefault(FromDefault, ToDefault);
717 void SetFromDeclarationAndToIntegerDiff(
718 ValueDecl *FromValueDecl,
bool FromAddressOf,
bool FromNullPtr,
719 Expr *FromExpr,
const llvm::APSInt &ToInt,
bool IsValidToInt,
720 QualType ToIntType,
Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
721 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
722 FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger;
723 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
724 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
725 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
726 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
727 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
728 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
729 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
730 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
731 SetDefault(FromDefault, ToDefault);
734 void SetFromIntegerAndToDeclarationDiff(
735 const llvm::APSInt &FromInt,
bool IsValidFromInt,
QualType FromIntType,
737 bool ToNullPtr,
Expr *ToExpr,
bool FromDefault,
bool ToDefault) {
738 assert(FlatTree[CurrentNode].Kind == Invalid &&
"Node is not empty.");
739 FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration;
740 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
741 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
742 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
743 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
744 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
745 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
746 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
747 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
748 SetDefault(FromDefault, ToDefault);
752 void SetDefault(
bool FromDefault,
bool ToDefault) {
753 assert((!FromDefault || !ToDefault) &&
"Both arguments cannot be default.");
754 FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;
755 FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;
759 void SetSame(
bool Same) {
760 FlatTree[CurrentNode].Same =
Same;
764 void SetKind(DiffKind Kind) {
765 FlatTree[CurrentNode].Kind =
Kind;
770 assert(FlatTree[CurrentNode].Kind != Invalid &&
771 "Cannot exit node before setting node information.");
772 CurrentNode = FlatTree[CurrentNode].ParentNode;
778 assert(FlatTree[CurrentNode].Kind == Template &&
779 "Only Template nodes can have children nodes.");
780 FlatTree.push_back(DiffNode(CurrentNode));
781 DiffNode &
Node = FlatTree[CurrentNode];
782 if (
Node.ChildNode == 0) {
784 Node.ChildNode = NextFreeNode;
789 for (i =
Node.ChildNode; FlatTree[i].NextNode != 0;
790 i = FlatTree[i].NextNode) {
792 FlatTree[i].NextNode = NextFreeNode;
794 CurrentNode = NextFreeNode;
800 void StartTraverse() {
802 CurrentNode = NextFreeNode;
808 ReadNode = FlatTree[ReadNode].ParentNode;
813 assert(FlatTree[ReadNode].Kind == Template &&
"Unexpected kind.");
814 FromTD = FlatTree[ReadNode].FromArgInfo.TD;
815 ToTD = FlatTree[ReadNode].ToArgInfo.TD;
816 FromQual = FlatTree[ReadNode].FromArgInfo.Qual;
817 ToQual = FlatTree[ReadNode].ToArgInfo.Qual;
821 assert(FlatTree[ReadNode].Kind ==
Type &&
"Unexpected kind");
822 FromType = FlatTree[ReadNode].FromArgInfo.ArgType;
823 ToType = FlatTree[ReadNode].ToArgInfo.ArgType;
826 void GetExpressionDiff(
Expr *&FromExpr,
Expr *&ToExpr) {
827 assert(FlatTree[ReadNode].Kind ==
Expression &&
"Unexpected kind");
828 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
829 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
833 assert(FlatTree[ReadNode].Kind == TemplateTemplate &&
"Unexpected kind.");
834 FromTD = FlatTree[ReadNode].FromArgInfo.TD;
835 ToTD = FlatTree[ReadNode].ToArgInfo.TD;
838 void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
839 bool &IsValidFromInt,
bool &IsValidToInt,
842 assert(FlatTree[ReadNode].Kind == Integer &&
"Unexpected kind.");
843 FromInt = FlatTree[ReadNode].FromArgInfo.Val;
844 ToInt = FlatTree[ReadNode].ToArgInfo.Val;
845 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
846 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
847 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
848 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
849 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
850 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
854 bool &FromAddressOf,
bool &ToAddressOf,
855 bool &FromNullPtr,
bool &ToNullPtr,
Expr *&FromExpr,
857 assert(FlatTree[ReadNode].Kind == Declaration &&
"Unexpected kind.");
858 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
859 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
860 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
861 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
862 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
863 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
864 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
865 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
868 void GetFromDeclarationAndToIntegerDiff(
869 ValueDecl *&FromValueDecl,
bool &FromAddressOf,
bool &FromNullPtr,
870 Expr *&FromExpr, llvm::APSInt &ToInt,
bool &IsValidToInt,
872 assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger &&
874 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
875 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
876 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
877 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
878 ToInt = FlatTree[ReadNode].ToArgInfo.Val;
879 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
880 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
881 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
884 void GetFromIntegerAndToDeclarationDiff(
885 llvm::APSInt &FromInt,
bool &IsValidFromInt,
QualType &FromIntType,
887 bool &ToNullPtr,
Expr *&ToExpr) {
888 assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration &&
890 FromInt = FlatTree[ReadNode].FromArgInfo.Val;
891 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
892 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
893 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
894 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
895 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
896 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
897 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
902 return FlatTree[ReadNode].FromArgInfo.IsDefault;
907 return FlatTree[ReadNode].ToArgInfo.IsDefault;
912 return FlatTree[ReadNode].Same;
917 return FlatTree[ReadNode].ChildNode != 0;
922 ReadNode = FlatTree[ReadNode].ChildNode;
927 bool AdvanceSibling() {
928 if (FlatTree[ReadNode].NextNode == 0)
931 ReadNode = FlatTree[ReadNode].NextNode;
936 bool HasNextSibling() {
937 return FlatTree[ReadNode].NextNode != 0;
947 return FlatTree[ReadNode].Kind;
964 struct InternalIterator {
982 : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
996 if (CurrentTA != EndTA)
return;
1004 bool isValid()
const {
return TST; }
1007 bool isEnd()
const {
1008 assert(TST &&
"InternalIterator is invalid with a null TST.");
1013 InternalIterator &operator++() {
1014 assert(TST &&
"InternalIterator is invalid with a null TST.");
1020 if (CurrentTA != EndTA) {
1022 if (CurrentTA != EndTA)
1042 if (CurrentTA != EndTA)
1050 assert(TST &&
"InternalIterator is invalid with a null TST.");
1051 assert(!isEnd() &&
"Index exceeds number of arguments.");
1052 if (CurrentTA == EndTA)
1059 pointer operator->()
const {
1060 assert(TST &&
"InternalIterator is invalid with a null TST.");
1065 InternalIterator SugaredIterator;
1066 InternalIterator DesugaredIterator;
1070 : SugaredIterator(TST),
1072 (TST->isSugared() && !TST->isTypeAlias())
1073 ? GetTemplateSpecializationType(Context, TST->desugar())
1077 TSTiterator &operator++() {
1079 if (DesugaredIterator.isValid())
1080 ++DesugaredIterator;
1086 return *SugaredIterator;
1090 pointer operator->()
const {
1095 bool isEnd()
const {
1096 return SugaredIterator.isEnd();
1101 bool hasDesugaredTA()
const {
1102 return DesugaredIterator.isValid() && !DesugaredIterator.isEnd();
1106 reference getDesugaredTA()
const {
1107 assert(DesugaredIterator.isValid() &&
1108 "Desugared TemplateArgument should not be used.");
1109 return *DesugaredIterator;
1123 Ty = SubstType->getReplacementType();
1131 dyn_cast<ClassTemplateSpecializationDecl>(RT->
getDecl());
1155 FromArgTST = GetTemplateSpecializationType(Context, FromType);
1156 ToArgTST = GetTemplateSpecializationType(Context, ToType);
1158 if (!FromArgTST || !ToArgTST)
1161 if (!hasSameTemplate(FromArgTST, ToArgTST))
1168 void DiffTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter) {
1169 QualType FromType = GetType(FromIter);
1172 bool FromDefault = FromIter.isEnd() && !FromType.
isNull();
1173 bool ToDefault = ToIter.isEnd() && !ToType.
isNull();
1177 if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {
1178 Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);
1182 assert(FromArgTST && ToArgTST &&
1183 "Both template specializations need to be valid.");
1190 FromQual, ToQual, FromDefault, ToDefault);
1191 DiffTemplate(FromArgTST, ToArgTST);
1197 void DiffTemplateTemplates(
const TSTiterator &FromIter,
1198 const TSTiterator &ToIter) {
1202 ToIter.isEnd() && ToDecl);
1208 static void InitializeNonTypeDiffVariables(
ASTContext &Context,
1209 const TSTiterator &Iter,
1211 llvm::APSInt &
Value,
bool &HasInt,
1212 QualType &IntType,
bool &IsNullPtr,
1214 bool &NeedAddressOf) {
1215 if (!Iter.isEnd()) {
1216 switch (Iter->getKind()) {
1218 llvm_unreachable(
"unknown ArgumentKind");
1220 Value = Iter->getAsIntegral();
1222 IntType = Iter->getIntegralType();
1225 VD = Iter->getAsDecl();
1226 QualType ArgType = Iter->getParamTypeForDecl();
1230 NeedAddressOf =
true;
1237 E = Iter->getAsExpr();
1239 }
else if (!
Default->isParameterPack()) {
1240 E =
Default->getDefaultArgument();
1243 if (!Iter.hasDesugaredTA())
return;
1248 llvm_unreachable(
"unknown ArgumentKind");
1260 NeedAddressOf =
true;
1278 void DiffNonTypes(
const TSTiterator &FromIter,
const TSTiterator &ToIter,
1281 Expr *FromExpr =
nullptr, *ToExpr =
nullptr;
1282 llvm::APSInt FromInt, ToInt;
1284 ValueDecl *FromValueDecl =
nullptr, *ToValueDecl =
nullptr;
1285 bool HasFromInt =
false, HasToInt =
false, FromNullPtr =
false,
1286 ToNullPtr =
false, NeedFromAddressOf =
false, NeedToAddressOf =
false;
1287 InitializeNonTypeDiffVariables(
1288 Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt,
1289 FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf);
1290 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt,
1291 HasToInt, ToIntType, ToNullPtr, ToExpr,
1292 ToValueDecl, NeedToAddressOf);
1294 bool FromDefault = FromIter.isEnd() &&
1295 (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);
1296 bool ToDefault = ToIter.isEnd() &&
1297 (ToExpr || ToValueDecl || HasToInt || ToNullPtr);
1299 bool FromDeclaration = FromValueDecl || FromNullPtr;
1300 bool ToDeclaration = ToValueDecl || ToNullPtr;
1302 if (FromDeclaration && HasToInt) {
1303 Tree.SetFromDeclarationAndToIntegerDiff(
1304 FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt,
1305 HasToInt, ToIntType, ToExpr, FromDefault, ToDefault);
1306 Tree.SetSame(
false);
1311 if (HasFromInt && ToDeclaration) {
1312 Tree.SetFromIntegerAndToDeclarationDiff(
1313 FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl,
1314 NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault);
1315 Tree.SetSame(
false);
1319 if (HasFromInt || HasToInt) {
1320 Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType,
1321 ToIntType, FromExpr, ToExpr, FromDefault, ToDefault);
1322 if (HasFromInt && HasToInt) {
1329 if (FromDeclaration || ToDeclaration) {
1330 Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf,
1331 NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1332 ToExpr, FromDefault, ToDefault);
1333 bool BothNull = FromNullPtr && ToNullPtr;
1334 bool SameValueDecl =
1335 FromValueDecl && ToValueDecl &&
1336 NeedFromAddressOf == NeedToAddressOf &&
1338 Tree.SetSame(BothNull || SameValueDecl);
1342 assert((FromExpr || ToExpr) &&
"Both template arguments cannot be empty.");
1343 Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault);
1344 Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));
1356 unsigned TotalArgs = 0;
1357 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST);
1358 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) {
1364 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->
size() - 1);
1365 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->
size() - 1);
1370 "Parameter Decl are not the same kind.");
1372 if (isa<TemplateTypeParmDecl>(FromParamND)) {
1373 DiffTypes(FromIter, ToIter);
1374 }
else if (isa<TemplateTemplateParmDecl>(FromParamND)) {
1375 DiffTemplateTemplates(FromIter, ToIter);
1376 }
else if (isa<NonTypeTemplateParmDecl>(FromParamND)) {
1378 cast<NonTypeTemplateParmDecl>(FromParamND);
1380 cast<NonTypeTemplateParmDecl>(ToParamND);
1381 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
1382 ToDefaultNonTypeDecl);
1384 llvm_unreachable(
"Unexpected Decl type.");
1394 static void makeTemplateList(
1398 TemplateList.push_back(TST);
1420 if (hasSameBaseTemplate(FromTST, ToTST))
1427 makeTemplateList(FromTemplateList, FromTST);
1428 makeTemplateList(ToTemplateList, ToTST);
1431 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(),
1432 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend();
1435 if (!hasSameBaseTemplate(*FromIter, *ToIter))
1441 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) {
1442 if (!hasSameBaseTemplate(*FromIter, *ToIter))
1446 FromTST = FromIter[-1];
1454 static QualType GetType(
const TSTiterator &Iter) {
1456 return Iter->getAsType();
1457 if (Iter.hasDesugaredTA())
1458 return Iter.getDesugaredTA().getAsType();
1464 static TemplateDecl *GetTemplateDecl(
const TSTiterator &Iter) {
1466 return Iter->getAsTemplate().getAsTemplateDecl();
1467 if (Iter.hasDesugaredTA())
1468 return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();
1476 if (FromExpr == ToExpr)
1479 if (!FromExpr || !ToExpr)
1482 llvm::FoldingSetNodeID FromID, ToID;
1483 FromExpr->
Profile(FromID, Context,
true);
1484 ToExpr->
Profile(ToID, Context,
true);
1485 return FromID == ToID;
1493 void TreeToString(
int Indent = 1) {
1496 OS.indent(2 * Indent);
1502 switch (
Tree.GetKind()) {
1503 case DiffTree::Invalid:
1504 llvm_unreachable(
"Template diffing failed with bad DiffNode");
1505 case DiffTree::Type: {
1507 Tree.GetTypeDiff(FromType, ToType);
1508 PrintTypeNames(FromType, ToType,
Tree.FromDefault(),
Tree.ToDefault(),
1512 case DiffTree::Expression: {
1513 Expr *FromExpr, *ToExpr;
1514 Tree.GetExpressionDiff(FromExpr, ToExpr);
1515 PrintExpr(FromExpr, ToExpr,
Tree.FromDefault(),
Tree.ToDefault(),
1519 case DiffTree::TemplateTemplate: {
1521 Tree.GetTemplateTemplateDiff(FromTD, ToTD);
1522 PrintTemplateTemplate(FromTD, ToTD,
Tree.FromDefault(),
1523 Tree.ToDefault(),
Tree.NodeIsSame());
1526 case DiffTree::Integer: {
1527 llvm::APSInt FromInt, ToInt;
1528 Expr *FromExpr, *ToExpr;
1529 bool IsValidFromInt, IsValidToInt;
1531 Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,
1532 FromIntType, ToIntType, FromExpr, ToExpr);
1533 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType,
1534 ToIntType, FromExpr, ToExpr,
Tree.FromDefault(),
1535 Tree.ToDefault(),
Tree.NodeIsSame());
1538 case DiffTree::Declaration: {
1540 bool FromAddressOf, ToAddressOf;
1541 bool FromNullPtr, ToNullPtr;
1542 Expr *FromExpr, *ToExpr;
1543 Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,
1544 ToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
1546 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
1547 FromNullPtr, ToNullPtr, FromExpr, ToExpr,
1548 Tree.FromDefault(),
Tree.ToDefault(),
Tree.NodeIsSame());
1551 case DiffTree::FromDeclarationAndToInteger: {
1560 Tree.GetFromDeclarationAndToIntegerDiff(
1561 FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt,
1562 IsValidToInt, ToIntType, ToExpr);
1563 assert((FromValueDecl || FromNullPtr) && IsValidToInt);
1564 PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr,
1565 FromExpr,
Tree.FromDefault(), ToInt, ToIntType,
1566 ToExpr,
Tree.ToDefault());
1569 case DiffTree::FromIntegerAndToDeclaration: {
1570 llvm::APSInt FromInt;
1571 bool IsValidFromInt;
1578 Tree.GetFromIntegerAndToDeclarationDiff(
1579 FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl,
1580 ToAddressOf, ToNullPtr, ToExpr);
1581 assert(IsValidFromInt && (ToValueDecl || ToNullPtr));
1582 PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr,
1583 Tree.FromDefault(), ToValueDecl, ToAddressOf,
1584 ToNullPtr, ToExpr,
Tree.ToDefault());
1587 case DiffTree::Template: {
1591 Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);
1593 PrintQualifiers(FromQual, ToQual);
1595 if (!
Tree.HasChildren()) {
1604 unsigned NumElideArgs = 0;
1605 bool AllArgsElided =
true;
1608 if (
Tree.NodeIsSame()) {
1612 AllArgsElided =
false;
1613 if (NumElideArgs > 0) {
1614 PrintElideArgs(NumElideArgs, Indent);
1619 TreeToString(Indent);
1620 if (
Tree.HasNextSibling())
1622 }
while (
Tree.AdvanceSibling());
1623 if (NumElideArgs > 0) {
1627 PrintElideArgs(NumElideArgs, Indent);
1643 assert(!IsBold &&
"Attempting to bold text that is already bold.");
1651 assert(IsBold &&
"Attempting to remove bold from unbold text.");
1663 bool FromDefault,
bool ToDefault,
bool Same) {
1665 "Only one template argument may be missing.");
1677 PrintQualifiers(FromQual, ToQual);
1682 std::string FromTypeStr = FromType.
isNull() ?
"(no argument)"
1684 std::string ToTypeStr = ToType.
isNull() ?
"(no argument)"
1688 if (FromTypeStr == ToTypeStr) {
1689 const auto *FromElTy = dyn_cast<ElaboratedType>(FromType),
1690 *ToElTy = dyn_cast<ElaboratedType>(ToType);
1691 if (FromElTy || ToElTy) {
1692 std::string FromNamedTypeStr =
1693 FromElTy ? FromElTy->getNamedType().getAsString(Policy)
1695 std::string ToNamedTypeStr =
1696 ToElTy ? ToElTy->getNamedType().getAsString(Policy) : ToTypeStr;
1697 if (FromNamedTypeStr != ToNamedTypeStr) {
1698 FromTypeStr = FromNamedTypeStr;
1699 ToTypeStr = ToNamedTypeStr;
1704 std::string FromCanTypeStr =
1707 if (FromCanTypeStr != ToCanTypeStr) {
1708 FromTypeStr = FromCanTypeStr;
1709 ToTypeStr = ToCanTypeStr;
1714 if (PrintTree)
OS <<
'[';
1715 OS << (FromDefault ?
"(default) " :
"");
1720 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1730 void PrintExpr(
const Expr *FromExpr,
const Expr *ToExpr,
bool FromDefault,
1731 bool ToDefault,
bool Same) {
1732 assert((FromExpr || ToExpr) &&
1733 "Only one template argument may be missing.");
1735 PrintExpr(FromExpr);
1736 }
else if (!PrintTree) {
1737 OS << (FromDefault ?
"(default) " :
"");
1739 PrintExpr(FromExpr);
1742 OS << (FromDefault ?
"[(default) " :
"[");
1744 PrintExpr(FromExpr);
1746 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1755 void PrintExpr(
const Expr *E) {
1760 OS <<
"(no argument)";
1766 bool FromDefault,
bool ToDefault,
bool Same) {
1767 assert((FromTD || ToTD) &&
"Only one template argument may be missing.");
1769 std::string FromName =
1770 std::string(FromTD ? FromTD->
getName() :
"(no argument)");
1771 std::string ToName = std::string(ToTD ? ToTD->
getName() :
"(no argument)");
1772 if (FromTD && ToTD && FromName == ToName) {
1779 }
else if (!PrintTree) {
1780 OS << (FromDefault ?
"(default) template " :
"template ");
1785 OS << (FromDefault ?
"[(default) template " :
"[template ");
1789 OS <<
" != " << (ToDefault ?
"(default) template " :
"template ");
1799 void PrintAPSInt(
const llvm::APSInt &FromInt,
const llvm::APSInt &ToInt,
1800 bool IsValidFromInt,
bool IsValidToInt,
QualType FromIntType,
1802 bool FromDefault,
bool ToDefault,
bool Same) {
1803 assert((IsValidFromInt || IsValidToInt) &&
1804 "Only one integral argument may be missing.");
1808 OS << ((FromInt == 0) ?
"false" :
"true");
1815 bool PrintType = IsValidFromInt && IsValidToInt &&
1819 OS << (FromDefault ?
"(default) " :
"");
1820 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1822 OS << (FromDefault ?
"[(default) " :
"[");
1823 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
1824 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1825 PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType);
1832 void PrintAPSInt(
const llvm::APSInt &Val,
Expr *E,
bool Valid,
1833 QualType IntType,
bool PrintType) {
1836 if (HasExtraInfo(E)) {
1852 OS << ((Val == 0) ?
"false" :
"true");
1859 OS <<
"(no argument)";
1866 bool HasExtraInfo(
Expr *E) {
1867 if (!E)
return false;
1871 if (isa<IntegerLiteral>(E))
return false;
1874 if (UO->getOpcode() == UO_Minus)
1875 if (isa<IntegerLiteral>(UO->getSubExpr()))
1878 if (isa<CXXBoolLiteralExpr>(E))
1884 void PrintValueDecl(
ValueDecl *VD,
bool AddressOf,
Expr *E,
bool NullPtr) {
1888 else if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
1892 TPO->printAsInit(OS, Policy);
1900 if (E && !isa<CXXNullPtrLiteralExpr>(E)) {
1915 OS <<
"(no argument)";
1921 bool FromAddressOf,
bool ToAddressOf,
bool FromNullPtr,
1922 bool ToNullPtr,
Expr *FromExpr,
Expr *ToExpr,
1923 bool FromDefault,
bool ToDefault,
bool Same) {
1924 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
1925 "Only one Decl argument may be NULL");
1928 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1929 }
else if (!PrintTree) {
1930 OS << (FromDefault ?
"(default) " :
"");
1932 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1935 OS << (FromDefault ?
"[(default) " :
"[");
1937 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
1939 OS <<
" != " << (ToDefault ?
"(default) " :
"");
1941 PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr);
1949 void PrintValueDeclAndInteger(
ValueDecl *VD,
bool NeedAddressOf,
1950 bool IsNullPtr,
Expr *VDExpr,
bool DefaultDecl,
1951 const llvm::APSInt &Val,
QualType IntType,
1952 Expr *IntExpr,
bool DefaultInt) {
1954 OS << (DefaultDecl ?
"(default) " :
"");
1956 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
1959 OS << (DefaultDecl ?
"[(default) " :
"[");
1961 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
1963 OS <<
" != " << (DefaultInt ?
"(default) " :
"");
1964 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
1971 void PrintIntegerAndValueDecl(
const llvm::APSInt &Val,
QualType IntType,
1973 bool NeedAddressOf,
bool IsNullPtr,
1974 Expr *VDExpr,
bool DefaultDecl) {
1976 OS << (DefaultInt ?
"(default) " :
"");
1977 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
1979 OS << (DefaultInt ?
"[(default) " :
"[");
1980 PrintAPSInt(Val, IntExpr,
true , IntType,
false );
1981 OS <<
" != " << (DefaultDecl ?
"(default) " :
"");
1983 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
1990 void PrintElideArgs(
unsigned NumElideArgs,
unsigned Indent) {
1993 for (
unsigned i = 0; i < Indent; ++i)
1996 if (NumElideArgs == 0)
return;
1997 if (NumElideArgs == 1)
2000 OS <<
"[" << NumElideArgs <<
" * ...]";
2010 if (FromQual == ToQual) {
2011 PrintQualifier(FromQual,
false);
2031 if (CommonQual.
empty() && FromQual.
empty()) {
2033 OS <<
"(no qualifiers) ";
2036 PrintQualifier(CommonQual,
false);
2037 PrintQualifier(FromQual,
true);
2042 OS <<
"(no qualifiers)";
2045 PrintQualifier(CommonQual,
false,
2047 PrintQualifier(ToQual,
true,
2052 PrintQualifier(CommonQual,
false);
2053 PrintQualifier(FromQual,
true);
2057 void PrintQualifier(
Qualifiers Q,
bool ApplyBold,
2058 bool AppendSpaceIfNonEmpty =
true) {
2059 if (Q.
empty())
return;
2060 if (ApplyBold) Bold();
2061 Q.
print(OS, Policy, AppendSpaceIfNonEmpty);
2062 if (ApplyBold) Unbold();
2068 QualType ToType,
bool PrintTree,
bool PrintFromType,
2069 bool ElideType,
bool ShowColor)
2071 Policy(Context.getLangOpts()),
2072 ElideType(ElideType),
2073 PrintTree(PrintTree),
2074 ShowColor(ShowColor),
2076 FromTemplateType(PrintFromType ? FromType : ToType),
2077 ToTemplateType(PrintFromType ? ToType : FromType),
2083 void DiffTemplate() {
2088 GetTemplateSpecializationType(Context, FromTemplateType);
2090 GetTemplateSpecializationType(Context, ToTemplateType);
2093 if (!FromOrigTST || !ToOrigTST)
2097 if (!hasSameTemplate(FromOrigTST, ToOrigTST)) {
2107 FromQual, ToQual,
false ,
2110 DiffTemplate(FromOrigTST, ToOrigTST);
2117 Tree.StartTraverse();
2122 assert(!IsBold &&
"Bold is applied to end of string.");
2133 bool PrintFromType,
bool ElideType,
2136 PrintFromType =
true;
2137 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 getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType) const
QualType getIncompleteArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return a unique reference to the type for an incomplete array of the specified element type.
QualType getBuiltinVaListType() const
Retrieve the type of the __builtin_va_list type.
QualType getObjCClassType() const
Represents the Objective-C Class type.
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 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.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts, ArrayType::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 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.
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 getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::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 getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element 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 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.
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 Kind getNullabilityAttrKind(NullabilityKind kind)
Retrieve the attribute kind corresponding to the given nullability kind.
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(unsigned 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) 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,...
@ Pack
The template argument is actually a parameter pack.
@ 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.
@ 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() 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.
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