]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/ASTStructuralEquivalence.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / AST / ASTStructuralEquivalence.h
1 //===- ASTStructuralEquivalence.h -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines the StructuralEquivalenceContext class which checks for
11 //  structural equivalence between types.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
16 #define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
17
18 #include "clang/AST/DeclBase.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/DenseSet.h"
21 #include "llvm/ADT/Optional.h"
22 #include <deque>
23 #include <utility>
24
25 namespace clang {
26
27 class ASTContext;
28 class Decl;
29 class DiagnosticBuilder;
30 class QualType;
31 class RecordDecl;
32 class SourceLocation;
33
34 /// \brief Whether to perform a normal or minimal equivalence check.
35 /// In case of `Minimal`, we do not perform a recursive check of decls with
36 /// external storage.
37 enum class StructuralEquivalenceKind {
38   Default,
39   Minimal,
40 };
41
42 struct StructuralEquivalenceContext {
43   /// AST contexts for which we are checking structural equivalence.
44   ASTContext &FromCtx, &ToCtx;
45
46   /// The set of "tentative" equivalences between two canonical
47   /// declarations, mapping from a declaration in the first context to the
48   /// declaration in the second context that we believe to be equivalent.
49   llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
50
51   /// Queue of declarations in the first context whose equivalence
52   /// with a declaration in the second context still needs to be verified.
53   std::deque<Decl *> DeclsToCheck;
54
55   /// Declaration (from, to) pairs that are known not to be equivalent
56   /// (which we have already complained about).
57   llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls;
58
59   StructuralEquivalenceKind EqKind;
60
61   /// Whether we're being strict about the spelling of types when
62   /// unifying two types.
63   bool StrictTypeSpelling;
64
65   /// Whether warn or error on tag type mismatches.
66   bool ErrorOnTagTypeMismatch;
67
68   /// Whether to complain about failures.
69   bool Complain;
70
71   /// \c true if the last diagnostic came from ToCtx.
72   bool LastDiagFromC2 = false;
73
74   StructuralEquivalenceContext(
75       ASTContext &FromCtx, ASTContext &ToCtx,
76       llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
77       StructuralEquivalenceKind EqKind,
78       bool StrictTypeSpelling = false, bool Complain = true,
79       bool ErrorOnTagTypeMismatch = false)
80       : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
81         EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
82         ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}
83
84   DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
85   DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
86
87   /// Determine whether the two declarations are structurally
88   /// equivalent.
89   /// Implementation functions (all static functions in
90   /// ASTStructuralEquivalence.cpp) must never call this function because that
91   /// will wreak havoc the internal state (\c DeclsToCheck and
92   /// \c TentativeEquivalences members) and can cause faulty equivalent results.
93   bool IsEquivalent(Decl *D1, Decl *D2);
94
95   /// Determine whether the two types are structurally equivalent.
96   /// Implementation functions (all static functions in
97   /// ASTStructuralEquivalence.cpp) must never call this function because that
98   /// will wreak havoc the internal state (\c DeclsToCheck and
99   /// \c TentativeEquivalences members) and can cause faulty equivalent results.
100   bool IsEquivalent(QualType T1, QualType T2);
101
102   /// Find the index of the given anonymous struct/union within its
103   /// context.
104   ///
105   /// \returns Returns the index of this anonymous struct/union in its context,
106   /// including the next assigned index (if none of them match). Returns an
107   /// empty option if the context is not a record, i.e.. if the anonymous
108   /// struct/union is at namespace or block scope.
109   ///
110   /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
111   /// probably makes more sense in some other common place then here.
112   static llvm::Optional<unsigned>
113   findUntaggedStructOrUnionIndex(RecordDecl *Anon);
114
115 private:
116   /// Finish checking all of the structural equivalences.
117   ///
118   /// \returns true if the equivalence check failed (non-equivalence detected),
119   /// false if equivalence was detected.
120   bool Finish();
121
122   /// Check for common properties at Finish.
123   /// \returns true if D1 and D2 may be equivalent,
124   /// false if they are for sure not.
125   bool CheckCommonEquivalence(Decl *D1, Decl *D2);
126
127   /// Check for class dependent properties at Finish.
128   /// \returns true if D1 and D2 may be equivalent,
129   /// false if they are for sure not.
130   bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2);
131 };
132
133 } // namespace clang
134
135 #endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H