|
|
|||
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
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|