diff options
author | Gabor Marton <gabor.marton@ericsson.com> | 2019-07-01 15:37:07 +0000 |
---|---|---|
committer | Gabor Marton <gabor.marton@ericsson.com> | 2019-07-01 15:37:07 +0000 |
commit | 2afbfb6b2268b8ba7fa9584784e8b11ef97c064a (patch) | |
tree | 3a228f091134b305481627873a179a0886877fee /clang/lib | |
parent | 1daad91af695ad3fe5b15c815362af262d44584a (diff) | |
download | bcm5719-llvm-2afbfb6b2268b8ba7fa9584784e8b11ef97c064a.tar.gz bcm5719-llvm-2afbfb6b2268b8ba7fa9584784e8b11ef97c064a.zip |
[ASTImporter] Mark erroneous nodes in shared st
Summary:
Now we store the errors for the Decls in the "to" context too. For
that, however, we have to put these errors in a shared state (among all
the ASTImporter objects which handle the same "to" context but different
"from" contexts).
After a series of imports from different "from" TUs we have a "to" context
which may have erroneous nodes in it. (Remember, the AST is immutable so
there is no way to delete a node once we had created it and we realized
the error later.) All these erroneous nodes are marked in
ASTImporterSharedState::ImportErrors. Clients of the ASTImporter may
use this as an input. E.g. the static analyzer engine may not try to
analyze a function if that is marked as erroneous (it can be queried via
ASTImporterSharedState::getImportDeclErrorIfAny()).
Reviewers: a_sidorin, a.sidorin, shafik
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62376
llvm-svn: 364785
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 58 | ||||
-rw-r--r-- | clang/lib/CrossTU/CrossTranslationUnit.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTMerge.cpp | 6 |
3 files changed, 52 insertions, 22 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 7d69ed9c98f..cc4cb16794f 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTImporter.h" -#include "clang/AST/ASTImporterLookupTable.h" +#include "clang/AST/ASTImporterSharedState.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/ASTStructuralEquivalence.h" @@ -7701,11 +7701,16 @@ void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod, ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, ASTContext &FromContext, FileManager &FromFileManager, bool MinimalImport, - ASTImporterLookupTable *LookupTable) - : LookupTable(LookupTable), ToContext(ToContext), FromContext(FromContext), + std::shared_ptr<ASTImporterSharedState> SharedState) + : SharedState(SharedState), ToContext(ToContext), FromContext(FromContext), ToFileManager(ToFileManager), FromFileManager(FromFileManager), Minimal(MinimalImport) { + // Create a default state without the lookup table: LLDB case. + if (!SharedState) { + this->SharedState = std::make_shared<ASTImporterSharedState>(); + } + ImportedDecls[FromContext.getTranslationUnitDecl()] = ToContext.getTranslationUnitDecl(); } @@ -7744,9 +7749,9 @@ ASTImporter::findDeclsInToCtx(DeclContext *DC, DeclarationName Name) { // then the enum constant 'A' and the variable 'A' violates ODR. // We can diagnose this only if we search in the redecl context. DeclContext *ReDC = DC->getRedeclContext(); - if (LookupTable) { + if (SharedState->getLookupTable()) { ASTImporterLookupTable::LookupResult LookupResult = - LookupTable->lookup(ReDC, Name); + SharedState->getLookupTable()->lookup(ReDC, Name); return FoundDeclsTy(LookupResult.begin(), LookupResult.end()); } else { // FIXME Can we remove this kind of lookup? @@ -7758,9 +7763,7 @@ ASTImporter::findDeclsInToCtx(DeclContext *DC, DeclarationName Name) { } void ASTImporter::AddToLookupTable(Decl *ToD) { - if (LookupTable) - if (auto *ToND = dyn_cast<NamedDecl>(ToD)) - LookupTable->add(ToND); + SharedState->addDeclToLookup(ToD); } Expected<Decl *> ASTImporter::ImportImpl(Decl *FromD) { @@ -7855,6 +7858,12 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) { // Check whether we've already imported this declaration. Decl *ToD = GetAlreadyImportedOrNull(FromD); if (ToD) { + // Already imported (possibly from another TU) and with an error. + if (auto Error = SharedState->getImportDeclErrorIfAny(ToD)) { + setImportDeclError(FromD, *Error); + return make_error<ImportError>(*Error); + } + // 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 @@ -7888,27 +7897,39 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) { // traverse of the 'to' context). auto PosF = ImportedFromDecls.find(ToD); if (PosF != ImportedFromDecls.end()) { - if (LookupTable) - if (auto *ToND = dyn_cast<NamedDecl>(ToD)) - LookupTable->remove(ToND); + SharedState->removeDeclFromLookup(ToD); ImportedFromDecls.erase(PosF); } // FIXME: AST may contain remaining references to the failed object. + // However, the ImportDeclErrors in the shared state contains all the + // failed objects together with their error. } - // After takeError the error is not usable anymore in ToDOrErr. + // Error encountered for the first time. + // After takeError the error is not usable any more 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 the mapped to Decl, which is in the "to" context. + if (Pos != ImportedDecls.end()) + SharedState->setImportDeclError(Pos->second, 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); + for (Decl *FromDi : Path) { + setImportDeclError(FromDi, ErrOut); + //FIXME Should we remove these Decls from ImportedDecls? + // Set the error for the mapped to Decl, which is in the "to" context. + auto Ii = ImportedDecls.find(FromDi); + if (Ii != ImportedDecls.end()) + SharedState->setImportDeclError(Ii->second, ErrOut); + // FIXME Should we remove these Decls from the LookupTable, + // and from ImportedFromDecls? + } SavedImportPaths[FromD].clear(); // Do not return ToDOrErr, error was taken out of it. @@ -7927,8 +7948,17 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) { return make_error<ImportError>(*Err); } + // We could import from the current TU without error. But previously we + // already had imported a Decl as `ToD` from another TU (with another + // ASTImporter object) and with an error. + if (auto Error = SharedState->getImportDeclErrorIfAny(ToD)) { + setImportDeclError(FromD, *Error); + return make_error<ImportError>(*Error); + } + // Make sure that ImportImpl registered the imported decl. assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?"); + // Notify subclasses. Imported(FromD, ToD); diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp index a532189969b..166bdc0fb33 100644 --- a/clang/lib/CrossTU/CrossTranslationUnit.cpp +++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp @@ -437,10 +437,10 @@ CrossTranslationUnitContext::importDefinition(const VarDecl *VD) { return importDefinitionImpl(VD); } -void CrossTranslationUnitContext::lazyInitLookupTable( +void CrossTranslationUnitContext::lazyInitImporterSharedSt( TranslationUnitDecl *ToTU) { - if (!LookupTable) - LookupTable = llvm::make_unique<ASTImporterLookupTable>(*ToTU); + if (!ImporterSharedSt) + ImporterSharedSt = std::make_shared<ASTImporterSharedState>(*ToTU); } ASTImporter & @@ -448,10 +448,10 @@ CrossTranslationUnitContext::getOrCreateASTImporter(ASTContext &From) { auto I = ASTUnitImporterMap.find(From.getTranslationUnitDecl()); if (I != ASTUnitImporterMap.end()) return *I->second; - lazyInitLookupTable(Context.getTranslationUnitDecl()); + lazyInitImporterSharedSt(Context.getTranslationUnitDecl()); ASTImporter *NewImporter = new ASTImporter( Context, Context.getSourceManager().getFileManager(), From, - From.getSourceManager().getFileManager(), false, LookupTable.get()); + From.getSourceManager().getFileManager(), false, ImporterSharedSt); ASTUnitImporterMap[From.getTranslationUnitDecl()].reset(NewImporter); return *NewImporter; } diff --git a/clang/lib/Frontend/ASTMerge.cpp b/clang/lib/Frontend/ASTMerge.cpp index f2709755b6b..14d781ccdf9 100644 --- a/clang/lib/Frontend/ASTMerge.cpp +++ b/clang/lib/Frontend/ASTMerge.cpp @@ -9,7 +9,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/ASTImporter.h" -#include "clang/AST/ASTImporterLookupTable.h" +#include "clang/AST/ASTImporterSharedState.h" #include "clang/Basic/Diagnostic.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" @@ -38,7 +38,7 @@ void ASTMergeAction::ExecuteAction() { &CI.getASTContext()); IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(CI.getDiagnostics().getDiagnosticIDs()); - ASTImporterLookupTable LookupTable( + auto SharedState = std::make_shared<ASTImporterSharedState>( *CI.getASTContext().getTranslationUnitDecl()); for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) { IntrusiveRefCntPtr<DiagnosticsEngine> @@ -55,7 +55,7 @@ void ASTMergeAction::ExecuteAction() { ASTImporter Importer(CI.getASTContext(), CI.getFileManager(), Unit->getASTContext(), Unit->getFileManager(), - /*MinimalImport=*/false, &LookupTable); + /*MinimalImport=*/false, SharedState); TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl(); for (auto *D : TU->decls()) { |