86#include "llvm/ADT/APInt.h"
87#include "llvm/ADT/APSInt.h"
88#include "llvm/ADT/StringExtras.h"
89#include "llvm/Support/Casting.h"
90#include "llvm/Support/Compiler.h"
91#include "llvm/Support/ErrorHandling.h"
160 llvm_unreachable(
"Unhandled kind of DeclarationName");
191 if (
static_cast<bool>(Callee1) !=
static_cast<bool>(Callee2))
195 if (!
static_cast<bool>(Callee1))
223 if (!Decl1 || !Decl2)
238 bool IsStmtEquivalent(
const Expr *E1,
const Expr *E2) {
255 std::optional<TypeSourceInfo *> Child1 = std::get<0>(Pair);
256 std::optional<TypeSourceInfo *> Child2 = std::get<1>(Pair);
258 if (!Child1 || !Child2)
262 (*Child2)->getType()))
290 bool IsStmtEquivalent(
const Stmt *S1,
const Stmt *S2) {
return true; }
300 return ::IsStructurallyEquivalent(Name1, Name2);
338 std::optional<TypeSourceInfo *> Child1 = std::get<0>(Pair);
339 std::optional<TypeSourceInfo *> Child2 = std::get<1>(Pair);
341 if (!Child1 || !Child2)
345 (*Child2)->getType()))
406 bool TraverseStmt(
const Stmt *S1,
const Stmt *S2) {
return true; }
413#define STMT(CLASS, PARENT) \
414 bool TraverseStmt(const CLASS *S1, const CLASS *S2) { \
415 if (!TraverseStmt(static_cast<const PARENT *>(S1), \
416 static_cast<const PARENT *>(S2))) \
418 return IsStmtEquivalent(S1, S2); \
420#include "clang/AST/StmtNodes.inc"
428 bool IsEquivalent(
const Stmt *S1,
const Stmt *S2) {
439 llvm_unreachable(
"Can't traverse NoStmtClass");
440#define STMT(CLASS, PARENT) \
441 case Stmt::StmtClass::CLASS##Class: \
442 return TraverseStmt(static_cast<const CLASS *>(S1), \
443 static_cast<const CLASS *>(S2));
444#define ABSTRACT_STMT(S)
445#include "clang/AST/StmtNodes.inc"
447 llvm_unreachable(
"Invalid statement kind");
500 if (
const auto *E2CXXOperatorCall = dyn_cast<CXXOperatorCallExpr>(S2)) {
501 if (
const auto *E1Unary = dyn_cast<UnaryOperator>(S1))
503 if (
const auto *E1Binary = dyn_cast<BinaryOperator>(S1))
506 if (
const auto *E1CXXOperatorCall = dyn_cast<CXXOperatorCallExpr>(S1)) {
507 if (
const auto *E2Unary = dyn_cast<UnaryOperator>(S2))
509 if (
const auto *E2Binary = dyn_cast<BinaryOperator>(S2))
514 StmtComparer Comparer(Context);
515 if (!Comparer.IsEquivalent(S1, S2))
520 std::optional<const Stmt *> Child1 = std::get<0>(Pair);
521 std::optional<const Stmt *> Child2 = std::get<1>(Pair);
524 if (!Child1 || !Child2)
535 if (!Name1 || !Name2)
536 return Name1 == Name2;
550 if ((
bool)Prefix1 != (
bool)Prefix2)
585 if (TemplateDeclN1 && TemplateDeclN2) {
591 }
else if (TemplateDeclN1 || TemplateDeclN2)
603 E1 = OS1->
end(), E2 = OS2->end();
604 for (; I1 != E1 && I2 != E2; ++I1, ++I2)
607 return I1 == E1 && I2 == E2;
620 DN2->getQualifier()))
624 DN2->getIdentifier());
635 P2->getArgumentPack()) &&
637 P2->getAssociatedDecl()) &&
706 llvm_unreachable(
"Invalid template argument kind");
713 if (Args1.size() != Args2.size())
715 for (
unsigned I = 0, N = Args1.size(); I != N; ++I) {
811 if (!Context.StrictTypeSpelling) {
828 TC = Type::FunctionNoProto;
831 TC = Type::FunctionNoProto;
839 if (cast<BuiltinType>(T1)->
getKind() != cast<BuiltinType>(T2)->
getKind())
845 cast<ComplexType>(T1)->getElementType(),
846 cast<ComplexType>(T2)->getElementType()))
852 case Type::ArrayParameter:
854 cast<AdjustedType>(T1)->getOriginalType(),
855 cast<AdjustedType>(T2)->getOriginalType()))
866 case Type::BlockPointer:
873 case Type::LValueReference:
874 case Type::RValueReference: {
875 const auto *Ref1 = cast<ReferenceType>(T1);
876 const auto *Ref2 = cast<ReferenceType>(T2);
877 if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
879 if (Ref1->isInnerRef() != Ref2->isInnerRef())
882 Ref2->getPointeeTypeAsWritten()))
887 case Type::MemberPointer: {
888 const auto *MemPtr1 = cast<MemberPointerType>(T1);
889 const auto *MemPtr2 = cast<MemberPointerType>(T2);
891 MemPtr2->getPointeeType()))
899 case Type::ConstantArray: {
900 const auto *Array1 = cast<ConstantArrayType>(T1);
901 const auto *Array2 = cast<ConstantArrayType>(T2);
902 if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
910 case Type::IncompleteArray:
912 cast<ArrayType>(T2)))
916 case Type::VariableArray: {
917 const auto *Array1 = cast<VariableArrayType>(T1);
918 const auto *Array2 = cast<VariableArrayType>(T2);
920 Array2->getSizeExpr()))
929 case Type::DependentSizedArray: {
930 const auto *Array1 = cast<DependentSizedArrayType>(T1);
931 const auto *Array2 = cast<DependentSizedArrayType>(T2);
933 Array2->getSizeExpr()))
942 case Type::DependentAddressSpace: {
943 const auto *DepAddressSpace1 = cast<DependentAddressSpaceType>(T1);
944 const auto *DepAddressSpace2 = cast<DependentAddressSpaceType>(T2);
946 DepAddressSpace2->getAddrSpaceExpr()))
949 DepAddressSpace2->getPointeeType()))
955 case Type::DependentSizedExtVector: {
956 const auto *Vec1 = cast<DependentSizedExtVectorType>(T1);
957 const auto *Vec2 = cast<DependentSizedExtVectorType>(T2);
959 Vec2->getSizeExpr()))
962 Vec2->getElementType()))
967 case Type::DependentVector: {
968 const auto *Vec1 = cast<DependentVectorType>(T1);
969 const auto *Vec2 = cast<DependentVectorType>(T2);
970 if (Vec1->getVectorKind() != Vec2->getVectorKind())
973 Vec2->getSizeExpr()))
976 Vec2->getElementType()))
982 case Type::ExtVector: {
983 const auto *Vec1 = cast<VectorType>(T1);
984 const auto *Vec2 = cast<VectorType>(T2);
986 Vec2->getElementType()))
988 if (Vec1->getNumElements() != Vec2->getNumElements())
990 if (Vec1->getVectorKind() != Vec2->getVectorKind())
995 case Type::DependentSizedMatrix: {
1010 case Type::ConstantMatrix: {
1023 case Type::FunctionProto: {
1024 const auto *Proto1 = cast<FunctionProtoType>(T1);
1025 const auto *Proto2 = cast<FunctionProtoType>(T2);
1027 if (Proto1->getNumParams() != Proto2->getNumParams())
1029 for (
unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
1031 Proto2->getParamType(I)))
1034 if (Proto1->isVariadic() != Proto2->isVariadic())
1037 if (Proto1->getMethodQuals() != Proto2->getMethodQuals())
1041 const auto *OrigProto1 =
1043 const auto *OrigProto2 =
1052 case Type::FunctionNoProto: {
1053 const auto *Function1 = cast<FunctionType>(T1);
1054 const auto *Function2 = cast<FunctionType>(T2);
1056 Function2->getReturnType()))
1059 Function2->getExtInfo()))
1064 case Type::UnresolvedUsing:
1066 cast<UnresolvedUsingType>(T1)->getDecl(),
1067 cast<UnresolvedUsingType>(T2)->getDecl()))
1071 case Type::Attributed:
1073 cast<AttributedType>(T1)->getModifiedType(),
1074 cast<AttributedType>(T2)->getModifiedType()))
1077 Context, cast<AttributedType>(T1)->getEquivalentType(),
1078 cast<AttributedType>(T2)->getEquivalentType()))
1082 case Type::CountAttributed:
1084 cast<CountAttributedType>(T1)->desugar(),
1085 cast<CountAttributedType>(T2)->desugar()))
1089 case Type::BTFTagAttributed:
1091 Context, cast<BTFTagAttributedType>(T1)->getWrappedType(),
1092 cast<BTFTagAttributedType>(T2)->getWrappedType()))
1098 cast<ParenType>(T2)->getInnerType()))
1102 case Type::MacroQualified:
1111 cast<UsingType>(T2)->getFoundDecl()))
1121 cast<TypedefType>(T2)->getDecl()) ||
1123 cast<TypedefType>(T2)->desugar()))
1127 case Type::TypeOfExpr:
1129 Context, cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
1130 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
1136 cast<TypeOfType>(T1)->getUnmodifiedType(),
1137 cast<TypeOfType>(T2)->getUnmodifiedType()))
1141 case Type::UnaryTransform:
1148 case Type::Decltype:
1150 cast<DecltypeType>(T1)->getUnderlyingExpr(),
1151 cast<DecltypeType>(T2)->getUnderlyingExpr()))
1156 auto *Auto1 = cast<AutoType>(T1);
1157 auto *Auto2 = cast<AutoType>(T2);
1159 Auto2->getDeducedType()))
1161 if (Auto1->isConstrained() != Auto2->isConstrained())
1163 if (Auto1->isConstrained()) {
1164 if (Auto1->getTypeConstraintConcept() !=
1165 Auto2->getTypeConstraintConcept())
1168 Auto1->getTypeConstraintArguments(),
1169 Auto2->getTypeConstraintArguments()))
1175 case Type::DeducedTemplateSpecialization: {
1176 const auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
1177 const auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
1179 DT2->getTemplateName()))
1182 DT2->getDeducedType()))
1190 cast<TagType>(T2)->getDecl()))
1194 case Type::TemplateTypeParm: {
1195 const auto *Parm1 = cast<TemplateTypeParmType>(T1);
1196 const auto *Parm2 = cast<TemplateTypeParmType>(T2);
1197 if (!Context.IgnoreTemplateParmDepth &&
1198 Parm1->getDepth() != Parm2->getDepth())
1200 if (Parm1->getIndex() != Parm2->getIndex())
1202 if (Parm1->isParameterPack() != Parm2->isParameterPack())
1209 case Type::SubstTemplateTypeParm: {
1210 const auto *Subst1 = cast<SubstTemplateTypeParmType>(T1);
1211 const auto *Subst2 = cast<SubstTemplateTypeParmType>(T2);
1213 Subst2->getReplacementType()))
1216 Subst2->getAssociatedDecl()))
1218 if (Subst1->getIndex() != Subst2->getIndex())
1220 if (Subst1->getPackIndex() != Subst2->getPackIndex())
1225 case Type::SubstTemplateTypeParmPack: {
1226 const auto *Subst1 = cast<SubstTemplateTypeParmPackType>(T1);
1227 const auto *Subst2 = cast<SubstTemplateTypeParmPackType>(T2);
1229 Subst2->getAssociatedDecl()))
1231 if (Subst1->getIndex() != Subst2->getIndex())
1234 Subst2->getArgumentPack()))
1239 case Type::TemplateSpecialization: {
1240 const auto *Spec1 = cast<TemplateSpecializationType>(T1);
1241 const auto *Spec2 = cast<TemplateSpecializationType>(T2);
1243 Spec2->getTemplateName()))
1246 Spec2->template_arguments()))
1251 case Type::Elaborated: {
1252 const auto *Elab1 = cast<ElaboratedType>(T1);
1253 const auto *Elab2 = cast<ElaboratedType>(T2);
1257 if (Elab1->getKeyword() != Elab2->getKeyword())
1260 Elab2->getQualifier()))
1263 Elab2->getNamedType()))
1268 case Type::InjectedClassName: {
1269 const auto *Inj1 = cast<InjectedClassNameType>(T1);
1270 const auto *Inj2 = cast<InjectedClassNameType>(T2);
1272 Inj1->getInjectedSpecializationType(),
1273 Inj2->getInjectedSpecializationType()))
1278 case Type::DependentName: {
1279 const auto *Typename1 = cast<DependentNameType>(T1);
1280 const auto *Typename2 = cast<DependentNameType>(T2);
1282 Typename2->getQualifier()))
1285 Typename2->getIdentifier()))
1291 case Type::DependentTemplateSpecialization: {
1292 const auto *Spec1 = cast<DependentTemplateSpecializationType>(T1);
1293 const auto *Spec2 = cast<DependentTemplateSpecializationType>(T2);
1295 Spec2->getQualifier()))
1298 Spec2->getIdentifier()))
1301 Spec2->template_arguments()))
1306 case Type::PackExpansion:
1308 cast<PackExpansionType>(T1)->getPattern(),
1309 cast<PackExpansionType>(T2)->getPattern()))
1313 case Type::PackIndexing:
1315 cast<PackIndexingType>(T1)->getPattern(),
1316 cast<PackIndexingType>(T2)->getPattern()))
1318 cast<PackIndexingType>(T1)->getIndexExpr(),
1319 cast<PackIndexingType>(T2)->getIndexExpr()))
1323 case Type::ObjCInterface: {
1324 const auto *Iface1 = cast<ObjCInterfaceType>(T1);
1325 const auto *Iface2 = cast<ObjCInterfaceType>(T2);
1332 case Type::ObjCTypeParam: {
1333 const auto *Obj1 = cast<ObjCTypeParamType>(T1);
1334 const auto *Obj2 = cast<ObjCTypeParamType>(T2);
1338 if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
1340 for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
1342 Obj2->getProtocol(I)))
1348 case Type::ObjCObject: {
1349 const auto *Obj1 = cast<ObjCObjectType>(T1);
1350 const auto *Obj2 = cast<ObjCObjectType>(T2);
1352 Obj2->getBaseType()))
1354 if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
1356 for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
1358 Obj2->getProtocol(I)))
1364 case Type::ObjCObjectPointer: {
1365 const auto *Ptr1 = cast<ObjCObjectPointerType>(T1);
1366 const auto *Ptr2 = cast<ObjCObjectPointerType>(T2);
1368 Ptr2->getPointeeType()))
1375 cast<AtomicType>(T2)->getValueType()))
1381 cast<PipeType>(T2)->getElementType()))
1384 case Type::BitInt: {
1385 const auto *Int1 = cast<BitIntType>(T1);
1386 const auto *Int2 = cast<BitIntType>(T2);
1388 if (Int1->isUnsigned() != Int2->isUnsigned() ||
1389 Int1->getNumBits() != Int2->getNumBits())
1393 case Type::DependentBitInt: {
1394 const auto *Int1 = cast<DependentBitIntType>(T1);
1395 const auto *Int2 = cast<DependentBitIntType>(T2);
1397 if (Int1->isUnsigned() != Int2->isUnsigned() ||
1399 Int2->getNumBitsExpr()))
1449 if (Context.Complain) {
1451 Owner2->getLocation(),
1452 Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
1454 Context.Diag2(Field2->
getLocation(), diag::note_odr_field_name)
1456 Context.Diag1(Field1->
getLocation(), diag::note_odr_field_name)
1464 if (Context.Complain) {
1466 Owner2->getLocation(),
1467 Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
1469 Context.Diag2(Field2->
getLocation(), diag::note_odr_field)
1471 Context.Diag1(Field1->
getLocation(), diag::note_odr_field)
1496 bool PropertiesEqual =
1510 if (!PropertiesEqual)
1514 if (
auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
1515 auto *Constructor2 = cast<CXXConstructorDecl>(Method2);
1516 if (!Constructor1->getExplicitSpecifier().isEquivalent(
1517 Constructor2->getExplicitSpecifier()))
1521 if (
auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
1522 auto *Conversion2 = cast<CXXConversionDecl>(Method2);
1523 if (!Conversion1->getExplicitSpecifier().isEquivalent(
1524 Conversion2->getExplicitSpecifier()))
1527 Conversion2->getConversionType()))
1551 "Must be called on lambda classes");
1582 if (
const auto *ND1 = dyn_cast<NamedDecl>(DC1)) {
1583 const auto *ND2 = cast<NamedDecl>(DC2);
1589 if (
auto *D1Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC1)) {
1590 auto *D2Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC2);
1607 return TypedefName->getIdentifier();
1621 if (Context.Complain) {
1622 Context.Diag2(D2->
getLocation(), Context.getApplicableDiagnostic(
1623 diag::err_odr_tag_type_inconsistent))
1625 Context.Diag1(D1->
getLocation(), diag::note_odr_tag_kind_here)
1634 if (std::optional<unsigned> Index1 =
1636 if (std::optional<unsigned> Index2 =
1639 if (*Index1 != *Index2)
1653 const auto *Spec1 = dyn_cast<ClassTemplateSpecializationDecl>(D1);
1654 const auto *Spec2 = dyn_cast<ClassTemplateSpecializationDecl>(D2);
1655 if (Spec1 && Spec2) {
1658 Spec2->getSpecializedTemplate()))
1662 if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
1665 for (
unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
1667 Spec2->getTemplateArgs().get(I)))
1672 else if (Spec1 || Spec2)
1688 if (Context.EqKind == StructuralEquivalenceKind::Minimal)
1697 if (
auto *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
1698 if (
auto *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
1699 if (D1CXX->hasExternalLexicalStorage() &&
1700 !D1CXX->isCompleteDefinition()) {
1704 if (D1CXX->isLambda() != D2CXX->isLambda())
1706 if (D1CXX->isLambda()) {
1711 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
1712 if (Context.Complain) {
1714 Context.getApplicableDiagnostic(
1715 diag::err_odr_tag_type_inconsistent))
1717 Context.Diag2(D2->
getLocation(), diag::note_odr_number_of_bases)
1718 << D2CXX->getNumBases();
1719 Context.Diag1(D1->
getLocation(), diag::note_odr_number_of_bases)
1720 << D1CXX->getNumBases();
1727 BaseEnd1 = D1CXX->bases_end(),
1728 Base2 = D2CXX->bases_begin();
1729 Base1 != BaseEnd1; ++Base1, ++Base2) {
1731 Base2->getType())) {
1732 if (Context.Complain) {
1734 Context.getApplicableDiagnostic(
1735 diag::err_odr_tag_type_inconsistent))
1737 Context.Diag2(Base2->getBeginLoc(), diag::note_odr_base)
1738 << Base2->getType() << Base2->getSourceRange();
1739 Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1740 << Base1->getType() << Base1->getSourceRange();
1746 if (Base1->isVirtual() != Base2->isVirtual()) {
1747 if (Context.Complain) {
1749 Context.getApplicableDiagnostic(
1750 diag::err_odr_tag_type_inconsistent))
1752 Context.Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
1753 << Base2->isVirtual() << Base2->getSourceRange();
1754 Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1755 << Base1->isVirtual() << Base1->getSourceRange();
1763 Friend2End = D2CXX->friend_end();
1765 Friend1End = D1CXX->friend_end();
1766 Friend1 != Friend1End; ++Friend1, ++Friend2) {
1767 if (Friend2 == Friend2End) {
1768 if (Context.Complain) {
1770 Context.getApplicableDiagnostic(
1771 diag::err_odr_tag_type_inconsistent))
1773 Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1774 Context.Diag2(D2->
getLocation(), diag::note_odr_missing_friend);
1780 if (Context.Complain) {
1782 Context.getApplicableDiagnostic(
1783 diag::err_odr_tag_type_inconsistent))
1785 Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1786 Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1792 if (Friend2 != Friend2End) {
1793 if (Context.Complain) {
1795 Context.getApplicableDiagnostic(
1796 diag::err_odr_tag_type_inconsistent))
1798 Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1799 Context.Diag1(D1->
getLocation(), diag::note_odr_missing_friend);
1803 }
else if (D1CXX->getNumBases() > 0) {
1804 if (Context.Complain) {
1806 Context.getApplicableDiagnostic(
1807 diag::err_odr_tag_type_inconsistent))
1810 Context.Diag1(Base1->
getBeginLoc(), diag::note_odr_base)
1812 Context.Diag2(D2->
getLocation(), diag::note_odr_missing_base);
1824 Field1 != Field1End; ++Field1, ++Field2) {
1825 if (Field2 == Field2End) {
1826 if (Context.Complain) {
1828 Context.getApplicableDiagnostic(
1829 diag::err_odr_tag_type_inconsistent))
1831 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
1832 << Field1->getDeclName() << Field1->getType();
1833 Context.Diag2(D2->
getLocation(), diag::note_odr_missing_field);
1842 if (Field2 != Field2End) {
1843 if (Context.Complain) {
1844 Context.Diag2(D2->
getLocation(), Context.getApplicableDiagnostic(
1845 diag::err_odr_tag_type_inconsistent))
1847 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
1848 << Field2->getDeclName() << Field2->getType();
1849 Context.Diag1(D1->
getLocation(), diag::note_odr_missing_field);
1860 const llvm::APSInt &FromVal = D1->
getInitVal();
1861 const llvm::APSInt &ToVal = D2->
getInitVal();
1862 if (FromVal.isSigned() != ToVal.isSigned())
1864 if (FromVal.getBitWidth() != ToVal.getBitWidth())
1866 if (FromVal != ToVal)
1895 EC1 != EC1End; ++EC1, ++EC2) {
1896 if (EC2 == EC2End) {
1897 if (Context.Complain) {
1899 Context.getApplicableDiagnostic(
1900 diag::err_odr_tag_type_inconsistent))
1902 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1903 << EC1->getDeclName() <<
toString(EC1->getInitVal(), 10);
1904 Context.Diag2(D2->
getLocation(), diag::note_odr_missing_enumerator);
1909 llvm::APSInt Val1 = EC1->getInitVal();
1910 llvm::APSInt Val2 = EC2->getInitVal();
1911 if (!llvm::APSInt::isSameValue(Val1, Val2) ||
1913 if (Context.Complain) {
1915 Context.getApplicableDiagnostic(
1916 diag::err_odr_tag_type_inconsistent))
1918 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1919 << EC2->getDeclName() <<
toString(EC2->getInitVal(), 10);
1920 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1921 << EC1->getDeclName() <<
toString(EC1->getInitVal(), 10);
1927 if (EC2 != EC2End) {
1928 if (Context.Complain) {
1929 Context.Diag2(D2->
getLocation(), Context.getApplicableDiagnostic(
1930 diag::err_odr_tag_type_inconsistent))
1932 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1933 << EC2->getDeclName() <<
toString(EC2->getInitVal(), 10);
1934 Context.Diag1(D1->
getLocation(), diag::note_odr_missing_enumerator);
1945 if (Params1->
size() != Params2->
size()) {
1946 if (Context.Complain) {
1948 Context.getApplicableDiagnostic(
1949 diag::err_odr_different_num_template_parameters))
1950 << Params1->
size() << Params2->
size();
1952 diag::note_odr_template_parameter_list);
1957 for (
unsigned I = 0, N = Params1->
size(); I != N; ++I) {
1959 if (Context.Complain) {
1961 Context.getApplicableDiagnostic(
1962 diag::err_odr_different_template_parameter_kind));
1964 diag::note_odr_template_parameter_here);
1981 if (Context.Complain) {
1983 Context.getApplicableDiagnostic(
1984 diag::err_odr_parameter_pack_non_pack))
1986 Context.Diag1(D1->
getLocation(), diag::note_odr_parameter_pack_non_pack)
1999 if (Context.Complain) {
2001 Context.getApplicableDiagnostic(
2002 diag::err_odr_parameter_pack_non_pack))
2004 Context.Diag1(D1->
getLocation(), diag::note_odr_parameter_pack_non_pack)
2015 if (Context.Complain) {
2017 Context.getApplicableDiagnostic(
2018 diag::err_odr_non_type_parameter_type_inconsistent))
2020 Context.Diag1(D1->
getLocation(), diag::note_odr_value_here)
2033 if (Context.Complain) {
2035 Context.getApplicableDiagnostic(
2036 diag::err_odr_parameter_pack_non_pack))
2038 Context.Diag1(D1->
getLocation(), diag::note_odr_parameter_pack_non_pack)
2159 cast<FieldDecl>(D2), Owner2Type);
2172 bool PropertiesEqual =
2176 if (!PropertiesEqual)
2183 if (NumArgs != Selector2.getNumArgs())
2187 unsigned SlotsToCheck = NumArgs > 0 ? NumArgs : 1;
2188 for (
unsigned I = 0; I < SlotsToCheck; ++I) {
2190 Selector2.getIdentifierInfoForSlot(I)))
2200 "Same number of arguments should be already enforced in Selector checks");
2206 (ParamT1 != ParamT1End) && (ParamT2 != ParamT2End);
2207 ++ParamT1, ++ParamT2) {
2223 if ((!Intf1 || !Intf2) && (Intf1 != Intf2))
2235 Protocol1 != Protocol1End; ++Protocol1, ++Protocol2) {
2236 if (Protocol2 == Protocol2End)
2239 (*Protocol2)->getIdentifier()))
2242 if (Protocol2 != Protocol2End)
2252 Ivar1 != Ivar1End; ++Ivar1, ++Ivar2) {
2253 if (Ivar2 == Ivar2End)
2258 if (Ivar2 != Ivar2End)
2266 Method1 != Method1End; ++Method1, ++Method2) {
2267 if (Method2 == Method2End)
2272 if (Method2 != Method2End)
2285 std::pair<Decl *, Decl *>
P{D1, D2};
2289 if (Context.NonEquivalentDecls.count(
P))
2295 bool Inserted = Context.VisitedDecls.insert(
P).second;
2299 Context.DeclsToCheck.push(
P);
2306 assert(
Complain &&
"Not allowed to complain");
2315 assert(
Complain &&
"Not allowed to complain");
2322std::optional<unsigned>
2327 const auto *Owner = dyn_cast<RecordDecl>(Anon->
getDeclContext());
2329 return std::nullopt;
2332 for (
const auto *
D : Owner->noload_decls()) {
2333 const auto *F = dyn_cast<FieldDecl>(
D);
2337 if (F->isAnonymousStructOrUnion()) {
2348 while (
const auto *ElabType = dyn_cast<ElaboratedType>(FieldType))
2349 FieldType = ElabType->getNamedType();
2351 if (
const auto *RecType = dyn_cast<RecordType>(FieldType)) {
2352 const RecordDecl *RecDecl = RecType->getDecl();
2366 unsigned ErrorDiagnostic) {
2368 return ErrorDiagnostic;
2370 switch (ErrorDiagnostic) {
2371 case diag::err_odr_variable_type_inconsistent:
2372 return diag::warn_odr_variable_type_inconsistent;
2373 case diag::err_odr_variable_multiple_def:
2374 return diag::warn_odr_variable_multiple_def;
2375 case diag::err_odr_function_type_inconsistent:
2376 return diag::warn_odr_function_type_inconsistent;
2377 case diag::err_odr_tag_type_inconsistent:
2378 return diag::warn_odr_tag_type_inconsistent;
2379 case diag::err_odr_field_type_inconsistent:
2380 return diag::warn_odr_field_type_inconsistent;
2381 case diag::err_odr_ivar_type_inconsistent:
2382 return diag::warn_odr_ivar_type_inconsistent;
2383 case diag::err_odr_objc_superclass_inconsistent:
2384 return diag::warn_odr_objc_superclass_inconsistent;
2385 case diag::err_odr_objc_method_result_type_inconsistent:
2386 return diag::warn_odr_objc_method_result_type_inconsistent;
2387 case diag::err_odr_objc_method_num_params_inconsistent:
2388 return diag::warn_odr_objc_method_num_params_inconsistent;
2389 case diag::err_odr_objc_method_param_type_inconsistent:
2390 return diag::warn_odr_objc_method_param_type_inconsistent;
2391 case diag::err_odr_objc_method_variadic_inconsistent:
2392 return diag::warn_odr_objc_method_variadic_inconsistent;
2393 case diag::err_odr_objc_property_type_inconsistent:
2394 return diag::warn_odr_objc_property_type_inconsistent;
2395 case diag::err_odr_objc_property_impl_kind_inconsistent:
2396 return diag::warn_odr_objc_property_impl_kind_inconsistent;
2397 case diag::err_odr_objc_synthesize_ivar_inconsistent:
2398 return diag::warn_odr_objc_synthesize_ivar_inconsistent;
2399 case diag::err_odr_different_num_template_parameters:
2400 return diag::warn_odr_different_num_template_parameters;
2401 case diag::err_odr_different_template_parameter_kind:
2402 return diag::warn_odr_different_template_parameter_kind;
2403 case diag::err_odr_parameter_pack_non_pack:
2404 return diag::warn_odr_parameter_pack_non_pack;
2405 case diag::err_odr_non_type_parameter_type_inconsistent:
2406 return diag::warn_odr_non_type_parameter_type_inconsistent;
2408 llvm_unreachable(
"Diagnostic kind not handled in preceding switch");
2448bool StructuralEquivalenceContext::CheckCommonEquivalence(
Decl *D1,
Decl *D2) {
2452 if ((Template1 !=
nullptr) != (Template2 !=
nullptr))
2462bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
2472#define ABSTRACT_DECL(DECL)
2473#define DECL(DERIVED, BASE) \
2474 case Decl::Kind::DERIVED: \
2475 return ::IsStructurallyEquivalent(*this, static_cast<DERIVED##Decl *>(D1), \
2476 static_cast<DERIVED##Decl *>(D2));
2477#include "clang/AST/DeclNodes.inc"
2482bool StructuralEquivalenceContext::Finish() {
2489 Decl *D2 =
P.second;
2492 CheckCommonEquivalence(D1, D2) && CheckKindSpecificEquivalence(D1, D2);
Defines the clang::ASTContext interface.
static bool IsTemplateDeclCommonStructurallyEquivalent(StructuralEquivalenceContext &Ctx, TemplateDecl *D1, TemplateDecl *D2)
static bool IsStructurallyEquivalentLambdas(StructuralEquivalenceContext &Context, CXXRecordDecl *D1, CXXRecordDecl *D2)
Determine structural equivalence of two lambda classes.
static bool NameIsStructurallyEquivalent(const TagDecl &D1, const TagDecl &D2)
static bool IsRecordContextStructurallyEquivalent(StructuralEquivalenceContext &Context, RecordDecl *D1, RecordDecl *D2)
Determine if context of a class is equivalent.
static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext &Context, const FunctionProtoType *Proto1, const FunctionProtoType *Proto2)
Check the equivalence of exception specifications.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, QualType T1, QualType T2)
Determine structural equivalence of two types.
static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context, const ArrayType *Array1, const ArrayType *Array2)
Determine structural equivalence for the common part of array types.
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines Expressions and AST nodes for C++2a concepts.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static QualType getUnderlyingType(const SubRegion *R)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
Defines the Objective-C statement AST node classes.
This file defines OpenACC AST classes for statement-level contructs.
This file defines OpenMP AST classes for executable directives and clauses.
static QualType getPointeeType(const MemRegion *R)
C Language Family Type Representation.
llvm::APInt getValue() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
QualType getRecordType(const RecordDecl *Decl) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
DiagnosticsEngine & getDiagnostics() const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
AddrLabelExpr - The GNU address of label extension, representing &&label.
LabelDecl * getLabel() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
Qualifiers getIndexTypeQualifiers() const
QualType getElementType() const
A structure for storing the information associated with a name that has been assumed to be a template...
DeclarationName getDeclName() const
Get the name of the template.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getType() const
Retrieves the type of the base class.
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a C++ member access expression where the actual member referenced could not be resolved be...
QualType getBaseType() const
DeclarationName getMember() const
Retrieve the name of the member that this expression refers to.
Represents a static or instance method of a struct/union/class.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
A call to an overloaded operator written using operator syntax.
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
An iterator over the friend declarations of a class.
Represents a C++ struct/union/class.
bool isLambda() const
Determine whether this class describes a lambda function object.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
unsigned getValue() const
CharacterLiteralKind getKind() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
CompoundStmt - This represents a group of statements like { stmt stmt }.
Declaration of a C++20 concept.
Expr * getConstraintExpr() const
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
bool isInlineNamespace() const
bool isFunctionOrMethod() const
Decl::Kind getDeclKind() const
DeclContext * getNonTransparentContext()
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration.
ASTContext & getASTContext() const LLVM_READONLY
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
TemplateDecl * getCXXDeductionGuideTemplate() const
If this name is the name of a C++ deduction guide, return the template associated with that name.
const IdentifierInfo * getCXXLiteralIdentifier() const
If this name is the name of a literal operator, retrieve the identifier associated with it.
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
@ CXXConversionFunctionName
QualType getCXXNameType() const
If this name is one of the C++ names (of a constructor, destructor, or conversion function),...
NameKind getNameKind() const
Determine what kind of name this is.
A qualified reference to a name whose declaration cannot yet be resolved.
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
DeclarationName getDeclName() const
Retrieve the name that this expression refers to.
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Expr * getColumnExpr() const
Expr * getRowExpr() const
Represents a dependent template name that cannot be resolved prior to template instantiation.
OverloadedOperatorKind getOperator() const
Return the overloaded operator to which this template name refers.
bool isIdentifier() const
Determine whether this template name refers to an identifier.
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
const IdentifierInfo * getIdentifier() const
Returns the identifier to which this template name refers.
bool isOverloadedOperator() const
Determine whether this template name refers to an overloaded operator.
A little helper class used to produce diagnostics.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
void notePriorDiagnosticFrom(const DiagnosticsEngine &Other)
Note that the prior diagnostic was emitted by some other DiagnosticsEngine, and we may be attaching a...
An instance of this object exists for each enum constant that is defined.
llvm::APSInt getInitVal() const
const Expr * getInitExpr() const
enumerator_iterator enumerator_begin() const
EnumDecl * getDefinition() const
enumerator_iterator enumerator_end() const
This represents one expression.
An expression trait intrinsic.
ExpressionTrait getTrait() const
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
llvm::APFloat getValue() const
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Represents a function declaration or definition.
bool isDeleted() const
Whether this function has been deleted.
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
bool isDefaulted() const
Whether this function is defaulted.
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
A class which abstracts out some details necessary for making a call.
CallingConv getCC() const
bool getNoCfCheck() const
unsigned getRegParm() const
bool getNoCallerSavedRegs() const
bool getHasRegParm() const
bool getProducesResult() const
Represents a C11 generic selection.
ArrayRef< TypeSourceInfo * > getAssocTypeSourceInfos() const
GotoStmt - This represents a direct goto.
LabelDecl * getLabel() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents the declaration of a label.
QualType getElementType() const
Returns type of the elements being stored in the matrix.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
DeclAccessPair getFoundDecl() const
Retrieves the declaration found by lookup.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
@ TypeSpec
A type, stored as a Type*.
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Identifier
An identifier, stored as an IdentifierInfo*.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace, stored as a NamespaceDecl*.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
unsigned getDepth() const
Get the nesting depth of the template parameter.
ObjCCategoryDecl - Represents a category declaration.
ivar_iterator ivar_begin() const
ivar_iterator ivar_end() const
ObjCInterfaceDecl * getClassInterface()
protocol_iterator protocol_end() const
protocol_iterator protocol_begin() const
ObjCProtocolList::iterator protocol_iterator
method_iterator meth_begin() const
method_iterator meth_end() const
Represents an ObjC class declaration.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCMethodDecl - Represents an instance or class method declaration.
unsigned param_size() const
param_type_iterator param_type_begin() const
param_type_iterator param_type_end() const
bool isDirectMethod() const
True if the method is tagged as objc_direct.
llvm::mapped_iterator< param_const_iterator, GetTypeFn > param_type_iterator
Selector getSelector() const
bool isInstanceMethod() const
QualType getReturnType() const
ObjCStringLiteral, used for Objective-C string literals i.e.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
NestedNameSpecifier * getQualifier() const
Fetches the nested-name qualifier, if one was given.
TemplateArgumentLoc const * getTemplateArgs() const
unsigned getNumTemplateArgs() const
DeclarationName getName() const
Gets the name looked up.
A structure for storing the information associated with an overloaded template name.
NamedDecl *const * iterator
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Represents a struct/union/class.
field_iterator field_end() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Smart pointer class that efficiently represents Objective-C method names.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
unsigned getNumArgs() const
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
SourceLocIdentKind getIdentKind() const
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
unsigned getTemplateDepth() const
Stmt - This represents one statement.
StmtClass getStmtClass() const
StringLiteral - This represents a string literal expression, e.g.
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
Represents a reference to a non-type template parameter that has been substituted with a template arg...
std::optional< unsigned > getPackIndex() const
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
TemplateArgument getArgumentPack() const
Retrieve the template argument pack containing the substituted template arguments.
A structure for storing an already-substituted template template parameter pack.
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
Represents the declaration of a struct/union/class/enum.
bool isBeingDefined() const
Return true if this decl is currently being defined.
TagKind getTagKind() const
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
Represents a template argument.
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
QualType getIntegralType() const
Retrieve the type of the integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ 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.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
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.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template declarations that this template name refers to,...
AssumedTemplateStorage * getAsAssumedTemplateName() const
Retrieve information on a name that has been assumed to be a template-name in order to permit a call ...
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
@ OverloadedTemplate
A set of overloaded template declarations.
@ Template
A single template declaration.
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
@ AssumedTemplate
An unqualified-id that has been assumed to name a function template that will be found by ADL.
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
SourceLocation getTemplateLoc() const
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
Declaration of a template type parameter.
bool isParameterPack() const
Returns whether this is a parameter pack.
Declaration of an alias template.
TypeAliasDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
QualType getType() const
Return the type wrapped by this type source info.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
ArrayRef< TypeSourceInfo * > getArgs() const
Retrieve the argument types.
TypeTrait getTrait() const
Determine which type trait this expression uses.
const T * castAs() const
Member-template castAs<specific type>.
TypeClass getTypeClass() const
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given unary opcode.
Represents a call to the builtin function __builtin_va_arg.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
const Expr * getInit() const
StorageClass getStorageClass() const
Returns the storage class as written in the source.
The JSON file list parser is used to communicate input to InstallAPI.
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
@ EST_Dynamic
throw(T1, T2)
llvm::DenseSet< std::pair< Decl *, Decl * > > & NonEquivalentDecls
Declaration (from, to) pairs that are known not to be equivalent (which we have already complained ab...
ASTContext & FromCtx
AST contexts for which we are checking structural equivalence.
bool LastDiagFromC2
true if the last diagnostic came from ToCtx.
std::queue< std::pair< Decl *, Decl * > > DeclsToCheck
llvm::DenseSet< std::pair< Decl *, Decl * > > VisitedDecls
bool ErrorOnTagTypeMismatch
Whether warn or error on tag type mismatches.
static std::optional< unsigned > findUntaggedStructOrUnionIndex(RecordDecl *Anon)
Find the index of the given anonymous struct/union within its context.
bool Complain
Whether to complain about failures.
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID)
unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic)
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID)
bool IsEquivalent(Decl *D1, Decl *D2)
Determine whether the two declarations are structurally equivalent.