- //===- ODRDiagsEmitter.h - Emits diagnostic for ODR mismatches --*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_AST_ODRDIAGSEMITTER_H 
- #define LLVM_CLANG_AST_ODRDIAGSEMITTER_H 
-   
- #include "clang/AST/ASTContext.h" 
- #include "clang/AST/DeclCXX.h" 
- #include "clang/AST/DeclObjC.h" 
- #include "clang/Basic/Diagnostic.h" 
- #include "clang/Basic/LangOptions.h" 
-   
- namespace clang { 
-   
- class ODRDiagsEmitter { 
- public: 
-   ODRDiagsEmitter(DiagnosticsEngine &Diags, const ASTContext &Context, 
-                   const LangOptions &LangOpts) 
-       : Diags(Diags), Context(Context), LangOpts(LangOpts) {} 
-   
-   /// Diagnose ODR mismatch between 2 FunctionDecl. 
-   /// 
-   /// Returns true if found a mismatch and diagnosed it. 
-   bool diagnoseMismatch(const FunctionDecl *FirstFunction, 
-                         const FunctionDecl *SecondFunction) const; 
-   
-   /// Diagnose ODR mismatch between 2 EnumDecl. 
-   /// 
-   /// Returns true if found a mismatch and diagnosed it. 
-   bool diagnoseMismatch(const EnumDecl *FirstEnum, 
-                         const EnumDecl *SecondEnum) const; 
-   
-   /// Diagnose ODR mismatch between 2 CXXRecordDecl. 
-   /// 
-   /// Returns true if found a mismatch and diagnosed it. 
-   /// To compare 2 declarations with merged and identical definition data 
-   /// you need to provide pre-merge definition data in \p SecondDD. 
-   bool 
-   diagnoseMismatch(const CXXRecordDecl *FirstRecord, 
-                    const CXXRecordDecl *SecondRecord, 
-                    const struct CXXRecordDecl::DefinitionData *SecondDD) const; 
-   
-   /// Diagnose ODR mismatch between 2 RecordDecl that are not CXXRecordDecl. 
-   /// 
-   /// Returns true if found a mismatch and diagnosed it. 
-   bool diagnoseMismatch(const RecordDecl *FirstRecord, 
-                         const RecordDecl *SecondRecord) const; 
-   
-   /// Diagnose ODR mismatch between 2 ObjCInterfaceDecl. 
-   /// 
-   /// Returns true if found a mismatch and diagnosed it. 
-   bool diagnoseMismatch( 
-       const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID, 
-       const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const; 
-   
-   /// Diagnose ODR mismatch between ObjCInterfaceDecl with different 
-   /// definitions. 
-   bool diagnoseMismatch(const ObjCInterfaceDecl *FirstID, 
-                         const ObjCInterfaceDecl *SecondID) const { 
-     assert(FirstID->data().Definition != SecondID->data().Definition && 
-            "Don't diagnose differences when definitions are merged already"); 
-     return diagnoseMismatch(FirstID, SecondID, &SecondID->data()); 
-   } 
-   
-   /// Diagnose ODR mismatch between 2 ObjCProtocolDecl. 
-   /// 
-   /// Returns true if found a mismatch and diagnosed it. 
-   /// To compare 2 declarations with merged and identical definition data 
-   /// you need to provide pre-merge definition data in \p SecondDD. 
-   bool diagnoseMismatch( 
-       const ObjCProtocolDecl *FirstProtocol, 
-       const ObjCProtocolDecl *SecondProtocol, 
-       const struct ObjCProtocolDecl::DefinitionData *SecondDD) const; 
-   
-   /// Diagnose ODR mismatch between ObjCProtocolDecl with different definitions. 
-   bool diagnoseMismatch(const ObjCProtocolDecl *FirstProtocol, 
-                         const ObjCProtocolDecl *SecondProtocol) const { 
-     assert(FirstProtocol->data().Definition != 
-                SecondProtocol->data().Definition && 
-            "Don't diagnose differences when definitions are merged already"); 
-     return diagnoseMismatch(FirstProtocol, SecondProtocol, 
-                             &SecondProtocol->data()); 
-   } 
-   
-   /// Get the best name we know for the module that owns the given 
-   /// declaration, or an empty string if the declaration is not from a module. 
-   static std::string getOwningModuleNameForDiagnostic(const Decl *D); 
-   
- private: 
-   using DeclHashes = llvm::SmallVector<std::pair<const Decl *, unsigned>, 4>; 
-   
-   // Used with err_module_odr_violation_mismatch_decl, 
-   // note_module_odr_violation_mismatch_decl, 
-   // err_module_odr_violation_mismatch_decl_unknown, 
-   // and note_module_odr_violation_mismatch_decl_unknown 
-   // This list should be the same Decl's as in ODRHash::isSubDeclToBeProcessed 
-   enum ODRMismatchDecl { 
-     EndOfClass, 
-     PublicSpecifer, 
-     PrivateSpecifer, 
-     ProtectedSpecifer, 
-     StaticAssert, 
-     Field, 
-     CXXMethod, 
-     TypeAlias, 
-     TypeDef, 
-     Var, 
-     Friend, 
-     FunctionTemplate, 
-     ObjCMethod, 
-     ObjCIvar, 
-     ObjCProperty, 
-     Other 
-   }; 
-   
-   struct DiffResult { 
-     const Decl *FirstDecl = nullptr, *SecondDecl = nullptr; 
-     ODRMismatchDecl FirstDiffType = Other, SecondDiffType = Other; 
-   }; 
-   
-   // If there is a diagnoseable difference, FirstDiffType and 
-   // SecondDiffType will not be Other and FirstDecl and SecondDecl will be 
-   // filled in if not EndOfClass. 
-   static DiffResult FindTypeDiffs(DeclHashes &FirstHashes, 
-                                   DeclHashes &SecondHashes); 
-   
-   DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const { 
-     return Diags.Report(Loc, DiagID); 
-   } 
-   
-   // Use this to diagnose that an unexpected Decl was encountered 
-   // or no difference was detected. This causes a generic error 
-   // message to be emitted. 
-   void diagnoseSubMismatchUnexpected(DiffResult &DR, 
-                                      const NamedDecl *FirstRecord, 
-                                      StringRef FirstModule, 
-                                      const NamedDecl *SecondRecord, 
-                                      StringRef SecondModule) const; 
-   
-   void diagnoseSubMismatchDifferentDeclKinds(DiffResult &DR, 
-                                              const NamedDecl *FirstRecord, 
-                                              StringRef FirstModule, 
-                                              const NamedDecl *SecondRecord, 
-                                              StringRef SecondModule) const; 
-   
-   bool diagnoseSubMismatchField(const NamedDecl *FirstRecord, 
-                                 StringRef FirstModule, StringRef SecondModule, 
-                                 const FieldDecl *FirstField, 
-                                 const FieldDecl *SecondField) const; 
-   
-   bool diagnoseSubMismatchTypedef(const NamedDecl *FirstRecord, 
-                                   StringRef FirstModule, StringRef SecondModule, 
-                                   const TypedefNameDecl *FirstTD, 
-                                   const TypedefNameDecl *SecondTD, 
-                                   bool IsTypeAlias) const; 
-   
-   bool diagnoseSubMismatchVar(const NamedDecl *FirstRecord, 
-                               StringRef FirstModule, StringRef SecondModule, 
-                               const VarDecl *FirstVD, 
-                               const VarDecl *SecondVD) const; 
-   
-   /// Check if protocol lists are the same and diagnose if they are different. 
-   /// 
-   /// Returns true if found a mismatch and diagnosed it. 
-   bool diagnoseSubMismatchProtocols(const ObjCProtocolList &FirstProtocols, 
-                                     const ObjCContainerDecl *FirstContainer, 
-                                     StringRef FirstModule, 
-                                     const ObjCProtocolList &SecondProtocols, 
-                                     const ObjCContainerDecl *SecondContainer, 
-                                     StringRef SecondModule) const; 
-   
-   /// Check if Objective-C methods are the same and diagnose if different. 
-   /// 
-   /// Returns true if found a mismatch and diagnosed it. 
-   bool diagnoseSubMismatchObjCMethod(const NamedDecl *FirstObjCContainer, 
-                                      StringRef FirstModule, 
-                                      StringRef SecondModule, 
-                                      const ObjCMethodDecl *FirstMethod, 
-                                      const ObjCMethodDecl *SecondMethod) const; 
-   
-   /// Check if Objective-C properties are the same and diagnose if different. 
-   /// 
-   /// Returns true if found a mismatch and diagnosed it. 
-   bool 
-   diagnoseSubMismatchObjCProperty(const NamedDecl *FirstObjCContainer, 
-                                   StringRef FirstModule, StringRef SecondModule, 
-                                   const ObjCPropertyDecl *FirstProp, 
-                                   const ObjCPropertyDecl *SecondProp) const; 
-   
- private: 
-   DiagnosticsEngine &Diags; 
-   const ASTContext &Context; 
-   const LangOptions &LangOpts; 
- }; 
-   
- } // namespace clang 
-   
- #endif 
-