diff options
author | Gabor Marton <martongabesz@gmail.com> | 2018-11-20 14:19:39 +0000 |
---|---|---|
committer | Gabor Marton <martongabesz@gmail.com> | 2018-11-20 14:19:39 +0000 |
commit | f5e4f0af7b450562af46a5df5e071bc79d021c16 (patch) | |
tree | 85712c1946e513d6c3381c332817da4066a357a9 /clang/lib | |
parent | 6e6b4ac18e7c580d6c439c768aa1954cd05a5342 (diff) | |
download | bcm5719-llvm-f5e4f0af7b450562af46a5df5e071bc79d021c16.tar.gz bcm5719-llvm-f5e4f0af7b450562af46a5df5e071bc79d021c16.zip |
[ASTImporter] Set redecl chain of functions before any other import
Summary:
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.
Reviewers: a_sidorin, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits
Differential Revision: https://reviews.llvm.org/D53702
llvm-svn: 347306
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 8c80ecd1e67..fd8200c5653 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3144,19 +3144,6 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { 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), @@ -3184,6 +3171,30 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { 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); @@ -3199,12 +3210,6 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { } 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) { |