summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTImporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ASTImporter.cpp')
-rw-r--r--clang/lib/AST/ASTImporter.cpp33
1 files changed, 27 insertions, 6 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index edefa45fb56..097046d93dd 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -57,6 +57,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
@@ -1631,16 +1632,32 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
auto ToDCOrErr = Importer.ImportContext(FromDC);
return ToDCOrErr.takeError();
}
+
+ // We use strict error handling in case of records and enums, but not
+ // with e.g. namespaces.
+ //
+ // FIXME Clients of the ASTImporter should be able to choose an
+ // appropriate error handling strategy for their needs. For instance,
+ // they may not want to mark an entire namespace as erroneous merely
+ // because there is an ODR error with two typedefs. As another example,
+ // the client may allow EnumConstantDecls with same names but with
+ // different values in two distinct translation units.
+ bool AccumulateChildErrors = isa<TagDecl>(FromDC);
+
+ Error ChildErrors = Error::success();
llvm::SmallVector<Decl *, 8> ImportedDecls;
for (auto *From : FromDC->decls()) {
ExpectedDecl ImportedOrErr = import(From);
- if (!ImportedOrErr)
- // Ignore the error, continue with next Decl.
- // FIXME: Handle this case somehow better.
- consumeError(ImportedOrErr.takeError());
+ if (!ImportedOrErr) {
+ if (AccumulateChildErrors)
+ ChildErrors =
+ joinErrors(std::move(ChildErrors), ImportedOrErr.takeError());
+ else
+ consumeError(ImportedOrErr.takeError());
+ }
}
- return Error::success();
+ return ChildErrors;
}
Error ASTNodeImporter::ImportDeclContext(
@@ -1698,6 +1715,11 @@ Error ASTNodeImporter::ImportDefinition(
}
To->startDefinition();
+ // Complete the definition even if error is returned.
+ // The RecordDecl may be already part of the AST so it is better to
+ // have it in complete state even if something is wrong with it.
+ auto DefinitionCompleter =
+ llvm::make_scope_exit([To]() { To->completeDefinition(); });
if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
return Err;
@@ -1822,7 +1844,6 @@ Error ASTNodeImporter::ImportDefinition(
if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
return Err;
- To->completeDefinition();
return Error::success();
}
OpenPOWER on IntegriCloud