xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/ASTImporter.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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/ASTImportError.h"
18 #include "clang/AST/DeclBase.h"
19 #include "clang/AST/DeclarationName.h"
20 #include "clang/AST/ExprCXX.h"
21 #include "clang/AST/NestedNameSpecifier.h"
22 #include "clang/AST/TemplateName.h"
23 #include "clang/AST/Type.h"
24 #include "clang/Basic/Diagnostic.h"
25 #include "clang/Basic/IdentifierTable.h"
26 #include "clang/Basic/LLVM.h"
27 #include "clang/Basic/SourceLocation.h"
28 #include "llvm/ADT/DenseMap.h"
29 #include "llvm/ADT/DenseSet.h"
30 #include "llvm/ADT/SmallVector.h"
31 #include <optional>
32 #include <utility>
33 
34 namespace clang {
35 
36 class ASTContext;
37 class ASTImporterSharedState;
38 class Attr;
39 class CXXBaseSpecifier;
40 class CXXCtorInitializer;
41 class Decl;
42 class DeclContext;
43 class Expr;
44 class FileManager;
45 class NamedDecl;
46 class Stmt;
47 class TagDecl;
48 class TranslationUnitDecl;
49 class TypeSourceInfo;
50 
51   // \brief Returns with a list of declarations started from the canonical decl
52   // then followed by subsequent decls in the translation unit.
53   // This gives a canonical list for each entry in the redecl chain.
54   // `Decl::redecls()` gives a list of decls which always start from the
55   // previous decl and the next item is actually the previous item in the order
56   // of source locations.  Thus, `Decl::redecls()` gives different lists for
57   // the different entries in a given redecl chain.
58   llvm::SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D);
59 
60   /// Imports selected nodes from one AST context into another context,
61   /// merging AST nodes where appropriate.
62   class ASTImporter {
63     friend class ASTNodeImporter;
64   public:
65     using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>;
66     using ImportedCXXBaseSpecifierMap =
67         llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;
68 
69     enum class ODRHandlingType { Conservative, Liberal };
70 
71     // An ImportPath is the list of the AST nodes which we visit during an
72     // Import call.
73     // If node `A` depends on node `B` then the path contains an `A`->`B` edge.
74     // From the call stack of the import functions we can read the very same
75     // path.
76     //
77     // Now imagine the following AST, where the `->` represents dependency in
78     // therms of the import.
79     // ```
80     // A->B->C->D
81     //    `->E
82     // ```
83     // We would like to import A.
84     // The import behaves like a DFS, so we will visit the nodes in this order:
85     // ABCDE.
86     // During the visitation we will have the following ImportPaths:
87     // ```
88     // A
89     // AB
90     // ABC
91     // ABCD
92     // ABC
93     // AB
94     // ABE
95     // AB
96     // A
97     // ```
98     // If during the visit of E there is an error then we set an error for E,
99     // then as the call stack shrinks for B, then for A:
100     // ```
101     // A
102     // AB
103     // ABC
104     // ABCD
105     // ABC
106     // AB
107     // ABE // Error! Set an error to E
108     // AB  // Set an error to B
109     // A   // Set an error to A
110     // ```
111     // However, during the import we could import C and D without any error and
112     // they are independent from A,B and E.
113     // We must not set up an error for C and D.
114     // So, at the end of the import we have an entry in `ImportDeclErrors` for
115     // A,B,E but not for C,D.
116     //
117     // Now what happens if there is a cycle in the import path?
118     // Let's consider this AST:
119     // ```
120     // A->B->C->A
121     //    `->E
122     // ```
123     // During the visitation we will have the below ImportPaths and if during
124     // the visit of E there is an error then we will set up an error for E,B,A.
125     // But what's up with C?
126     // ```
127     // A
128     // AB
129     // ABC
130     // ABCA
131     // ABC
132     // AB
133     // ABE // Error! Set an error to E
134     // AB  // Set an error to B
135     // A   // Set an error to A
136     // ```
137     // This time we know that both B and C are dependent on A.
138     // This means we must set up an error for C too.
139     // As the call stack reverses back we get to A and we must set up an error
140     // to all nodes which depend on A (this includes C).
141     // But C is no longer on the import path, it just had been previously.
142     // Such situation can happen only if during the visitation we had a cycle.
143     // If we didn't have any cycle, then the normal way of passing an Error
144     // object through the call stack could handle the situation.
145     // This is why we must track cycles during the import process for each
146     // visited declaration.
147     class ImportPathTy {
148     public:
149       using VecTy = llvm::SmallVector<Decl *, 32>;
150 
push(Decl * D)151       void push(Decl *D) {
152         Nodes.push_back(D);
153         ++Aux[D];
154       }
155 
pop()156       void pop() {
157         if (Nodes.empty())
158           return;
159         --Aux[Nodes.back()];
160         Nodes.pop_back();
161       }
162 
163       /// Returns true if the last element can be found earlier in the path.
hasCycleAtBack()164       bool hasCycleAtBack() const {
165         auto Pos = Aux.find(Nodes.back());
166         return Pos != Aux.end() && Pos->second > 1;
167       }
168 
169       using Cycle = llvm::iterator_range<VecTy::const_reverse_iterator>;
getCycleAtBack()170       Cycle getCycleAtBack() const {
171         assert(Nodes.size() >= 2);
172         return Cycle(Nodes.rbegin(),
173                      std::find(Nodes.rbegin() + 1, Nodes.rend(), Nodes.back()) +
174                          1);
175       }
176 
177       /// Returns the copy of the cycle.
copyCycleAtBack()178       VecTy copyCycleAtBack() const {
179         auto R = getCycleAtBack();
180         return VecTy(R.begin(), R.end());
181       }
182 
183     private:
184       // All nodes of the path.
185       VecTy Nodes;
186       // Auxiliary container to be able to answer "Do we have a cycle ending
187       // at last element?" as fast as possible.
188       // We count each Decl's occurrence over the path.
189       llvm::SmallDenseMap<Decl *, int, 32> Aux;
190     };
191 
192   private:
193     std::shared_ptr<ASTImporterSharedState> SharedState = nullptr;
194 
195     /// The path which we go through during the import of a given AST node.
196     ImportPathTy ImportPath;
197     /// Sometimes we have to save some part of an import path, so later we can
198     /// set up properties to the saved nodes.
199     /// We may have several of these import paths associated to one Decl.
200     using SavedImportPathsForOneDecl =
201         llvm::SmallVector<ImportPathTy::VecTy, 32>;
202     using SavedImportPathsTy =
203         llvm::SmallDenseMap<Decl *, SavedImportPathsForOneDecl, 32>;
204     SavedImportPathsTy SavedImportPaths;
205 
206     /// The contexts we're importing to and from.
207     ASTContext &ToContext, &FromContext;
208 
209     /// The file managers we're importing to and from.
210     FileManager &ToFileManager, &FromFileManager;
211 
212     /// Whether to perform a minimal import.
213     bool Minimal;
214 
215     ODRHandlingType ODRHandling;
216 
217     /// Whether the last diagnostic came from the "from" context.
218     bool LastDiagFromFrom = false;
219 
220     /// Mapping from the already-imported types in the "from" context
221     /// to the corresponding types in the "to" context.
222     llvm::DenseMap<const Type *, const Type *> ImportedTypes;
223 
224     /// Mapping from the already-imported declarations in the "from"
225     /// context to the corresponding declarations in the "to" context.
226     llvm::DenseMap<Decl *, Decl *> ImportedDecls;
227 
228     /// Mapping from the already-imported declarations in the "from"
229     /// context to the error status of the import of that declaration.
230     /// This map contains only the declarations that were not correctly
231     /// imported. The same declaration may or may not be included in
232     /// ImportedDecls. This map is updated continuously during imports and never
233     /// cleared (like ImportedDecls).
234     llvm::DenseMap<Decl *, ASTImportError> ImportDeclErrors;
235 
236     /// Mapping from the already-imported declarations in the "to"
237     /// context to the corresponding declarations in the "from" context.
238     llvm::DenseMap<Decl *, Decl *> ImportedFromDecls;
239 
240     /// Mapping from the already-imported statements in the "from"
241     /// context to the corresponding statements in the "to" context.
242     llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
243 
244     /// Mapping from the already-imported FileIDs in the "from" source
245     /// manager to the corresponding FileIDs in the "to" source manager.
246     llvm::DenseMap<FileID, FileID> ImportedFileIDs;
247 
248     /// Mapping from the already-imported CXXBasesSpecifier in
249     ///  the "from" source manager to the corresponding CXXBasesSpecifier
250     ///  in the "to" source manager.
251     ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers;
252 
253     /// Declaration (from, to) pairs that are known not to be equivalent
254     /// (which we have already complained about).
255     NonEquivalentDeclSet NonEquivalentDecls;
256 
257     using FoundDeclsTy = SmallVector<NamedDecl *, 2>;
258     FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
259 
260     void AddToLookupTable(Decl *ToD);
261     llvm::Error ImportAttrs(Decl *ToD, Decl *FromD);
262 
263   protected:
264     /// Can be overwritten by subclasses to implement their own import logic.
265     /// The overwritten method should call this method if it didn't import the
266     /// decl on its own.
267     virtual Expected<Decl *> ImportImpl(Decl *From);
268 
269     /// Used only in unittests to verify the behaviour of the error handling.
returnWithErrorInTest()270     virtual bool returnWithErrorInTest() { return false; };
271 
272   public:
273 
274     /// \param ToContext The context we'll be importing into.
275     ///
276     /// \param ToFileManager The file manager we'll be importing into.
277     ///
278     /// \param FromContext The context we'll be importing from.
279     ///
280     /// \param FromFileManager The file manager we'll be importing into.
281     ///
282     /// \param MinimalImport If true, the importer will attempt to import
283     /// as little as it can, e.g., by importing declarations as forward
284     /// declarations that can be completed at a later point.
285     ///
286     /// \param SharedState The importer specific lookup table which may be
287     /// shared amongst several ASTImporter objects.
288     /// If not set then the original C/C++ lookup is used.
289     ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
290                 ASTContext &FromContext, FileManager &FromFileManager,
291                 bool MinimalImport,
292                 std::shared_ptr<ASTImporterSharedState> SharedState = nullptr);
293 
294     virtual ~ASTImporter();
295 
296     /// Whether the importer will perform a minimal import, creating
297     /// to-be-completed forward declarations when possible.
isMinimalImport()298     bool isMinimalImport() const { return Minimal; }
299 
setODRHandling(ODRHandlingType T)300     void setODRHandling(ODRHandlingType T) { ODRHandling = T; }
301 
302     /// \brief Import the given object, returns the result.
303     ///
304     /// \param To Import the object into this variable.
305     /// \param From Object to import.
306     /// \return Error information (success or error).
307     template <typename ImportT>
importInto(ImportT & To,const ImportT & From)308     [[nodiscard]] llvm::Error importInto(ImportT &To, const ImportT &From) {
309       auto ToOrErr = Import(From);
310       if (ToOrErr)
311         To = *ToOrErr;
312       return ToOrErr.takeError();
313     }
314 
315     /// Import cleanup objects owned by ExprWithCleanup.
316     llvm::Expected<ExprWithCleanups::CleanupObject>
317     Import(ExprWithCleanups::CleanupObject From);
318 
319     /// Import the given type from the "from" context into the "to"
320     /// context.
321     ///
322     /// \returns The equivalent type in the "to" context, or the import error.
323     llvm::Expected<const Type *> Import(const Type *FromT);
324 
325     /// Import the given qualified type from the "from" context into the "to"
326     /// context. A null type is imported as a null type (no error).
327     ///
328     /// \returns The equivalent type in the "to" context, or the import error.
329     llvm::Expected<QualType> Import(QualType FromT);
330 
331     /// Import the given type source information from the
332     /// "from" context into the "to" context.
333     ///
334     /// \returns The equivalent type source information in the "to"
335     /// context, or the import error.
336     llvm::Expected<TypeSourceInfo *> Import(TypeSourceInfo *FromTSI);
337 
338     /// Import the given attribute from the "from" context into the
339     /// "to" context.
340     ///
341     /// \returns The equivalent attribute in the "to" context, or the import
342     /// error.
343     llvm::Expected<Attr *> Import(const Attr *FromAttr);
344 
345     /// Import the given declaration from the "from" context into the
346     /// "to" context.
347     ///
348     /// \returns The equivalent declaration in the "to" context, or the import
349     /// error.
350     llvm::Expected<Decl *> Import(Decl *FromD);
Import(const Decl * FromD)351     llvm::Expected<const Decl *> Import(const Decl *FromD) {
352       return Import(const_cast<Decl *>(FromD));
353     }
354 
355     llvm::Expected<InheritedConstructor>
356     Import(const InheritedConstructor &From);
357 
358     /// Return the copy of the given declaration in the "to" context if
359     /// it has already been imported from the "from" context.  Otherwise return
360     /// nullptr.
361     Decl *GetAlreadyImportedOrNull(const Decl *FromD) const;
362 
363     /// Return the translation unit from where the declaration was
364     /// imported. If it does not exist nullptr is returned.
365     TranslationUnitDecl *GetFromTU(Decl *ToD);
366 
367     /// Return the declaration in the "from" context from which the declaration
368     /// in the "to" context was imported. If it was not imported or of the wrong
369     /// type a null value is returned.
370     template <typename DeclT>
getImportedFromDecl(const DeclT * ToD)371     std::optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
372       auto FromI = ImportedFromDecls.find(ToD);
373       if (FromI == ImportedFromDecls.end())
374         return {};
375       auto *FromD = dyn_cast<DeclT>(FromI->second);
376       if (!FromD)
377         return {};
378       return FromD;
379     }
380 
381     /// Import the given declaration context from the "from"
382     /// AST context into the "to" AST context.
383     ///
384     /// \returns the equivalent declaration context in the "to"
385     /// context, or error value.
386     llvm::Expected<DeclContext *> ImportContext(DeclContext *FromDC);
387 
388     /// Import the given expression from the "from" context into the
389     /// "to" context.
390     ///
391     /// \returns The equivalent expression in the "to" context, or the import
392     /// error.
393     llvm::Expected<Expr *> Import(Expr *FromE);
394 
395     /// Import the given statement from the "from" context into the
396     /// "to" context.
397     ///
398     /// \returns The equivalent statement in the "to" context, or the import
399     /// error.
400     llvm::Expected<Stmt *> Import(Stmt *FromS);
401 
402     /// Import the given nested-name-specifier from the "from"
403     /// context into the "to" context.
404     ///
405     /// \returns The equivalent nested-name-specifier in the "to"
406     /// context, or the import error.
407     llvm::Expected<NestedNameSpecifier *> Import(NestedNameSpecifier *FromNNS);
408 
409     /// Import the given nested-name-specifier-loc from the "from"
410     /// context into the "to" context.
411     ///
412     /// \returns The equivalent nested-name-specifier-loc in the "to"
413     /// context, or the import error.
414     llvm::Expected<NestedNameSpecifierLoc>
415     Import(NestedNameSpecifierLoc FromNNS);
416 
417     /// Import the given template name from the "from" context into the
418     /// "to" context, or the import error.
419     llvm::Expected<TemplateName> Import(TemplateName From);
420 
421     /// Import the given source location from the "from" context into
422     /// the "to" context.
423     ///
424     /// \returns The equivalent source location in the "to" context, or the
425     /// import error.
426     llvm::Expected<SourceLocation> Import(SourceLocation FromLoc);
427 
428     /// Import the given source range from the "from" context into
429     /// the "to" context.
430     ///
431     /// \returns The equivalent source range in the "to" context, or the import
432     /// error.
433     llvm::Expected<SourceRange> Import(SourceRange FromRange);
434 
435     /// Import the given declaration name from the "from"
436     /// context into the "to" context.
437     ///
438     /// \returns The equivalent declaration name in the "to" context, or the
439     /// import error.
440     llvm::Expected<DeclarationName> Import(DeclarationName FromName);
441 
442     /// Import the given identifier from the "from" context
443     /// into the "to" context.
444     ///
445     /// \returns The equivalent identifier in the "to" context. Note: It
446     /// returns nullptr only if the FromId was nullptr.
447     IdentifierInfo *Import(const IdentifierInfo *FromId);
448 
449     /// Import the given Objective-C selector from the "from"
450     /// context into the "to" context.
451     ///
452     /// \returns The equivalent selector in the "to" context, or the import
453     /// error.
454     llvm::Expected<Selector> Import(Selector FromSel);
455 
456     /// Import the given file ID from the "from" context into the
457     /// "to" context.
458     ///
459     /// \returns The equivalent file ID in the source manager of the "to"
460     /// context, or the import error.
461     llvm::Expected<FileID> Import(FileID, bool IsBuiltin = false);
462 
463     /// Import the given C++ constructor initializer from the "from"
464     /// context into the "to" context.
465     ///
466     /// \returns The equivalent initializer in the "to" context, or the import
467     /// error.
468     llvm::Expected<CXXCtorInitializer *> Import(CXXCtorInitializer *FromInit);
469 
470     /// Import the given CXXBaseSpecifier from the "from" context into
471     /// the "to" context.
472     ///
473     /// \returns The equivalent CXXBaseSpecifier in the source manager of the
474     /// "to" context, or the import error.
475     llvm::Expected<CXXBaseSpecifier *> Import(const CXXBaseSpecifier *FromSpec);
476 
477     /// Import the given APValue from the "from" context into
478     /// the "to" context.
479     ///
480     /// \return the equivalent APValue in the "to" context or the import
481     /// error.
482     llvm::Expected<APValue> Import(const APValue &FromValue);
483 
484     /// Import the definition of the given declaration, including all of
485     /// the declarations it contains.
486     [[nodiscard]] llvm::Error ImportDefinition(Decl *From);
487 
488     /// Cope with a name conflict when importing a declaration into the
489     /// given context.
490     ///
491     /// This routine is invoked whenever there is a name conflict while
492     /// importing a declaration. The returned name will become the name of the
493     /// imported declaration. By default, the returned name is the same as the
494     /// original name, leaving the conflict unresolve such that name lookup
495     /// for this name is likely to find an ambiguity later.
496     ///
497     /// Subclasses may override this routine to resolve the conflict, e.g., by
498     /// renaming the declaration being imported.
499     ///
500     /// \param Name the name of the declaration being imported, which conflicts
501     /// with other declarations.
502     ///
503     /// \param DC the declaration context (in the "to" AST context) in which
504     /// the name is being imported.
505     ///
506     /// \param IDNS the identifier namespace in which the name will be found.
507     ///
508     /// \param Decls the set of declarations with the same name as the
509     /// declaration being imported.
510     ///
511     /// \param NumDecls the number of conflicting declarations in \p Decls.
512     ///
513     /// \returns the name that the newly-imported declaration should have. Or
514     /// an error if we can't handle the name conflict.
515     virtual Expected<DeclarationName>
516     HandleNameConflict(DeclarationName Name, DeclContext *DC, unsigned IDNS,
517                        NamedDecl **Decls, unsigned NumDecls);
518 
519     /// Retrieve the context that AST nodes are being imported into.
getToContext()520     ASTContext &getToContext() const { return ToContext; }
521 
522     /// Retrieve the context that AST nodes are being imported from.
getFromContext()523     ASTContext &getFromContext() const { return FromContext; }
524 
525     /// Retrieve the file manager that AST nodes are being imported into.
getToFileManager()526     FileManager &getToFileManager() const { return ToFileManager; }
527 
528     /// Retrieve the file manager that AST nodes are being imported from.
getFromFileManager()529     FileManager &getFromFileManager() const { return FromFileManager; }
530 
531     /// Report a diagnostic in the "to" context.
532     DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
533 
534     /// Report a diagnostic in the "from" context.
535     DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
536 
537     /// Return the set of declarations that we know are not equivalent.
getNonEquivalentDecls()538     NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
539 
540     /// Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
541     /// Mark the Decl as complete, filling it in as much as possible.
542     ///
543     /// \param D A declaration in the "to" context.
544     virtual void CompleteDecl(Decl* D);
545 
546     /// Subclasses can override this function to observe all of the \c From ->
547     /// \c To declaration mappings as they are imported.
Imported(Decl * From,Decl * To)548     virtual void Imported(Decl *From, Decl *To) {}
549 
550     void RegisterImportedDecl(Decl *FromD, Decl *ToD);
551 
552     /// Store and assign the imported declaration to its counterpart.
553     /// It may happen that several decls from the 'from' context are mapped to
554     /// the same decl in the 'to' context.
555     Decl *MapImported(Decl *From, Decl *To);
556 
557     /// Called by StructuralEquivalenceContext.  If a RecordDecl is
558     /// being compared to another RecordDecl as part of import, completing the
559     /// other RecordDecl may trigger importation of the first RecordDecl. This
560     /// happens especially for anonymous structs.  If the original of the second
561     /// RecordDecl can be found, we can complete it without the need for
562     /// importation, eliminating this loop.
GetOriginalDecl(Decl * To)563     virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
564 
565     /// Return if import of the given declaration has failed and if yes
566     /// the kind of the problem. This gives the first error encountered with
567     /// the node.
568     std::optional<ASTImportError> getImportDeclErrorIfAny(Decl *FromD) const;
569 
570     /// Mark (newly) imported declaration with error.
571     void setImportDeclError(Decl *From, ASTImportError Error);
572 
573     /// Determine whether the given types are structurally
574     /// equivalent.
575     bool IsStructurallyEquivalent(QualType From, QualType To,
576                                   bool Complain = true);
577 
578     /// Determine the index of a field in its parent record.
579     /// F should be a field (or indirect field) declaration.
580     /// \returns The index of the field in its parent context (starting from 0).
581     /// On error `std::nullopt` is returned (parent context is non-record).
582     static std::optional<unsigned> getFieldIndex(Decl *F);
583   };
584 
585 } // namespace clang
586 
587 #endif // LLVM_CLANG_AST_ASTIMPORTER_H
588