Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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