martong created this revision.
martong added a reviewer: a_sidorin.
Herald added subscribers: cfe-commits, Szelethus, dkrupp, rnkovacs.
Herald added a reviewer: a.sidorin.
FunctionDecl import starts with a lookup and then we create a new Decl.
Then in case of CXXConstructorDecl we further import other Decls
(base classes, members through CXXConstructorDecl::inits()) before connecting
the redecl chain. During those in-between imports structural eq fails
because the canonical decl is different. This commit fixes this.
Synthesizing a test seemed extremely hard, however, Xerces analysis
reproduces the problem.
Repository:
rC Clang
https://reviews.llvm.org/D53702
Files:
lib/AST/ASTImporter.cpp
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -3139,19 +3139,6 @@
FromConstructor->isExplicit(),
D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
return ToFunction;
- if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
- SmallVector<CXXCtorInitializer *, 4> CtorInitializers(NumInitializers);
- // Import first, then allocate memory and copy if there was no error.
- if (Error Err = ImportContainerChecked(
- FromConstructor->inits(), CtorInitializers))
- return std::move(Err);
- auto **Memory =
- new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
- std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
- auto *ToCtor = cast<CXXConstructorDecl>(ToFunction);
- ToCtor->setCtorInitializers(Memory);
- ToCtor->setNumCtorInitializers(NumInitializers);
- }
} else if (isa<CXXDestructorDecl>(D)) {
if (GetImportedOrCreateDecl<CXXDestructorDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
@@ -3179,6 +3166,30 @@
return ToFunction;
}
+ // Connect the redecl chain.
+ if (FoundByLookup) {
+ auto *Recent = const_cast<FunctionDecl *>(
+ FoundByLookup->getMostRecentDecl());
+ ToFunction->setPreviousDecl(Recent);
+ }
+
+ // Import Ctor initializers.
+ if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
+ if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
+ SmallVector<CXXCtorInitializer *, 4> CtorInitializers(NumInitializers);
+ // Import first, then allocate memory and copy if there was no error.
+ if (Error Err = ImportContainerChecked(
+ FromConstructor->inits(), CtorInitializers))
+ return std::move(Err);
+ auto **Memory =
+ new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
+ std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
+ auto *ToCtor = cast<CXXConstructorDecl>(ToFunction);
+ ToCtor->setCtorInitializers(Memory);
+ ToCtor->setNumCtorInitializers(NumInitializers);
+ }
+ }
+
ToFunction->setQualifierInfo(ToQualifierLoc);
ToFunction->setAccess(D->getAccess());
ToFunction->setLexicalDeclContext(LexicalDC);
@@ -3194,12 +3205,6 @@
}
ToFunction->setParams(Parameters);
- if (FoundByLookup) {
- auto *Recent = const_cast<FunctionDecl *>(
- FoundByLookup->getMostRecentDecl());
- ToFunction->setPreviousDecl(Recent);
- }
-
// We need to complete creation of FunctionProtoTypeLoc manually with setting
// params it refers to.
if (TInfo) {
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -3139,19 +3139,6 @@
FromConstructor->isExplicit(),
D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
return ToFunction;
- if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
- SmallVector<CXXCtorInitializer *, 4> CtorInitializers(NumInitializers);
- // Import first, then allocate memory and copy if there was no error.
- if (Error Err = ImportContainerChecked(
- FromConstructor->inits(), CtorInitializers))
- return std::move(Err);
- auto **Memory =
- new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
- std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
- auto *ToCtor = cast<CXXConstructorDecl>(ToFunction);
- ToCtor->setCtorInitializers(Memory);
- ToCtor->setNumCtorInitializers(NumInitializers);
- }
} else if (isa<CXXDestructorDecl>(D)) {
if (GetImportedOrCreateDecl<CXXDestructorDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
@@ -3179,6 +3166,30 @@
return ToFunction;
}
+ // Connect the redecl chain.
+ if (FoundByLookup) {
+ auto *Recent = const_cast<FunctionDecl *>(
+ FoundByLookup->getMostRecentDecl());
+ ToFunction->setPreviousDecl(Recent);
+ }
+
+ // Import Ctor initializers.
+ if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
+ if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
+ SmallVector<CXXCtorInitializer *, 4> CtorInitializers(NumInitializers);
+ // Import first, then allocate memory and copy if there was no error.
+ if (Error Err = ImportContainerChecked(
+ FromConstructor->inits(), CtorInitializers))
+ return std::move(Err);
+ auto **Memory =
+ new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
+ std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
+ auto *ToCtor = cast<CXXConstructorDecl>(ToFunction);
+ ToCtor->setCtorInitializers(Memory);
+ ToCtor->setNumCtorInitializers(NumInitializers);
+ }
+ }
+
ToFunction->setQualifierInfo(ToQualifierLoc);
ToFunction->setAccess(D->getAccess());
ToFunction->setLexicalDeclContext(LexicalDC);
@@ -3194,12 +3205,6 @@
}
ToFunction->setParams(Parameters);
- if (FoundByLookup) {
- auto *Recent = const_cast<FunctionDecl *>(
- FoundByLookup->getMostRecentDecl());
- ToFunction->setPreviousDecl(Recent);
- }
-
// We need to complete creation of FunctionProtoTypeLoc manually with setting
// params it refers to.
if (TInfo) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits