Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  
  24. namespace clang {
  25.  
  26. class ASTContext;
  27. class Decl;
  28. class DiagnosticBuilder;
  29. class QualType;
  30. class RecordDecl;
  31. class 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.
  36. enum class StructuralEquivalenceKind {
  37.   Default,
  38.   Minimal,
  39. };
  40.  
  41. struct StructuralEquivalenceContext {
  42.   /// AST contexts for which we are checking structural equivalence.
  43.   ASTContext &FromCtx, &ToCtx;
  44.  
  45.   // Queue of from-to Decl pairs that are to be checked to determine the final
  46.   // result of equivalence of a starting Decl pair.
  47.   std::queue<std::pair<Decl *, Decl *>> DeclsToCheck;
  48.  
  49.   // Set of from-to Decl pairs that are already visited during the check
  50.   // (are in or were once in \c DeclsToCheck) of a starting Decl pair.
  51.   llvm::DenseSet<std::pair<Decl *, Decl *>> VisitedDecls;
  52.  
  53.   /// Declaration (from, to) pairs that are known not to be equivalent
  54.   /// (which we have already complained about).
  55.   llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls;
  56.  
  57.   StructuralEquivalenceKind EqKind;
  58.  
  59.   /// Whether we're being strict about the spelling of types when
  60.   /// unifying two types.
  61.   bool StrictTypeSpelling;
  62.  
  63.   /// Whether warn or error on tag type mismatches.
  64.   bool ErrorOnTagTypeMismatch;
  65.  
  66.   /// Whether to complain about failures.
  67.   bool Complain;
  68.  
  69.   /// \c true if the last diagnostic came from ToCtx.
  70.   bool LastDiagFromC2 = false;
  71.  
  72.   StructuralEquivalenceContext(
  73.       ASTContext &FromCtx, ASTContext &ToCtx,
  74.       llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
  75.       StructuralEquivalenceKind EqKind,
  76.       bool StrictTypeSpelling = false, bool Complain = true,
  77.       bool ErrorOnTagTypeMismatch = false)
  78.       : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
  79.         EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
  80.         ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}
  81.  
  82.   DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
  83.   DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
  84.  
  85.   /// Determine whether the two declarations are structurally
  86.   /// equivalent.
  87.   /// Implementation functions (all static functions in
  88.   /// ASTStructuralEquivalence.cpp) must never call this function because that
  89.   /// will wreak havoc the internal state (\c DeclsToCheck and
  90.   /// \c VisitedDecls members) and can cause faulty equivalent results.
  91.   bool IsEquivalent(Decl *D1, Decl *D2);
  92.  
  93.   /// Determine whether the two types are structurally equivalent.
  94.   /// Implementation functions (all static functions in
  95.   /// ASTStructuralEquivalence.cpp) must never call this function because that
  96.   /// will wreak havoc the internal state (\c DeclsToCheck and
  97.   /// \c VisitedDecls members) and can cause faulty equivalent results.
  98.   bool IsEquivalent(QualType T1, QualType T2);
  99.  
  100.   /// Determine whether the two statements are structurally equivalent.
  101.   /// Implementation functions (all static functions in
  102.   /// ASTStructuralEquivalence.cpp) must never call this function because that
  103.   /// will wreak havoc the internal state (\c DeclsToCheck and
  104.   /// \c VisitedDecls members) and can cause faulty equivalent results.
  105.   bool IsEquivalent(Stmt *S1, Stmt *S2);
  106.  
  107.   /// Find the index of the given anonymous struct/union within its
  108.   /// context.
  109.   ///
  110.   /// \returns Returns the index of this anonymous struct/union in its context,
  111.   /// including the next assigned index (if none of them match). Returns an
  112.   /// empty option if the context is not a record, i.e.. if the anonymous
  113.   /// struct/union is at namespace or block scope.
  114.   ///
  115.   /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
  116.   /// probably makes more sense in some other common place then here.
  117.   static std::optional<unsigned>
  118.   findUntaggedStructOrUnionIndex(RecordDecl *Anon);
  119.  
  120.   // If ErrorOnTagTypeMismatch is set, return the error, otherwise get the
  121.   // relevant warning for the input error diagnostic.
  122.   unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic);
  123.  
  124. private:
  125.   /// Finish checking all of the structural equivalences.
  126.   ///
  127.   /// \returns true if the equivalence check failed (non-equivalence detected),
  128.   /// false if equivalence was detected.
  129.   bool Finish();
  130.  
  131.   /// Check for common properties at Finish.
  132.   /// \returns true if D1 and D2 may be equivalent,
  133.   /// false if they are for sure not.
  134.   bool CheckCommonEquivalence(Decl *D1, Decl *D2);
  135.  
  136.   /// Check for class dependent properties at Finish.
  137.   /// \returns true if D1 and D2 may be equivalent,
  138.   /// false if they are for sure not.
  139.   bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2);
  140. };
  141.  
  142. } // namespace clang
  143.  
  144. #endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
  145.