this patch is the continuation of my previous patch regarding the ImportError in ASTImportError.h
Reviewed By: martong
Differential Revision: https://reviews.llvm.org/D125340
namespace clang {
+<<<<<<< HEAD
+class ASTImportError : public llvm::ErrorInfo<ASTImportError> {
+=======
class ImportError : public llvm::ErrorInfo<ImportError> {
+>>>>>>> 4bf928bce44adda059aba715664c41462536d483
public:
/// \brief Kind of error when importing an AST component.
enum ErrorKind {
static char ID;
+<<<<<<< HEAD
+ ASTImportError() : Error(Unknown) {}
+ ASTImportError(const ASTImportError &Other) : Error(Other.Error) {}
+ ASTImportError &operator=(const ASTImportError &Other) {
+ Error = Other.Error;
+ return *this;
+ }
+ ASTImportError(ErrorKind Error) : Error(Error) {}
+=======
ImportError() : Error(Unknown) {}
ImportError(const ImportError &Other) : Error(Other.Error) {}
ImportError &operator=(const ImportError &Other) {
return *this;
}
ImportError(ErrorKind Error) : Error(Error) {}
+>>>>>>> 4bf928bce44adda059aba715664c41462536d483
std::string toString() const;
/// imported. The same declaration may or may not be included in
/// ImportedDecls. This map is updated continuously during imports and never
/// cleared (like ImportedDecls).
- llvm::DenseMap<Decl *, ImportError> ImportDeclErrors;
+ llvm::DenseMap<Decl *, ASTImportError> ImportDeclErrors;
/// Mapping from the already-imported declarations in the "to"
/// context to the corresponding declarations in the "from" context.
/// Return if import of the given declaration has failed and if yes
/// the kind of the problem. This gives the first error encountered with
/// the node.
- llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *FromD) const;
+ llvm::Optional<ASTImportError> getImportDeclErrorIfAny(Decl *FromD) const;
/// Mark (newly) imported declaration with error.
- void setImportDeclError(Decl *From, ImportError Error);
+ void setImportDeclError(Decl *From, ASTImportError Error);
/// Determine whether the given types are structurally
/// equivalent.
/// imported. The same declaration may or may not be included in
/// ImportedFromDecls. This map is updated continuously during imports and
/// never cleared (like ImportedFromDecls).
- llvm::DenseMap<Decl *, ImportError> ImportErrors;
+ llvm::DenseMap<Decl *, ASTImportError> ImportErrors;
/// Set of the newly created declarations.
llvm::DenseSet<Decl *> NewDecls;
LookupTable->remove(ND);
}
- llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *ToD) const {
+ llvm::Optional<ASTImportError> getImportDeclErrorIfAny(Decl *ToD) const {
auto Pos = ImportErrors.find(ToD);
if (Pos != ImportErrors.end())
return Pos->second;
else
- return Optional<ImportError>();
+ return Optional<ASTImportError>();
}
- void setImportDeclError(Decl *To, ImportError Error) {
+ void setImportDeclError(Decl *To, ASTImportError Error) {
ImportErrors[To] = Error;
}
using ExpectedSLoc = llvm::Expected<SourceLocation>;
using ExpectedName = llvm::Expected<DeclarationName>;
- std::string ImportError::toString() const {
+ std::string ASTImportError::toString() const {
// FIXME: Improve error texts.
switch (Error) {
case NameConflict:
return "Invalid error code.";
}
- void ImportError::log(raw_ostream &OS) const {
- OS << toString();
- }
+ void ASTImportError::log(raw_ostream &OS) const { OS << toString(); }
- std::error_code ImportError::convertToErrorCode() const {
+ std::error_code ASTImportError::convertToErrorCode() const {
llvm_unreachable("Function not implemented.");
}
- char ImportError::ID;
+ char ASTImportError::ID;
template <class T>
SmallVector<Decl *, 2>
ExpectedType ASTNodeImporter::VisitType(const Type *T) {
Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
<< T->getTypeClassName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
}
ExpectedType ASTNodeImporter::VisitAtomicType(const AtomicType *T){
if (RT && RT->getDecl() == D) {
Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
<< D->getDeclKindName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
}
}
}
ExpectedDecl ASTNodeImporter::VisitDecl(Decl *D) {
Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
<< D->getDeclKindName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
}
ExpectedDecl ASTNodeImporter::VisitImportDecl(ImportDecl *D) {
Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
<< D->getDeclKindName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
}
ExpectedDecl ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) {
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
}
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
}
Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
<< FoundIvar->getType();
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
}
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
// Check the number of parameters.
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
// Check parameter types.
Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
<< (*FoundP)->getType();
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
}
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
// FIXME: Any other bits we need to merge?
Importer.FromDiag(D->getLocation(),
diag::note_odr_objc_missing_superclass);
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
}
Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
<< FoundProp->getType();
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
// FIXME: Check property attributes, getters, setters, etc.?
<< D->getPropertyDecl()->getDeclName()
<< (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
// For @synthesize, check that we have the same
diag::note_odr_objc_synthesize_ivar_here)
<< D->getPropertyIvarDecl()->getDeclName();
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
// Merge the existing implementation with the new implementation.
}
} else { // ODR violation.
// FIXME HandleNameConflict
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
}
ExpectedStmt ASTNodeImporter::VisitStmt(Stmt *S) {
Importer.FromDiag(S->getBeginLoc(), diag::err_unsupported_ast_node)
<< S->getStmtClassName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
}
ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
if (Importer.returnWithErrorInTest())
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
SmallVector<IdentifierInfo *, 4> Names;
for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(I));
ExpectedStmt ASTNodeImporter::VisitExpr(Expr *E) {
Importer.FromDiag(E->getBeginLoc(), diag::err_unsupported_ast_node)
<< E->getStmtClassName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
}
ExpectedStmt ASTNodeImporter::VisitSourceLocExpr(SourceLocExpr *E) {
}
default:
llvm_unreachable("Cast expression of unsupported type!");
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
}
}
ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
} else {
llvm_unreachable("Unknown cast type");
- return make_error<ImportError>();
+ return make_error<ASTImportError>();
}
}
// FIXME: Handle BlockDecl when we implement importing BlockExpr in
// ASTNodeImporter.
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
}
ExpectedTypePtr ASTImporter::Import(const Type *FromT) {
// Check whether there was a previous failed import.
// If yes return the existing error.
if (auto Error = getImportDeclErrorIfAny(FromD))
- return make_error<ImportError>(*Error);
+ return make_error<ASTImportError>(*Error);
// Check whether we've already imported this declaration.
Decl *ToD = GetAlreadyImportedOrNull(FromD);
// Already imported (possibly from another TU) and with an error.
if (auto Error = SharedState->getImportDeclErrorIfAny(ToD)) {
setImportDeclError(FromD, *Error);
- return make_error<ImportError>(*Error);
+ return make_error<ASTImportError>(*Error);
}
// If FromD has some updated flags after last import, apply it.
// 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;
+ ASTImportError ErrOut;
handleAllErrors(ToDOrErr.takeError(),
- [&ErrOut](const ImportError &E) { ErrOut = E; });
+ [&ErrOut](const ASTImportError &E) { ErrOut = E; });
setImportDeclError(FromD, ErrOut);
// Set the error for the mapped to Decl, which is in the "to" context.
if (Pos != ImportedDecls.end())
SavedImportPaths.erase(FromD);
// Do not return ToDOrErr, error was taken out of it.
- return make_error<ImportError>(ErrOut);
+ return make_error<ASTImportError>(ErrOut);
}
ToD = *ToDOrErr;
if (!ToD) {
auto Err = getImportDeclErrorIfAny(FromD);
assert(Err);
- return make_error<ImportError>(*Err);
+ return make_error<ASTImportError>(*Err);
}
// We could import from the current TU without error. But previously we
// ASTImporter object) and with an error.
if (auto Error = SharedState->getImportDeclErrorIfAny(ToD)) {
setImportDeclError(FromD, *Error);
- return make_error<ImportError>(*Error);
+ return make_error<ASTImportError>(*Error);
}
// Make sure that ImportImpl registered the imported decl.
Cache->getBufferOrNone(FromContext.getDiagnostics(),
FromSM.getFileManager(), SourceLocation{});
if (!FromBuf)
- return llvm::make_error<ImportError>(ImportError::Unknown);
+ return llvm::make_error<ASTImportError>(ASTImportError::Unknown);
std::unique_ptr<llvm::MemoryBuffer> ToBuf =
llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
*ToExprOrErr, *RParenLocOrErr);
} else {
// FIXME: assert?
- return make_error<ImportError>();
+ return make_error<ASTImportError>();
}
}
unsigned NumDecls) {
if (ODRHandling == ODRHandlingType::Conservative)
// Report error at any name conflict.
- return make_error<ImportError>(ImportError::NameConflict);
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
else
// Allow to create the new Decl with the same name.
return Name;
return To;
}
-llvm::Optional<ImportError>
+llvm::Optional<ASTImportError>
ASTImporter::getImportDeclErrorIfAny(Decl *FromD) const {
auto Pos = ImportDeclErrors.find(FromD);
if (Pos != ImportDeclErrors.end())
return Pos->second;
else
- return Optional<ImportError>();
+ return Optional<ASTImportError>();
}
-void ASTImporter::setImportDeclError(Decl *From, ImportError Error) {
+void ASTImporter::setImportDeclError(Decl *From, ASTImportError Error) {
auto InsertRes = ImportDeclErrors.insert({From, Error});
(void)InsertRes;
// Either we set the error for the first time, or we already had set one and
auto ToDeclOrError = Importer.Import(D);
if (!ToDeclOrError) {
- handleAllErrors(ToDeclOrError.takeError(),
- [&](const ImportError &IE) {
- switch (IE.Error) {
- case ImportError::NameConflict:
- ++NumNameConflicts;
- break;
- case ImportError::UnsupportedConstruct:
- ++NumUnsupportedNodeFound;
- break;
- case ImportError::Unknown:
- llvm_unreachable("Unknown import error happened.");
- break;
- }
- });
+ handleAllErrors(ToDeclOrError.takeError(), [&](const ASTImportError &IE) {
+ switch (IE.Error) {
+ case ASTImportError::NameConflict:
+ ++NumNameConflicts;
+ break;
+ case ASTImportError::UnsupportedConstruct:
+ ++NumUnsupportedNodeFound;
+ break;
+ case ASTImportError::Unknown:
+ llvm_unreachable("Unknown import error happened.");
+ break;
+ }
+ });
return llvm::make_error<IndexError>(index_error_code::failed_import);
}
auto *ToDecl = cast<T>(*ToDeclOrError);
auto Imported = importNode(FromAST.get(), ToAST.get(), Importer, ToImport);
if (!Imported) {
std::string ErrorText;
- handleAllErrors(
- Imported.takeError(),
- [&ErrorText](const ImportError &Err) { ErrorText = Err.message(); });
+ handleAllErrors(Imported.takeError(),
+ [&ErrorText](const ASTImportError &Err) {
+ ErrorText = Err.message();
+ });
return testing::AssertionFailure()
<< "Import failed, error: \"" << ErrorText << "\"!";
}
template <class T>
::testing::AssertionResult isImportError(llvm::Expected<T> &ValOrErr,
- ImportError::ErrorKind Kind) {
+ ASTImportError::ErrorKind Kind) {
if (ValOrErr) {
return ::testing::AssertionFailure() << "Expected<> is expected to contain "
"error but does contain value \""
std::ostringstream OS;
bool Result = false;
auto Err = llvm::handleErrors(
- ValOrErr.takeError(), [&OS, &Result, Kind](clang::ImportError &IE) {
+ ValOrErr.takeError(), [&OS, &Result, Kind](clang::ASTImportError &IE) {
if (IE.Error == Kind) {
Result = true;
OS << "Expected<> contains an ImportError " << IE.toString();
// Check that a Decl was not imported because of NameConflict.
static void CheckImportNameConflict(llvm::Expected<Decl *> &Result,
Decl *ToTU, Decl *ToD) {
- EXPECT_TRUE(isImportError(Result, ImportError::NameConflict));
+ EXPECT_TRUE(isImportError(Result, ASTImportError::NameConflict));
EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 1u);
}
auto ToBlockOrError = importOrError(FromBlock, Lang_CXX03);
- const auto ExpectUnsupportedConstructError = [](const ImportError &Error) {
- EXPECT_EQ(ImportError::UnsupportedConstruct, Error.Error);
+ const auto ExpectUnsupportedConstructError = [](const ASTImportError &Error) {
+ EXPECT_EQ(ASTImportError::UnsupportedConstruct, Error.Error);
};
llvm::handleAllErrors(ToBlockOrError.takeError(),
ExpectUnsupportedConstructError);
// But an error is set to the counterpart in the "from" context.
ASTImporter *Importer = findFromTU(FromSpec)->Importer.get();
- Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromSpec);
+ Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromSpec);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::NameConflict);
+ EXPECT_EQ(OptErr->Error, ASTImportError::NameConflict);
}
// Check a case when a new AST node is created but not linked to the AST before
0u);
ASTImporter *Importer = findFromTU(FromFoo)->Importer.get();
- Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFoo);
+ Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFoo);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
}
// Check a case when a new AST node is created and linked to the AST before
// An error is set to the counterpart in the "from" context both for the fwd
// decl and the definition.
ASTImporter *Importer = findFromTU(FromProto)->Importer.get();
- Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromProto);
+ Optional<ASTImportError> OptErr =
+ Importer->getImportDeclErrorIfAny(FromProto);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
OptErr = Importer->getImportDeclErrorIfAny(FromDef);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
}
// An error should be set for a class if we cannot import one member.
// An error is set for X.
EXPECT_FALSE(ImportedX);
ASTImporter *Importer = findFromTU(FromX)->Importer.get();
- Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
+ Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
// An error is set for f().
auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
FromTU, cxxMethodDecl(hasName("f")));
OptErr = Importer->getImportDeclErrorIfAny(FromF);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
// And any subsequent import should fail.
CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX03);
EXPECT_FALSE(ImportedF);
// An error is set to the templated CXXRecordDecl of F.
ASTImporter *Importer = findFromTU(FromFRD)->Importer.get();
- Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFRD);
+ Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFRD);
EXPECT_TRUE(OptErr);
// An error is set to A.
// There is no error set for X.
EXPECT_TRUE(ImportedX);
ASTImporter *Importer = findFromTU(FromX)->Importer.get();
- Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
+ Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
ASSERT_FALSE(OptErr);
// An error is set for f().
FromTU, functionDecl(hasName("f")));
OptErr = Importer->getImportDeclErrorIfAny(FromF);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
// And any subsequent import should fail.
FunctionDecl *ImportedF = Import(FromF, Lang_CXX03);
EXPECT_FALSE(ImportedF);
// An error is set for X ...
EXPECT_FALSE(ImportedX);
ASTImporter *Importer = findFromTU(FromX)->Importer.get();
- Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
+ Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
}
// ... but the node had been created.
auto *ToXDef = FirstDeclMatcher<CXXRecordDecl>().match(
ToTU, cxxRecordDecl(hasName("X"), isDefinition()));
// An error is set for "ToXDef" in the shared state.
- Optional<ImportError> OptErr =
+ Optional<ASTImportError> OptErr =
SharedStatePtr->getImportDeclErrorIfAny(ToXDef);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
auto *ToXFwd = FirstDeclMatcher<CXXRecordDecl>().match(
ToTU, cxxRecordDecl(hasName("X"), unless(isDefinition())));
// The import should fail.
EXPECT_FALSE(ImportedX);
ASTImporter *Importer = findFromTU(FromX)->Importer.get();
- Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
+ Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
// And an error is set for this new X in the "from" ctx.
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
}
}
EXPECT_FALSE(Import(FromFooA, Lang_CXX11));
ASTImporter *Importer = findFromTU(FromFooA)->Importer.get();
auto CheckError = [&Importer](Decl *FromD) {
- Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromD);
+ Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromD);
ASSERT_TRUE(OptErr);
- EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+ EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
};
CheckError(FromFooA);
EXPECT_FALSE(Import(FromFooB, Lang_CXX11));