clang  19.0.0git
ODRDiagsEmitter.h
Go to the documentation of this file.
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"
17 
18 namespace clang {
19 
21 public:
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:
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
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::LangOptions interface.
SourceLocation Loc
Definition: SemaObjC.cpp:755
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:193
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1553
Represents an enum.
Definition: Decl.h:3870
Represents a function declaration or definition.
Definition: Decl.h:1972
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
bool diagnoseMismatch(const FunctionDecl *FirstFunction, const FunctionDecl *SecondFunction) const
Diagnose ODR mismatch between 2 FunctionDecl.
bool diagnoseMismatch(const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID) const
Diagnose ODR mismatch between ObjCInterfaceDecl with different definitions.
ODRDiagsEmitter(DiagnosticsEngine &Diags, const ASTContext &Context, const LangOptions &LangOpts)
bool diagnoseMismatch(const ObjCProtocolDecl *FirstProtocol, const ObjCProtocolDecl *SecondProtocol) const
Diagnose ODR mismatch between ObjCProtocolDecl with different definitions.
static std::string getOwningModuleNameForDiagnostic(const Decl *D)
Get the best name we know for the module that owns the given declaration, or an empty string if the d...
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
Represents a struct/union/class.
Definition: Decl.h:4171
The JSON file list parser is used to communicate input to InstallAPI.