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()))
734 cast<AutoType>(T2)->getDeducedType()))
738 case Type::DeducedTemplateSpecialization: {
739 const auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
740 const auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
742 DT2->getTemplateName()))
745 DT2->getDeducedType()))
753 cast<TagType>(T2)->getDecl()))
757 case Type::TemplateTypeParm: {
758 const auto *Parm1 = cast<TemplateTypeParmType>(T1);
759 const auto *Parm2 = cast<TemplateTypeParmType>(T2);
760 if (Parm1->getDepth() != Parm2->getDepth())
762 if (Parm1->getIndex() != Parm2->getIndex())
764 if (Parm1->isParameterPack() != Parm2->isParameterPack())
771 case Type::SubstTemplateTypeParm: {
772 const auto *Subst1 = cast<SubstTemplateTypeParmType>(T1);
773 const auto *Subst2 = cast<SubstTemplateTypeParmType>(T2);
775 QualType(Subst1->getReplacedParameter(), 0),
776 QualType(Subst2->getReplacedParameter(), 0)))
779 Subst2->getReplacementType()))
784 case Type::SubstTemplateTypeParmPack: {
785 const auto *Subst1 = cast<SubstTemplateTypeParmPackType>(T1);
786 const auto *Subst2 = cast<SubstTemplateTypeParmPackType>(T2);
788 QualType(Subst1->getReplacedParameter(), 0),
789 QualType(Subst2->getReplacedParameter(), 0)))
792 Subst2->getArgumentPack()))
797 case Type::TemplateSpecialization: {
798 const auto *Spec1 = cast<TemplateSpecializationType>(T1);
799 const auto *Spec2 = cast<TemplateSpecializationType>(T2);
801 Spec2->getTemplateName()))
803 if (Spec1->getNumArgs() != Spec2->getNumArgs())
805 for (
unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
813 case Type::Elaborated: {
814 const auto *Elab1 = cast<ElaboratedType>(T1);
815 const auto *Elab2 = cast<ElaboratedType>(T2);
817 if (Elab1->getKeyword() != Elab2->getKeyword())
820 Elab2->getQualifier()))
823 Elab2->getNamedType()))
828 case Type::InjectedClassName: {
829 const auto *Inj1 = cast<InjectedClassNameType>(T1);
830 const auto *Inj2 = cast<InjectedClassNameType>(T2);
832 Inj1->getInjectedSpecializationType(),
833 Inj2->getInjectedSpecializationType()))
838 case Type::DependentName: {
839 const auto *Typename1 = cast<DependentNameType>(T1);
840 const auto *Typename2 = cast<DependentNameType>(T2);
842 Typename2->getQualifier()))
845 Typename2->getIdentifier()))
851 case Type::DependentTemplateSpecialization: {
852 const auto *Spec1 = cast<DependentTemplateSpecializationType>(T1);
853 const auto *Spec2 = cast<DependentTemplateSpecializationType>(T2);
855 Spec2->getQualifier()))
858 Spec2->getIdentifier()))
860 if (Spec1->getNumArgs() != Spec2->getNumArgs())
862 for (
unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
870 case Type::PackExpansion:
872 cast<PackExpansionType>(T1)->getPattern(),
873 cast<PackExpansionType>(T2)->getPattern()))
877 case Type::ObjCInterface: {
878 const auto *Iface1 = cast<ObjCInterfaceType>(T1);
879 const auto *Iface2 = cast<ObjCInterfaceType>(T2);
886 case Type::ObjCTypeParam: {
887 const auto *Obj1 = cast<ObjCTypeParamType>(T1);
888 const auto *Obj2 = cast<ObjCTypeParamType>(T2);
892 if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
894 for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
896 Obj2->getProtocol(I)))
902 case Type::ObjCObject: {
903 const auto *Obj1 = cast<ObjCObjectType>(T1);
904 const auto *Obj2 = cast<ObjCObjectType>(T2);
906 Obj2->getBaseType()))
908 if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
910 for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
912 Obj2->getProtocol(I)))
918 case Type::ObjCObjectPointer: {
919 const auto *Ptr1 = cast<ObjCObjectPointerType>(T1);
920 const auto *Ptr2 = cast<ObjCObjectPointerType>(T2);
922 Ptr2->getPointeeType()))
929 cast<AtomicType>(T2)->getValueType()))
935 cast<PipeType>(T2)->getElementType()))
964 Owner2->getLocation(),
979 Owner2->getLocation(),
993 Owner2->getLocation(),
1018 if (Bits1 != Bits2) {
1020 Context.
Diag2(Owner2->getLocation(),
1022 diag::err_odr_tag_type_inconsistent))
1040 bool PropertiesEqual =
1052 if (!PropertiesEqual)
1056 if (
auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
1057 auto *Constructor2 = cast<CXXConstructorDecl>(Method2);
1058 if (!Constructor1->getExplicitSpecifier().isEquivalent(
1059 Constructor2->getExplicitSpecifier()))
1063 if (
auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
1064 auto *Conversion2 = cast<CXXConversionDecl>(Method2);
1065 if (!Conversion1->getExplicitSpecifier().isEquivalent(
1066 Conversion2->getExplicitSpecifier()))
1069 Conversion2->getConversionType()))
1093 "Must be called on lambda classes");
1107 diag::err_odr_tag_type_inconsistent))
1123 if (*Index1 != *Index2)
1133 if (Spec1 && Spec2) {
1136 Spec2->getSpecializedTemplate()))
1140 if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
1143 for (
unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
1145 Spec2->getTemplateArgs().get(I)))
1150 else if (Spec1 || Spec2)
1175 if (
auto *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
1176 if (
auto *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
1177 if (D1CXX->hasExternalLexicalStorage() &&
1178 !D1CXX->isCompleteDefinition()) {
1182 if (D1CXX->isLambda() != D2CXX->isLambda())
1184 if (D1CXX->isLambda()) {
1189 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
1193 diag::err_odr_tag_type_inconsistent))
1196 << D2CXX->getNumBases();
1198 << D1CXX->getNumBases();
1205 BaseEnd1 = D1CXX->bases_end(),
1206 Base2 = D2CXX->bases_begin();
1207 Base1 != BaseEnd1; ++Base1, ++Base2) {
1209 Base2->getType())) {
1213 diag::err_odr_tag_type_inconsistent))
1215 Context.
Diag2(Base2->getBeginLoc(), diag::note_odr_base)
1216 << Base2->getType() << Base2->getSourceRange();
1217 Context.
Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1218 << Base1->getType() << Base1->getSourceRange();
1224 if (Base1->isVirtual() != Base2->isVirtual()) {
1228 diag::err_odr_tag_type_inconsistent))
1230 Context.
Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
1231 << Base2->isVirtual() << Base2->getSourceRange();
1232 Context.
Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1233 << Base1->isVirtual() << Base1->getSourceRange();
1241 Friend2End = D2CXX->friend_end();
1243 Friend1End = D1CXX->friend_end();
1244 Friend1 != Friend1End; ++Friend1, ++Friend2) {
1245 if (Friend2 == Friend2End) {
1249 diag::err_odr_tag_type_inconsistent))
1251 Context.
Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1261 diag::err_odr_tag_type_inconsistent))
1263 Context.
Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1264 Context.
Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1270 if (Friend2 != Friend2End) {
1274 diag::err_odr_tag_type_inconsistent))
1276 Context.
Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1281 }
else if (D1CXX->getNumBases() > 0) {
1285 diag::err_odr_tag_type_inconsistent))
1301 Field1 != Field1End; ++Field1, ++Field2) {
1302 if (Field2 == Field2End) {
1306 diag::err_odr_tag_type_inconsistent))
1308 Context.
Diag1(Field1->getLocation(), diag::note_odr_field)
1309 << Field1->getDeclName() << Field1->getType();
1319 if (Field2 != Field2End) {
1322 diag::err_odr_tag_type_inconsistent))
1324 Context.
Diag2(Field2->getLocation(), diag::note_odr_field)
1325 << Field2->getDeclName() << Field2->getType();
1349 EC1 != EC1End; ++EC1, ++EC2) {
1350 if (EC2 == EC2End) {
1354 diag::err_odr_tag_type_inconsistent))
1356 Context.
Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1357 << EC1->getDeclName() << EC1->getInitVal().toString(10);
1365 if (!llvm::APSInt::isSameValue(Val1, Val2) ||
1370 diag::err_odr_tag_type_inconsistent))
1372 Context.
Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1373 << EC2->getDeclName() << EC2->getInitVal().toString(10);
1374 Context.
Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1375 << EC1->getDeclName() << EC1->getInitVal().toString(10);
1381 if (EC2 != EC2End) {
1384 diag::err_odr_tag_type_inconsistent))
1386 Context.
Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1387 << EC2->getDeclName() << EC2->getInitVal().toString(10);
1399 if (Params1->
size() != Params2->
size()) {
1403 diag::err_odr_different_num_template_parameters))
1404 << Params1->
size() << Params2->
size();
1406 diag::note_odr_template_parameter_list);
1411 for (
unsigned I = 0, N = Params1->
size(); I != N; ++I) {
1416 diag::err_odr_different_template_parameter_kind));
1418 diag::note_odr_template_parameter_here);
1438 diag::err_odr_parameter_pack_non_pack))
1456 diag::err_odr_parameter_pack_non_pack))
1469 diag::err_odr_non_type_parameter_type_inconsistent))
1487 diag::err_odr_parameter_pack_non_pack))
1579 std::pair<Decl *, Decl *>
P{D1, D2};
1600 assert(
Complain &&
"Not allowed to complain");
1609 assert(
Complain &&
"Not allowed to complain");
1626 for (
const auto *D : Owner->noload_decls()) {
1631 if (F->isAnonymousStructOrUnion()) {
1642 while (
const auto *ElabType = dyn_cast<ElaboratedType>(FieldType))
1643 FieldType = ElabType->getNamedType();
1645 if (
const auto *RecType = dyn_cast<RecordType>(FieldType)) {
1646 const RecordDecl *RecDecl = RecType->getDecl();
1660 unsigned ErrorDiagnostic) {
1662 return ErrorDiagnostic;
1664 switch (ErrorDiagnostic) {
1665 case diag::err_odr_variable_type_inconsistent:
1666 return diag::warn_odr_variable_type_inconsistent;
1667 case diag::err_odr_variable_multiple_def:
1668 return diag::warn_odr_variable_multiple_def;
1669 case diag::err_odr_function_type_inconsistent:
1670 return diag::warn_odr_function_type_inconsistent;
1671 case diag::err_odr_tag_type_inconsistent:
1672 return diag::warn_odr_tag_type_inconsistent;
1673 case diag::err_odr_field_type_inconsistent:
1674 return diag::warn_odr_field_type_inconsistent;
1675 case diag::err_odr_ivar_type_inconsistent:
1676 return diag::warn_odr_ivar_type_inconsistent;
1677 case diag::err_odr_objc_superclass_inconsistent:
1678 return diag::warn_odr_objc_superclass_inconsistent;
1679 case diag::err_odr_objc_method_result_type_inconsistent:
1680 return diag::warn_odr_objc_method_result_type_inconsistent;
1681 case diag::err_odr_objc_method_num_params_inconsistent:
1682 return diag::warn_odr_objc_method_num_params_inconsistent;
1683 case diag::err_odr_objc_method_param_type_inconsistent:
1684 return diag::warn_odr_objc_method_param_type_inconsistent;
1685 case diag::err_odr_objc_method_variadic_inconsistent:
1686 return diag::warn_odr_objc_method_variadic_inconsistent;
1687 case diag::err_odr_objc_property_type_inconsistent:
1688 return diag::warn_odr_objc_property_type_inconsistent;
1689 case diag::err_odr_objc_property_impl_kind_inconsistent:
1690 return diag::warn_odr_objc_property_impl_kind_inconsistent;
1691 case diag::err_odr_objc_synthesize_ivar_inconsistent:
1692 return diag::warn_odr_objc_synthesize_ivar_inconsistent;
1693 case diag::err_odr_different_num_template_parameters:
1694 return diag::warn_odr_different_num_template_parameters;
1695 case diag::err_odr_different_template_parameter_kind:
1696 return diag::warn_odr_different_template_parameter_kind;
1697 case diag::err_odr_parameter_pack_non_pack:
1698 return diag::warn_odr_parameter_pack_non_pack;
1699 case diag::err_odr_non_type_parameter_type_inconsistent:
1700 return diag::warn_odr_non_type_parameter_type_inconsistent;
1702 llvm_unreachable(
"Diagnostic kind not handled in preceding switch");
1733 bool StructuralEquivalenceContext::CheckCommonEquivalence(
Decl *D1,
Decl *D2) {
1737 if ((Template1 !=
nullptr) != (Template2 !=
nullptr))
1747 bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
1751 if (
auto *Record1 = dyn_cast<RecordDecl>(D1)) {
1752 if (
auto *Record2 = dyn_cast<RecordDecl>(D2)) {
1755 if (!Name1 && Record1->getTypedefNameForAnonDecl())
1756 Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
1758 if (!Name2 && Record2->getTypedefNameForAnonDecl())
1759 Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
1767 }
else if (
auto *Enum1 = dyn_cast<EnumDecl>(D1)) {
1768 if (
auto *Enum2 = dyn_cast<EnumDecl>(D2)) {
1771 if (!Name1 && Enum1->getTypedefNameForAnonDecl())
1772 Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
1774 if (!Name2 && Enum2->getTypedefNameForAnonDecl())
1775 Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
1783 }
else if (
const auto *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
1784 if (
const auto *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
1786 Typedef2->getIdentifier()) ||
1788 Typedef2->getUnderlyingType()))
1794 }
else if (
auto *ClassTemplate1 = dyn_cast<ClassTemplateDecl>(D1)) {
1795 if (
auto *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
1803 }
else if (
auto *FunctionTemplate1 = dyn_cast<FunctionTemplateDecl>(D1)) {
1804 if (
auto *FunctionTemplate2 = dyn_cast<FunctionTemplateDecl>(D2)) {
1812 }
else if (
auto *ConceptDecl1 = dyn_cast<ConceptDecl>(D1)) {
1813 if (
auto *ConceptDecl2 = dyn_cast<ConceptDecl>(D2)) {
1820 }
else if (
auto *TTP1 = dyn_cast<TemplateTypeParmDecl>(D1)) {
1821 if (
auto *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
1828 }
else if (
auto *NTTP1 = dyn_cast<NonTypeTemplateParmDecl>(D1)) {
1829 if (
auto *NTTP2 = dyn_cast<NonTypeTemplateParmDecl>(D2)) {
1836 }
else if (
auto *TTP1 = dyn_cast<TemplateTemplateParmDecl>(D1)) {
1837 if (
auto *TTP2 = dyn_cast<TemplateTemplateParmDecl>(D2)) {
1844 }
else if (
auto *MD1 = dyn_cast<CXXMethodDecl>(D1)) {
1845 if (
auto *MD2 = dyn_cast<CXXMethodDecl>(D2)) {
1852 }
else if (
FunctionDecl *FD1 = dyn_cast<FunctionDecl>(D1)) {
1854 if (FD1->isOverloadedOperator()) {
1855 if (!FD2->isOverloadedOperator())
1857 if (FD1->getOverloadedOperator() != FD2->getOverloadedOperator())
1861 FD2->getIdentifier()))
1869 }
else if (
FriendDecl *FrD1 = dyn_cast<FriendDecl>(D1)) {
1870 if (
FriendDecl *FrD2 = dyn_cast<FriendDecl>(D2)) {
1882 bool StructuralEquivalenceContext::Finish() {
1889 Decl *D2 = P.second;
1892 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...