|
@@ -12,7 +12,7 @@
|
|
//===----------------------------------------------------------------------===//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
#include "clang/AST/ASTImporter.h"
|
|
#include "clang/AST/ASTImporter.h"
|
|
-#include "clang/AST/ASTImporterLookupTable.h"
|
|
|
|
|
|
+#include "clang/AST/ASTImporterSharedState.h"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/AST/ASTDiagnostic.h"
|
|
#include "clang/AST/ASTDiagnostic.h"
|
|
#include "clang/AST/ASTStructuralEquivalence.h"
|
|
#include "clang/AST/ASTStructuralEquivalence.h"
|
|
@@ -7701,11 +7701,16 @@ void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
|
|
ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
|
|
ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
|
|
ASTContext &FromContext, FileManager &FromFileManager,
|
|
ASTContext &FromContext, FileManager &FromFileManager,
|
|
bool MinimalImport,
|
|
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),
|
|
ToFileManager(ToFileManager), FromFileManager(FromFileManager),
|
|
Minimal(MinimalImport) {
|
|
Minimal(MinimalImport) {
|
|
|
|
|
|
|
|
+ // Create a default state without the lookup table: LLDB case.
|
|
|
|
+ if (!SharedState) {
|
|
|
|
+ this->SharedState = std::make_shared<ASTImporterSharedState>();
|
|
|
|
+ }
|
|
|
|
+
|
|
ImportedDecls[FromContext.getTranslationUnitDecl()] =
|
|
ImportedDecls[FromContext.getTranslationUnitDecl()] =
|
|
ToContext.getTranslationUnitDecl();
|
|
ToContext.getTranslationUnitDecl();
|
|
}
|
|
}
|
|
@@ -7744,9 +7749,9 @@ ASTImporter::findDeclsInToCtx(DeclContext *DC, DeclarationName Name) {
|
|
// then the enum constant 'A' and the variable 'A' violates ODR.
|
|
// then the enum constant 'A' and the variable 'A' violates ODR.
|
|
// We can diagnose this only if we search in the redecl context.
|
|
// We can diagnose this only if we search in the redecl context.
|
|
DeclContext *ReDC = DC->getRedeclContext();
|
|
DeclContext *ReDC = DC->getRedeclContext();
|
|
- if (LookupTable) {
|
|
|
|
|
|
+ if (SharedState->getLookupTable()) {
|
|
ASTImporterLookupTable::LookupResult LookupResult =
|
|
ASTImporterLookupTable::LookupResult LookupResult =
|
|
- LookupTable->lookup(ReDC, Name);
|
|
|
|
|
|
+ SharedState->getLookupTable()->lookup(ReDC, Name);
|
|
return FoundDeclsTy(LookupResult.begin(), LookupResult.end());
|
|
return FoundDeclsTy(LookupResult.begin(), LookupResult.end());
|
|
} else {
|
|
} else {
|
|
// FIXME Can we remove this kind of lookup?
|
|
// FIXME Can we remove this kind of lookup?
|
|
@@ -7758,9 +7763,7 @@ ASTImporter::findDeclsInToCtx(DeclContext *DC, DeclarationName Name) {
|
|
}
|
|
}
|
|
|
|
|
|
void ASTImporter::AddToLookupTable(Decl *ToD) {
|
|
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) {
|
|
Expected<Decl *> ASTImporter::ImportImpl(Decl *FromD) {
|
|
@@ -7855,6 +7858,12 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) {
|
|
// Check whether we've already imported this declaration.
|
|
// Check whether we've already imported this declaration.
|
|
Decl *ToD = GetAlreadyImportedOrNull(FromD);
|
|
Decl *ToD = GetAlreadyImportedOrNull(FromD);
|
|
if (ToD) {
|
|
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
|
|
// If FromD has some updated flags after last import, apply it
|
|
updateFlags(FromD, ToD);
|
|
updateFlags(FromD, ToD);
|
|
// If we encounter a cycle during an import then we save the relevant part
|
|
// 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).
|
|
// traverse of the 'to' context).
|
|
auto PosF = ImportedFromDecls.find(ToD);
|
|
auto PosF = ImportedFromDecls.find(ToD);
|
|
if (PosF != ImportedFromDecls.end()) {
|
|
if (PosF != ImportedFromDecls.end()) {
|
|
- if (LookupTable)
|
|
|
|
- if (auto *ToND = dyn_cast<NamedDecl>(ToD))
|
|
|
|
- LookupTable->remove(ToND);
|
|
|
|
|
|
+ SharedState->removeDeclFromLookup(ToD);
|
|
ImportedFromDecls.erase(PosF);
|
|
ImportedFromDecls.erase(PosF);
|
|
}
|
|
}
|
|
|
|
|
|
// FIXME: AST may contain remaining references to the failed object.
|
|
// 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?).
|
|
// Get a copy of the error object (any more simple solution for this?).
|
|
ImportError ErrOut;
|
|
ImportError ErrOut;
|
|
handleAllErrors(ToDOrErr.takeError(),
|
|
handleAllErrors(ToDOrErr.takeError(),
|
|
[&ErrOut](const ImportError &E) { ErrOut = E; });
|
|
[&ErrOut](const ImportError &E) { ErrOut = E; });
|
|
setImportDeclError(FromD, ErrOut);
|
|
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
|
|
// Set the error for all nodes which have been created before we
|
|
// recognized the error.
|
|
// recognized the error.
|
|
for (const auto &Path : SavedImportPaths[FromD])
|
|
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();
|
|
SavedImportPaths[FromD].clear();
|
|
|
|
|
|
// Do not return ToDOrErr, error was taken out of it.
|
|
// 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);
|
|
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.
|
|
// Make sure that ImportImpl registered the imported decl.
|
|
assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
|
|
assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
|
|
|
|
+
|
|
// Notify subclasses.
|
|
// Notify subclasses.
|
|
Imported(FromD, ToD);
|
|
Imported(FromD, ToD);
|
|
|
|
|