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