89#include "llvm/ADT/APInt.h" 
   90#include "llvm/ADT/APSInt.h" 
   91#include "llvm/ADT/StringExtras.h" 
   92#include "llvm/Support/Compiler.h" 
   93#include "llvm/Support/ErrorHandling.h" 
  162  llvm_unreachable(
"Unhandled kind of DeclarationName");
 
 
  169  StructuralEquivalenceContext &Context;
 
  175  bool IsStmtEquivalent(
const AddrLabelExpr *E1, 
const AddrLabelExpr *E2) {
 
  179  bool IsStmtEquivalent(
const AtomicExpr *E1, 
const AtomicExpr *E2) {
 
  183  bool IsStmtEquivalent(
const BinaryOperator *E1, 
const BinaryOperator *E2) {
 
  187  bool IsStmtEquivalent(
const CallExpr *E1, 
const CallExpr *E2) {
 
  193    if (
static_cast<bool>(Callee1) != 
static_cast<bool>(Callee2))
 
  197    if (!
static_cast<bool>(Callee1))
 
  204  bool IsStmtEquivalent(
const CharacterLiteral *E1,
 
  205                        const CharacterLiteral *E2) {
 
  209  bool IsStmtEquivalent(
const ChooseExpr *E1, 
const ChooseExpr *E2) {
 
  222  bool IsStmtEquivalent(
const DeclRefExpr *DRE1, 
const DeclRefExpr *DRE2) {
 
  223    const ValueDecl *Decl1 = DRE1->
getDecl();
 
  224    const ValueDecl *Decl2 = DRE2->
getDecl();
 
  225    if (!Decl1 || !Decl2)
 
  228                                    const_cast<ValueDecl *
>(Decl2));
 
  231  bool IsStmtEquivalent(
const DependentScopeDeclRefExpr *DE1,
 
  232                        const DependentScopeDeclRefExpr *DE2) {
 
  240  bool IsStmtEquivalent(
const Expr *E1, 
const Expr *E2) {
 
  244  bool IsStmtEquivalent(
const ExpressionTraitExpr *E1,
 
  245                        const ExpressionTraitExpr *E2) {
 
  249  bool IsStmtEquivalent(
const FloatingLiteral *E1, 
const FloatingLiteral *E2) {
 
  253  bool IsStmtEquivalent(
const GenericSelectionExpr *E1,
 
  254                        const GenericSelectionExpr *E2) {
 
  257      std::optional<TypeSourceInfo *> Child1 = std::get<0>(Pair);
 
  258      std::optional<TypeSourceInfo *> Child2 = std::get<1>(Pair);
 
  260      if (!Child1 || !Child2)
 
  264                                    (*Child2)->getType()))
 
  271  bool IsStmtEquivalent(
const ImplicitCastExpr *CastE1,
 
  272                        const ImplicitCastExpr *CastE2) {
 
  277  bool IsStmtEquivalent(
const IntegerLiteral *E1, 
const IntegerLiteral *E2) {
 
  281  bool IsStmtEquivalent(
const MemberExpr *E1, 
const MemberExpr *E2) {
 
  286  bool IsStmtEquivalent(
const ObjCStringLiteral *E1,
 
  287                        const ObjCStringLiteral *E2) {
 
  292  bool IsStmtEquivalent(
const Stmt *S1, 
const Stmt *S2) { 
return true; }
 
  294  bool IsStmtEquivalent(
const GotoStmt *S1, 
const GotoStmt *S2) {
 
  302    return ::IsStructurallyEquivalent(Name1, Name2);
 
  305  bool IsStmtEquivalent(
const SourceLocExpr *E1, 
const SourceLocExpr *E2) {
 
  309  bool IsStmtEquivalent(
const StmtExpr *E1, 
const StmtExpr *E2) {
 
  313  bool IsStmtEquivalent(
const StringLiteral *E1, 
const StringLiteral *E2) {
 
  317  bool IsStmtEquivalent(
const SubstNonTypeTemplateParmExpr *E1,
 
  318                        const SubstNonTypeTemplateParmExpr *E2) {
 
  329  bool IsStmtEquivalent(
const SubstNonTypeTemplateParmPackExpr *E1,
 
  330                        const SubstNonTypeTemplateParmPackExpr *E2) {
 
  335  bool IsStmtEquivalent(
const TypeTraitExpr *E1, 
const TypeTraitExpr *E2) {
 
  340      std::optional<TypeSourceInfo *> Child1 = std::get<0>(Pair);
 
  341      std::optional<TypeSourceInfo *> Child2 = std::get<1>(Pair);
 
  343      if (!Child1 || !Child2)
 
  347                                    (*Child2)->getType()))
 
  353  bool IsStmtEquivalent(
const CXXDependentScopeMemberExpr *E1,
 
  354                        const CXXDependentScopeMemberExpr *E2) {
 
  362  bool IsStmtEquivalent(
const UnaryExprOrTypeTraitExpr *E1,
 
  363                        const UnaryExprOrTypeTraitExpr *E2) {
 
  370  bool IsStmtEquivalent(
const UnaryOperator *E1, 
const UnaryOperator *E2) {
 
  374  bool IsStmtEquivalent(
const VAArgExpr *E1, 
const VAArgExpr *E2) {
 
  379  bool IsStmtEquivalent(
const OverloadExpr *E1, 
const OverloadExpr *E2) {
 
  403  bool IsStmtEquivalent(
const CXXBoolLiteralExpr *E1, 
const CXXBoolLiteralExpr *E2) {
 
  408  bool TraverseStmt(
const Stmt *S1, 
const Stmt *S2) { 
return true; }
 
  415#define STMT(CLASS, PARENT)                                                    \ 
  416  bool TraverseStmt(const CLASS *S1, const CLASS *S2) {                        \ 
  417    if (!TraverseStmt(static_cast<const PARENT *>(S1),                         \ 
  418                      static_cast<const PARENT *>(S2)))                        \ 
  420    return IsStmtEquivalent(S1, S2);                                           \ 
 
  422#include "clang/AST/StmtNodes.inc" 
  430  bool IsEquivalent(
const Stmt *S1, 
const Stmt *S2) {
 
  441      llvm_unreachable(
"Can't traverse NoStmtClass");
 
  442#define STMT(CLASS, PARENT)                                                    \ 
  443  case Stmt::StmtClass::CLASS##Class:                                          \ 
  444    return TraverseStmt(static_cast<const CLASS *>(S1),                        \ 
  445                        static_cast<const CLASS *>(S2)); 
  446#define ABSTRACT_STMT(S) 
  447#include "clang/AST/StmtNodes.inc" 
  449    llvm_unreachable(
"Invalid statement kind");
 
  457                                      const Decl *PrimaryDecl = 
nullptr) {
 
  468  const Attr *D1Attr = 
nullptr, *D2Attr = 
nullptr;
 
  474    const auto *DiagnoseDecl = 
cast<TypeDecl>(PrimaryDecl ? PrimaryDecl : D2);
 
  475    Context.Diag2(DiagnoseDecl->getLocation(),
 
  476                  diag::warn_odr_tag_type_with_attributes)
 
  477        << Context.ToCtx.getTypeDeclType(DiagnoseDecl)
 
  478        << (PrimaryDecl != 
nullptr);
 
  480      Context.Diag1(D1Attr->
getLoc(), diag::note_odr_attr_here) << D1Attr;
 
  482      Context.Diag1(D2Attr->getLoc(), diag::note_odr_attr_here) << D2Attr;
 
 
  539  if (
const auto *E2CXXOperatorCall = dyn_cast<CXXOperatorCallExpr>(S2)) {
 
  540    if (
const auto *E1Unary = dyn_cast<UnaryOperator>(S1))
 
  542    if (
const auto *E1Binary = dyn_cast<BinaryOperator>(S1))
 
  545  if (
const auto *E1CXXOperatorCall = dyn_cast<CXXOperatorCallExpr>(S1)) {
 
  546    if (
const auto *E2Unary = dyn_cast<UnaryOperator>(S2))
 
  548    if (
const auto *E2Binary = dyn_cast<BinaryOperator>(S2))
 
  553  StmtComparer Comparer(Context);
 
  554  if (!Comparer.IsEquivalent(S1, S2))
 
  559    std::optional<const Stmt *> Child1 = std::get<0>(Pair);
 
  560    std::optional<const Stmt *> Child2 = std::get<1>(Pair);
 
  563    if (!Child1 || !Child2)
 
 
  574  if (!Name1 || !Name2)
 
  575    return Name1 == Name2;
 
 
  628  if (TemplateDeclN1 && TemplateDeclN2) {
 
  634  } 
else if (TemplateDeclN1 || TemplateDeclN2)
 
  646                                        E1 = OS1->
end(), E2 = OS2->end();
 
  647    for (; I1 != E1 && I2 != E2; ++I1, ++I2)
 
  650    return I1 == E1 && I2 == E2;
 
  668                                    P2->getArgumentPack()) &&
 
  670                                    P2->getAssociatedDecl()) &&
 
  683     llvm_unreachable(
"unimplemented");
 
 
  742  llvm_unreachable(
"Invalid template argument kind");
 
 
  749  if (Args1.size() != Args2.size())
 
  751  for (
unsigned I = 0, N = Args1.size(); I != N; ++I) {
 
 
  847  if (!Context.StrictTypeSpelling) {
 
  864      TC = Type::FunctionNoProto;
 
  867      TC = Type::FunctionNoProto;
 
  868    else if (Context.LangOpts.C23 && !Context.StrictTypeSpelling &&
 
  908  case Type::ArrayParameter:
 
  922  case Type::BlockPointer:
 
  929  case Type::LValueReference:
 
  930  case Type::RValueReference: {
 
  933    if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
 
  935    if (Ref1->isInnerRef() != Ref2->isInnerRef())
 
  938                                  Ref2->getPointeeTypeAsWritten()))
 
  943  case Type::MemberPointer: {
 
  947                                  MemPtr2->getPointeeType()))
 
  950                                  MemPtr2->getQualifier()))
 
  953                  *D2 = MemPtr2->getMostRecentCXXRecordDecl();
 
  961  case Type::ConstantArray: {
 
  964    if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
 
  972  case Type::IncompleteArray:
 
  978  case Type::VariableArray: {
 
  982                                  Array2->getSizeExpr()))
 
  991  case Type::DependentSizedArray: {
 
  995                                  Array2->getSizeExpr()))
 
 1004  case Type::DependentAddressSpace: {
 
 1008                                  DepAddressSpace2->getAddrSpaceExpr()))
 
 1011                                  DepAddressSpace2->getPointeeType()))
 
 1017  case Type::DependentSizedExtVector: {
 
 1021                                  Vec2->getSizeExpr()))
 
 1024                                  Vec2->getElementType()))
 
 1029  case Type::DependentVector: {
 
 1032    if (Vec1->getVectorKind() != Vec2->getVectorKind())
 
 1035                                  Vec2->getSizeExpr()))
 
 1038                                  Vec2->getElementType()))
 
 1044  case Type::ExtVector: {
 
 1048                                  Vec2->getElementType()))
 
 1050    if (Vec1->getNumElements() != Vec2->getNumElements())
 
 1052    if (Vec1->getVectorKind() != Vec2->getVectorKind())
 
 1057  case Type::DependentSizedMatrix: {
 
 1072  case Type::ConstantMatrix: {
 
 1085  case Type::FunctionProto: {
 
 1089    if (Proto1->getNumParams() != Proto2->getNumParams())
 
 1091    for (
unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
 
 1093                                    Proto2->getParamType(I)))
 
 1096    if (Proto1->isVariadic() != Proto2->isVariadic())
 
 1099    if (Proto1->getMethodQuals() != Proto2->getMethodQuals())
 
 1103    const auto *OrigProto1 =
 
 1105    const auto *OrigProto2 =
 
 1114  case Type::FunctionNoProto: {
 
 1118                                  Function2->getReturnType()))
 
 1121                                  Function2->getExtInfo()))
 
 1126  case Type::UnresolvedUsing:
 
 1133  case Type::Attributed:
 
 1144  case Type::CountAttributed:
 
 1151  case Type::BTFTagAttributed:
 
 1158  case Type::HLSLAttributedResource:
 
 1172  case Type::HLSLInlineSpirv:
 
 1180    for (
size_t I = 0; I < cast<HLSLInlineSpirvType>(T1)->getOperands().size();
 
 1195  case Type::MacroQualified:
 
 1204    if (U1->getKeyword() != U2->getKeyword())
 
 1207                                  U2->getQualifier()))
 
 1215  case Type::Typedef: {
 
 1217    if (U1->getKeyword() != U2->getKeyword())
 
 1220                                  U2->getQualifier()))
 
 1224    if (U1->typeMatchesDecl() != U2->typeMatchesDecl())
 
 1226    if (!U1->typeMatchesDecl() &&
 
 1232  case Type::TypeOfExpr:
 
 1246  case Type::UnaryTransform:
 
 1253  case Type::Decltype:
 
 1264                                  Auto2->getDeducedType()))
 
 1266    if (Auto1->isConstrained() != Auto2->isConstrained())
 
 1268    if (Auto1->isConstrained()) {
 
 1269      if (Auto1->getTypeConstraintConcept() !=
 
 1270          Auto2->getTypeConstraintConcept())
 
 1273                                    Auto1->getTypeConstraintArguments(),
 
 1274                                    Auto2->getTypeConstraintArguments()))
 
 1280  case Type::DeducedTemplateSpecialization: {
 
 1284                                  DT2->getTemplateName()))
 
 1287                                  DT2->getDeducedType()))
 
 1294  case Type::InjectedClassName: {
 
 1296    if (TT1->getKeyword() != TT2->getKeyword())
 
 1298    if (TT1->isTagOwned() != TT2->isTagOwned())
 
 1301                                  TT2->getQualifier()))
 
 1308  case Type::TemplateTypeParm: {
 
 1311    if (!Context.IgnoreTemplateParmDepth &&
 
 1312        Parm1->getDepth() != Parm2->getDepth())
 
 1314    if (Parm1->getIndex() != Parm2->getIndex())
 
 1316    if (Parm1->isParameterPack() != Parm2->isParameterPack())
 
 1323  case Type::SubstTemplateTypeParm: {
 
 1327                                  Subst2->getReplacementType()))
 
 1330                                  Subst2->getAssociatedDecl()))
 
 1332    if (Subst1->getIndex() != Subst2->getIndex())
 
 1334    if (Subst1->getPackIndex() != Subst2->getPackIndex())
 
 1339  case Type::SubstBuiltinTemplatePack: {
 
 1343                                  Subst2->getArgumentPack()))
 
 1347  case Type::SubstTemplateTypeParmPack: {
 
 1351                                  Subst2->getAssociatedDecl()))
 
 1353    if (Subst1->getIndex() != Subst2->getIndex())
 
 1356                                  Subst2->getArgumentPack()))
 
 1361  case Type::TemplateSpecialization: {
 
 1365                                  Spec2->getTemplateName()))
 
 1368                                  Spec2->template_arguments()))
 
 1373  case Type::DependentName: {
 
 1377                                  Typename2->getQualifier()))
 
 1380                                  Typename2->getIdentifier()))
 
 1386  case Type::PackExpansion:
 
 1393  case Type::PackIndexing:
 
 1403  case Type::ObjCInterface: {
 
 1412  case Type::ObjCTypeParam: {
 
 1418    if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
 
 1420    for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
 
 1422                                    Obj2->getProtocol(I)))
 
 1428  case Type::ObjCObject: {
 
 1432                                  Obj2->getBaseType()))
 
 1434    if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
 
 1436    for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
 
 1438                                    Obj2->getProtocol(I)))
 
 1444  case Type::ObjCObjectPointer: {
 
 1448                                  Ptr2->getPointeeType()))
 
 1464  case Type::BitInt: {
 
 1468    if (Int1->isUnsigned() != Int2->isUnsigned() ||
 
 1469        Int1->getNumBits() != Int2->getNumBits())
 
 1473  case Type::DependentBitInt: {
 
 1477    if (Int1->isUnsigned() != Int2->isUnsigned() ||
 
 1479                                  Int2->getNumBitsExpr()))
 
 1483  case Type::PredefinedSugar: {
 
 1486    if (TP1->getKind() != TP2->getKind())
 
 
 1524  if (Context.LangOpts.C23 &&
 
 1542    if (Context.Complain) {
 
 1544          Owner2->getLocation(),
 
 1545          Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
 
 1546          << Owner2Type << (&Context.FromCtx != &Context.ToCtx);
 
 1547      Context.Diag2(Field2->
getLocation(), diag::note_odr_field_name)
 
 1549      Context.Diag1(Field1->
getLocation(), diag::note_odr_field_name)
 
 1557    if (Context.Complain) {
 
 1559          Owner2->getLocation(),
 
 1560          Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
 
 1561          << Owner2Type << (&Context.FromCtx != &Context.ToCtx);
 
 1562      Context.Diag2(Field2->
getLocation(), diag::note_odr_field)
 
 1564      Context.Diag1(Field1->
getLocation(), diag::note_odr_field)
 
 1576    bool Diagnose = 
true;
 
 1580    if (Diagnose && Context.Complain) {
 
 1581      auto DiagNote = [&](
const FieldDecl *FD,
 
 1589          (Context.*
Diag)(FD->
getLocation(), diag::note_odr_field_not_bit_field)
 
 1595          Owner2->getLocation(),
 
 1596          Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
 
 1597          << Owner2Type << (&Context.FromCtx != &Context.ToCtx);
 
 
 1612                                  Context.ToCtx.getCanonicalTagType(Owner2));
 
 
 1619  if (!Method1 && !Method2)
 
 1621  if (!Method1 || !Method2)
 
 1624  bool PropertiesEqual =
 
 1638  if (!PropertiesEqual)
 
 1642  if (
auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
 
 1644    if (!Constructor1->getExplicitSpecifier().isEquivalent(
 
 1645            Constructor2->getExplicitSpecifier()))
 
 1649  if (
auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
 
 1651    if (!Conversion1->getExplicitSpecifier().isEquivalent(
 
 1652            Conversion2->getExplicitSpecifier()))
 
 1655                                  Conversion2->getConversionType()))
 
 
 1679         "Must be called on lambda classes");
 
 
 1710    if (
const auto *ND1 = dyn_cast<NamedDecl>(DC1)) {
 
 1717    if (
auto *D1Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC1)) {
 
 1718      auto *D2Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC2);
 
 
 1734    if (
const TypedefNameDecl *TypedefName = D.getTypedefNameForAnonDecl())
 
 1735      return TypedefName->getIdentifier();
 
 
 1769    if (Context.Complain) {
 
 1770      Context.Diag2(D2->
getLocation(), Context.getApplicableDiagnostic(
 
 1771                                           diag::err_odr_tag_type_inconsistent))
 
 1772          << Context.ToCtx.getCanonicalTagType(D2)
 
 1773          << (&Context.FromCtx != &Context.ToCtx);
 
 1774      Context.Diag1(D1->
getLocation(), diag::note_odr_tag_kind_here)
 
 1788        if (*Index1 != *Index2)
 
 1796  if (Context.LangOpts.C23 &&
 
 1805  if (!Context.LangOpts.C23 &&
 
 1811  const auto *Spec1 = dyn_cast<ClassTemplateSpecializationDecl>(D1);
 
 1812  const auto *Spec2 = dyn_cast<ClassTemplateSpecializationDecl>(D2);
 
 1813  if (Spec1 && Spec2) {
 
 1816                                  Spec2->getSpecializedTemplate()))
 
 1820    if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
 
 1823    for (
unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
 
 1825                                    Spec2->getTemplateArgs().get(I)))
 
 1830  else if (Spec1 || Spec2)
 
 1839    return !Context.LangOpts.C23;
 
 1855  if (
auto *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
 
 1856    if (
auto *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
 
 1857      if (D1CXX->hasExternalLexicalStorage() &&
 
 1858          !D1CXX->isCompleteDefinition()) {
 
 1859        D1CXX->getASTContext().getExternalSource()->CompleteType(D1CXX);
 
 1862      if (D1CXX->isLambda() != D2CXX->isLambda())
 
 1864      if (D1CXX->isLambda()) {
 
 1869      if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
 
 1870        if (Context.Complain) {
 
 1872                        Context.getApplicableDiagnostic(
 
 1873                            diag::err_odr_tag_type_inconsistent))
 
 1874              << Context.ToCtx.getCanonicalTagType(D2)
 
 1875              << (&Context.FromCtx != &Context.ToCtx);
 
 1876          Context.Diag2(D2->
getLocation(), diag::note_odr_number_of_bases)
 
 1877              << D2CXX->getNumBases();
 
 1878          Context.Diag1(D1->
getLocation(), diag::note_odr_number_of_bases)
 
 1879              << D1CXX->getNumBases();
 
 1886                                              BaseEnd1 = D1CXX->bases_end(),
 
 1887                                              Base2 = D2CXX->bases_begin();
 
 1888           Base1 != BaseEnd1; ++Base1, ++Base2) {
 
 1890                                      Base2->getType())) {
 
 1891          if (Context.Complain) {
 
 1893                          Context.getApplicableDiagnostic(
 
 1894                              diag::err_odr_tag_type_inconsistent))
 
 1895                << Context.ToCtx.getCanonicalTagType(D2)
 
 1896                << (&Context.FromCtx != &Context.ToCtx);
 
 1897            Context.Diag2(Base2->getBeginLoc(), diag::note_odr_base)
 
 1898                << Base2->getType() << Base2->getSourceRange();
 
 1899            Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
 
 1900                << Base1->getType() << Base1->getSourceRange();
 
 1906        if (Base1->isVirtual() != Base2->isVirtual()) {
 
 1907          if (Context.Complain) {
 
 1909                          Context.getApplicableDiagnostic(
 
 1910                              diag::err_odr_tag_type_inconsistent))
 
 1911                << Context.ToCtx.getCanonicalTagType(D2)
 
 1912                << (&Context.FromCtx != &Context.ToCtx);
 
 1913            Context.Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
 
 1914                << Base2->isVirtual() << Base2->getSourceRange();
 
 1915            Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
 
 1916                << Base1->isVirtual() << Base1->getSourceRange();
 
 1924                                     Friend2End = D2CXX->friend_end();
 
 1926                                          Friend1End = D1CXX->friend_end();
 
 1927           Friend1 != Friend1End; ++Friend1, ++Friend2) {
 
 1928        if (Friend2 == Friend2End) {
 
 1929          if (Context.Complain) {
 
 1931                          Context.getApplicableDiagnostic(
 
 1932                              diag::err_odr_tag_type_inconsistent))
 
 1933                << Context.ToCtx.getCanonicalTagType(D2CXX)
 
 1934                << (&Context.FromCtx != &Context.ToCtx);
 
 1935            Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
 
 1936            Context.Diag2(D2->
getLocation(), diag::note_odr_missing_friend);
 
 1942          if (Context.Complain) {
 
 1944                          Context.getApplicableDiagnostic(
 
 1945                              diag::err_odr_tag_type_inconsistent))
 
 1946                << Context.ToCtx.getCanonicalTagType(D2CXX)
 
 1947                << (&Context.FromCtx != &Context.ToCtx);
 
 1948            Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
 
 1949            Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
 
 1955      if (Friend2 != Friend2End) {
 
 1956        if (Context.Complain) {
 
 1958                        Context.getApplicableDiagnostic(
 
 1959                            diag::err_odr_tag_type_inconsistent))
 
 1960              << Context.ToCtx.getCanonicalTagType(D2)
 
 1961              << (&Context.FromCtx != &Context.ToCtx);
 
 1962          Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
 
 1963          Context.Diag1(D1->
getLocation(), diag::note_odr_missing_friend);
 
 1967    } 
else if (D1CXX->getNumBases() > 0) {
 
 1968      if (Context.Complain) {
 
 1970                      Context.getApplicableDiagnostic(
 
 1971                          diag::err_odr_tag_type_inconsistent))
 
 1972            << Context.ToCtx.getCanonicalTagType(D2)
 
 1973            << (&Context.FromCtx != &Context.ToCtx);
 
 1975        Context.Diag1(Base1->
getBeginLoc(), diag::note_odr_base)
 
 1977        Context.Diag2(D2->
getLocation(), diag::note_odr_missing_base);
 
 1984  CanQualType D2Type = Context.ToCtx.getCanonicalTagType(D2);
 
 1989       Field1 != Field1End; ++Field1, ++Field2) {
 
 1990    if (Field2 == Field2End) {
 
 1991      if (Context.Complain) {
 
 1993                      Context.getApplicableDiagnostic(
 
 1994                          diag::err_odr_tag_type_inconsistent))
 
 1995            << Context.ToCtx.getCanonicalTagType(D2)
 
 1996            << (&Context.FromCtx != &Context.ToCtx);
 
 1997        Context.Diag1(Field1->getLocation(), diag::note_odr_field)
 
 1998            << Field1->getDeclName() << Field1->getType();
 
 1999        Context.Diag2(D2->
getLocation(), diag::note_odr_missing_field);
 
 2008  if (Field2 != Field2End) {
 
 2009    if (Context.Complain) {
 
 2010      Context.Diag2(D2->
getLocation(), Context.getApplicableDiagnostic(
 
 2011                                           diag::err_odr_tag_type_inconsistent))
 
 2012          << Context.ToCtx.getCanonicalTagType(D2)
 
 2013          << (&Context.FromCtx != &Context.ToCtx);
 
 2014      Context.Diag2(Field2->getLocation(), diag::note_odr_field)
 
 2015          << Field2->getDeclName() << Field2->getType();
 
 2016      Context.Diag1(D1->
getLocation(), diag::note_odr_missing_field);
 
 
 2027  const llvm::APSInt &FromVal = D1->
getInitVal();
 
 2028  const llvm::APSInt &ToVal = D2->
getInitVal();
 
 2029  if (FromVal.isSigned() != ToVal.isSigned())
 
 2031  if (FromVal.getBitWidth() != ToVal.getBitWidth())
 
 2033  if (FromVal != ToVal)
 
 
 2060  if (Context.LangOpts.C23 &&
 
 2066  if (Context.LangOpts.C23) {
 
 2068      if (Context.Complain) {
 
 2070                      Context.getApplicableDiagnostic(
 
 2071                          diag::err_odr_tag_type_inconsistent))
 
 2072            << Context.ToCtx.getCanonicalTagType(D2)
 
 2073            << (&Context.FromCtx != &Context.ToCtx);
 
 2076                          ? diag::note_odr_fixed_underlying_type
 
 2077                          : diag::note_odr_missing_fixed_underlying_type)
 
 2081                          ? diag::note_odr_fixed_underlying_type
 
 2082                          : diag::note_odr_missing_fixed_underlying_type)
 
 2088      assert(D2->
isFixed() && 
"enums expected to have fixed underlying types");
 
 2091        if (Context.Complain) {
 
 2093                        Context.getApplicableDiagnostic(
 
 2094                            diag::err_odr_tag_type_inconsistent))
 
 2095              << Context.ToCtx.getCanonicalTagType(D2)
 
 2096              << (&Context.FromCtx != &Context.ToCtx);
 
 2098                        diag::note_odr_incompatible_fixed_underlying_type)
 
 2107  auto CopyEnumerators =
 
 2110          Cont.push_back(ECD);
 
 2117  if (Context.LangOpts.C23) {
 
 2119      return LHS->
getName() < RHS->getName();
 
 2121    llvm::sort(D1Enums, Sorter);
 
 2122    llvm::sort(D2Enums, Sorter);
 
 2125  auto EC2 = D2Enums.begin(), EC2End = D2Enums.end();
 
 2126  for (
auto EC1 = D1Enums.begin(), EC1End = D1Enums.end(); EC1 != EC1End;
 
 2128    if (EC2 == EC2End) {
 
 2129      if (Context.Complain) {
 
 2131                      Context.getApplicableDiagnostic(
 
 2132                          diag::err_odr_tag_type_inconsistent))
 
 2133            << Context.ToCtx.getCanonicalTagType(D2)
 
 2134            << (&Context.FromCtx != &Context.ToCtx);
 
 2135        Context.Diag1((*EC1)->getLocation(), diag::note_odr_enumerator)
 
 2136            << (*EC1)->getDeclName() << 
toString((*EC1)->getInitVal(), 10);
 
 2137        Context.Diag2(D2->
getLocation(), diag::note_odr_missing_enumerator);
 
 2142    llvm::APSInt Val1 = (*EC1)->getInitVal();
 
 2143    llvm::APSInt Val2 = (*EC2)->getInitVal();
 
 2144    if (!llvm::APSInt::isSameValue(Val1, Val2) ||
 
 2146                                  (*EC2)->getIdentifier())) {
 
 2147      if (Context.Complain) {
 
 2149                      Context.getApplicableDiagnostic(
 
 2150                          diag::err_odr_tag_type_inconsistent))
 
 2151            << Context.ToCtx.getCanonicalTagType(D2)
 
 2152            << (&Context.FromCtx != &Context.ToCtx);
 
 2153        Context.Diag2((*EC2)->getLocation(), diag::note_odr_enumerator)
 
 2154            << (*EC2)->getDeclName() << 
toString((*EC2)->getInitVal(), 10);
 
 2155        Context.Diag1((*EC1)->getLocation(), diag::note_odr_enumerator)
 
 2156            << (*EC1)->getDeclName() << 
toString((*EC1)->getInitVal(), 10);
 
 2160    if (Context.LangOpts.C23 &&
 
 2165  if (EC2 != EC2End) {
 
 2166    if (Context.Complain) {
 
 2167      Context.Diag2(D2->
getLocation(), Context.getApplicableDiagnostic(
 
 2168                                           diag::err_odr_tag_type_inconsistent))
 
 2169          << Context.ToCtx.getCanonicalTagType(D2)
 
 2170          << (&Context.FromCtx != &Context.ToCtx);
 
 2171      Context.Diag2((*EC2)->getLocation(), diag::note_odr_enumerator)
 
 2172          << (*EC2)->getDeclName() << 
toString((*EC2)->getInitVal(), 10);
 
 2173      Context.Diag1(D1->
getLocation(), diag::note_odr_missing_enumerator);
 
 
 2184  if (Params1->
size() != Params2->
size()) {
 
 2185    if (Context.Complain) {
 
 2187                    Context.getApplicableDiagnostic(
 
 2188                        diag::err_odr_different_num_template_parameters))
 
 2189          << Params1->
size() << Params2->
size();
 
 2191                    diag::note_odr_template_parameter_list);
 
 2196  for (
unsigned I = 0, N = Params1->
size(); I != N; ++I) {
 
 2198      if (Context.Complain) {
 
 2200                      Context.getApplicableDiagnostic(
 
 2201                          diag::err_odr_different_template_parameter_kind));
 
 2203                      diag::note_odr_template_parameter_here);
 
 
 2220    if (Context.Complain) {
 
 2222                    Context.getApplicableDiagnostic(
 
 2223                        diag::err_odr_parameter_pack_non_pack))
 
 2225      Context.Diag1(D1->
getLocation(), diag::note_odr_parameter_pack_non_pack)
 
 
 2238    if (Context.Complain) {
 
 2240                    Context.getApplicableDiagnostic(
 
 2241                        diag::err_odr_parameter_pack_non_pack))
 
 2243      Context.Diag1(D1->
getLocation(), diag::note_odr_parameter_pack_non_pack)
 
 2254    if (Context.Complain) {
 
 2256                    Context.getApplicableDiagnostic(
 
 2257                        diag::err_odr_non_type_parameter_type_inconsistent))
 
 2259      Context.Diag1(D1->
getLocation(), diag::note_odr_value_here)
 
 
 2272    if (Context.Complain) {
 
 2274                    Context.getApplicableDiagnostic(
 
 2275                        diag::err_odr_parameter_pack_non_pack))
 
 2277      Context.Diag1(D1->
getLocation(), diag::note_odr_parameter_pack_non_pack)
 
 
 2412  bool PropertiesEqual =
 
 2416  if (!PropertiesEqual)
 
 2423  if (NumArgs != Selector2.getNumArgs())
 
 2427  unsigned SlotsToCheck = NumArgs > 0 ? NumArgs : 1;
 
 2428  for (
unsigned I = 0; I < SlotsToCheck; ++I) {
 
 2430                                  Selector2.getIdentifierInfoForSlot(I)))
 
 2440      "Same number of arguments should be already enforced in Selector checks");
 
 2446       (ParamT1 != ParamT1End) && (ParamT2 != ParamT2End);
 
 2447       ++ParamT1, ++ParamT2) {
 
 
 2463  if ((!Intf1 || !Intf2) && (Intf1 != Intf2))
 
 2475       Protocol1 != Protocol1End; ++Protocol1, ++Protocol2) {
 
 2476    if (Protocol2 == Protocol2End)
 
 2479                                  (*Protocol2)->getIdentifier()))
 
 2482  if (Protocol2 != Protocol2End)
 
 2487      Intf2 ? Context.ToCtx.getObjCInterfaceType(Intf2) : 
QualType();
 
 2492       Ivar1 != Ivar1End; ++Ivar1, ++Ivar2) {
 
 2493    if (Ivar2 == Ivar2End)
 
 2498  if (Ivar2 != Ivar2End)
 
 2506       Method1 != Method1End; ++Method1, ++Method2) {
 
 2507    if (Method2 == Method2End)
 
 2512  if (Method2 != Method2End)
 
 
 2525  std::pair<Decl *, Decl *> P{D1, D2};
 
 2529  if (Context.NonEquivalentDecls.count(
 
 2530          std::make_tuple(D1, D2, Context.IgnoreTemplateParmDepth)))
 
 2536  bool Inserted = Context.VisitedDecls.insert(P).second;
 
 2540  Context.DeclsToCheck.push(P);
 
 
 2547  assert(
Complain && 
"Not allowed to complain");
 
 2549    FromCtx.getDiagnostics().notePriorDiagnosticFrom(
ToCtx.getDiagnostics());
 
 2551  return FromCtx.getDiagnostics().Report(Loc, DiagID);
 
 
 2556  assert(
Complain && 
"Not allowed to complain");
 
 2558    ToCtx.getDiagnostics().notePriorDiagnosticFrom(
FromCtx.getDiagnostics());
 
 2560  return ToCtx.getDiagnostics().Report(Loc, DiagID);
 
 
 2566  CanQualType AnonTy = Context.getCanonicalTagType(Anon);
 
 2568  const auto *Owner = dyn_cast<RecordDecl>(Anon->
getDeclContext());
 
 2570    return std::nullopt;
 
 2573  for (
const auto *D : Owner->noload_decls()) {
 
 2574    const auto *F = dyn_cast<FieldDecl>(D);
 
 2578    if (F->isAnonymousStructOrUnion()) {
 
 2579      if (Context.hasSameType(F->getType(), AnonTy))
 
 2588    if (
const auto *RecType = dyn_cast<RecordType>(FieldType)) {
 
 2589      const RecordDecl *RecDecl = RecType->getDecl();
 
 2591        if (Context.hasSameType(FieldType, AnonTy))
 
 
 2603    unsigned ErrorDiagnostic) {
 
 2605    return ErrorDiagnostic;
 
 2607  switch (ErrorDiagnostic) {
 
 2608  case diag::err_odr_variable_type_inconsistent:
 
 2609    return diag::warn_odr_variable_type_inconsistent;
 
 2610  case diag::err_odr_variable_multiple_def:
 
 2611    return diag::warn_odr_variable_multiple_def;
 
 2612  case diag::err_odr_function_type_inconsistent:
 
 2613    return diag::warn_odr_function_type_inconsistent;
 
 2614  case diag::err_odr_tag_type_inconsistent:
 
 2615    return diag::warn_odr_tag_type_inconsistent;
 
 2616  case diag::err_odr_field_type_inconsistent:
 
 2617    return diag::warn_odr_field_type_inconsistent;
 
 2618  case diag::err_odr_ivar_type_inconsistent:
 
 2619    return diag::warn_odr_ivar_type_inconsistent;
 
 2620  case diag::err_odr_objc_superclass_inconsistent:
 
 2621    return diag::warn_odr_objc_superclass_inconsistent;
 
 2622  case diag::err_odr_objc_method_result_type_inconsistent:
 
 2623    return diag::warn_odr_objc_method_result_type_inconsistent;
 
 2624  case diag::err_odr_objc_method_num_params_inconsistent:
 
 2625    return diag::warn_odr_objc_method_num_params_inconsistent;
 
 2626  case diag::err_odr_objc_method_param_type_inconsistent:
 
 2627    return diag::warn_odr_objc_method_param_type_inconsistent;
 
 2628  case diag::err_odr_objc_method_variadic_inconsistent:
 
 2629    return diag::warn_odr_objc_method_variadic_inconsistent;
 
 2630  case diag::err_odr_objc_property_type_inconsistent:
 
 2631    return diag::warn_odr_objc_property_type_inconsistent;
 
 2632  case diag::err_odr_objc_property_impl_kind_inconsistent:
 
 2633    return diag::warn_odr_objc_property_impl_kind_inconsistent;
 
 2634  case diag::err_odr_objc_synthesize_ivar_inconsistent:
 
 2635    return diag::warn_odr_objc_synthesize_ivar_inconsistent;
 
 2636  case diag::err_odr_different_num_template_parameters:
 
 2637    return diag::warn_odr_different_num_template_parameters;
 
 2638  case diag::err_odr_different_template_parameter_kind:
 
 2639    return diag::warn_odr_different_template_parameter_kind;
 
 2640  case diag::err_odr_parameter_pack_non_pack:
 
 2641    return diag::warn_odr_parameter_pack_non_pack;
 
 2642  case diag::err_odr_non_type_parameter_type_inconsistent:
 
 2643    return diag::warn_odr_non_type_parameter_type_inconsistent;
 
 2645  llvm_unreachable(
"Diagnostic kind not handled in preceding switch");
 
 
 2685bool StructuralEquivalenceContext::CheckCommonEquivalence(
Decl *D1, 
Decl *D2) {
 
 2689  if ((Template1 != 
nullptr) != (Template2 != 
nullptr))
 
 2699bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
 
 2709#define ABSTRACT_DECL(DECL) 
 2710#define DECL(DERIVED, BASE)                                                    \ 
 2711  case Decl::Kind::DERIVED:                                                    \ 
 2712    return ::IsStructurallyEquivalent(*this, static_cast<DERIVED##Decl *>(D1), \ 
 2713                                      static_cast<DERIVED##Decl *>(D2)); 
 2714#include "clang/AST/DeclNodes.inc" 
 2719bool StructuralEquivalenceContext::Finish() {
 
 2726    Decl *D2 = P.second;
 
 2729        CheckCommonEquivalence(D1, D2) && CheckKindSpecificEquivalence(D1, D2);
 
Defines the clang::ASTContext interface.
static bool IsTemplateDeclCommonStructurallyEquivalent(StructuralEquivalenceContext &Ctx, TemplateDecl *D1, TemplateDecl *D2)
static bool CheckStructurallyEquivalentAttributes(StructuralEquivalenceContext &Context, const Decl *D1, const Decl *D2, const Decl *PrimaryDecl=nullptr)
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 OpenACC nodes for declarative directives.
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 DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
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.
This file defines SYCL AST classes used to represent calls to SYCL kernels.
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 ...
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.
Attr - This represents one attribute.
SourceLocation getLoc() const
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.
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.
CXXBaseSpecifier * base_class_iterator
Iterator that traverses the base classes of a 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.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
unsigned getValue() const
CharacterLiteralKind getKind() const
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
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.
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()
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
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
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.
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.
IdentifierOrOverloadedOperator getName() const
NestedNameSpecifier getQualifier() const
Return the nested name specifier that qualifies this name.
A little helper class used to produce diagnostics.
An instance of this object exists for each enum constant that is defined.
llvm::APSInt getInitVal() const
const Expr * getInitExpr() const
enumerator_range enumerators() const
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
EnumDecl * getDefinition() const
ExpressionTrait getTrait() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
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
ArrayRef< TypeSourceInfo * > getAssocTypeSourceInfos() const
LabelDecl * getLabel() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
QualType getElementType() const
Returns type of the elements being stored in the matrix.
DeclAccessPair getFoundDecl() const
Retrieves the declaration found by lookup.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents C++ namespaces and their aliases.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
CXXRecordDecl * getAsMicrosoftSuper() const
NamespaceAndPrefix getAsNamespaceAndPrefix() const
const Type * getAsType() const
@ MicrosoftSuper
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Global
The global specifier '::'. There is no stored value.
@ Type
A type, stored as a Type*.
@ Namespace
A namespace-like entity, stored as a NamespaceBaseDecl*.
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()
specific_decl_iterator< ObjCIvarDecl > ivar_iterator
protocol_iterator protocol_end() const
protocol_iterator protocol_begin() const
ObjCProtocolList::iterator protocol_iterator
method_iterator meth_begin() const
specific_decl_iterator< ObjCMethodDecl > method_iterator
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.
Selector getSelector() const
bool isInstanceMethod() const
llvm::mapped_iterator< param_const_iterator, GetTypeFn > param_type_iterator
QualType getReturnType() const
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.
QualType getCanonicalType() const
Represents a struct/union/class.
field_iterator field_end() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
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
SourceLocIdentKind getIdentKind() const
Encodes a location in the source.
unsigned getTemplateDepth() const
Stmt - This represents one statement.
StmtClass getStmtClass() const
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
UnsignedOrNone getPackIndex() const
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
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(bool IgnoreDeduced=false) 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,...
@ DeducedTemplate
A template name that refers to another TemplateName with deduced default arguments.
@ 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.
TemplateNameKind templateParameterKind() const
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.
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>.
bool isBuiltinType() const
Helper methods to distinguish type categories.
TypeClass getTypeClass() const
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
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 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.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
U cast(CodeGen::Address addr)
@ EST_Dynamic
throw(T1, T2)
const IdentifierInfo * getIdentifier() const
Returns the identifier to which this template name refers.
OverloadedOperatorKind getOperator() const
Return the overloaded operator to which this template name refers.
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
static UnsignedOrNone findUntaggedStructOrUnionIndex(RecordDecl *Anon)
Find the index of the given anonymous struct/union within its context.
bool IgnoreTemplateParmDepth
Whether to ignore comparing the depth of template param(TemplateTypeParm)
bool ErrorOnTagTypeMismatch
Whether warn or error on tag type mismatches.
NonEquivalentDeclSet & NonEquivalentDecls
Declaration (from, to) pairs that are known not to be equivalent (which we have already complained ab...
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.