123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- 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 "llvm/ADT/Optional.h"
- #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 llvm::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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|