Skip to content

Commit

Permalink
[ASTImporter] Fix redecl failures of Class and ClassTemplate
Browse files Browse the repository at this point in the history
Summary:
Redecl chains of classes and class templates are not handled well
currently. We want to handle them similarly to functions, i.e. try to
keep the structure of the original AST as much as possible. The aim is
to not squash a prototype with a definition, rather we create both and
put them in a redecl chain.

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58502

llvm-svn: 355390
  • Loading branch information
martong committed Mar 5, 2019
1 parent 3bcb0aa commit 41e3892
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 40 deletions.
34 changes: 2 additions & 32 deletions clang/lib/AST/ASTImporter.cpp
Expand Up @@ -2553,26 +2553,6 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
Decl::FOK_None;
}

// If this record has a definition in the translation unit we're coming from,
// but this particular declaration is not that definition, import the
// definition and map to that.
TagDecl *Definition = D->getDefinition();
if (Definition && Definition != D &&
// Friend template declaration must be imported on its own.
!IsFriendTemplate &&
// In contrast to a normal CXXRecordDecl, the implicit
// CXXRecordDecl of ClassTemplateSpecializationDecl is its redeclaration.
// The definition of the implicit CXXRecordDecl in this case is the
// ClassTemplateSpecializationDecl itself. Thus, we start with an extra
// condition in order to be able to import the implict Decl.
!D->isImplicit()) {
ExpectedDecl ImportedDefOrErr = import(Definition);
if (!ImportedDefOrErr)
return ImportedDefOrErr.takeError();

return Importer.MapImported(D, *ImportedDefOrErr);
}

// Import the major distinguishing characteristics of this record.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
Expand Down Expand Up @@ -2601,7 +2581,8 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
auto FoundDecls =
Importer.findDeclsInToCtx(DC, SearchName);
if (!FoundDecls.empty()) {
// We're going to have to compare D against potentially conflicting Decls, so complete it.
// We're going to have to compare D against potentially conflicting Decls,
// so complete it.
if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
D->getASTContext().getExternalSource()->CompleteType(D);
}
Expand Down Expand Up @@ -4976,17 +4957,6 @@ static ClassTemplateDecl *getDefinition(ClassTemplateDecl *D) {
ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
bool IsFriend = D->getFriendObjectKind() != Decl::FOK_None;

// If this template has a definition in the translation unit we're coming
// from, but this particular declaration is not that definition, import the
// definition and map to that.
ClassTemplateDecl *Definition = getDefinition(D);
if (Definition && Definition != D && !IsFriend) {
if (ExpectedDecl ImportedDefOrErr = import(Definition))
return Importer.MapImported(D, *ImportedDefOrErr);
else
return ImportedDefOrErr.takeError();
}

// Import the major distinguishing characteristics of this class template.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
Expand Down
12 changes: 4 additions & 8 deletions clang/unittests/AST/ASTImporterTest.cpp
Expand Up @@ -4241,34 +4241,30 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,

ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportDefinitionAfterImportedPrototype)
// FIXME This does not pass, possible error with Class import.
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, DISABLED_,
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
ImportDefinitionAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportDefinitionAfterImportedPrototype)
// FIXME Enable this test, once we import function templates chains correctly.
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
DISABLED_,
ImportDefinitionAfterImportedPrototype)
// FIXME This does not pass, possible error with ClassTemplate import.
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, DISABLED_,
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportDefinitionAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
ImportDefinitionAfterImportedPrototype)

ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
ImportPrototypeAfterImportedDefinition)
// FIXME This does not pass, possible error with Class import.
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, DISABLED_,
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
ImportPrototypeAfterImportedDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypeAfterImportedDefinition)
// FIXME Enable this test, once we import function templates chains correctly.
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
DISABLED_,
ImportPrototypeAfterImportedDefinition)
// FIXME This does not pass, possible error with ClassTemplate import.
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, DISABLED_,
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportPrototypeAfterImportedDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
ImportPrototypeAfterImportedDefinition)
Expand Down

0 comments on commit 41e3892

Please sign in to comment.