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.
80
82
83 /// Whether we're being strict about the spelling of types when
84 /// unifying two types.
86
87 /// Whether warn or error on tag type mismatches.
89
90 /// Whether to complain about failures.
92
93 /// \c true if the last diagnostic came from ToCtx.
94 bool LastDiagFromC2 = false;
95
96 /// Whether to ignore comparing the depth of template param(TemplateTypeParm)
98
112
113 DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
114 DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
115
116 /// Determine whether the two declarations are structurally
117 /// equivalent.
118 /// Implementation functions (all static functions in
119 /// ASTStructuralEquivalence.cpp) must never call this function because that
120 /// will wreak havoc the internal state (\c DeclsToCheck and
121 /// \c VisitedDecls members) and can cause faulty equivalent results.
122 bool IsEquivalent(Decl *D1, Decl *D2);
123
124 /// Determine whether the two types are structurally equivalent.
125 /// Implementation functions (all static functions in
126 /// ASTStructuralEquivalence.cpp) must never call this function because that
127 /// will wreak havoc the internal state (\c DeclsToCheck and
128 /// \c VisitedDecls members) and can cause faulty equivalent results.
129 bool IsEquivalent(QualType T1, QualType T2);
130
131 /// Determine whether the two statements are structurally equivalent.
132 /// Implementation functions (all static functions in
133 /// ASTStructuralEquivalence.cpp) must never call this function because that
134 /// will wreak havoc the internal state (\c DeclsToCheck and
135 /// \c VisitedDecls members) and can cause faulty equivalent results.
136 bool IsEquivalent(Stmt *S1, Stmt *S2);
137
138 /// Find the index of the given anonymous struct/union within its
139 /// context.
140 ///
141 /// \returns Returns the index of this anonymous struct/union in its context,
142 /// including the next assigned index (if none of them match). Returns an
143 /// empty option if the context is not a record, i.e.. if the anonymous
144 /// struct/union is at namespace or block scope.
145 ///
146 /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
147 /// probably makes more sense in some other common place then here.
149
150 // If ErrorOnTagTypeMismatch is set, return the error, otherwise get the
151 // relevant warning for the input error diagnostic.
152 unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic);
153
154 /// Iterate over the decl pairs in DeclsToCheck until either an inequivalent
155 /// pair is found or the queue is empty.
156 bool checkDeclQueue();
157
158private:
159 /// Finish checking all of the structural equivalences.
160 ///
161 /// \returns true if the equivalence check failed (non-equivalence detected),
162 /// false if equivalence was detected.
163 bool Finish();
164
165 /// Check for common properties at Finish.
166 /// \returns true if D1 and D2 may be equivalent,
167 /// false if they are for sure not.
168 bool CheckCommonEquivalence(Decl *D1, Decl *D2);
169
170 /// Check for class dependent properties at Finish.
171 /// \returns true if D1 and D2 may be equivalent,
172 /// false if they are for sure not.
173 bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2);
174};
175
176/// Expose these functions so that they can be called by the functions that
177/// check equivalence of attribute arguments.
180 QualType T2);
181bool isEquivalent(StructuralEquivalenceContext &Context, const Stmt *S1,
182 const Stmt *S2);
183bool isEquivalent(const IdentifierInfo *Name1, const IdentifierInfo *Name2);
184} // namespace ASTStructuralEquivalence
185
186} // namespace clang
187
188#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:226
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:4327
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.
AttrScopedAttrEquivalenceContext(const AttrScopedAttrEquivalenceContext &)=delete
AttrScopedAttrEquivalenceContext & operator=(const AttrScopedAttrEquivalenceContext &)=delete
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.