123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|