|
|
|||
File indexing completed on 2026-05-10 08:36:29
0001 //===- ASTStructuralEquivalence.h -------------------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file defines the StructuralEquivalenceContext class which checks for 0010 // structural equivalence between types. 0011 // 0012 //===----------------------------------------------------------------------===// 0013 0014 #ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H 0015 #define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H 0016 0017 #include "clang/AST/DeclBase.h" 0018 #include "llvm/ADT/DenseMap.h" 0019 #include "llvm/ADT/DenseSet.h" 0020 #include <optional> 0021 #include <queue> 0022 #include <utility> 0023 0024 namespace clang { 0025 0026 class ASTContext; 0027 class Decl; 0028 class DiagnosticBuilder; 0029 class QualType; 0030 class RecordDecl; 0031 class SourceLocation; 0032 0033 /// \brief Whether to perform a normal or minimal equivalence check. 0034 /// In case of `Minimal`, we do not perform a recursive check of decls with 0035 /// external storage. 0036 enum class StructuralEquivalenceKind { 0037 Default, 0038 Minimal, 0039 }; 0040 0041 struct StructuralEquivalenceContext { 0042 /// Store declaration pairs already found to be non-equivalent. 0043 /// key: (from, to, IgnoreTemplateParmDepth) 0044 using NonEquivalentDeclSet = llvm::DenseSet<std::tuple<Decl *, Decl *, int>>; 0045 0046 /// AST contexts for which we are checking structural equivalence. 0047 ASTContext &FromCtx, &ToCtx; 0048 0049 // Queue of from-to Decl pairs that are to be checked to determine the final 0050 // result of equivalence of a starting Decl pair. 0051 std::queue<std::pair<Decl *, Decl *>> DeclsToCheck; 0052 0053 // Set of from-to Decl pairs that are already visited during the check 0054 // (are in or were once in \c DeclsToCheck) of a starting Decl pair. 0055 llvm::DenseSet<std::pair<Decl *, Decl *>> VisitedDecls; 0056 0057 /// Declaration (from, to) pairs that are known not to be equivalent 0058 /// (which we have already complained about). 0059 NonEquivalentDeclSet &NonEquivalentDecls; 0060 0061 StructuralEquivalenceKind EqKind; 0062 0063 /// Whether we're being strict about the spelling of types when 0064 /// unifying two types. 0065 bool StrictTypeSpelling; 0066 0067 /// Whether warn or error on tag type mismatches. 0068 bool ErrorOnTagTypeMismatch; 0069 0070 /// Whether to complain about failures. 0071 bool Complain; 0072 0073 /// \c true if the last diagnostic came from ToCtx. 0074 bool LastDiagFromC2 = false; 0075 0076 /// Whether to ignore comparing the depth of template param(TemplateTypeParm) 0077 bool IgnoreTemplateParmDepth; 0078 0079 StructuralEquivalenceContext(ASTContext &FromCtx, ASTContext &ToCtx, 0080 NonEquivalentDeclSet &NonEquivalentDecls, 0081 StructuralEquivalenceKind EqKind, 0082 bool StrictTypeSpelling = false, 0083 bool Complain = true, 0084 bool ErrorOnTagTypeMismatch = false, 0085 bool IgnoreTemplateParmDepth = false) 0086 : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls), 0087 EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling), 0088 ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain), 0089 IgnoreTemplateParmDepth(IgnoreTemplateParmDepth) {} 0090 0091 DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID); 0092 DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID); 0093 0094 /// Determine whether the two declarations are structurally 0095 /// equivalent. 0096 /// Implementation functions (all static functions in 0097 /// ASTStructuralEquivalence.cpp) must never call this function because that 0098 /// will wreak havoc the internal state (\c DeclsToCheck and 0099 /// \c VisitedDecls members) and can cause faulty equivalent results. 0100 bool IsEquivalent(Decl *D1, Decl *D2); 0101 0102 /// Determine whether the two types are structurally equivalent. 0103 /// Implementation functions (all static functions in 0104 /// ASTStructuralEquivalence.cpp) must never call this function because that 0105 /// will wreak havoc the internal state (\c DeclsToCheck and 0106 /// \c VisitedDecls members) and can cause faulty equivalent results. 0107 bool IsEquivalent(QualType T1, QualType T2); 0108 0109 /// Determine whether the two statements are structurally equivalent. 0110 /// Implementation functions (all static functions in 0111 /// ASTStructuralEquivalence.cpp) must never call this function because that 0112 /// will wreak havoc the internal state (\c DeclsToCheck and 0113 /// \c VisitedDecls members) and can cause faulty equivalent results. 0114 bool IsEquivalent(Stmt *S1, Stmt *S2); 0115 0116 /// Find the index of the given anonymous struct/union within its 0117 /// context. 0118 /// 0119 /// \returns Returns the index of this anonymous struct/union in its context, 0120 /// including the next assigned index (if none of them match). Returns an 0121 /// empty option if the context is not a record, i.e.. if the anonymous 0122 /// struct/union is at namespace or block scope. 0123 /// 0124 /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It 0125 /// probably makes more sense in some other common place then here. 0126 static std::optional<unsigned> 0127 findUntaggedStructOrUnionIndex(RecordDecl *Anon); 0128 0129 // If ErrorOnTagTypeMismatch is set, return the error, otherwise get the 0130 // relevant warning for the input error diagnostic. 0131 unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic); 0132 0133 private: 0134 /// Finish checking all of the structural equivalences. 0135 /// 0136 /// \returns true if the equivalence check failed (non-equivalence detected), 0137 /// false if equivalence was detected. 0138 bool Finish(); 0139 0140 /// Check for common properties at Finish. 0141 /// \returns true if D1 and D2 may be equivalent, 0142 /// false if they are for sure not. 0143 bool CheckCommonEquivalence(Decl *D1, Decl *D2); 0144 0145 /// Check for class dependent properties at Finish. 0146 /// \returns true if D1 and D2 may be equivalent, 0147 /// false if they are for sure not. 0148 bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2); 0149 }; 0150 0151 } // namespace clang 0152 0153 #endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|