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