Author: Gabor Marton Date: 2020-11-30T17:55:25+01:00 New Revision: 70eb2ce395be1fe39ceede6719aa667658d1e5a3
URL: https://github.com/llvm/llvm-project/commit/70eb2ce395be1fe39ceede6719aa667658d1e5a3 DIFF: https://github.com/llvm/llvm-project/commit/70eb2ce395be1fe39ceede6719aa667658d1e5a3.diff LOG: [ASTImporter] Support import of CXXDeductionGuideDecl CXXDeductionGuideDecl is a FunctionDecl, but its constructor should be called appropriately, at least to set the kind variable properly. Differential Revision: https://reviews.llvm.org/D92109 Added: Modified: clang/lib/AST/ASTImporter.cpp clang/unittests/AST/ASTImporterTest.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 01ee8d275af1..1b014314996b 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -499,6 +499,7 @@ namespace clang { ExpectedDecl VisitCXXConstructorDecl(CXXConstructorDecl *D); ExpectedDecl VisitCXXDestructorDecl(CXXDestructorDecl *D); ExpectedDecl VisitCXXConversionDecl(CXXConversionDecl *D); + ExpectedDecl VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D); ExpectedDecl VisitFieldDecl(FieldDecl *D); ExpectedDecl VisitIndirectFieldDecl(IndirectFieldDecl *D); ExpectedDecl VisitFriendDecl(FriendDecl *D); @@ -3328,6 +3329,17 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { return ToPOrErr.takeError(); } + // Common code to import an explicit specifier of diff erent kind of functions. + auto ImportExplicitExpr = [this, &Err](auto *Fun) -> ExpectedExpr { + Expr *ExplicitExpr = nullptr; + if (Fun->getExplicitSpecifier().getExpr()) { + ExplicitExpr = importChecked(Err, Fun->getExplicitSpecifier().getExpr()); + if (Err) + return std::move(Err); + } + return ExplicitExpr; + }; + // Create the imported function. FunctionDecl *ToFunction = nullptr; if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) { @@ -3369,17 +3381,13 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { ToDtor->setOperatorDelete(ToOperatorDelete, ToThisArg); } else if (CXXConversionDecl *FromConversion = dyn_cast<CXXConversionDecl>(D)) { - Expr *ExplicitExpr = nullptr; - if (FromConversion->getExplicitSpecifier().getExpr()) { - auto Imp = import(FromConversion->getExplicitSpecifier().getExpr()); - if (!Imp) - return Imp.takeError(); - ExplicitExpr = *Imp; - } + ExpectedExpr ExplicitExpr = ImportExplicitExpr(FromConversion); + if (!ExplicitExpr) + return ExplicitExpr.takeError(); if (GetImportedOrCreateDecl<CXXConversionDecl>( ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC), ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(), - ExplicitSpecifier(ExplicitExpr, + ExplicitSpecifier(*ExplicitExpr, FromConversion->getExplicitSpecifier().getKind()), D->getConstexprKind(), SourceLocation(), TrailingRequiresClause)) return ToFunction; @@ -3390,6 +3398,18 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { Method->isInlineSpecified(), D->getConstexprKind(), SourceLocation(), TrailingRequiresClause)) return ToFunction; + } else if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) { + ExpectedExpr ExplicitExpr = ImportExplicitExpr(Guide); + if (!ExplicitExpr) + return ExplicitExpr.takeError(); + if (GetImportedOrCreateDecl<CXXDeductionGuideDecl>( + ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart, + ExplicitSpecifier(*ExplicitExpr, + Guide->getExplicitSpecifier().getKind()), + NameInfo, T, TInfo, ToEndLoc)) + return ToFunction; + cast<CXXDeductionGuideDecl>(ToFunction) + ->setIsCopyDeductionCandidate(Guide->isCopyDeductionCandidate()); } else { if (GetImportedOrCreateDecl( ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart, @@ -3517,6 +3537,11 @@ ExpectedDecl ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) { return VisitCXXMethodDecl(D); } +ExpectedDecl +ASTNodeImporter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { + return VisitFunctionDecl(D); +} + ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { // Import the major distinguishing characteristics of a variable. DeclContext *DC, *LexicalDC; diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 81a92a10f48d..7e56b3ed501f 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -5957,6 +5957,47 @@ TEST_P(ImportWithExternalSource, CompleteRecordBeforeImporting) { EXPECT_EQ(Record, CompletedTags.front()); } +TEST_P(ImportFunctions, CTADImplicit) { + Decl *FromTU = getTuDecl( + R"( + template <typename T> struct A { + A(T); + }; + A a{(int)0}; + )", + Lang_CXX17, "input.cc"); + auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( + FromTU, + cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>"))))); + auto *ToD = Import(FromD, Lang_CXX17); + ASSERT_TRUE(ToD); + EXPECT_TRUE(ToD->isCopyDeductionCandidate()); + // Check that the deduced class template is also imported. + EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull( + FromD->getDeducedTemplate())); +} + +TEST_P(ImportFunctions, CTADUserDefinedExplicit) { + Decl *FromTU = getTuDecl( + R"( + template <typename T> struct A { + A(T); + }; + template <typename T> explicit A(T) -> A<float>; + A a{(int)0}; // calls A<float>::A(float) + )", + Lang_CXX17, "input.cc"); + auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( + FromTU, cxxDeductionGuideDecl(unless(isImplicit()))); + // Not-implicit: i.e. not compiler-generated, user defined. + ASSERT_FALSE(FromD->isImplicit()); + ASSERT_TRUE(FromD->isExplicit()); // Has the explicit keyword. + auto *ToD = Import(FromD, Lang_CXX17); + ASSERT_TRUE(ToD); + EXPECT_FALSE(FromD->isImplicit()); + EXPECT_TRUE(ToD->isExplicit()); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, ); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits