- //===- ASTStructuralEquivalence.h -------------------------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- //  This file defines the StructuralEquivalenceContext class which checks for 
- //  structural equivalence between types. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H 
- #define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H 
-   
- #include "clang/AST/DeclBase.h" 
- #include "llvm/ADT/DenseMap.h" 
- #include "llvm/ADT/DenseSet.h" 
- #include <optional> 
- #include <queue> 
- #include <utility> 
-   
- namespace clang { 
-   
- class ASTContext; 
- class Decl; 
- class DiagnosticBuilder; 
- class QualType; 
- class RecordDecl; 
- class SourceLocation; 
-   
- /// \brief Whether to perform a normal or minimal equivalence check. 
- /// In case of `Minimal`, we do not perform a recursive check of decls with 
- /// external storage. 
- enum class StructuralEquivalenceKind { 
-   Default, 
-   Minimal, 
- }; 
-   
- struct StructuralEquivalenceContext { 
-   /// AST contexts for which we are checking structural equivalence. 
-   ASTContext &FromCtx, &ToCtx; 
-   
-   // Queue of from-to Decl pairs that are to be checked to determine the final 
-   // result of equivalence of a starting Decl pair. 
-   std::queue<std::pair<Decl *, Decl *>> DeclsToCheck; 
-   
-   // Set of from-to Decl pairs that are already visited during the check 
-   // (are in or were once in \c DeclsToCheck) of a starting Decl pair. 
-   llvm::DenseSet<std::pair<Decl *, Decl *>> VisitedDecls; 
-   
-   /// Declaration (from, to) pairs that are known not to be equivalent 
-   /// (which we have already complained about). 
-   llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls; 
-   
-   StructuralEquivalenceKind EqKind; 
-   
-   /// Whether we're being strict about the spelling of types when 
-   /// unifying two types. 
-   bool StrictTypeSpelling; 
-   
-   /// Whether warn or error on tag type mismatches. 
-   bool ErrorOnTagTypeMismatch; 
-   
-   /// Whether to complain about failures. 
-   bool Complain; 
-   
-   /// \c true if the last diagnostic came from ToCtx. 
-   bool LastDiagFromC2 = false; 
-   
-   StructuralEquivalenceContext( 
-       ASTContext &FromCtx, ASTContext &ToCtx, 
-       llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls, 
-       StructuralEquivalenceKind EqKind, 
-       bool StrictTypeSpelling = false, bool Complain = true, 
-       bool ErrorOnTagTypeMismatch = false) 
-       : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls), 
-         EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling), 
-         ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {} 
-   
-   DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID); 
-   DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID); 
-   
-   /// Determine whether the two declarations are structurally 
-   /// equivalent. 
-   /// Implementation functions (all static functions in 
-   /// ASTStructuralEquivalence.cpp) must never call this function because that 
-   /// will wreak havoc the internal state (\c DeclsToCheck and 
-   /// \c VisitedDecls members) and can cause faulty equivalent results. 
-   bool IsEquivalent(Decl *D1, Decl *D2); 
-   
-   /// Determine whether the two types are structurally equivalent. 
-   /// Implementation functions (all static functions in 
-   /// ASTStructuralEquivalence.cpp) must never call this function because that 
-   /// will wreak havoc the internal state (\c DeclsToCheck and 
-   /// \c VisitedDecls members) and can cause faulty equivalent results. 
-   bool IsEquivalent(QualType T1, QualType T2); 
-   
-   /// Determine whether the two statements are structurally equivalent. 
-   /// Implementation functions (all static functions in 
-   /// ASTStructuralEquivalence.cpp) must never call this function because that 
-   /// will wreak havoc the internal state (\c DeclsToCheck and 
-   /// \c VisitedDecls members) and can cause faulty equivalent results. 
-   bool IsEquivalent(Stmt *S1, Stmt *S2); 
-   
-   /// Find the index of the given anonymous struct/union within its 
-   /// context. 
-   /// 
-   /// \returns Returns the index of this anonymous struct/union in its context, 
-   /// including the next assigned index (if none of them match). Returns an 
-   /// empty option if the context is not a record, i.e.. if the anonymous 
-   /// struct/union is at namespace or block scope. 
-   /// 
-   /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It 
-   /// probably makes more sense in some other common place then here. 
-   static std::optional<unsigned> 
-   findUntaggedStructOrUnionIndex(RecordDecl *Anon); 
-   
-   // If ErrorOnTagTypeMismatch is set, return the error, otherwise get the 
-   // relevant warning for the input error diagnostic. 
-   unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic); 
-   
- private: 
-   /// Finish checking all of the structural equivalences. 
-   /// 
-   /// \returns true if the equivalence check failed (non-equivalence detected), 
-   /// false if equivalence was detected. 
-   bool Finish(); 
-   
-   /// Check for common properties at Finish. 
-   /// \returns true if D1 and D2 may be equivalent, 
-   /// false if they are for sure not. 
-   bool CheckCommonEquivalence(Decl *D1, Decl *D2); 
-   
-   /// Check for class dependent properties at Finish. 
-   /// \returns true if D1 and D2 may be equivalent, 
-   /// false if they are for sure not. 
-   bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2); 
- }; 
-   
- } // namespace clang 
-   
- #endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H 
-