Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- ODRDiagsEmitter.h - Emits diagnostic for ODR mismatches --*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef LLVM_CLANG_AST_ODRDIAGSEMITTER_H
  10. #define LLVM_CLANG_AST_ODRDIAGSEMITTER_H
  11.  
  12. #include "clang/AST/ASTContext.h"
  13. #include "clang/AST/DeclCXX.h"
  14. #include "clang/AST/DeclObjC.h"
  15. #include "clang/Basic/Diagnostic.h"
  16. #include "clang/Basic/LangOptions.h"
  17.  
  18. namespace clang {
  19.  
  20. class ODRDiagsEmitter {
  21. public:
  22.   ODRDiagsEmitter(DiagnosticsEngine &Diags, const ASTContext &Context,
  23.                   const LangOptions &LangOpts)
  24.       : Diags(Diags), Context(Context), LangOpts(LangOpts) {}
  25.  
  26.   /// Diagnose ODR mismatch between 2 FunctionDecl.
  27.   ///
  28.   /// Returns true if found a mismatch and diagnosed it.
  29.   bool diagnoseMismatch(const FunctionDecl *FirstFunction,
  30.                         const FunctionDecl *SecondFunction) const;
  31.  
  32.   /// Diagnose ODR mismatch between 2 EnumDecl.
  33.   ///
  34.   /// Returns true if found a mismatch and diagnosed it.
  35.   bool diagnoseMismatch(const EnumDecl *FirstEnum,
  36.                         const EnumDecl *SecondEnum) const;
  37.  
  38.   /// Diagnose ODR mismatch between 2 CXXRecordDecl.
  39.   ///
  40.   /// Returns true if found a mismatch and diagnosed it.
  41.   /// To compare 2 declarations with merged and identical definition data
  42.   /// you need to provide pre-merge definition data in \p SecondDD.
  43.   bool
  44.   diagnoseMismatch(const CXXRecordDecl *FirstRecord,
  45.                    const CXXRecordDecl *SecondRecord,
  46.                    const struct CXXRecordDecl::DefinitionData *SecondDD) const;
  47.  
  48.   /// Diagnose ODR mismatch between 2 RecordDecl that are not CXXRecordDecl.
  49.   ///
  50.   /// Returns true if found a mismatch and diagnosed it.
  51.   bool diagnoseMismatch(const RecordDecl *FirstRecord,
  52.                         const RecordDecl *SecondRecord) const;
  53.  
  54.   /// Diagnose ODR mismatch between 2 ObjCInterfaceDecl.
  55.   ///
  56.   /// Returns true if found a mismatch and diagnosed it.
  57.   bool diagnoseMismatch(
  58.       const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
  59.       const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const;
  60.  
  61.   /// Diagnose ODR mismatch between ObjCInterfaceDecl with different
  62.   /// definitions.
  63.   bool diagnoseMismatch(const ObjCInterfaceDecl *FirstID,
  64.                         const ObjCInterfaceDecl *SecondID) const {
  65.     assert(FirstID->data().Definition != SecondID->data().Definition &&
  66.            "Don't diagnose differences when definitions are merged already");
  67.     return diagnoseMismatch(FirstID, SecondID, &SecondID->data());
  68.   }
  69.  
  70.   /// Diagnose ODR mismatch between 2 ObjCProtocolDecl.
  71.   ///
  72.   /// Returns true if found a mismatch and diagnosed it.
  73.   /// To compare 2 declarations with merged and identical definition data
  74.   /// you need to provide pre-merge definition data in \p SecondDD.
  75.   bool diagnoseMismatch(
  76.       const ObjCProtocolDecl *FirstProtocol,
  77.       const ObjCProtocolDecl *SecondProtocol,
  78.       const struct ObjCProtocolDecl::DefinitionData *SecondDD) const;
  79.  
  80.   /// Diagnose ODR mismatch between ObjCProtocolDecl with different definitions.
  81.   bool diagnoseMismatch(const ObjCProtocolDecl *FirstProtocol,
  82.                         const ObjCProtocolDecl *SecondProtocol) const {
  83.     assert(FirstProtocol->data().Definition !=
  84.                SecondProtocol->data().Definition &&
  85.            "Don't diagnose differences when definitions are merged already");
  86.     return diagnoseMismatch(FirstProtocol, SecondProtocol,
  87.                             &SecondProtocol->data());
  88.   }
  89.  
  90.   /// Get the best name we know for the module that owns the given
  91.   /// declaration, or an empty string if the declaration is not from a module.
  92.   static std::string getOwningModuleNameForDiagnostic(const Decl *D);
  93.  
  94. private:
  95.   using DeclHashes = llvm::SmallVector<std::pair<const Decl *, unsigned>, 4>;
  96.  
  97.   // Used with err_module_odr_violation_mismatch_decl,
  98.   // note_module_odr_violation_mismatch_decl,
  99.   // err_module_odr_violation_mismatch_decl_unknown,
  100.   // and note_module_odr_violation_mismatch_decl_unknown
  101.   // This list should be the same Decl's as in ODRHash::isSubDeclToBeProcessed
  102.   enum ODRMismatchDecl {
  103.     EndOfClass,
  104.     PublicSpecifer,
  105.     PrivateSpecifer,
  106.     ProtectedSpecifer,
  107.     StaticAssert,
  108.     Field,
  109.     CXXMethod,
  110.     TypeAlias,
  111.     TypeDef,
  112.     Var,
  113.     Friend,
  114.     FunctionTemplate,
  115.     ObjCMethod,
  116.     ObjCIvar,
  117.     ObjCProperty,
  118.     Other
  119.   };
  120.  
  121.   struct DiffResult {
  122.     const Decl *FirstDecl = nullptr, *SecondDecl = nullptr;
  123.     ODRMismatchDecl FirstDiffType = Other, SecondDiffType = Other;
  124.   };
  125.  
  126.   // If there is a diagnoseable difference, FirstDiffType and
  127.   // SecondDiffType will not be Other and FirstDecl and SecondDecl will be
  128.   // filled in if not EndOfClass.
  129.   static DiffResult FindTypeDiffs(DeclHashes &FirstHashes,
  130.                                   DeclHashes &SecondHashes);
  131.  
  132.   DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
  133.     return Diags.Report(Loc, DiagID);
  134.   }
  135.  
  136.   // Use this to diagnose that an unexpected Decl was encountered
  137.   // or no difference was detected. This causes a generic error
  138.   // message to be emitted.
  139.   void diagnoseSubMismatchUnexpected(DiffResult &DR,
  140.                                      const NamedDecl *FirstRecord,
  141.                                      StringRef FirstModule,
  142.                                      const NamedDecl *SecondRecord,
  143.                                      StringRef SecondModule) const;
  144.  
  145.   void diagnoseSubMismatchDifferentDeclKinds(DiffResult &DR,
  146.                                              const NamedDecl *FirstRecord,
  147.                                              StringRef FirstModule,
  148.                                              const NamedDecl *SecondRecord,
  149.                                              StringRef SecondModule) const;
  150.  
  151.   bool diagnoseSubMismatchField(const NamedDecl *FirstRecord,
  152.                                 StringRef FirstModule, StringRef SecondModule,
  153.                                 const FieldDecl *FirstField,
  154.                                 const FieldDecl *SecondField) const;
  155.  
  156.   bool diagnoseSubMismatchTypedef(const NamedDecl *FirstRecord,
  157.                                   StringRef FirstModule, StringRef SecondModule,
  158.                                   const TypedefNameDecl *FirstTD,
  159.                                   const TypedefNameDecl *SecondTD,
  160.                                   bool IsTypeAlias) const;
  161.  
  162.   bool diagnoseSubMismatchVar(const NamedDecl *FirstRecord,
  163.                               StringRef FirstModule, StringRef SecondModule,
  164.                               const VarDecl *FirstVD,
  165.                               const VarDecl *SecondVD) const;
  166.  
  167.   /// Check if protocol lists are the same and diagnose if they are different.
  168.   ///
  169.   /// Returns true if found a mismatch and diagnosed it.
  170.   bool diagnoseSubMismatchProtocols(const ObjCProtocolList &FirstProtocols,
  171.                                     const ObjCContainerDecl *FirstContainer,
  172.                                     StringRef FirstModule,
  173.                                     const ObjCProtocolList &SecondProtocols,
  174.                                     const ObjCContainerDecl *SecondContainer,
  175.                                     StringRef SecondModule) const;
  176.  
  177.   /// Check if Objective-C methods are the same and diagnose if different.
  178.   ///
  179.   /// Returns true if found a mismatch and diagnosed it.
  180.   bool diagnoseSubMismatchObjCMethod(const NamedDecl *FirstObjCContainer,
  181.                                      StringRef FirstModule,
  182.                                      StringRef SecondModule,
  183.                                      const ObjCMethodDecl *FirstMethod,
  184.                                      const ObjCMethodDecl *SecondMethod) const;
  185.  
  186.   /// Check if Objective-C properties are the same and diagnose if different.
  187.   ///
  188.   /// Returns true if found a mismatch and diagnosed it.
  189.   bool
  190.   diagnoseSubMismatchObjCProperty(const NamedDecl *FirstObjCContainer,
  191.                                   StringRef FirstModule, StringRef SecondModule,
  192.                                   const ObjCPropertyDecl *FirstProp,
  193.                                   const ObjCPropertyDecl *SecondProp) const;
  194.  
  195. private:
  196.   DiagnosticsEngine &Diags;
  197.   const ASTContext &Context;
  198.   const LangOptions &LangOpts;
  199. };
  200.  
  201. } // namespace clang
  202.  
  203. #endif
  204.