Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:28

0001 //===- ASTImporter.h - Importing ASTs from other Contexts -------*- 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 defines the ASTImporter class which imports AST nodes from one
0010 //  context into another context.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_AST_ASTIMPORTER_H
0015 #define LLVM_CLANG_AST_ASTIMPORTER_H
0016 
0017 #include "clang/AST/ASTImportError.h"
0018 #include "clang/AST/DeclBase.h"
0019 #include "clang/AST/DeclarationName.h"
0020 #include "clang/AST/ExprCXX.h"
0021 #include "clang/AST/NestedNameSpecifier.h"
0022 #include "clang/AST/TemplateName.h"
0023 #include "clang/AST/Type.h"
0024 #include "clang/Basic/Diagnostic.h"
0025 #include "clang/Basic/IdentifierTable.h"
0026 #include "clang/Basic/LLVM.h"
0027 #include "clang/Basic/SourceLocation.h"
0028 #include "llvm/ADT/DenseMap.h"
0029 #include "llvm/ADT/DenseSet.h"
0030 #include "llvm/ADT/SmallVector.h"
0031 #include <optional>
0032 #include <utility>
0033 
0034 namespace clang {
0035 
0036 class ASTContext;
0037 class ASTImporterSharedState;
0038 class Attr;
0039 class CXXBaseSpecifier;
0040 class CXXCtorInitializer;
0041 class Decl;
0042 class DeclContext;
0043 class Expr;
0044 class FileManager;
0045 class NamedDecl;
0046 class Stmt;
0047 class TagDecl;
0048 class TranslationUnitDecl;
0049 class TypeSourceInfo;
0050 
0051   // \brief Returns with a list of declarations started from the canonical decl
0052   // then followed by subsequent decls in the translation unit.
0053   // This gives a canonical list for each entry in the redecl chain.
0054   // `Decl::redecls()` gives a list of decls which always start from the
0055   // previous decl and the next item is actually the previous item in the order
0056   // of source locations.  Thus, `Decl::redecls()` gives different lists for
0057   // the different entries in a given redecl chain.
0058   llvm::SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D);
0059 
0060   /// Imports selected nodes from one AST context into another context,
0061   /// merging AST nodes where appropriate.
0062   class ASTImporter {
0063     friend class ASTNodeImporter;
0064   public:
0065     using NonEquivalentDeclSet =
0066         llvm::DenseSet<std::tuple<Decl *, Decl *, int>>;
0067     using ImportedCXXBaseSpecifierMap =
0068         llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;
0069 
0070     enum class ODRHandlingType { Conservative, Liberal };
0071 
0072     // An ImportPath is the list of the AST nodes which we visit during an
0073     // Import call.
0074     // If node `A` depends on node `B` then the path contains an `A`->`B` edge.
0075     // From the call stack of the import functions we can read the very same
0076     // path.
0077     //
0078     // Now imagine the following AST, where the `->` represents dependency in
0079     // therms of the import.
0080     // ```
0081     // A->B->C->D
0082     //    `->E
0083     // ```
0084     // We would like to import A.
0085     // The import behaves like a DFS, so we will visit the nodes in this order:
0086     // ABCDE.
0087     // During the visitation we will have the following ImportPaths:
0088     // ```
0089     // A
0090     // AB
0091     // ABC
0092     // ABCD
0093     // ABC
0094     // AB
0095     // ABE
0096     // AB
0097     // A
0098     // ```
0099     // If during the visit of E there is an error then we set an error for E,
0100     // then as the call stack shrinks for B, then for A:
0101     // ```
0102     // A
0103     // AB
0104     // ABC
0105     // ABCD
0106     // ABC
0107     // AB
0108     // ABE // Error! Set an error to E
0109     // AB  // Set an error to B
0110     // A   // Set an error to A
0111     // ```
0112     // However, during the import we could import C and D without any error and
0113     // they are independent from A,B and E.
0114     // We must not set up an error for C and D.
0115     // So, at the end of the import we have an entry in `ImportDeclErrors` for
0116     // A,B,E but not for C,D.
0117     //
0118     // Now what happens if there is a cycle in the import path?
0119     // Let's consider this AST:
0120     // ```
0121     // A->B->C->A
0122     //    `->E
0123     // ```
0124     // During the visitation we will have the below ImportPaths and if during
0125     // the visit of E there is an error then we will set up an error for E,B,A.
0126     // But what's up with C?
0127     // ```
0128     // A
0129     // AB
0130     // ABC
0131     // ABCA
0132     // ABC
0133     // AB
0134     // ABE // Error! Set an error to E
0135     // AB  // Set an error to B
0136     // A   // Set an error to A
0137     // ```
0138     // This time we know that both B and C are dependent on A.
0139     // This means we must set up an error for C too.
0140     // As the call stack reverses back we get to A and we must set up an error
0141     // to all nodes which depend on A (this includes C).
0142     // But C is no longer on the import path, it just had been previously.
0143     // Such situation can happen only if during the visitation we had a cycle.
0144     // If we didn't have any cycle, then the normal way of passing an Error
0145     // object through the call stack could handle the situation.
0146     // This is why we must track cycles during the import process for each
0147     // visited declaration.
0148     class ImportPathTy {
0149     public:
0150       using VecTy = llvm::SmallVector<Decl *, 32>;
0151 
0152       void push(Decl *D) {
0153         Nodes.push_back(D);
0154         ++Aux[D];
0155       }
0156 
0157       void pop() {
0158         if (Nodes.empty())
0159           return;
0160         --Aux[Nodes.back()];
0161         Nodes.pop_back();
0162       }
0163 
0164       /// Returns true if the last element can be found earlier in the path.
0165       bool hasCycleAtBack() const {
0166         auto Pos = Aux.find(Nodes.back());
0167         return Pos != Aux.end() && Pos->second > 1;
0168       }
0169 
0170       using Cycle = llvm::iterator_range<VecTy::const_reverse_iterator>;
0171       Cycle getCycleAtBack() const {
0172         assert(Nodes.size() >= 2);
0173         return Cycle(Nodes.rbegin(),
0174                      std::find(Nodes.rbegin() + 1, Nodes.rend(), Nodes.back()) +
0175                          1);
0176       }
0177 
0178       /// Returns the copy of the cycle.
0179       VecTy copyCycleAtBack() const {
0180         auto R = getCycleAtBack();
0181         return VecTy(R.begin(), R.end());
0182       }
0183 
0184     private:
0185       // All nodes of the path.
0186       VecTy Nodes;
0187       // Auxiliary container to be able to answer "Do we have a cycle ending
0188       // at last element?" as fast as possible.
0189       // We count each Decl's occurrence over the path.
0190       llvm::SmallDenseMap<Decl *, int, 32> Aux;
0191     };
0192 
0193   private:
0194     std::shared_ptr<ASTImporterSharedState> SharedState = nullptr;
0195 
0196     /// The path which we go through during the import of a given AST node.
0197     ImportPathTy ImportPath;
0198     /// Sometimes we have to save some part of an import path, so later we can
0199     /// set up properties to the saved nodes.
0200     /// We may have several of these import paths associated to one Decl.
0201     using SavedImportPathsForOneDecl =
0202         llvm::SmallVector<ImportPathTy::VecTy, 32>;
0203     using SavedImportPathsTy =
0204         llvm::SmallDenseMap<Decl *, SavedImportPathsForOneDecl, 32>;
0205     SavedImportPathsTy SavedImportPaths;
0206 
0207     /// The contexts we're importing to and from.
0208     ASTContext &ToContext, &FromContext;
0209 
0210     /// The file managers we're importing to and from.
0211     FileManager &ToFileManager, &FromFileManager;
0212 
0213     /// Whether to perform a minimal import.
0214     bool Minimal;
0215 
0216     ODRHandlingType ODRHandling;
0217 
0218     /// Whether the last diagnostic came from the "from" context.
0219     bool LastDiagFromFrom = false;
0220 
0221     /// Mapping from the already-imported types in the "from" context
0222     /// to the corresponding types in the "to" context.
0223     llvm::DenseMap<const Type *, const Type *> ImportedTypes;
0224 
0225     /// Mapping from the already-imported declarations in the "from"
0226     /// context to the corresponding declarations in the "to" context.
0227     llvm::DenseMap<Decl *, Decl *> ImportedDecls;
0228 
0229     /// Mapping from the already-imported declarations in the "from"
0230     /// context to the error status of the import of that declaration.
0231     /// This map contains only the declarations that were not correctly
0232     /// imported. The same declaration may or may not be included in
0233     /// ImportedDecls. This map is updated continuously during imports and never
0234     /// cleared (like ImportedDecls).
0235     llvm::DenseMap<Decl *, ASTImportError> ImportDeclErrors;
0236 
0237     /// Mapping from the already-imported declarations in the "to"
0238     /// context to the corresponding declarations in the "from" context.
0239     llvm::DenseMap<Decl *, Decl *> ImportedFromDecls;
0240 
0241     /// Mapping from the already-imported statements in the "from"
0242     /// context to the corresponding statements in the "to" context.
0243     llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
0244 
0245     /// Mapping from the already-imported FileIDs in the "from" source
0246     /// manager to the corresponding FileIDs in the "to" source manager.
0247     llvm::DenseMap<FileID, FileID> ImportedFileIDs;
0248 
0249     /// Mapping from the already-imported CXXBasesSpecifier in
0250     ///  the "from" source manager to the corresponding CXXBasesSpecifier
0251     ///  in the "to" source manager.
0252     ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers;
0253 
0254     /// Declaration (from, to) pairs that are known not to be equivalent
0255     /// (which we have already complained about).
0256     NonEquivalentDeclSet NonEquivalentDecls;
0257 
0258     using FoundDeclsTy = SmallVector<NamedDecl *, 2>;
0259     FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
0260 
0261     void AddToLookupTable(Decl *ToD);
0262 
0263   protected:
0264     /// Can be overwritten by subclasses to implement their own import logic.
0265     /// The overwritten method should call this method if it didn't import the
0266     /// decl on its own.
0267     virtual Expected<Decl *> ImportImpl(Decl *From);
0268 
0269     /// Used only in unittests to verify the behaviour of the error handling.
0270     virtual bool returnWithErrorInTest() { return false; };
0271 
0272   public:
0273 
0274     /// \param ToContext The context we'll be importing into.
0275     ///
0276     /// \param ToFileManager The file manager we'll be importing into.
0277     ///
0278     /// \param FromContext The context we'll be importing from.
0279     ///
0280     /// \param FromFileManager The file manager we'll be importing into.
0281     ///
0282     /// \param MinimalImport If true, the importer will attempt to import
0283     /// as little as it can, e.g., by importing declarations as forward
0284     /// declarations that can be completed at a later point.
0285     ///
0286     /// \param SharedState The importer specific lookup table which may be
0287     /// shared amongst several ASTImporter objects.
0288     /// If not set then the original C/C++ lookup is used.
0289     ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
0290                 ASTContext &FromContext, FileManager &FromFileManager,
0291                 bool MinimalImport,
0292                 std::shared_ptr<ASTImporterSharedState> SharedState = nullptr);
0293 
0294     virtual ~ASTImporter();
0295 
0296     /// Whether the importer will perform a minimal import, creating
0297     /// to-be-completed forward declarations when possible.
0298     bool isMinimalImport() const { return Minimal; }
0299 
0300     void setODRHandling(ODRHandlingType T) { ODRHandling = T; }
0301 
0302     /// \brief Import the given object, returns the result.
0303     ///
0304     /// \param To Import the object into this variable.
0305     /// \param From Object to import.
0306     /// \return Error information (success or error).
0307     template <typename ImportT>
0308     [[nodiscard]] llvm::Error importInto(ImportT &To, const ImportT &From) {
0309       auto ToOrErr = Import(From);
0310       if (ToOrErr)
0311         To = *ToOrErr;
0312       return ToOrErr.takeError();
0313     }
0314 
0315     /// Import cleanup objects owned by ExprWithCleanup.
0316     llvm::Expected<ExprWithCleanups::CleanupObject>
0317     Import(ExprWithCleanups::CleanupObject From);
0318 
0319     /// Import the given type from the "from" context into the "to"
0320     /// context.
0321     ///
0322     /// \returns The equivalent type in the "to" context, or the import error.
0323     llvm::Expected<const Type *> Import(const Type *FromT);
0324 
0325     /// Import the given qualified type from the "from" context into the "to"
0326     /// context. A null type is imported as a null type (no error).
0327     ///
0328     /// \returns The equivalent type in the "to" context, or the import error.
0329     llvm::Expected<QualType> Import(QualType FromT);
0330 
0331     /// Import the given type source information from the
0332     /// "from" context into the "to" context.
0333     ///
0334     /// \returns The equivalent type source information in the "to"
0335     /// context, or the import error.
0336     llvm::Expected<TypeSourceInfo *> Import(TypeSourceInfo *FromTSI);
0337 
0338     /// Import the given attribute from the "from" context into the
0339     /// "to" context.
0340     ///
0341     /// \returns The equivalent attribute in the "to" context, or the import
0342     /// error.
0343     llvm::Expected<Attr *> Import(const Attr *FromAttr);
0344 
0345     /// Import the given declaration from the "from" context into the
0346     /// "to" context.
0347     ///
0348     /// \returns The equivalent declaration in the "to" context, or the import
0349     /// error.
0350     llvm::Expected<Decl *> Import(Decl *FromD);
0351     llvm::Expected<const Decl *> Import(const Decl *FromD) {
0352       return Import(const_cast<Decl *>(FromD));
0353     }
0354 
0355     llvm::Expected<InheritedConstructor>
0356     Import(const InheritedConstructor &From);
0357 
0358     /// Return the copy of the given declaration in the "to" context if
0359     /// it has already been imported from the "from" context.  Otherwise return
0360     /// nullptr.
0361     Decl *GetAlreadyImportedOrNull(const Decl *FromD) const;
0362 
0363     /// Return the translation unit from where the declaration was
0364     /// imported. If it does not exist nullptr is returned.
0365     TranslationUnitDecl *GetFromTU(Decl *ToD);
0366 
0367     /// Return the declaration in the "from" context from which the declaration
0368     /// in the "to" context was imported. If it was not imported or of the wrong
0369     /// type a null value is returned.
0370     template <typename DeclT>
0371     std::optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
0372       auto FromI = ImportedFromDecls.find(ToD);
0373       if (FromI == ImportedFromDecls.end())
0374         return {};
0375       auto *FromD = dyn_cast<DeclT>(FromI->second);
0376       if (!FromD)
0377         return {};
0378       return FromD;
0379     }
0380 
0381     /// Import the given declaration context from the "from"
0382     /// AST context into the "to" AST context.
0383     ///
0384     /// \returns the equivalent declaration context in the "to"
0385     /// context, or error value.
0386     llvm::Expected<DeclContext *> ImportContext(DeclContext *FromDC);
0387 
0388     /// Import the given expression from the "from" context into the
0389     /// "to" context.
0390     ///
0391     /// \returns The equivalent expression in the "to" context, or the import
0392     /// error.
0393     llvm::Expected<Expr *> Import(Expr *FromE);
0394 
0395     /// Import the given statement from the "from" context into the
0396     /// "to" context.
0397     ///
0398     /// \returns The equivalent statement in the "to" context, or the import
0399     /// error.
0400     llvm::Expected<Stmt *> Import(Stmt *FromS);
0401 
0402     /// Import the given nested-name-specifier from the "from"
0403     /// context into the "to" context.
0404     ///
0405     /// \returns The equivalent nested-name-specifier in the "to"
0406     /// context, or the import error.
0407     llvm::Expected<NestedNameSpecifier *> Import(NestedNameSpecifier *FromNNS);
0408 
0409     /// Import the given nested-name-specifier-loc from the "from"
0410     /// context into the "to" context.
0411     ///
0412     /// \returns The equivalent nested-name-specifier-loc in the "to"
0413     /// context, or the import error.
0414     llvm::Expected<NestedNameSpecifierLoc>
0415     Import(NestedNameSpecifierLoc FromNNS);
0416 
0417     /// Import the given template name from the "from" context into the
0418     /// "to" context, or the import error.
0419     llvm::Expected<TemplateName> Import(TemplateName From);
0420 
0421     /// Import the given source location from the "from" context into
0422     /// the "to" context.
0423     ///
0424     /// \returns The equivalent source location in the "to" context, or the
0425     /// import error.
0426     llvm::Expected<SourceLocation> Import(SourceLocation FromLoc);
0427 
0428     /// Import the given source range from the "from" context into
0429     /// the "to" context.
0430     ///
0431     /// \returns The equivalent source range in the "to" context, or the import
0432     /// error.
0433     llvm::Expected<SourceRange> Import(SourceRange FromRange);
0434 
0435     /// Import the given declaration name from the "from"
0436     /// context into the "to" context.
0437     ///
0438     /// \returns The equivalent declaration name in the "to" context, or the
0439     /// import error.
0440     llvm::Expected<DeclarationName> Import(DeclarationName FromName);
0441 
0442     /// Import the given identifier from the "from" context
0443     /// into the "to" context.
0444     ///
0445     /// \returns The equivalent identifier in the "to" context. Note: It
0446     /// returns nullptr only if the FromId was nullptr.
0447     IdentifierInfo *Import(const IdentifierInfo *FromId);
0448 
0449     /// Import the given Objective-C selector from the "from"
0450     /// context into the "to" context.
0451     ///
0452     /// \returns The equivalent selector in the "to" context, or the import
0453     /// error.
0454     llvm::Expected<Selector> Import(Selector FromSel);
0455 
0456     /// Import the given file ID from the "from" context into the
0457     /// "to" context.
0458     ///
0459     /// \returns The equivalent file ID in the source manager of the "to"
0460     /// context, or the import error.
0461     llvm::Expected<FileID> Import(FileID, bool IsBuiltin = false);
0462 
0463     /// Import the given C++ constructor initializer from the "from"
0464     /// context into the "to" context.
0465     ///
0466     /// \returns The equivalent initializer in the "to" context, or the import
0467     /// error.
0468     llvm::Expected<CXXCtorInitializer *> Import(CXXCtorInitializer *FromInit);
0469 
0470     /// Import the given CXXBaseSpecifier from the "from" context into
0471     /// the "to" context.
0472     ///
0473     /// \returns The equivalent CXXBaseSpecifier in the source manager of the
0474     /// "to" context, or the import error.
0475     llvm::Expected<CXXBaseSpecifier *> Import(const CXXBaseSpecifier *FromSpec);
0476 
0477     /// Import the given APValue from the "from" context into
0478     /// the "to" context.
0479     ///
0480     /// \return the equivalent APValue in the "to" context or the import
0481     /// error.
0482     llvm::Expected<APValue> Import(const APValue &FromValue);
0483 
0484     /// Import the definition of the given declaration, including all of
0485     /// the declarations it contains.
0486     [[nodiscard]] llvm::Error ImportDefinition(Decl *From);
0487 
0488     llvm::Error
0489     ImportTemplateArguments(ArrayRef<TemplateArgument> FromArgs,
0490                             SmallVectorImpl<TemplateArgument> &ToArgs);
0491     Expected<TemplateArgument> Import(const TemplateArgument &From);
0492 
0493     /// Cope with a name conflict when importing a declaration into the
0494     /// given context.
0495     ///
0496     /// This routine is invoked whenever there is a name conflict while
0497     /// importing a declaration. The returned name will become the name of the
0498     /// imported declaration. By default, the returned name is the same as the
0499     /// original name, leaving the conflict unresolve such that name lookup
0500     /// for this name is likely to find an ambiguity later.
0501     ///
0502     /// Subclasses may override this routine to resolve the conflict, e.g., by
0503     /// renaming the declaration being imported.
0504     ///
0505     /// \param Name the name of the declaration being imported, which conflicts
0506     /// with other declarations.
0507     ///
0508     /// \param DC the declaration context (in the "to" AST context) in which
0509     /// the name is being imported.
0510     ///
0511     /// \param IDNS the identifier namespace in which the name will be found.
0512     ///
0513     /// \param Decls the set of declarations with the same name as the
0514     /// declaration being imported.
0515     ///
0516     /// \param NumDecls the number of conflicting declarations in \p Decls.
0517     ///
0518     /// \returns the name that the newly-imported declaration should have. Or
0519     /// an error if we can't handle the name conflict.
0520     virtual Expected<DeclarationName>
0521     HandleNameConflict(DeclarationName Name, DeclContext *DC, unsigned IDNS,
0522                        NamedDecl **Decls, unsigned NumDecls);
0523 
0524     /// Retrieve the context that AST nodes are being imported into.
0525     ASTContext &getToContext() const { return ToContext; }
0526 
0527     /// Retrieve the context that AST nodes are being imported from.
0528     ASTContext &getFromContext() const { return FromContext; }
0529 
0530     /// Retrieve the file manager that AST nodes are being imported into.
0531     FileManager &getToFileManager() const { return ToFileManager; }
0532 
0533     /// Retrieve the file manager that AST nodes are being imported from.
0534     FileManager &getFromFileManager() const { return FromFileManager; }
0535 
0536     /// Report a diagnostic in the "to" context.
0537     DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
0538 
0539     /// Report a diagnostic in the "from" context.
0540     DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
0541 
0542     /// Return the set of declarations that we know are not equivalent.
0543     NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
0544 
0545     /// Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
0546     /// Mark the Decl as complete, filling it in as much as possible.
0547     ///
0548     /// \param D A declaration in the "to" context.
0549     virtual void CompleteDecl(Decl* D);
0550 
0551     /// Subclasses can override this function to observe all of the \c From ->
0552     /// \c To declaration mappings as they are imported.
0553     virtual void Imported(Decl *From, Decl *To) {}
0554 
0555     void RegisterImportedDecl(Decl *FromD, Decl *ToD);
0556 
0557     /// Store and assign the imported declaration to its counterpart.
0558     /// It may happen that several decls from the 'from' context are mapped to
0559     /// the same decl in the 'to' context.
0560     Decl *MapImported(Decl *From, Decl *To);
0561 
0562     /// Called by StructuralEquivalenceContext.  If a RecordDecl is
0563     /// being compared to another RecordDecl as part of import, completing the
0564     /// other RecordDecl may trigger importation of the first RecordDecl. This
0565     /// happens especially for anonymous structs.  If the original of the second
0566     /// RecordDecl can be found, we can complete it without the need for
0567     /// importation, eliminating this loop.
0568     virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
0569 
0570     /// Return if import of the given declaration has failed and if yes
0571     /// the kind of the problem. This gives the first error encountered with
0572     /// the node.
0573     std::optional<ASTImportError> getImportDeclErrorIfAny(Decl *FromD) const;
0574 
0575     /// Mark (newly) imported declaration with error.
0576     void setImportDeclError(Decl *From, ASTImportError Error);
0577 
0578     /// Determine whether the given types are structurally
0579     /// equivalent.
0580     bool IsStructurallyEquivalent(QualType From, QualType To,
0581                                   bool Complain = true);
0582 
0583     /// Determine the index of a field in its parent record.
0584     /// F should be a field (or indirect field) declaration.
0585     /// \returns The index of the field in its parent context (starting from 0).
0586     /// On error `std::nullopt` is returned (parent context is non-record).
0587     static std::optional<unsigned> getFieldIndex(Decl *F);
0588   };
0589 
0590 } // namespace clang
0591 
0592 #endif // LLVM_CLANG_AST_ASTIMPORTER_H