Home | History | Annotate | Download | only in AST
      1 //===--- ASTStructuralEquivalence.h - ---------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file defines the StructuralEquivalenceContext class which checks for
     11 //  structural equivalence between types.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
     16 #define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
     17 
     18 #include "llvm/ADT/DenseMap.h"
     19 #include "llvm/ADT/DenseSet.h"
     20 #include "llvm/ADT/Optional.h"
     21 #include <deque>
     22 
     23 namespace clang {
     24 
     25 class ASTContext;
     26 class Decl;
     27 class DiagnosticBuilder;
     28 class QualType;
     29 class RecordDecl;
     30 class SourceLocation;
     31 
     32 struct StructuralEquivalenceContext {
     33   /// AST contexts for which we are checking structural equivalence.
     34   ASTContext &FromCtx, &ToCtx;
     35 
     36   /// The set of "tentative" equivalences between two canonical
     37   /// declarations, mapping from a declaration in the first context to the
     38   /// declaration in the second context that we believe to be equivalent.
     39   llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
     40 
     41   /// Queue of declarations in the first context whose equivalence
     42   /// with a declaration in the second context still needs to be verified.
     43   std::deque<Decl *> DeclsToCheck;
     44 
     45   /// Declaration (from, to) pairs that are known not to be equivalent
     46   /// (which we have already complained about).
     47   llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls;
     48 
     49   /// Whether we're being strict about the spelling of types when
     50   /// unifying two types.
     51   bool StrictTypeSpelling;
     52 
     53   /// Whether warn or error on tag type mismatches.
     54   bool ErrorOnTagTypeMismatch;
     55 
     56   /// Whether to complain about failures.
     57   bool Complain;
     58 
     59   /// \c true if the last diagnostic came from ToCtx.
     60   bool LastDiagFromC2;
     61 
     62   StructuralEquivalenceContext(
     63       ASTContext &FromCtx, ASTContext &ToCtx,
     64       llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
     65       bool StrictTypeSpelling = false, bool Complain = true)
     66       : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
     67         StrictTypeSpelling(StrictTypeSpelling), Complain(Complain),
     68         LastDiagFromC2(false) {}
     69 
     70   DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
     71   DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
     72 
     73   /// Determine whether the two declarations are structurally
     74   /// equivalent.
     75   bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
     76 
     77   /// Determine whether the two types are structurally equivalent.
     78   bool IsStructurallyEquivalent(QualType T1, QualType T2);
     79 
     80   /// Find the index of the given anonymous struct/union within its
     81   /// context.
     82   ///
     83   /// \returns Returns the index of this anonymous struct/union in its context,
     84   /// including the next assigned index (if none of them match). Returns an
     85   /// empty option if the context is not a record, i.e.. if the anonymous
     86   /// struct/union is at namespace or block scope.
     87   ///
     88   /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
     89   /// probably makes more sense in some other common place then here.
     90   static llvm::Optional<unsigned>
     91   findUntaggedStructOrUnionIndex(RecordDecl *Anon);
     92 
     93 private:
     94   /// Finish checking all of the structural equivalences.
     95   ///
     96   /// \returns true if an error occurred, false otherwise.
     97   bool Finish();
     98 };
     99 } // namespace clang
    100 
    101 #endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
    102