clang 23.0.0git
ASTStructuralEquivalence.h
Go to the documentation of this file.
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
24namespace clang {
25
26class ASTContext;
27class Decl;
29class QualType;
30class RecordDecl;
31class 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.
40
42 /// Store declaration pairs already found to be non-equivalent.
43 /// key: (from, to, IgnoreTemplateParmDepth)
44 using NonEquivalentDeclSet = llvm::DenseSet<std::tuple<Decl *, Decl *, int>>;
45
46 /// The language options to use for making a structural equivalence check.
48
49 /// AST contexts for which we are checking structural equivalence.
51
52 // Queue of from-to Decl pairs that are to be checked to determine the final
53 // result of equivalence of a starting Decl pair.
54 std::queue<std::pair<Decl *, Decl *>> DeclsToCheck;
55
56 // Set of from-to Decl pairs that are already visited during the check
57 // (are in or were once in \c DeclsToCheck) of a starting Decl pair.
58 llvm::DenseSet<std::pair<Decl *, Decl *>> VisitedDecls;
59
60 /// Declaration (from, to) pairs that are known not to be equivalent
61 /// (which we have already complained about).
63
64 /// RAII helper that is used to suppress diagnostics during attribute
65 /// equivalence checking.
76
78
79 /// Whether we're being strict about the spelling of types when
80 /// unifying two types.
82
83 /// Whether warn or error on tag type mismatches.
85
86 /// Whether to complain about failures.
88
89 /// \c true if the last diagnostic came from ToCtx.
90 bool LastDiagFromC2 = false;
91
92 /// Whether to ignore comparing the depth of template param(TemplateTypeParm)
94
108
109 DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
110 DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
111
112 /// Determine whether the two declarations are structurally
113 /// equivalent.
114 /// Implementation functions (all static functions in
115 /// ASTStructuralEquivalence.cpp) must never call this function because that
116 /// will wreak havoc the internal state (\c DeclsToCheck and
117 /// \c VisitedDecls members) and can cause faulty equivalent results.
118 bool IsEquivalent(Decl *D1, Decl *D2);
119
120 /// Determine whether the two types are structurally equivalent.
121 /// Implementation functions (all static functions in
122 /// ASTStructuralEquivalence.cpp) must never call this function because that
123 /// will wreak havoc the internal state (\c DeclsToCheck and
124 /// \c VisitedDecls members) and can cause faulty equivalent results.
125 bool IsEquivalent(QualType T1, QualType T2);
126
127 /// Determine whether the two statements are structurally equivalent.
128 /// Implementation functions (all static functions in
129 /// ASTStructuralEquivalence.cpp) must never call this function because that
130 /// will wreak havoc the internal state (\c DeclsToCheck and
131 /// \c VisitedDecls members) and can cause faulty equivalent results.
132 bool IsEquivalent(Stmt *S1, Stmt *S2);
133
134 /// Find the index of the given anonymous struct/union within its
135 /// context.
136 ///
137 /// \returns Returns the index of this anonymous struct/union in its context,
138 /// including the next assigned index (if none of them match). Returns an
139 /// empty option if the context is not a record, i.e.. if the anonymous
140 /// struct/union is at namespace or block scope.
141 ///
142 /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
143 /// probably makes more sense in some other common place then here.
145
146 // If ErrorOnTagTypeMismatch is set, return the error, otherwise get the
147 // relevant warning for the input error diagnostic.
148 unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic);
149
150 /// Iterate over the decl pairs in DeclsToCheck until either an inequivalent
151 /// pair is found or the queue is empty.
152 bool checkDeclQueue();
153
154private:
155 /// Finish checking all of the structural equivalences.
156 ///
157 /// \returns true if the equivalence check failed (non-equivalence detected),
158 /// false if equivalence was detected.
159 bool Finish();
160
161 /// Check for common properties at Finish.
162 /// \returns true if D1 and D2 may be equivalent,
163 /// false if they are for sure not.
164 bool CheckCommonEquivalence(Decl *D1, Decl *D2);
165
166 /// Check for class dependent properties at Finish.
167 /// \returns true if D1 and D2 may be equivalent,
168 /// false if they are for sure not.
169 bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2);
170};
171
172/// Expose these functions so that they can be called by the functions that
173/// check equivalence of attribute arguments.
176 QualType T2);
177bool isEquivalent(StructuralEquivalenceContext &Context, const Stmt *S1,
178 const Stmt *S2);
179bool isEquivalent(const IdentifierInfo *Name1, const IdentifierInfo *Name2);
180} // namespace ASTStructuralEquivalence
181
182} // namespace clang
183
184#endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:220
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
A little helper class used to produce diagnostics.
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
A (possibly-)qualified type.
Definition TypeBase.h:937
Represents a struct/union/class.
Definition Decl.h:4324
Encodes a location in the source.
Stmt - This represents one statement.
Definition Stmt.h:86
Expose these functions so that they can be called by the functions that check equivalence of attribut...
bool isEquivalent(StructuralEquivalenceContext &Context, QualType T1, QualType T2)
Determine structural equivalence of two types.
The JSON file list parser is used to communicate input to InstallAPI.
StructuralEquivalenceKind
Whether to perform a normal or minimal equivalence check.
const LangOptions & LangOpts
The language options to use for making a structural equivalence check.
ASTContext & FromCtx
AST contexts for which we are checking structural equivalence.
bool LastDiagFromC2
true if the last diagnostic came from ToCtx.
bool checkDeclQueue()
Iterate over the decl pairs in DeclsToCheck until either an inequivalent pair is found or the queue i...
bool StrictTypeSpelling
Whether we're being strict about the spelling of types when unifying two types.
StructuralEquivalenceContext(const LangOptions &LangOpts, ASTContext &FromCtx, ASTContext &ToCtx, NonEquivalentDeclSet &NonEquivalentDecls, StructuralEquivalenceKind EqKind, bool StrictTypeSpelling=false, bool Complain=true, bool ErrorOnTagTypeMismatch=false, bool IgnoreTemplateParmDepth=false)
std::queue< std::pair< Decl *, Decl * > > DeclsToCheck
llvm::DenseSet< std::pair< Decl *, Decl * > > VisitedDecls
static UnsignedOrNone findUntaggedStructOrUnionIndex(RecordDecl *Anon)
Find the index of the given anonymous struct/union within its context.
bool IgnoreTemplateParmDepth
Whether to ignore comparing the depth of template param(TemplateTypeParm)
bool ErrorOnTagTypeMismatch
Whether warn or error on tag type mismatches.
NonEquivalentDeclSet & NonEquivalentDecls
Declaration (from, to) pairs that are known not to be equivalent (which we have already complained ab...
bool Complain
Whether to complain about failures.
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID)
unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic)
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID)
llvm::DenseSet< std::tuple< Decl *, Decl *, int > > NonEquivalentDeclSet
Store declaration pairs already found to be non-equivalent.
bool IsEquivalent(Decl *D1, Decl *D2)
Determine whether the two declarations are structurally equivalent.