Clang Project

clang_source_code/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
20namespace 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.
47class ExternalASTMerger : public ExternalASTSource {
48public:
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 *, DCOriginOriginMap;
57  typedef std::vector<std::unique_ptr<ASTImporter>> ImporterVector;
58private:
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
67public:
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
88private:
89  /// The target for this ExtenralASTMerger.
90  ImporterTarget Target;
91
92public:
93  ExternalASTMerger(const ImporterTarget &Target,
94                    llvm::ArrayRef<ImporterSourceSources);
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<ImporterSourceSources);
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<ImporterSourceSources);
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 *ToDCDCOrigin Origin);
136
137  /// Regardless of any checks, override the Origin for a DeclContext.
138  void ForceRecordOrigin(const DeclContext *ToDCDCOrigin 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; }
155private:
156  /// Records and origin in Origins.
157  void RecordOriginImpl(const DeclContext *ToDCDCOrigin 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
165public:
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
176
clang::ExternalASTMerger::DCOrigin
clang::ExternalASTMerger::DCOrigin::DC
clang::ExternalASTMerger::DCOrigin::AST
clang::ExternalASTMerger::Importers
clang::ExternalASTMerger::Origins
clang::ExternalASTMerger::LogStream
clang::ExternalASTMerger::ImporterTarget
clang::ExternalASTMerger::ImporterTarget::AST
clang::ExternalASTMerger::ImporterTarget::FM
clang::ExternalASTMerger::ImporterSource
clang::ExternalASTMerger::ImporterSource::AST
clang::ExternalASTMerger::ImporterSource::FM
clang::ExternalASTMerger::ImporterSource::OM
clang::ExternalASTMerger::Target
clang::ExternalASTMerger::AddSources
clang::ExternalASTMerger::RemoveSources
clang::ExternalASTMerger::FindExternalVisibleDeclsByName
clang::ExternalASTMerger::FindExternalLexicalDecls
clang::ExternalASTMerger::CompleteType
clang::ExternalASTMerger::CompleteType
clang::ExternalASTMerger::CanComplete
clang::ExternalASTMerger::MaybeRecordOrigin
clang::ExternalASTMerger::ForceRecordOrigin
clang::ExternalASTMerger::GetOrigins
clang::ExternalASTMerger::HasImporterForOrigin
clang::ExternalASTMerger::ImporterForOrigin
clang::ExternalASTMerger::SetLogStream
clang::ExternalASTMerger::RecordOriginImpl
clang::ExternalASTMerger::ForEachMatchingDC
clang::ExternalASTMerger::logs
clang::ExternalASTMerger::LoggingEnabled