Skip to content

Commit 3e7350f

Browse files
committed
[ODRHash diagnostics] Move ODRDiagsEmitter to libAST in separate files. NFC.
Intend to use `ODRDiagsEmitter` during parsing to diagnose a parsed definition differing from a definition with the same name from a hidden [sub]module. Differential Revision: https://reviews.llvm.org/D128695
1 parent 95d497f commit 3e7350f

File tree

6 files changed

+1959
-1955
lines changed

6 files changed

+1959
-1955
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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/Basic/Diagnostic.h"
15+
#include "clang/Basic/LangOptions.h"
16+
17+
namespace clang {
18+
19+
class ODRDiagsEmitter {
20+
public:
21+
ODRDiagsEmitter(DiagnosticsEngine &Diags, const ASTContext &Context,
22+
const LangOptions &LangOpts)
23+
: Diags(Diags), Context(Context), LangOpts(LangOpts) {}
24+
25+
/// Diagnose ODR mismatch between 2 FunctionDecl.
26+
///
27+
/// Returns true if found a mismatch and diagnosed it.
28+
bool diagnoseMismatch(const FunctionDecl *FirstFunction,
29+
const FunctionDecl *SecondFunction) const;
30+
31+
/// Diagnose ODR mismatch between 2 EnumDecl.
32+
///
33+
/// Returns true if found a mismatch and diagnosed it.
34+
bool diagnoseMismatch(const EnumDecl *FirstEnum,
35+
const EnumDecl *SecondEnum) const;
36+
37+
/// Diagnose ODR mismatch between 2 CXXRecordDecl.
38+
///
39+
/// Returns true if found a mismatch and diagnosed it.
40+
/// To compare 2 declarations with merged and identical definition data
41+
/// you need to provide pre-merge definition data in \p SecondDD.
42+
bool
43+
diagnoseMismatch(const CXXRecordDecl *FirstRecord,
44+
const CXXRecordDecl *SecondRecord,
45+
const struct CXXRecordDecl::DefinitionData *SecondDD) const;
46+
47+
/// Get the best name we know for the module that owns the given
48+
/// declaration, or an empty string if the declaration is not from a module.
49+
static std::string getOwningModuleNameForDiagnostic(const Decl *D);
50+
51+
private:
52+
using DeclHashes = llvm::SmallVector<std::pair<const Decl *, unsigned>, 4>;
53+
54+
// Used with err_module_odr_violation_mismatch_decl and
55+
// note_module_odr_violation_mismatch_decl
56+
// This list should be the same Decl's as in ODRHash::isDeclToBeProcessed
57+
enum ODRMismatchDecl {
58+
EndOfClass,
59+
PublicSpecifer,
60+
PrivateSpecifer,
61+
ProtectedSpecifer,
62+
StaticAssert,
63+
Field,
64+
CXXMethod,
65+
TypeAlias,
66+
TypeDef,
67+
Var,
68+
Friend,
69+
FunctionTemplate,
70+
Other
71+
};
72+
73+
struct DiffResult {
74+
const Decl *FirstDecl = nullptr, *SecondDecl = nullptr;
75+
ODRMismatchDecl FirstDiffType = Other, SecondDiffType = Other;
76+
};
77+
78+
// If there is a diagnoseable difference, FirstDiffType and
79+
// SecondDiffType will not be Other and FirstDecl and SecondDecl will be
80+
// filled in if not EndOfClass.
81+
static DiffResult FindTypeDiffs(DeclHashes &FirstHashes,
82+
DeclHashes &SecondHashes);
83+
84+
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
85+
return Diags.Report(Loc, DiagID);
86+
}
87+
88+
// Use this to diagnose that an unexpected Decl was encountered
89+
// or no difference was detected. This causes a generic error
90+
// message to be emitted.
91+
void diagnoseSubMismatchUnexpected(DiffResult &DR,
92+
const NamedDecl *FirstRecord,
93+
StringRef FirstModule,
94+
const NamedDecl *SecondRecord,
95+
StringRef SecondModule) const;
96+
97+
void diagnoseSubMismatchDifferentDeclKinds(DiffResult &DR,
98+
const NamedDecl *FirstRecord,
99+
StringRef FirstModule,
100+
const NamedDecl *SecondRecord,
101+
StringRef SecondModule) const;
102+
103+
bool diagnoseSubMismatchField(const NamedDecl *FirstRecord,
104+
StringRef FirstModule, StringRef SecondModule,
105+
const FieldDecl *FirstField,
106+
const FieldDecl *SecondField) const;
107+
108+
bool diagnoseSubMismatchTypedef(const NamedDecl *FirstRecord,
109+
StringRef FirstModule, StringRef SecondModule,
110+
const TypedefNameDecl *FirstTD,
111+
const TypedefNameDecl *SecondTD,
112+
bool IsTypeAlias) const;
113+
114+
bool diagnoseSubMismatchVar(const NamedDecl *FirstRecord,
115+
StringRef FirstModule, StringRef SecondModule,
116+
const VarDecl *FirstVD,
117+
const VarDecl *SecondVD) const;
118+
119+
private:
120+
DiagnosticsEngine &Diags;
121+
const ASTContext &Context;
122+
const LangOptions &LangOpts;
123+
};
124+
125+
} // namespace clang
126+
127+
#endif

0 commit comments

Comments
 (0)