|
|
|||
File indexing completed on 2026-05-10 08:36:37
0001 //===--- ExternalASTMerger.h - Merging External AST Interface ---*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file declares the ExternalASTMerger, which vends a combination of ASTs 0010 // from several different ASTContext/FileManager pairs 0011 // 0012 //===----------------------------------------------------------------------===// 0013 #ifndef LLVM_CLANG_AST_EXTERNALASTMERGER_H 0014 #define LLVM_CLANG_AST_EXTERNALASTMERGER_H 0015 0016 #include "clang/AST/ASTImporter.h" 0017 #include "clang/AST/ASTImporterSharedState.h" 0018 #include "clang/AST/ExternalASTSource.h" 0019 #include "llvm/Support/raw_ostream.h" 0020 0021 namespace clang { 0022 0023 /// ExternalASTSource implementation that merges information from several 0024 /// ASTContexts. 0025 /// 0026 /// ExternalASTMerger maintains a vector of ASTImporters that it uses to import 0027 /// (potentially incomplete) Decls and DeclContexts from the source ASTContexts 0028 /// in response to ExternalASTSource API calls. 0029 /// 0030 /// When lookup occurs in the resulting imported DeclContexts, the original 0031 /// DeclContexts need to be queried. Roughly, there are three cases here: 0032 /// 0033 /// - The DeclContext of origin can be found by simple name lookup. In this 0034 /// case, no additional state is required. 0035 /// 0036 /// - The DeclContext of origin is different from what would be found by name 0037 /// lookup. In this case, Origins contains an entry overriding lookup and 0038 /// specifying the correct pair of DeclContext/ASTContext. 0039 /// 0040 /// - The DeclContext of origin was determined by another ExternalASTMerger. 0041 /// (This is possible when the source ASTContext for one of the Importers has 0042 /// its own ExternalASTMerger). The origin must be properly forwarded in this 0043 /// case. 0044 /// 0045 /// ExternalASTMerger's job is to maintain the data structures necessary to 0046 /// allow this. The data structures themselves can be extracted (read-only) and 0047 /// copied for re-use. 0048 class ExternalASTMerger : public ExternalASTSource { 0049 public: 0050 /// A single origin for a DeclContext. Unlike Decls, DeclContexts do 0051 /// not allow their containing ASTContext to be determined in all cases. 0052 struct DCOrigin { 0053 DeclContext *DC; 0054 ASTContext *AST; 0055 }; 0056 0057 typedef std::map<const DeclContext *, DCOrigin> OriginMap; 0058 typedef std::vector<std::unique_ptr<ASTImporter>> ImporterVector; 0059 private: 0060 /// One importer exists for each source. 0061 ImporterVector Importers; 0062 /// Overrides in case name lookup would return nothing or would return 0063 /// the wrong thing. 0064 OriginMap Origins; 0065 /// The installed log stream. 0066 llvm::raw_ostream *LogStream; 0067 0068 public: 0069 /// The target for an ExternalASTMerger. 0070 /// 0071 /// ASTImporters require both ASTContext and FileManager to be able to 0072 /// import SourceLocations properly. 0073 struct ImporterTarget { 0074 ASTContext &AST; 0075 FileManager &FM; 0076 }; 0077 /// A source for an ExternalASTMerger. 0078 /// 0079 /// ASTImporters require both ASTContext and FileManager to be able to 0080 /// import SourceLocations properly. Additionally, when import occurs for 0081 /// a DeclContext whose origin has been overridden, then this 0082 /// ExternalASTMerger must be able to determine that. 0083 class ImporterSource { 0084 ASTContext &AST; 0085 FileManager &FM; 0086 const OriginMap &OM; 0087 /// True iff the source only exists temporary, i.e., it will be removed from 0088 /// the ExternalASTMerger during the life time of the ExternalASTMerger. 0089 bool Temporary; 0090 /// If the ASTContext of this source has an ExternalASTMerger that imports 0091 /// into this source, then this will point to that other ExternalASTMerger. 0092 ExternalASTMerger *Merger; 0093 0094 public: 0095 ImporterSource(ASTContext &AST, FileManager &FM, const OriginMap &OM, 0096 bool Temporary = false, ExternalASTMerger *Merger = nullptr) 0097 : AST(AST), FM(FM), OM(OM), Temporary(Temporary), Merger(Merger) {} 0098 ASTContext &getASTContext() const { return AST; } 0099 FileManager &getFileManager() const { return FM; } 0100 const OriginMap &getOriginMap() const { return OM; } 0101 bool isTemporary() const { return Temporary; } 0102 ExternalASTMerger *getMerger() const { return Merger; } 0103 }; 0104 0105 private: 0106 /// The target for this ExternalASTMerger. 0107 ImporterTarget Target; 0108 /// ExternalASTMerger has multiple ASTImporters that import into the same 0109 /// TU. This is the shared state for all ASTImporters of this 0110 /// ExternalASTMerger. 0111 /// See also the CrossTranslationUnitContext that has a similar setup. 0112 std::shared_ptr<ASTImporterSharedState> SharedState; 0113 0114 public: 0115 ExternalASTMerger(const ImporterTarget &Target, 0116 llvm::ArrayRef<ImporterSource> Sources); 0117 0118 /// Asks all connected ASTImporters if any of them imported the given 0119 /// declaration. If any ASTImporter did import the given declaration, 0120 /// then this function returns the declaration that D was imported from. 0121 /// Returns nullptr if no ASTImporter did import D. 0122 Decl *FindOriginalDecl(Decl *D); 0123 0124 /// Add a set of ASTContexts as possible origins. 0125 /// 0126 /// Usually the set will be initialized in the constructor, but long-lived 0127 /// ExternalASTMergers may need to import from new sources (for example, 0128 /// newly-parsed source files). 0129 /// 0130 /// Ensures that Importers does not gain duplicate entries as a result. 0131 void AddSources(llvm::ArrayRef<ImporterSource> Sources); 0132 0133 /// Remove a set of ASTContexts as possible origins. 0134 /// 0135 /// Sometimes an origin goes away (for example, if a source file gets 0136 /// superseded by a newer version). 0137 /// 0138 /// The caller is responsible for ensuring that this doesn't leave 0139 /// DeclContexts that can't be completed. 0140 void RemoveSources(llvm::ArrayRef<ImporterSource> Sources); 0141 0142 /// Implementation of the ExternalASTSource API. 0143 bool FindExternalVisibleDeclsByName(const DeclContext *DC, 0144 DeclarationName Name, 0145 const DeclContext *OriginalDC) override; 0146 0147 /// Implementation of the ExternalASTSource API. 0148 void 0149 FindExternalLexicalDecls(const DeclContext *DC, 0150 llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, 0151 SmallVectorImpl<Decl *> &Result) override; 0152 0153 /// Implementation of the ExternalASTSource API. 0154 void CompleteType(TagDecl *Tag) override; 0155 0156 /// Implementation of the ExternalASTSource API. 0157 void CompleteType(ObjCInterfaceDecl *Interface) override; 0158 0159 /// Returns true if DC can be found in any source AST context. 0160 bool CanComplete(DeclContext *DC); 0161 0162 /// Records an origin in Origins only if name lookup would find 0163 /// something different or nothing at all. 0164 void MaybeRecordOrigin(const DeclContext *ToDC, DCOrigin Origin); 0165 0166 /// Regardless of any checks, override the Origin for a DeclContext. 0167 void ForceRecordOrigin(const DeclContext *ToDC, DCOrigin Origin); 0168 0169 /// Get a read-only view of the Origins map, for use in constructing 0170 /// an ImporterSource for another ExternalASTMerger. 0171 const OriginMap &GetOrigins() { return Origins; } 0172 0173 /// Returns true if Importers contains an ASTImporter whose source is 0174 /// OriginContext. 0175 bool HasImporterForOrigin(ASTContext &OriginContext); 0176 0177 /// Returns a reference to the ASTImporter from Importers whose origin 0178 /// is OriginContext. This allows manual import of ASTs while preserving the 0179 /// OriginMap correctly. 0180 ASTImporter &ImporterForOrigin(ASTContext &OriginContext); 0181 0182 /// Sets the current log stream. 0183 void SetLogStream(llvm::raw_string_ostream &Stream) { LogStream = &Stream; } 0184 private: 0185 /// Records and origin in Origins. 0186 void RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin, 0187 ASTImporter &importer); 0188 0189 /// Performs an action for every DeclContext that is identified as 0190 /// corresponding (either by forced origin or by name lookup) to DC. 0191 template <typename CallbackType> 0192 void ForEachMatchingDC(const DeclContext *DC, CallbackType Callback); 0193 0194 public: 0195 /// Log something if there is a logging callback installed. 0196 llvm::raw_ostream &logs() { return *LogStream; } 0197 0198 /// True if the log stream is not llvm::nulls(); 0199 bool LoggingEnabled() { return LogStream != &llvm::nulls(); } 0200 }; 0201 0202 } // end namespace clang 0203 0204 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|