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       bool ErrorOnTagTypeMismatch = false)
     67       : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
     68         StrictTypeSpelling(StrictTypeSpelling),
     69         ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain),
     70         LastDiagFromC2(false) {}
     71 
     72   DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
     73   DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
     74 
     75   /// Determine whether the two declarations are structurally
     76   /// equivalent.
     77   bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
     78 
     79   /// Determine whether the two types are structurally equivalent.
     80   bool IsStructurallyEquivalent(QualType T1, QualType T2);
     81 
     82   /// Find the index of the given anonymous struct/union within its
     83   /// context.
     84   ///
     85   /// \returns Returns the index of this anonymous struct/union in its context,
     86   /// including the next assigned index (if none of them match). Returns an
     87   /// empty option if the context is not a record, i.e.. if the anonymous
     88   /// struct/union is at namespace or block scope.
     89   ///
     90   /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
     91   /// probably makes more sense in some other common place then here.
     92   static llvm::Optional<unsigned>
     93   findUntaggedStructOrUnionIndex(RecordDecl *Anon);
     94 
     95 private:
     96   /// Finish checking all of the structural equivalences.
     97   ///
     98   /// \returns true if an error occurred, false otherwise.
     99   bool Finish();
    100 };
    101 } // namespace clang
    102 
    103 #endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
    104