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