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