summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorGabor Marton <gabor.marton@ericsson.com>2019-07-01 15:37:07 +0000
committerGabor Marton <gabor.marton@ericsson.com>2019-07-01 15:37:07 +0000
commit2afbfb6b2268b8ba7fa9584784e8b11ef97c064a (patch)
tree3a228f091134b305481627873a179a0886877fee /clang/lib
parent1daad91af695ad3fe5b15c815362af262d44584a (diff)
downloadbcm5719-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.cpp58
-rw-r--r--clang/lib/CrossTU/CrossTranslationUnit.cpp10
-rw-r--r--clang/lib/Frontend/ASTMerge.cpp6
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()) {
OpenPOWER on IntegriCloud