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
//===- ASTStructuralEquivalence.h -------------------------------*- 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
//  This file defines the StructuralEquivalenceContext class which checks for
10
//  structural equivalence between types.
11
//
12
//===----------------------------------------------------------------------===//
13
 
14
#ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
15
#define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
16
 
17
#include "clang/AST/DeclBase.h"
18
#include "llvm/ADT/DenseMap.h"
19
#include "llvm/ADT/DenseSet.h"
20
#include <optional>
21
#include <queue>
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
  // Queue of from-to Decl pairs that are to be checked to determine the final
46
  // result of equivalence of a starting Decl pair.
47
  std::queue<std::pair<Decl *, Decl *>> DeclsToCheck;
48
 
49
  // Set of from-to Decl pairs that are already visited during the check
50
  // (are in or were once in \c DeclsToCheck) of a starting Decl pair.
51
  llvm::DenseSet<std::pair<Decl *, Decl *>> VisitedDecls;
52
 
53
  /// Declaration (from, to) pairs that are known not to be equivalent
54
  /// (which we have already complained about).
55
  llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls;
56
 
57
  StructuralEquivalenceKind EqKind;
58
 
59
  /// Whether we're being strict about the spelling of types when
60
  /// unifying two types.
61
  bool StrictTypeSpelling;
62
 
63
  /// Whether warn or error on tag type mismatches.
64
  bool ErrorOnTagTypeMismatch;
65
 
66
  /// Whether to complain about failures.
67
  bool Complain;
68
 
69
  /// \c true if the last diagnostic came from ToCtx.
70
  bool LastDiagFromC2 = false;
71
 
72
  StructuralEquivalenceContext(
73
      ASTContext &FromCtx, ASTContext &ToCtx,
74
      llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
75
      StructuralEquivalenceKind EqKind,
76
      bool StrictTypeSpelling = false, bool Complain = true,
77
      bool ErrorOnTagTypeMismatch = false)
78
      : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
79
        EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
80
        ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}
81
 
82
  DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
83
  DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
84
 
85
  /// Determine whether the two declarations are structurally
86
  /// equivalent.
87
  /// Implementation functions (all static functions in
88
  /// ASTStructuralEquivalence.cpp) must never call this function because that
89
  /// will wreak havoc the internal state (\c DeclsToCheck and
90
  /// \c VisitedDecls members) and can cause faulty equivalent results.
91
  bool IsEquivalent(Decl *D1, Decl *D2);
92
 
93
  /// Determine whether the two types are structurally equivalent.
94
  /// Implementation functions (all static functions in
95
  /// ASTStructuralEquivalence.cpp) must never call this function because that
96
  /// will wreak havoc the internal state (\c DeclsToCheck and
97
  /// \c VisitedDecls members) and can cause faulty equivalent results.
98
  bool IsEquivalent(QualType T1, QualType T2);
99
 
100
  /// Determine whether the two statements are structurally equivalent.
101
  /// Implementation functions (all static functions in
102
  /// ASTStructuralEquivalence.cpp) must never call this function because that
103
  /// will wreak havoc the internal state (\c DeclsToCheck and
104
  /// \c VisitedDecls members) and can cause faulty equivalent results.
105
  bool IsEquivalent(Stmt *S1, Stmt *S2);
106
 
107
  /// Find the index of the given anonymous struct/union within its
108
  /// context.
109
  ///
110
  /// \returns Returns the index of this anonymous struct/union in its context,
111
  /// including the next assigned index (if none of them match). Returns an
112
  /// empty option if the context is not a record, i.e.. if the anonymous
113
  /// struct/union is at namespace or block scope.
114
  ///
115
  /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
116
  /// probably makes more sense in some other common place then here.
117
  static std::optional<unsigned>
118
  findUntaggedStructOrUnionIndex(RecordDecl *Anon);
119
 
120
  // If ErrorOnTagTypeMismatch is set, return the error, otherwise get the
121
  // relevant warning for the input error diagnostic.
122
  unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic);
123
 
124
private:
125
  /// Finish checking all of the structural equivalences.
126
  ///
127
  /// \returns true if the equivalence check failed (non-equivalence detected),
128
  /// false if equivalence was detected.
129
  bool Finish();
130
 
131
  /// Check for common properties at Finish.
132
  /// \returns true if D1 and D2 may be equivalent,
133
  /// false if they are for sure not.
134
  bool CheckCommonEquivalence(Decl *D1, Decl *D2);
135
 
136
  /// Check for class dependent properties at Finish.
137
  /// \returns true if D1 and D2 may be equivalent,
138
  /// false if they are for sure not.
139
  bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2);
140
};
141
 
142
} // namespace clang
143
 
144
#endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H