85 #include "llvm/ADT/APInt.h" 86 #include "llvm/ADT/APSInt.h" 87 #include "llvm/ADT/None.h" 88 #include "llvm/ADT/Optional.h" 89 #include "llvm/Support/Casting.h" 90 #include "llvm/Support/Compiler.h" 91 #include "llvm/Support/ErrorHandling.h" 95 using namespace clang;
154 llvm_unreachable(
"Unhandled kind of DeclarationName");
164 if (
auto *DE1 = dyn_cast<DependentScopeDeclRefExpr>(E1)) {
172 DE2->getQualifier());
173 }
else if (
auto CastE1 = dyn_cast<ImplicitCastExpr>(E1)) {
181 CastE2->getSubExpr());
190 if (!Name1 || !Name2)
191 return Name1 == Name2;
205 if ((
bool)Prefix1 != (
bool)Prefix2)
240 if (TemplateDeclN1 && TemplateDeclN2) {
246 }
else if (TemplateDeclN1 || TemplateDeclN2)
258 E1 = OS1->
end(), E2 = OS2->end();
259 for (; I1 != E1 && I2 != E2; ++I1, ++I2)
262 return I1 == E1 && I2 == E2;
275 DN2->getQualifier()))
279 DN2->getIdentifier());
290 P2->getArgumentPack()) &&
292 P2->getParameterPack());
351 for (
unsigned I = 0, N = Arg1.
pack_size(); I != N; ++I)
359 llvm_unreachable(
"Invalid template argument kind");
460 TC = Type::FunctionNoProto;
463 TC = Type::FunctionNoProto;
471 if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->
getKind())
477 cast<ComplexType>(T1)->getElementType(),
478 cast<ComplexType>(T2)->getElementType()))
485 cast<AdjustedType>(T1)->getOriginalType(),
486 cast<AdjustedType>(T2)->getOriginalType()))
492 cast<PointerType>(T1)->getPointeeType(),
493 cast<PointerType>(T2)->getPointeeType()))
497 case Type::BlockPointer:
499 cast<BlockPointerType>(T1)->getPointeeType(),
500 cast<BlockPointerType>(T2)->getPointeeType()))
504 case Type::LValueReference:
505 case Type::RValueReference: {
506 const auto *Ref1 = cast<ReferenceType>(T1);
507 const auto *Ref2 = cast<ReferenceType>(T2);
508 if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
510 if (Ref1->isInnerRef() != Ref2->isInnerRef())
513 Ref2->getPointeeTypeAsWritten()))
518 case Type::MemberPointer: {
519 const auto *MemPtr1 = cast<MemberPointerType>(T1);
520 const auto *MemPtr2 = cast<MemberPointerType>(T2);
522 MemPtr2->getPointeeType()))
530 case Type::ConstantArray: {
531 const auto *Array1 = cast<ConstantArrayType>(T1);
532 const auto *Array2 = cast<ConstantArrayType>(T2);
533 if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
541 case Type::IncompleteArray:
543 cast<ArrayType>(T2)))
547 case Type::VariableArray: {
548 const auto *Array1 = cast<VariableArrayType>(T1);
549 const auto *Array2 = cast<VariableArrayType>(T2);
551 Array2->getSizeExpr()))
560 case Type::DependentSizedArray: {
561 const auto *Array1 = cast<DependentSizedArrayType>(T1);
562 const auto *Array2 = cast<DependentSizedArrayType>(T2);
564 Array2->getSizeExpr()))
573 case Type::DependentAddressSpace: {
574 const auto *DepAddressSpace1 = cast<DependentAddressSpaceType>(T1);
575 const auto *DepAddressSpace2 = cast<DependentAddressSpaceType>(T2);
577 DepAddressSpace2->getAddrSpaceExpr()))
580 DepAddressSpace2->getPointeeType()))
586 case Type::DependentSizedExtVector: {
587 const auto *Vec1 = cast<DependentSizedExtVectorType>(T1);
588 const auto *Vec2 = cast<DependentSizedExtVectorType>(T2);
590 Vec2->getSizeExpr()))
593 Vec2->getElementType()))
598 case Type::DependentVector: {
599 const auto *Vec1 = cast<DependentVectorType>(T1);
600 const auto *Vec2 = cast<DependentVectorType>(T2);
601 if (Vec1->getVectorKind() != Vec2->getVectorKind())
604 Vec2->getSizeExpr()))
607 Vec2->getElementType()))
613 case Type::ExtVector: {
614 const auto *Vec1 = cast<VectorType>(T1);
615 const auto *Vec2 = cast<VectorType>(T2);
617 Vec2->getElementType()))
619 if (Vec1->getNumElements() != Vec2->getNumElements())
621 if (Vec1->getVectorKind() != Vec2->getVectorKind())
626 case Type::FunctionProto: {
627 const auto *Proto1 = cast<FunctionProtoType>(T1);
628 const auto *Proto2 = cast<FunctionProtoType>(T2);
630 if (Proto1->getNumParams() != Proto2->getNumParams())
632 for (
unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
634 Proto2->getParamType(I)))
637 if (Proto1->isVariadic() != Proto2->isVariadic())
640 if (Proto1->getMethodQuals() != Proto2->getMethodQuals())
644 const auto *OrigProto1 =
646 const auto *OrigProto2 =
655 case Type::FunctionNoProto: {
656 const auto *Function1 = cast<FunctionType>(T1);
657 const auto *Function2 = cast<FunctionType>(T2);
659 Function2->getReturnType()))
662 Function2->getExtInfo()))
667 case Type::UnresolvedUsing:
669 cast<UnresolvedUsingType>(T1)->getDecl(),
670 cast<UnresolvedUsingType>(T2)->getDecl()))
674 case Type::Attributed:
676 cast<AttributedType>(T1)->getModifiedType(),
677 cast<AttributedType>(T2)->getModifiedType()))
680 Context, cast<AttributedType>(T1)->getEquivalentType(),
681 cast<AttributedType>(T2)->getEquivalentType()))
687 cast<ParenType>(T2)->getInnerType()))
691 case Type::MacroQualified:
693 Context, cast<MacroQualifiedType>(T1)->getUnderlyingType(),
700 cast<TypedefType>(T2)->getDecl()))
704 case Type::TypeOfExpr:
706 Context, cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
707 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
713 cast<TypeOfType>(T1)->getUnderlyingType(),
718 case Type::UnaryTransform:
720 Context, cast<UnaryTransformType>(T1)->getUnderlyingType(),
727 cast<DecltypeType>(T1)->getUnderlyingExpr(),
728 cast<DecltypeType>(T2)->getUnderlyingExpr()))
733 auto *Auto1 = cast<AutoType>(T1);
734 auto *Auto2 = cast<AutoType>(T2);
736 Auto2->getDeducedType()))
738 if (Auto1->isConstrained() != Auto2->isConstrained())
740 if (Auto1->isConstrained()) {
741 if (Auto1->getTypeConstraintConcept() !=
742 Auto2->getTypeConstraintConcept())
745 Auto1->getTypeConstraintArguments();
747 Auto2->getTypeConstraintArguments();
748 if (Auto1Args.size() != Auto2Args.size())
750 for (
unsigned I = 0, N = Auto1Args.size(); I != N; ++I) {
758 case Type::DeducedTemplateSpecialization: {
759 const auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
760 const auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
762 DT2->getTemplateName()))
765 DT2->getDeducedType()))
773 cast<TagType>(T2)->getDecl()))
777 case Type::TemplateTypeParm: {
778 const auto *Parm1 = cast<TemplateTypeParmType>(T1);
779 const auto *Parm2 = cast<TemplateTypeParmType>(T2);
780 if (Parm1->getDepth() != Parm2->getDepth())
782 if (Parm1->getIndex() != Parm2->getIndex())
784 if (Parm1->isParameterPack() != Parm2->isParameterPack())
791 case Type::SubstTemplateTypeParm: {
792 const auto *Subst1 = cast<SubstTemplateTypeParmType>(T1);
793 const auto *Subst2 = cast<SubstTemplateTypeParmType>(T2);
795 QualType(Subst1->getReplacedParameter(), 0),
796 QualType(Subst2->getReplacedParameter(), 0)))
799 Subst2->getReplacementType()))
804 case Type::SubstTemplateTypeParmPack: {
805 const auto *Subst1 = cast<SubstTemplateTypeParmPackType>(T1);
806 const auto *Subst2 = cast<SubstTemplateTypeParmPackType>(T2);
808 QualType(Subst1->getReplacedParameter(), 0),
809 QualType(Subst2->getReplacedParameter(), 0)))
812 Subst2->getArgumentPack()))
817 case Type::TemplateSpecialization: {
818 const auto *Spec1 = cast<TemplateSpecializationType>(T1);
819 const auto *Spec2 = cast<TemplateSpecializationType>(T2);
821 Spec2->getTemplateName()))
823 if (Spec1->getNumArgs() != Spec2->getNumArgs())
825 for (
unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
833 case Type::Elaborated: {
834 const auto *Elab1 = cast<ElaboratedType>(T1);
835 const auto *Elab2 = cast<ElaboratedType>(T2);
837 if (Elab1->getKeyword() != Elab2->getKeyword())
840 Elab2->getQualifier()))
843 Elab2->getNamedType()))
848 case Type::InjectedClassName: {
849 const auto *Inj1 = cast<InjectedClassNameType>(T1);
850 const auto *Inj2 = cast<InjectedClassNameType>(T2);
852 Inj1->getInjectedSpecializationType(),
853 Inj2->getInjectedSpecializationType()))
858 case Type::DependentName: {
859 const auto *Typename1 = cast<DependentNameType>(T1);
860 const auto *Typename2 = cast<DependentNameType>(T2);
862 Typename2->getQualifier()))
865 Typename2->getIdentifier()))
871 case Type::DependentTemplateSpecialization: {
872 const auto *Spec1 = cast<DependentTemplateSpecializationType>(T1);
873 const auto *Spec2 = cast<DependentTemplateSpecializationType>(T2);
875 Spec2->getQualifier()))
878 Spec2->getIdentifier()))
880 if (Spec1->getNumArgs() != Spec2->getNumArgs())
882 for (
unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
890 case Type::PackExpansion:
892 cast<PackExpansionType>(T1)->getPattern(),
893 cast<PackExpansionType>(T2)->getPattern()))
897 case Type::ObjCInterface: {
898 const auto *Iface1 = cast<ObjCInterfaceType>(T1);
899 const auto *Iface2 = cast<ObjCInterfaceType>(T2);
906 case Type::ObjCTypeParam: {
907 const auto *Obj1 = cast<ObjCTypeParamType>(T1);
908 const auto *Obj2 = cast<ObjCTypeParamType>(T2);
912 if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
914 for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
916 Obj2->getProtocol(I)))
922 case Type::ObjCObject: {
923 const auto *Obj1 = cast<ObjCObjectType>(T1);
924 const auto *Obj2 = cast<ObjCObjectType>(T2);
926 Obj2->getBaseType()))
928 if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
930 for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
932 Obj2->getProtocol(I)))
938 case Type::ObjCObjectPointer: {
939 const auto *Ptr1 = cast<ObjCObjectPointerType>(T1);
940 const auto *Ptr2 = cast<ObjCObjectPointerType>(T2);
942 Ptr2->getPointeeType()))
949 cast<AtomicType>(T2)->getValueType()))
955 cast<PipeType>(T2)->getElementType()))
984 Owner2->getLocation(),
999 Owner2->getLocation(),
1013 Owner2->getLocation(),
1038 if (Bits1 != Bits2) {
1040 Context.
Diag2(Owner2->getLocation(),
1042 diag::err_odr_tag_type_inconsistent))
1060 bool PropertiesEqual =
1072 if (!PropertiesEqual)
1076 if (
auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
1077 auto *Constructor2 = cast<CXXConstructorDecl>(Method2);
1078 if (!Constructor1->getExplicitSpecifier().isEquivalent(
1079 Constructor2->getExplicitSpecifier()))
1083 if (
auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
1084 auto *Conversion2 = cast<CXXConversionDecl>(Method2);
1085 if (!Conversion1->getExplicitSpecifier().isEquivalent(
1086 Conversion2->getExplicitSpecifier()))
1089 Conversion2->getConversionType()))
1113 "Must be called on lambda classes");
1127 diag::err_odr_tag_type_inconsistent))
1143 if (*Index1 != *Index2)
1153 if (Spec1 && Spec2) {
1156 Spec2->getSpecializedTemplate()))
1160 if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
1163 for (
unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
1165 Spec2->getTemplateArgs().get(I)))
1170 else if (Spec1 || Spec2)
1195 if (
auto *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
1196 if (
auto *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
1197 if (D1CXX->hasExternalLexicalStorage() &&
1198 !D1CXX->isCompleteDefinition()) {
1202 if (D1CXX->isLambda() != D2CXX->isLambda())
1204 if (D1CXX->isLambda()) {
1209 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
1213 diag::err_odr_tag_type_inconsistent))
1216 << D2CXX->getNumBases();
1218 << D1CXX->getNumBases();
1225 BaseEnd1 = D1CXX->bases_end(),
1226 Base2 = D2CXX->bases_begin();
1227 Base1 != BaseEnd1; ++Base1, ++Base2) {
1229 Base2->getType())) {
1233 diag::err_odr_tag_type_inconsistent))
1235 Context.
Diag2(Base2->getBeginLoc(), diag::note_odr_base)
1236 << Base2->getType() << Base2->getSourceRange();
1237 Context.
Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1238 << Base1->getType() << Base1->getSourceRange();
1244 if (Base1->isVirtual() != Base2->isVirtual()) {
1248 diag::err_odr_tag_type_inconsistent))
1250 Context.
Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
1251 << Base2->isVirtual() << Base2->getSourceRange();
1252 Context.
Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1253 << Base1->isVirtual() << Base1->getSourceRange();
1261 Friend2End = D2CXX->friend_end();
1263 Friend1End = D1CXX->friend_end();
1264 Friend1 != Friend1End; ++Friend1, ++Friend2) {
1265 if (Friend2 == Friend2End) {
1269 diag::err_odr_tag_type_inconsistent))
1271 Context.
Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1281 diag::err_odr_tag_type_inconsistent))
1283 Context.
Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1284 Context.
Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1290 if (Friend2 != Friend2End) {
1294 diag::err_odr_tag_type_inconsistent))
1296 Context.
Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1301 }
else if (D1CXX->getNumBases() > 0) {
1305 diag::err_odr_tag_type_inconsistent))
1321 Field1 != Field1End; ++Field1, ++Field2) {
1322 if (Field2 == Field2End) {
1326 diag::err_odr_tag_type_inconsistent))
1328 Context.
Diag1(Field1->getLocation(), diag::note_odr_field)
1329 << Field1->getDeclName() << Field1->getType();
1339 if (Field2 != Field2End) {
1342 diag::err_odr_tag_type_inconsistent))
1344 Context.
Diag2(Field2->getLocation(), diag::note_odr_field)
1345 << Field2->getDeclName() << Field2->getType();
1369 EC1 != EC1End; ++EC1, ++EC2) {
1370 if (EC2 == EC2End) {
1374 diag::err_odr_tag_type_inconsistent))
1376 Context.
Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1377 << EC1->getDeclName() << EC1->getInitVal().toString(10);
1385 if (!llvm::APSInt::isSameValue(Val1, Val2) ||
1390 diag::err_odr_tag_type_inconsistent))
1392 Context.
Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1393 << EC2->getDeclName() << EC2->getInitVal().toString(10);
1394 Context.
Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1395 << EC1->getDeclName() << EC1->getInitVal().toString(10);
1401 if (EC2 != EC2End) {
1404 diag::err_odr_tag_type_inconsistent))
1406 Context.
Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1407 << EC2->getDeclName() << EC2->getInitVal().toString(10);
1419 if (Params1->
size() != Params2->
size()) {
1423 diag::err_odr_different_num_template_parameters))
1424 << Params1->
size() << Params2->
size();
1426 diag::note_odr_template_parameter_list);
1431 for (
unsigned I = 0, N = Params1->
size(); I != N; ++I) {
1436 diag::err_odr_different_template_parameter_kind));
1438 diag::note_odr_template_parameter_here);
1458 diag::err_odr_parameter_pack_non_pack))
1476 diag::err_odr_parameter_pack_non_pack))
1489 diag::err_odr_non_type_parameter_type_inconsistent))
1507 diag::err_odr_parameter_pack_non_pack))
1599 std::pair<Decl *, Decl *>
P{D1, D2};
1620 assert(
Complain &&
"Not allowed to complain");
1629 assert(
Complain &&
"Not allowed to complain");
1646 for (
const auto *D : Owner->noload_decls()) {
1651 if (F->isAnonymousStructOrUnion()) {
1662 while (
const auto *ElabType = dyn_cast<ElaboratedType>(FieldType))
1663 FieldType = ElabType->getNamedType();
1665 if (
const auto *RecType = dyn_cast<RecordType>(FieldType)) {
1666 const RecordDecl *RecDecl = RecType->getDecl();
1680 unsigned ErrorDiagnostic) {
1682 return ErrorDiagnostic;
1684 switch (ErrorDiagnostic) {
1685 case diag::err_odr_variable_type_inconsistent:
1686 return diag::warn_odr_variable_type_inconsistent;
1687 case diag::err_odr_variable_multiple_def:
1688 return diag::warn_odr_variable_multiple_def;
1689 case diag::err_odr_function_type_inconsistent:
1690 return diag::warn_odr_function_type_inconsistent;
1691 case diag::err_odr_tag_type_inconsistent:
1692 return diag::warn_odr_tag_type_inconsistent;
1693 case diag::err_odr_field_type_inconsistent:
1694 return diag::warn_odr_field_type_inconsistent;
1695 case diag::err_odr_ivar_type_inconsistent:
1696 return diag::warn_odr_ivar_type_inconsistent;
1697 case diag::err_odr_objc_superclass_inconsistent:
1698 return diag::warn_odr_objc_superclass_inconsistent;
1699 case diag::err_odr_objc_method_result_type_inconsistent:
1700 return diag::warn_odr_objc_method_result_type_inconsistent;
1701 case diag::err_odr_objc_method_num_params_inconsistent:
1702 return diag::warn_odr_objc_method_num_params_inconsistent;
1703 case diag::err_odr_objc_method_param_type_inconsistent:
1704 return diag::warn_odr_objc_method_param_type_inconsistent;
1705 case diag::err_odr_objc_method_variadic_inconsistent:
1706 return diag::warn_odr_objc_method_variadic_inconsistent;
1707 case diag::err_odr_objc_property_type_inconsistent:
1708 return diag::warn_odr_objc_property_type_inconsistent;
1709 case diag::err_odr_objc_property_impl_kind_inconsistent:
1710 return diag::warn_odr_objc_property_impl_kind_inconsistent;
1711 case diag::err_odr_objc_synthesize_ivar_inconsistent:
1712 return diag::warn_odr_objc_synthesize_ivar_inconsistent;
1713 case diag::err_odr_different_num_template_parameters:
1714 return diag::warn_odr_different_num_template_parameters;
1715 case diag::err_odr_different_template_parameter_kind:
1716 return diag::warn_odr_different_template_parameter_kind;
1717 case diag::err_odr_parameter_pack_non_pack:
1718 return diag::warn_odr_parameter_pack_non_pack;
1719 case diag::err_odr_non_type_parameter_type_inconsistent:
1720 return diag::warn_odr_non_type_parameter_type_inconsistent;
1722 llvm_unreachable(
"Diagnostic kind not handled in preceding switch");
1753 bool StructuralEquivalenceContext::CheckCommonEquivalence(
Decl *D1,
Decl *D2) {
1757 if ((Template1 !=
nullptr) != (Template2 !=
nullptr))
1767 bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
1771 if (
auto *Record1 = dyn_cast<RecordDecl>(D1)) {
1772 if (
auto *Record2 = dyn_cast<RecordDecl>(D2)) {
1775 if (!Name1 && Record1->getTypedefNameForAnonDecl())
1776 Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
1778 if (!Name2 && Record2->getTypedefNameForAnonDecl())
1779 Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
1787 }
else if (
auto *Enum1 = dyn_cast<EnumDecl>(D1)) {
1788 if (
auto *Enum2 = dyn_cast<EnumDecl>(D2)) {
1791 if (!Name1 && Enum1->getTypedefNameForAnonDecl())
1792 Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
1794 if (!Name2 && Enum2->getTypedefNameForAnonDecl())
1795 Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
1803 }
else if (
const auto *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
1804 if (
const auto *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
1806 Typedef2->getIdentifier()) ||
1808 Typedef2->getUnderlyingType()))
1814 }
else if (
auto *ClassTemplate1 = dyn_cast<ClassTemplateDecl>(D1)) {
1815 if (
auto *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
1823 }
else if (
auto *FunctionTemplate1 = dyn_cast<FunctionTemplateDecl>(D1)) {
1824 if (
auto *FunctionTemplate2 = dyn_cast<FunctionTemplateDecl>(D2)) {
1832 }
else if (
auto *ConceptDecl1 = dyn_cast<ConceptDecl>(D1)) {
1833 if (
auto *ConceptDecl2 = dyn_cast<ConceptDecl>(D2)) {
1840 }
else if (
auto *TTP1 = dyn_cast<TemplateTypeParmDecl>(D1)) {
1841 if (
auto *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
1848 }
else if (
auto *NTTP1 = dyn_cast<NonTypeTemplateParmDecl>(D1)) {
1849 if (
auto *NTTP2 = dyn_cast<NonTypeTemplateParmDecl>(D2)) {
1856 }
else if (
auto *TTP1 = dyn_cast<TemplateTemplateParmDecl>(D1)) {
1857 if (
auto *TTP2 = dyn_cast<TemplateTemplateParmDecl>(D2)) {
1864 }
else if (
auto *MD1 = dyn_cast<CXXMethodDecl>(D1)) {
1865 if (
auto *MD2 = dyn_cast<CXXMethodDecl>(D2)) {
1872 }
else if (
FunctionDecl *FD1 = dyn_cast<FunctionDecl>(D1)) {
1874 if (FD1->isOverloadedOperator()) {
1875 if (!FD2->isOverloadedOperator())
1877 if (FD1->getOverloadedOperator() != FD2->getOverloadedOperator())
1881 FD2->getIdentifier()))
1889 }
else if (
FriendDecl *FrD1 = dyn_cast<FriendDecl>(D1)) {
1890 if (
FriendDecl *FrD2 = dyn_cast<FriendDecl>(D2)) {
1902 bool StructuralEquivalenceContext::Finish() {
1909 Decl *D2 = P.second;
1912 CheckCommonEquivalence(D1, D2) && CheckKindSpecificEquivalence(D1, D2);
TemplateTemplateParmDecl * getParameterPack() const
Retrieve the template template parameter pack being substituted.
Defines the clang::ASTContext interface.
enumerator_iterator enumerator_end() const
Represents a function declaration or definition.
A (possibly-)qualified type.
static llvm::Optional< unsigned > findUntaggedStructOrUnionIndex(RecordDecl *Anon)
Find the index of the given anonymous struct/union within its context.
OverloadedOperatorKind getOperator() const
Return the overloaded operator to which this template name refers.
bool getNoCfCheck() const
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
unsigned getNumExceptions() const
Return the number of types in the exception specification.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext &Context, const FunctionProtoType *Proto1, const FunctionProtoType *Proto2)
Check the equivalence of exception specifications.
C Language Family Type Representation.
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in...
The template argument is an expression, and we've not resolved it to one of the other forms yet...
Decl - This represents one declaration (or definition), e.g.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
Defines the C++ template declaration subclasses.
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
DiagnosticsEngine & getDiagnostics() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
The template argument is a declaration that was provided for a pointer, reference, or pointer to member non-type template parameter.
DeclarationName getDeclName() const
Get the name of the template.
NamedDecl * getParam(unsigned Idx)
A template template parameter that has been substituted for some other template name.
QualType getElementType() const
const IdentifierInfo * getIdentifier() const
Returns the identifier to which this template name refers.
An identifier, stored as an IdentifierInfo*.
FriendDecl - Represents the declaration of a friend entity, which can be a function, a type, or a templated function or type.
Represents an empty template argument, e.g., one that has not been deduced.
ASTContext & FromCtx
AST contexts for which we are checking structural equivalence.
A namespace, stored as a NamespaceDecl*.
Stores a list of template parameters for a TemplateDecl and its derived classes.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
Defines the clang::Expr interface and subclasses for C++ expressions.
QualType getIntegralType() const
Retrieve the type of the integral value.
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID)
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a struct/union/class.
An iterator over the friend declarations of a class.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a class template specialization, which refers to a class template with a given set of temp...
One of these records is kept for each identifier that is lexed.
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
unsigned getRegParm() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents a dependent template name that cannot be resolved prior to template instantiation.
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
NameKind getNameKind() const
Determine what kind of name this is.
bool ErrorOnTagTypeMismatch
Whether warn or error on tag type mismatches.
Represents a member of a struct/union/class.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
Defines the ExceptionSpecificationType enumeration and various utility functions. ...
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID)
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
SourceLocation getTemplateLoc() const
bool getProducesResult() const
bool StrictTypeSpelling
Whether we're being strict about the spelling of types when unifying two types.
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
bool isBitField() const
Determines whether this field is a bitfield.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
A qualified template name, where the qualification is kept to describe the source code as written...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
TagKind getTagKind() const
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
An unqualified-id that has been assumed to name a function template that will be found by ADL...
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
bool isLambda() const
Determine whether this class describes a lambda function object.
field_iterator field_begin() const
unsigned getBitWidthValue(const ASTContext &Ctx) const
NamedDecl *const * iterator
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
bool getNoCallerSavedRegs() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
StructuralEquivalenceKind EqKind
A little helper class used to produce diagnostics.
Represents a prototype with parameter type info, e.g.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any...
A dependent template name that has not been resolved to a template (or set of templates).
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
SourceLocation getBeginLoc() const LLVM_READONLY
static bool IsTemplateDeclCommonStructurallyEquivalent(StructuralEquivalenceContext &Ctx, TemplateDecl *D1, TemplateDecl *D2)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
QualType getCXXNameType() const
If this name is one of the C++ names (of a constructor, destructor, or conversion function)...
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
This represents one expression.
bool isDefaulted() const
Whether this function is defaulted per C++0x.
Declaration of a template type parameter.
bool LastDiagFromC2
true if the last diagnostic came from ToCtx.
bool getHasRegParm() const
const T * castAs() const
Member-template castAs<specific type>.
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
std::queue< std::pair< Decl *, Decl * > > DeclsToCheck
field_iterator field_end() const
DeclContext * getDeclContext()
unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic)
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents a C++ template name within the type system.
EnumDecl * getDefinition() const
bool isIdentifier() const
Determine whether this template name refers to an identifier.
A namespace alias, stored as a NamespaceAliasDecl*.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context, const ArrayType *Array1, const ArrayType *Array2)
Determine structural equivalence for the common part of array types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
enumerator_iterator enumerator_begin() const
QualType getRecordType(const RecordDecl *Decl) const
ArraySizeModifier getSizeModifier() const
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
A type, stored as a Type*.
A template template parameter pack that has been substituted for a template template argument pack...
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
Decl::Kind getDeclKind() const
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template declarations that this template name refers to...
bool isParameterPack() const
Returns whether this is a parameter pack.
Encodes a location in the source.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
bool isPure() const
Whether this virtual function is pure, i.e.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, QualType T1, QualType T2)
Determine structural equivalence of two types.
A structure for storing an already-substituted template template parameter pack.
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...
ASTContext & getASTContext() const LLVM_READONLY
CallingConv getCC() const
static QualType getUnderlyingType(const SubRegion *R)
Represents a static or instance method of a struct/union/class.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
bool isOverloadedOperator() const
Determine whether this template name refers to an overloaded operator.
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Qualifiers getIndexTypeQualifiers() const
TypeClass getTypeClass() const
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
A qualified reference to a name whose declaration cannot yet be resolved.
StringRef getName() const
Return the actual identifier string.
Represents a template argument.
Dataflow Directional Tag Classes.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
The template argument is a pack expansion of a template name that was provided for a template templat...
AccessSpecifier getAccess() const
The name of a declaration.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
A type that was preceded by the 'template' keyword, stored as a Type*.
pack_iterator pack_begin() const
Iterator referencing the first argument of a template argument pack.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
bool IsEquivalent(Decl *D1, Decl *D2)
Determine whether the two declarations are structurally equivalent.
static bool IsStructurallyEquivalentLambdas(StructuralEquivalenceContext &Context, CXXRecordDecl *D1, CXXRecordDecl *D2)
Determine structural equivalence of two lambda classes.
llvm::DenseSet< std::pair< Decl *, Decl * > > & NonEquivalentDecls
Declaration (from, to) pairs that are known not to be equivalent (which we have already complained ab...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
The template argument is a type.
AssumedTemplateStorage * getAsAssumedTemplateName() const
Retrieve information on a name that has been assumed to be a template-name in order to permit a call ...
The template argument is actually a parameter pack.
llvm::DenseSet< std::pair< Decl *, Decl * > > VisitedDecls
Represents a base class of a C++ class.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
ArgKind getKind() const
Return the kind of stored template argument.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
TemplateDecl * getCXXDeductionGuideTemplate() const
If this name is the name of a C++ deduction guide, return the template associated with that name...
Defines the clang::SourceLocation class and associated facilities.
Represents a C++ struct/union/class.
The template argument is a template name that was provided for a template template parameter...
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
A structure for storing the information associated with an overloaded template name.
A structure for storing the information associated with a name that has been assumed to be a template...
Declaration of a class template.
static Decl::Kind getKind(const Decl *D)
QualType getAsType() const
Retrieve the type for a type template argument.
bool isDeleted() const
Whether this function has been deleted.
bool Complain
Whether to complain about failures.
IdentifierInfo * getCXXLiteralIdentifier() const
If this name is the name of a literal operator, retrieve the identifier associated with it...
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
A set of overloaded template declarations.
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration...
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Expr * getConstraintExpr() const
The global specifier '::'. There is no stored value.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion, return the pattern as a template name.
Declaration of a template function.
A class which abstracts out some details necessary for making a call.
SourceLocation getLocation() const
QualType getType() const
Return the type wrapped by this type source info.
A single template declaration.
bool isBeingDefined() const
Return true if this decl is currently being defined.
QualType getType() const
Retrieves the type of the base class.
void notePriorDiagnosticFrom(const DiagnosticsEngine &Other)
Note that the prior diagnostic was emitted by some other DiagnosticsEngine, and we may be attaching a...