File indexing completed on 2026-05-10 08:36:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_AST_ODRDIAGSEMITTER_H
0010 #define LLVM_CLANG_AST_ODRDIAGSEMITTER_H
0011
0012 #include "clang/AST/ASTContext.h"
0013 #include "clang/AST/DeclCXX.h"
0014 #include "clang/AST/DeclObjC.h"
0015 #include "clang/Basic/Diagnostic.h"
0016 #include "clang/Basic/LangOptions.h"
0017
0018 namespace clang {
0019
0020 class ODRDiagsEmitter {
0021 public:
0022 ODRDiagsEmitter(DiagnosticsEngine &Diags, const ASTContext &Context,
0023 const LangOptions &LangOpts)
0024 : Diags(Diags), Context(Context), LangOpts(LangOpts) {}
0025
0026
0027
0028
0029 bool diagnoseMismatch(const FunctionDecl *FirstFunction,
0030 const FunctionDecl *SecondFunction) const;
0031
0032
0033
0034
0035 bool diagnoseMismatch(const EnumDecl *FirstEnum,
0036 const EnumDecl *SecondEnum) const;
0037
0038
0039
0040
0041
0042
0043 bool
0044 diagnoseMismatch(const CXXRecordDecl *FirstRecord,
0045 const CXXRecordDecl *SecondRecord,
0046 const struct CXXRecordDecl::DefinitionData *SecondDD) const;
0047
0048
0049
0050
0051 bool diagnoseMismatch(const RecordDecl *FirstRecord,
0052 const RecordDecl *SecondRecord) const;
0053
0054
0055
0056
0057 bool diagnoseMismatch(
0058 const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
0059 const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const;
0060
0061
0062
0063 bool diagnoseMismatch(const ObjCInterfaceDecl *FirstID,
0064 const ObjCInterfaceDecl *SecondID) const {
0065 assert(FirstID->data().Definition != SecondID->data().Definition &&
0066 "Don't diagnose differences when definitions are merged already");
0067 return diagnoseMismatch(FirstID, SecondID, &SecondID->data());
0068 }
0069
0070
0071
0072
0073
0074
0075 bool diagnoseMismatch(
0076 const ObjCProtocolDecl *FirstProtocol,
0077 const ObjCProtocolDecl *SecondProtocol,
0078 const struct ObjCProtocolDecl::DefinitionData *SecondDD) const;
0079
0080
0081 bool diagnoseMismatch(const ObjCProtocolDecl *FirstProtocol,
0082 const ObjCProtocolDecl *SecondProtocol) const {
0083 assert(FirstProtocol->data().Definition !=
0084 SecondProtocol->data().Definition &&
0085 "Don't diagnose differences when definitions are merged already");
0086 return diagnoseMismatch(FirstProtocol, SecondProtocol,
0087 &SecondProtocol->data());
0088 }
0089
0090
0091
0092 static std::string getOwningModuleNameForDiagnostic(const Decl *D);
0093
0094 private:
0095 using DeclHashes = llvm::SmallVector<std::pair<const Decl *, unsigned>, 4>;
0096
0097
0098
0099
0100
0101
0102 enum ODRMismatchDecl {
0103 EndOfClass,
0104 PublicSpecifer,
0105 PrivateSpecifer,
0106 ProtectedSpecifer,
0107 StaticAssert,
0108 Field,
0109 CXXMethod,
0110 TypeAlias,
0111 TypeDef,
0112 Var,
0113 Friend,
0114 FunctionTemplate,
0115 ObjCMethod,
0116 ObjCIvar,
0117 ObjCProperty,
0118 Other
0119 };
0120
0121 struct DiffResult {
0122 const Decl *FirstDecl = nullptr, *SecondDecl = nullptr;
0123 ODRMismatchDecl FirstDiffType = Other, SecondDiffType = Other;
0124 };
0125
0126
0127
0128
0129 static DiffResult FindTypeDiffs(DeclHashes &FirstHashes,
0130 DeclHashes &SecondHashes);
0131
0132 DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
0133 return Diags.Report(Loc, DiagID);
0134 }
0135
0136
0137
0138
0139 void diagnoseSubMismatchUnexpected(DiffResult &DR,
0140 const NamedDecl *FirstRecord,
0141 StringRef FirstModule,
0142 const NamedDecl *SecondRecord,
0143 StringRef SecondModule) const;
0144
0145 void diagnoseSubMismatchDifferentDeclKinds(DiffResult &DR,
0146 const NamedDecl *FirstRecord,
0147 StringRef FirstModule,
0148 const NamedDecl *SecondRecord,
0149 StringRef SecondModule) const;
0150
0151 bool diagnoseSubMismatchField(const NamedDecl *FirstRecord,
0152 StringRef FirstModule, StringRef SecondModule,
0153 const FieldDecl *FirstField,
0154 const FieldDecl *SecondField) const;
0155
0156 bool diagnoseSubMismatchTypedef(const NamedDecl *FirstRecord,
0157 StringRef FirstModule, StringRef SecondModule,
0158 const TypedefNameDecl *FirstTD,
0159 const TypedefNameDecl *SecondTD,
0160 bool IsTypeAlias) const;
0161
0162 bool diagnoseSubMismatchVar(const NamedDecl *FirstRecord,
0163 StringRef FirstModule, StringRef SecondModule,
0164 const VarDecl *FirstVD,
0165 const VarDecl *SecondVD) const;
0166
0167
0168
0169
0170 bool diagnoseSubMismatchProtocols(const ObjCProtocolList &FirstProtocols,
0171 const ObjCContainerDecl *FirstContainer,
0172 StringRef FirstModule,
0173 const ObjCProtocolList &SecondProtocols,
0174 const ObjCContainerDecl *SecondContainer,
0175 StringRef SecondModule) const;
0176
0177
0178
0179
0180 bool diagnoseSubMismatchObjCMethod(const NamedDecl *FirstObjCContainer,
0181 StringRef FirstModule,
0182 StringRef SecondModule,
0183 const ObjCMethodDecl *FirstMethod,
0184 const ObjCMethodDecl *SecondMethod) const;
0185
0186
0187
0188
0189 bool
0190 diagnoseSubMismatchObjCProperty(const NamedDecl *FirstObjCContainer,
0191 StringRef FirstModule, StringRef SecondModule,
0192 const ObjCPropertyDecl *FirstProp,
0193 const ObjCPropertyDecl *SecondProp) const;
0194
0195 private:
0196 DiagnosticsEngine &Diags;
0197 const ASTContext &Context;
0198 const LangOptions &LangOpts;
0199 };
0200
0201 }
0202
0203 #endif