diff options
author | Gabor Marton <gabor.marton@ericsson.com> | 2019-12-12 17:13:35 +0100 |
---|---|---|
committer | Gabor Marton <gabor.marton@ericsson.com> | 2019-12-12 17:49:03 +0100 |
commit | 25234fd69e32e51bc800686075265f535d69d990 (patch) | |
tree | 09abce424fd366e878c476720de566867d0b9bc7 /clang/unittests/AST/ASTImporterTest.cpp | |
parent | 11b2b2f4b10023585cfc53e0dfd06441532ab954 (diff) | |
download | bcm5719-llvm-25234fd69e32e51bc800686075265f535d69d990.tar.gz bcm5719-llvm-25234fd69e32e51bc800686075265f535d69d990.zip |
[ASTImporter] Support functions with placeholder return types ...
Summary:
Support functions with placeholder return types even in cases when the type is
declared in the body of the function.
Example: auto f() { struct X{}; return X(); }
Reviewers: balazske, a_sidorin, a.sidorin, shafik
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, teemperor, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D70819
Diffstat (limited to 'clang/unittests/AST/ASTImporterTest.cpp')
-rw-r--r-- | clang/unittests/AST/ASTImporterTest.cpp | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index abf29966e92..6652111fd48 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -10,9 +10,11 @@ // //===----------------------------------------------------------------------===// +#include "clang/ASTMatchers/ASTMatchers.h" #include "llvm/ADT/StringMap.h" #include "clang/AST/DeclContextInternals.h" +#include "gtest/gtest.h" #include "ASTImporterFixtures.h" #include "MatchVerifier.h" @@ -5623,6 +5625,188 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImplicitlyDeclareSelf) { EXPECT_TRUE(ToMethod->getSelfDecl() != nullptr); } +struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {}; + +TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) { + Decl *FromTU = getTuDecl( + R"( + auto X = [](long l) { + using int_type = long; + auto dur = 13; + return static_cast<int_type>(dur); + }; + )", + Lang_CXX14, "input0.cc"); + CXXMethodDecl *From = + FirstDeclMatcher<CXXMethodDecl>().match(FromTU, cxxMethodDecl()); + + // Explicitly set the return type of the lambda's operator() to the TypeAlias. + // Normally the return type would be the built-in 'long' type. However, there + // are cases when Clang does not use the canonical type and the TypeAlias is + // used. I could not create such an AST from regular source code, it requires + // some special state in the preprocessor. I've found such an AST when Clang + // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce + // that with creduce, because after preprocessing, the AST no longer + // contained the TypeAlias as a return type of the lambda. + ASTContext &Ctx = From->getASTContext(); + TypeAliasDecl *FromTA = + FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl()); + QualType TT = Ctx.getTypedefType(FromTA); + const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType()); + QualType NewFunType = + Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo()); + From->setType(NewFunType); + + CXXMethodDecl *To = Import(From, Lang_CXX14); + EXPECT_TRUE(To); + EXPECT_TRUE(isa<TypedefType>(To->getReturnType())); +} + +TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside) { + Decl *FromTU = getTuDecl( + R"( + auto foo() { + struct X {}; + return X(); + } + )", + Lang_CXX14, "input0.cc"); + FunctionDecl *From = + FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); + + FunctionDecl *To = Import(From, Lang_CXX14); + EXPECT_TRUE(To); + EXPECT_TRUE(isa<AutoType>(To->getReturnType())); +} + +TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside2) { + Decl *FromTU = getTuDecl( + R"( + auto foo() { + struct X {}; + return X(); + } + )", + Lang_CXX14, "input0.cc"); + FunctionDecl *From = + FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); + + // This time import the type directly. + QualType ToT = ImportType(From->getType(), From, Lang_CXX14); + const FunctionProtoType *FPT = cast<FunctionProtoType>(ToT); + EXPECT_TRUE(isa<AutoType>(FPT->getReturnType())); +} + +TEST_P(ImportAutoFunctions, ReturnWithTypedefToStructDeclaredInside) { + Decl *FromTU = getTuDecl( + R"( + auto foo() { + struct X {}; + using Y = X; + return Y(); + } + )", + Lang_CXX14, "input0.cc"); + FunctionDecl *From = + FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); + + FunctionDecl *To = Import(From, Lang_CXX14); + EXPECT_TRUE(To); + EXPECT_TRUE(isa<AutoType>(To->getReturnType())); +} + +TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredNestedInside) { + Decl *FromTU = getTuDecl( + R"( + auto foo() { + struct X { struct Y{}; }; + return X::Y(); + } + )", + Lang_CXX14, "input0.cc"); + FunctionDecl *From = + FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); + + FunctionDecl *To = Import(From, Lang_CXX14); + EXPECT_TRUE(To); + EXPECT_TRUE(isa<AutoType>(To->getReturnType())); +} + +TEST_P(ImportAutoFunctions, ReturnWithInternalLambdaType) { + Decl *FromTU = getTuDecl( + R"( + auto f() { + auto l = []() { + struct X {}; + return X(); + }; + return l(); + } + )", + Lang_CXX17, "input0.cc"); + FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("f"))); + + FunctionDecl *To = Import(From, Lang_CXX17); + EXPECT_TRUE(To); + EXPECT_TRUE(isa<AutoType>(To->getReturnType())); +} + +TEST_P(ImportAutoFunctions, ReturnWithTypeInIf) { + Decl *FromTU = getTuDecl( + R"( + auto f() { + if (struct X {} x; true) + return X(); + else + return X(); + } + )", + Lang_CXX17, "input0.cc"); + FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("f"))); + + FunctionDecl *To = Import(From, Lang_CXX17); + EXPECT_TRUE(To); + EXPECT_TRUE(isa<AutoType>(To->getReturnType())); +} + +TEST_P(ImportAutoFunctions, ReturnWithTypeInFor) { + Decl *FromTU = getTuDecl( + R"( + auto f() { + for (struct X {} x;;) + return X(); + } + )", + Lang_CXX17, "input0.cc"); + FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("f"))); + + FunctionDecl *To = Import(From, Lang_CXX17); + EXPECT_TRUE(To); + EXPECT_TRUE(isa<AutoType>(To->getReturnType())); +} + +TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) { + Decl *FromTU = getTuDecl( + R"( + auto f() { + switch (struct X {} x; 10) { + case 10: + return X(); + } + } + )", + Lang_CXX17, "input0.cc"); + FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("f"))); + + FunctionDecl *To = Import(From, Lang_CXX17); + EXPECT_TRUE(To); + EXPECT_TRUE(isa<AutoType>(To->getReturnType())); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, ); @@ -5650,6 +5834,9 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedirectingImporterTest, INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctions, DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportAutoFunctions, + DefaultTestValuesForRunOptions, ); + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionTemplates, DefaultTestValuesForRunOptions, ); |