diff options
Diffstat (limited to 'clang/lib/AST/ASTImporter.cpp')
| -rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 097046d93dd..b2de0455e2a 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -7842,6 +7842,10 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) { if (!FromD) return nullptr; + // Push FromD to the stack, and remove that when we return. + ImportPath.push(FromD); + auto ImportPathBuilder = + llvm::make_scope_exit([this]() { ImportPath.pop(); }); // Check whether there was a previous failed import. // If yes return the existing error. @@ -7853,6 +7857,10 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) { if (ToD) { // If FromD has some updated flags after last import, apply it updateFlags(FromD, ToD); + // If we encounter a cycle during an import then we save the relevant part + // of the import path associated to the Decl. + if (ImportPath.hasCycleAtBack()) + SavedImportPaths[FromD].push_back(ImportPath.copyCycleAtBack()); return ToD; } @@ -7889,16 +7897,20 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) { // FIXME: AST may contain remaining references to the failed object. } - // Error encountered for the first time. - assert(!getImportDeclErrorIfAny(FromD) && - "Import error already set for Decl."); - - // After takeError the error is not usable any more in ToDOrErr. + // After takeError the error is not usable anymore in ToDOrErr. // Get a copy of the error object (any more simple solution for this?). ImportError ErrOut; handleAllErrors(ToDOrErr.takeError(), [&ErrOut](const ImportError &E) { ErrOut = E; }); setImportDeclError(FromD, ErrOut); + + // Set the error for all nodes which have been created before we + // recognized the error. + for (const auto &Path : SavedImportPaths[FromD]) + for (Decl *Di : Path) + setImportDeclError(Di, ErrOut); + SavedImportPaths[FromD].clear(); + // Do not return ToDOrErr, error was taken out of it. return make_error<ImportError>(ErrOut); } @@ -7921,6 +7933,7 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) { Imported(FromD, ToD); updateFlags(FromD, ToD); + SavedImportPaths[FromD].clear(); return ToDOrErr; } @@ -8641,9 +8654,10 @@ ASTImporter::getImportDeclErrorIfAny(Decl *FromD) const { } void ASTImporter::setImportDeclError(Decl *From, ImportError Error) { - assert(ImportDeclErrors.find(From) == ImportDeclErrors.end() && - "Setting import error allowed only once for a Decl."); - ImportDeclErrors[From] = Error; + auto InsertRes = ImportDeclErrors.insert({From, Error}); + // Either we set the error for the first time, or we already had set one and + // now we want to set the same error. + assert(InsertRes.second || InsertRes.first->second.Error == Error.Error); } bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To, |

