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