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