1 | //===- ASTImporter.h - Importing ASTs from other Contexts -------*- 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 defines the ASTImporter class which imports AST nodes from one |
10 | // context into another context. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CLANG_AST_ASTIMPORTER_H |
15 | #define LLVM_CLANG_AST_ASTIMPORTER_H |
16 | |
17 | #include "clang/AST/DeclarationName.h" |
18 | #include "clang/AST/NestedNameSpecifier.h" |
19 | #include "clang/AST/TemplateName.h" |
20 | #include "clang/AST/Type.h" |
21 | #include "clang/Basic/Diagnostic.h" |
22 | #include "clang/Basic/IdentifierTable.h" |
23 | #include "clang/Basic/LLVM.h" |
24 | #include "clang/Basic/SourceLocation.h" |
25 | #include "llvm/ADT/DenseMap.h" |
26 | #include "llvm/ADT/DenseSet.h" |
27 | #include "llvm/ADT/Optional.h" |
28 | #include "llvm/ADT/SmallVector.h" |
29 | #include "llvm/Support/Error.h" |
30 | #include <utility> |
31 | |
32 | namespace clang { |
33 | |
34 | class ASTContext; |
35 | class Attr; |
36 | class ASTImporterLookupTable; |
37 | class CXXBaseSpecifier; |
38 | class CXXCtorInitializer; |
39 | class Decl; |
40 | class DeclContext; |
41 | class Expr; |
42 | class FileManager; |
43 | class NamedDecl; |
44 | class Stmt; |
45 | class TagDecl; |
46 | class TranslationUnitDecl; |
47 | class TypeSourceInfo; |
48 | |
49 | class ImportError : public llvm::ErrorInfo<ImportError> { |
50 | public: |
51 | /// \brief Kind of error when importing an AST component. |
52 | enum ErrorKind { |
53 | NameConflict, /// Naming ambiguity (likely ODR violation). |
54 | UnsupportedConstruct, /// Not supported node or case. |
55 | Unknown /// Other error. |
56 | }; |
57 | |
58 | ErrorKind Error; |
59 | |
60 | static char ID; |
61 | |
62 | ImportError() : Error(Unknown) { } |
63 | ImportError(const ImportError &Other) : Error(Other.Error) { } |
64 | ImportError(ErrorKind Error) : Error(Error) { } |
65 | |
66 | std::string toString() const; |
67 | |
68 | void log(raw_ostream &OS) const override; |
69 | std::error_code convertToErrorCode() const override; |
70 | }; |
71 | |
72 | // \brief Returns with a list of declarations started from the canonical decl |
73 | // then followed by subsequent decls in the translation unit. |
74 | // This gives a canonical list for each entry in the redecl chain. |
75 | // `Decl::redecls()` gives a list of decls which always start from the |
76 | // previous decl and the next item is actually the previous item in the order |
77 | // of source locations. Thus, `Decl::redecls()` gives different lists for |
78 | // the different entries in a given redecl chain. |
79 | llvm::SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D); |
80 | |
81 | /// Imports selected nodes from one AST context into another context, |
82 | /// merging AST nodes where appropriate. |
83 | class ASTImporter { |
84 | friend class ASTNodeImporter; |
85 | public: |
86 | using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>; |
87 | using ImportedCXXBaseSpecifierMap = |
88 | llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>; |
89 | |
90 | private: |
91 | |
92 | /// Pointer to the import specific lookup table, which may be shared |
93 | /// amongst several ASTImporter objects. |
94 | /// This is an externally managed resource (and should exist during the |
95 | /// lifetime of the ASTImporter object) |
96 | /// If not set then the original C/C++ lookup is used. |
97 | ASTImporterLookupTable *LookupTable = nullptr; |
98 | |
99 | /// The contexts we're importing to and from. |
100 | ASTContext &ToContext, &FromContext; |
101 | |
102 | /// The file managers we're importing to and from. |
103 | FileManager &ToFileManager, &FromFileManager; |
104 | |
105 | /// Whether to perform a minimal import. |
106 | bool Minimal; |
107 | |
108 | /// Whether the last diagnostic came from the "from" context. |
109 | bool LastDiagFromFrom = false; |
110 | |
111 | /// Mapping from the already-imported types in the "from" context |
112 | /// to the corresponding types in the "to" context. |
113 | llvm::DenseMap<const Type *, const Type *> ImportedTypes; |
114 | |
115 | /// Mapping from the already-imported declarations in the "from" |
116 | /// context to the corresponding declarations in the "to" context. |
117 | llvm::DenseMap<Decl *, Decl *> ImportedDecls; |
118 | |
119 | /// Mapping from the already-imported declarations in the "to" |
120 | /// context to the corresponding declarations in the "from" context. |
121 | llvm::DenseMap<Decl *, Decl *> ImportedFromDecls; |
122 | |
123 | /// Mapping from the already-imported statements in the "from" |
124 | /// context to the corresponding statements in the "to" context. |
125 | llvm::DenseMap<Stmt *, Stmt *> ImportedStmts; |
126 | |
127 | /// Mapping from the already-imported FileIDs in the "from" source |
128 | /// manager to the corresponding FileIDs in the "to" source manager. |
129 | llvm::DenseMap<FileID, FileID> ImportedFileIDs; |
130 | |
131 | /// Mapping from the already-imported CXXBasesSpecifier in |
132 | /// the "from" source manager to the corresponding CXXBasesSpecifier |
133 | /// in the "to" source manager. |
134 | ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers; |
135 | |
136 | /// Declaration (from, to) pairs that are known not to be equivalent |
137 | /// (which we have already complained about). |
138 | NonEquivalentDeclSet NonEquivalentDecls; |
139 | |
140 | using FoundDeclsTy = SmallVector<NamedDecl *, 2>; |
141 | FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name); |
142 | |
143 | void AddToLookupTable(Decl *ToD); |
144 | |
145 | public: |
146 | |
147 | /// \param ToContext The context we'll be importing into. |
148 | /// |
149 | /// \param ToFileManager The file manager we'll be importing into. |
150 | /// |
151 | /// \param FromContext The context we'll be importing from. |
152 | /// |
153 | /// \param FromFileManager The file manager we'll be importing into. |
154 | /// |
155 | /// \param MinimalImport If true, the importer will attempt to import |
156 | /// as little as it can, e.g., by importing declarations as forward |
157 | /// declarations that can be completed at a later point. |
158 | /// |
159 | /// \param LookupTable The importer specific lookup table which may be |
160 | /// shared amongst several ASTImporter objects. |
161 | /// If not set then the original C/C++ lookup is used. |
162 | ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, |
163 | ASTContext &FromContext, FileManager &FromFileManager, |
164 | bool MinimalImport, |
165 | ASTImporterLookupTable *LookupTable = nullptr); |
166 | |
167 | virtual ~ASTImporter(); |
168 | |
169 | /// Whether the importer will perform a minimal import, creating |
170 | /// to-be-completed forward declarations when possible. |
171 | bool isMinimalImport() const { return Minimal; } |
172 | |
173 | /// \brief Import the given object, returns the result. |
174 | /// |
175 | /// \param To Import the object into this variable. |
176 | /// \param From Object to import. |
177 | /// \return Error information (success or error). |
178 | template <typename ImportT> |
179 | LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) { |
180 | auto ToOrErr = Import_New(From); |
181 | if (ToOrErr) |
182 | To = *ToOrErr; |
183 | return ToOrErr.takeError(); |
184 | } |
185 | |
186 | /// Import the given type from the "from" context into the "to" |
187 | /// context. A null type is imported as a null type (no error). |
188 | /// |
189 | /// \returns The equivalent type in the "to" context, or the import error. |
190 | llvm::Expected<QualType> Import_New(QualType FromT); |
191 | // FIXME: Remove this version. |
192 | QualType Import(QualType FromT); |
193 | |
194 | /// Import the given type source information from the |
195 | /// "from" context into the "to" context. |
196 | /// |
197 | /// \returns The equivalent type source information in the "to" |
198 | /// context, or the import error. |
199 | llvm::Expected<TypeSourceInfo *> Import_New(TypeSourceInfo *FromTSI); |
200 | // FIXME: Remove this version. |
201 | TypeSourceInfo *Import(TypeSourceInfo *FromTSI); |
202 | |
203 | /// Import the given attribute from the "from" context into the |
204 | /// "to" context. |
205 | /// |
206 | /// \returns The equivalent attribute in the "to" context, or the import |
207 | /// error. |
208 | llvm::Expected<Attr *> Import_New(const Attr *FromAttr); |
209 | // FIXME: Remove this version. |
210 | Attr *Import(const Attr *FromAttr); |
211 | |
212 | /// Import the given declaration from the "from" context into the |
213 | /// "to" context. |
214 | /// |
215 | /// \returns The equivalent declaration in the "to" context, or the import |
216 | /// error. |
217 | llvm::Expected<Decl *> Import_New(Decl *FromD); |
218 | llvm::Expected<Decl *> Import_New(const Decl *FromD) { |
219 | return Import_New(const_cast<Decl *>(FromD)); |
220 | } |
221 | // FIXME: Remove this version. |
222 | Decl *Import(Decl *FromD); |
223 | Decl *Import(const Decl *FromD) { |
224 | return Import(const_cast<Decl *>(FromD)); |
225 | } |
226 | |
227 | /// Return the copy of the given declaration in the "to" context if |
228 | /// it has already been imported from the "from" context. Otherwise return |
229 | /// nullptr. |
230 | Decl *GetAlreadyImportedOrNull(const Decl *FromD) const; |
231 | |
232 | /// Return the translation unit from where the declaration was |
233 | /// imported. If it does not exist nullptr is returned. |
234 | TranslationUnitDecl *GetFromTU(Decl *ToD); |
235 | |
236 | /// Import the given declaration context from the "from" |
237 | /// AST context into the "to" AST context. |
238 | /// |
239 | /// \returns the equivalent declaration context in the "to" |
240 | /// context, or error value. |
241 | llvm::Expected<DeclContext *> ImportContext(DeclContext *FromDC); |
242 | |
243 | /// Import the given expression from the "from" context into the |
244 | /// "to" context. |
245 | /// |
246 | /// \returns The equivalent expression in the "to" context, or the import |
247 | /// error. |
248 | llvm::Expected<Expr *> Import_New(Expr *FromE); |
249 | // FIXME: Remove this version. |
250 | Expr *Import(Expr *FromE); |
251 | |
252 | /// Import the given statement from the "from" context into the |
253 | /// "to" context. |
254 | /// |
255 | /// \returns The equivalent statement in the "to" context, or the import |
256 | /// error. |
257 | llvm::Expected<Stmt *> Import_New(Stmt *FromS); |
258 | // FIXME: Remove this version. |
259 | Stmt *Import(Stmt *FromS); |
260 | |
261 | /// Import the given nested-name-specifier from the "from" |
262 | /// context into the "to" context. |
263 | /// |
264 | /// \returns The equivalent nested-name-specifier in the "to" |
265 | /// context, or the import error. |
266 | llvm::Expected<NestedNameSpecifier *> |
267 | Import_New(NestedNameSpecifier *FromNNS); |
268 | // FIXME: Remove this version. |
269 | NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS); |
270 | |
271 | /// Import the given nested-name-specifier-loc from the "from" |
272 | /// context into the "to" context. |
273 | /// |
274 | /// \returns The equivalent nested-name-specifier-loc in the "to" |
275 | /// context, or the import error. |
276 | llvm::Expected<NestedNameSpecifierLoc> |
277 | Import_New(NestedNameSpecifierLoc FromNNS); |
278 | // FIXME: Remove this version. |
279 | NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS); |
280 | |
281 | /// Import the given template name from the "from" context into the |
282 | /// "to" context, or the import error. |
283 | llvm::Expected<TemplateName> Import_New(TemplateName From); |
284 | // FIXME: Remove this version. |
285 | TemplateName Import(TemplateName From); |
286 | |
287 | /// Import the given source location from the "from" context into |
288 | /// the "to" context. |
289 | /// |
290 | /// \returns The equivalent source location in the "to" context, or the |
291 | /// import error. |
292 | llvm::Expected<SourceLocation> Import_New(SourceLocation FromLoc); |
293 | // FIXME: Remove this version. |
294 | SourceLocation Import(SourceLocation FromLoc); |
295 | |
296 | /// Import the given source range from the "from" context into |
297 | /// the "to" context. |
298 | /// |
299 | /// \returns The equivalent source range in the "to" context, or the import |
300 | /// error. |
301 | llvm::Expected<SourceRange> Import_New(SourceRange FromRange); |
302 | // FIXME: Remove this version. |
303 | SourceRange Import(SourceRange FromRange); |
304 | |
305 | /// Import the given declaration name from the "from" |
306 | /// context into the "to" context. |
307 | /// |
308 | /// \returns The equivalent declaration name in the "to" context, or the |
309 | /// import error. |
310 | llvm::Expected<DeclarationName> Import_New(DeclarationName FromName); |
311 | // FIXME: Remove this version. |
312 | DeclarationName Import(DeclarationName FromName); |
313 | |
314 | /// Import the given identifier from the "from" context |
315 | /// into the "to" context. |
316 | /// |
317 | /// \returns The equivalent identifier in the "to" context. Note: It |
318 | /// returns nullptr only if the FromId was nullptr. |
319 | IdentifierInfo *Import(const IdentifierInfo *FromId); |
320 | |
321 | /// Import the given Objective-C selector from the "from" |
322 | /// context into the "to" context. |
323 | /// |
324 | /// \returns The equivalent selector in the "to" context, or the import |
325 | /// error. |
326 | llvm::Expected<Selector> Import_New(Selector FromSel); |
327 | // FIXME: Remove this version. |
328 | Selector Import(Selector FromSel); |
329 | |
330 | /// Import the given file ID from the "from" context into the |
331 | /// "to" context. |
332 | /// |
333 | /// \returns The equivalent file ID in the source manager of the "to" |
334 | /// context, or the import error. |
335 | llvm::Expected<FileID> Import_New(FileID, bool IsBuiltin = false); |
336 | // FIXME: Remove this version. |
337 | FileID Import(FileID, bool IsBuiltin = false); |
338 | |
339 | /// Import the given C++ constructor initializer from the "from" |
340 | /// context into the "to" context. |
341 | /// |
342 | /// \returns The equivalent initializer in the "to" context, or the import |
343 | /// error. |
344 | llvm::Expected<CXXCtorInitializer *> |
345 | Import_New(CXXCtorInitializer *FromInit); |
346 | // FIXME: Remove this version. |
347 | CXXCtorInitializer *Import(CXXCtorInitializer *FromInit); |
348 | |
349 | /// Import the given CXXBaseSpecifier from the "from" context into |
350 | /// the "to" context. |
351 | /// |
352 | /// \returns The equivalent CXXBaseSpecifier in the source manager of the |
353 | /// "to" context, or the import error. |
354 | llvm::Expected<CXXBaseSpecifier *> |
355 | Import_New(const CXXBaseSpecifier *FromSpec); |
356 | // FIXME: Remove this version. |
357 | CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec); |
358 | |
359 | /// Import the definition of the given declaration, including all of |
360 | /// the declarations it contains. |
361 | LLVM_NODISCARD llvm::Error ImportDefinition_New(Decl *From); |
362 | |
363 | // FIXME: Compatibility function. |
364 | // Usages of this should be changed to ImportDefinition_New. |
365 | void ImportDefinition(Decl *From); |
366 | |
367 | /// Cope with a name conflict when importing a declaration into the |
368 | /// given context. |
369 | /// |
370 | /// This routine is invoked whenever there is a name conflict while |
371 | /// importing a declaration. The returned name will become the name of the |
372 | /// imported declaration. By default, the returned name is the same as the |
373 | /// original name, leaving the conflict unresolve such that name lookup |
374 | /// for this name is likely to find an ambiguity later. |
375 | /// |
376 | /// Subclasses may override this routine to resolve the conflict, e.g., by |
377 | /// renaming the declaration being imported. |
378 | /// |
379 | /// \param Name the name of the declaration being imported, which conflicts |
380 | /// with other declarations. |
381 | /// |
382 | /// \param DC the declaration context (in the "to" AST context) in which |
383 | /// the name is being imported. |
384 | /// |
385 | /// \param IDNS the identifier namespace in which the name will be found. |
386 | /// |
387 | /// \param Decls the set of declarations with the same name as the |
388 | /// declaration being imported. |
389 | /// |
390 | /// \param NumDecls the number of conflicting declarations in \p Decls. |
391 | /// |
392 | /// \returns the name that the newly-imported declaration should have. |
393 | virtual DeclarationName HandleNameConflict(DeclarationName Name, |
394 | DeclContext *DC, |
395 | unsigned IDNS, |
396 | NamedDecl **Decls, |
397 | unsigned NumDecls); |
398 | |
399 | /// Retrieve the context that AST nodes are being imported into. |
400 | ASTContext &getToContext() const { return ToContext; } |
401 | |
402 | /// Retrieve the context that AST nodes are being imported from. |
403 | ASTContext &getFromContext() const { return FromContext; } |
404 | |
405 | /// Retrieve the file manager that AST nodes are being imported into. |
406 | FileManager &getToFileManager() const { return ToFileManager; } |
407 | |
408 | /// Retrieve the file manager that AST nodes are being imported from. |
409 | FileManager &getFromFileManager() const { return FromFileManager; } |
410 | |
411 | /// Report a diagnostic in the "to" context. |
412 | DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID); |
413 | |
414 | /// Report a diagnostic in the "from" context. |
415 | DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID); |
416 | |
417 | /// Return the set of declarations that we know are not equivalent. |
418 | NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; } |
419 | |
420 | /// Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl. |
421 | /// Mark the Decl as complete, filling it in as much as possible. |
422 | /// |
423 | /// \param D A declaration in the "to" context. |
424 | virtual void CompleteDecl(Decl* D); |
425 | |
426 | /// Subclasses can override this function to observe all of the \c From -> |
427 | /// \c To declaration mappings as they are imported. |
428 | virtual void Imported(Decl *From, Decl *To) {} |
429 | |
430 | /// Store and assign the imported declaration to its counterpart. |
431 | Decl *MapImported(Decl *From, Decl *To); |
432 | |
433 | /// Called by StructuralEquivalenceContext. If a RecordDecl is |
434 | /// being compared to another RecordDecl as part of import, completing the |
435 | /// other RecordDecl may trigger importation of the first RecordDecl. This |
436 | /// happens especially for anonymous structs. If the original of the second |
437 | /// RecordDecl can be found, we can complete it without the need for |
438 | /// importation, eliminating this loop. |
439 | virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; } |
440 | |
441 | /// Determine whether the given types are structurally |
442 | /// equivalent. |
443 | bool IsStructurallyEquivalent(QualType From, QualType To, |
444 | bool Complain = true); |
445 | |
446 | /// Determine the index of a field in its parent record. |
447 | /// F should be a field (or indirect field) declaration. |
448 | /// \returns The index of the field in its parent context (starting from 0). |
449 | /// On error `None` is returned (parent context is non-record). |
450 | static llvm::Optional<unsigned> getFieldIndex(Decl *F); |
451 | |
452 | }; |
453 | |
454 | } // namespace clang |
455 | |
456 | #endif // LLVM_CLANG_AST_ASTIMPORTER_H |
457 |