]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / include / clang / AST / ExternalASTMerger.h
1 //===--- ExternalASTMerger.h - Merging External AST Interface ---*- 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 declares the ExternalASTMerger, which vends a combination of ASTs
10 //  from several different ASTContext/FileManager pairs
11 //
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_AST_EXTERNALASTMERGER_H
14 #define LLVM_CLANG_AST_EXTERNALASTMERGER_H
15
16 #include "clang/AST/ASTImporter.h"
17 #include "clang/AST/ExternalASTSource.h"
18 #include "llvm/Support/raw_ostream.h"
19
20 namespace clang {
21
22 /// ExternalASTSource implementation that merges information from several
23 /// ASTContexts.
24 ///
25 /// ExtermalASTMerger maintains a vector of ASTImporters that it uses to import
26 /// (potentially incomplete) Decls and DeclContexts from the source ASTContexts
27 /// in response to ExternalASTSource API calls.
28 ///
29 /// When lookup occurs in the resulting imported DeclContexts, the original
30 /// DeclContexts need to be queried.  Roughly, there are three cases here:
31 ///
32 /// - The DeclContext of origin can be found by simple name lookup.  In this
33 ///   case, no additional state is required.
34 ///
35 /// - The DeclContext of origin is different from what would be found by name
36 ///   lookup.  In this case, Origins contains an entry overriding lookup and
37 ///   specifying the correct pair of DeclContext/ASTContext.
38 ///
39 /// - The DeclContext of origin was determined by another ExterenalASTMerger.
40 ///   (This is possible when the source ASTContext for one of the Importers has
41 ///   its own ExternalASTMerger).  The origin must be properly forwarded in this
42 ///   case.
43 ///
44 /// ExternalASTMerger's job is to maintain the data structures necessary to
45 /// allow this.  The data structures themselves can be extracted (read-only) and
46 /// copied for re-use.
47 class ExternalASTMerger : public ExternalASTSource {
48 public:
49   /// A single origin for a DeclContext.  Unlike Decls, DeclContexts do
50   /// not allow their containing ASTContext to be determined in all cases.
51   struct DCOrigin {
52     DeclContext *DC;
53     ASTContext *AST;
54   };
55
56   typedef std::map<const DeclContext *, DCOrigin> OriginMap;
57   typedef std::vector<std::unique_ptr<ASTImporter>> ImporterVector;
58 private:
59   /// One importer exists for each source.
60   ImporterVector Importers;
61   /// Overrides in case name lookup would return nothing or would return
62   /// the wrong thing.
63   OriginMap Origins;
64   /// The installed log stream.
65   llvm::raw_ostream *LogStream;
66
67 public:
68   /// The target for an ExternalASTMerger.
69   ///
70   /// ASTImporters require both ASTContext and FileManager to be able to
71   /// import SourceLocations properly.
72   struct ImporterTarget {
73     ASTContext &AST;
74     FileManager &FM;
75   };
76   /// A source for an ExternalASTMerger.
77   ///
78   /// ASTImporters require both ASTContext and FileManager to be able to
79   /// import SourceLocations properly.  Additionally, when import occurs for
80   /// a DeclContext whose origin has been overridden, then this
81   /// ExternalASTMerger must be able to determine that.
82   struct ImporterSource {
83     ASTContext &AST;
84     FileManager &FM;
85     const OriginMap &OM;
86   };
87
88 private:
89   /// The target for this ExtenralASTMerger.
90   ImporterTarget Target;
91
92 public:
93   ExternalASTMerger(const ImporterTarget &Target,
94                     llvm::ArrayRef<ImporterSource> Sources);
95
96   /// Add a set of ASTContexts as possible origins.
97   ///
98   /// Usually the set will be initialized in the constructor, but long-lived
99   /// ExternalASTMergers may need to import from new sources (for example,
100   /// newly-parsed source files).
101   ///
102   /// Ensures that Importers does not gain duplicate entries as a result.
103   void AddSources(llvm::ArrayRef<ImporterSource> Sources);
104
105   /// Remove a set of ASTContexts as possible origins.
106   ///
107   /// Sometimes an origin goes away (for example, if a source file gets
108   /// superseded by a newer version).
109   ///
110   /// The caller is responsible for ensuring that this doesn't leave
111   /// DeclContexts that can't be completed.
112   void RemoveSources(llvm::ArrayRef<ImporterSource> Sources);
113
114   /// Implementation of the ExternalASTSource API.
115   bool FindExternalVisibleDeclsByName(const DeclContext *DC,
116                                       DeclarationName Name) override;
117
118   /// Implementation of the ExternalASTSource API.
119   void
120   FindExternalLexicalDecls(const DeclContext *DC,
121                            llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
122                            SmallVectorImpl<Decl *> &Result) override;
123
124   /// Implementation of the ExternalASTSource API.
125   void CompleteType(TagDecl *Tag) override;
126
127   /// Implementation of the ExternalASTSource API.
128   void CompleteType(ObjCInterfaceDecl *Interface) override;
129
130   /// Returns true if DC can be found in any source AST context.
131   bool CanComplete(DeclContext *DC);
132
133   /// Records an origin in Origins only if name lookup would find
134   /// something different or nothing at all.
135   void MaybeRecordOrigin(const DeclContext *ToDC, DCOrigin Origin);
136
137   /// Regardless of any checks, override the Origin for a DeclContext.
138   void ForceRecordOrigin(const DeclContext *ToDC, DCOrigin Origin);
139
140   /// Get a read-only view of the Origins map, for use in constructing
141   /// an ImporterSource for another ExternalASTMerger.
142   const OriginMap &GetOrigins() { return Origins; }
143
144   /// Returns true if Importers contains an ASTImporter whose source is
145   /// OriginContext.
146   bool HasImporterForOrigin(ASTContext &OriginContext);
147
148   /// Returns a reference to the ASTRImporter from Importers whose origin
149   /// is OriginContext.  This allows manual import of ASTs while preserving the
150   /// OriginMap correctly.
151   ASTImporter &ImporterForOrigin(ASTContext &OriginContext);
152
153   /// Sets the current log stream.
154   void SetLogStream(llvm::raw_string_ostream &Stream) { LogStream = &Stream; }
155 private:
156   /// Records and origin in Origins.
157   void RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin,
158                                   ASTImporter &importer);
159
160   /// Performs an action for every DeclContext that is identified as
161   /// corresponding (either by forced origin or by name lookup) to DC.
162   template <typename CallbackType>
163   void ForEachMatchingDC(const DeclContext *DC, CallbackType Callback);
164
165 public:
166   /// Log something if there is a logging callback installed.
167   llvm::raw_ostream &logs() { return *LogStream; }
168
169   /// True if the log stream is not llvm::nulls();
170   bool LoggingEnabled() { return LogStream != &llvm::nulls(); }
171 };
172
173 } // end namespace clang
174
175 #endif