[clang][ASTImporter] Fix import of function with auto return type.
Fix a case of importing a function with auto return type that is resolved with a type template argument that is declared inside the function. Fixes #55500 Reviewed By: martong Differential Revision: https://reviews.llvm.org/D127396
This commit is contained in:
parent
76b57ef88c
commit
f93dee1033
|
@ -3227,23 +3227,32 @@ static bool isAncestorDeclContextOf(const DeclContext *DC, const Decl *D) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool hasTypeDeclaredInsideFunction(QualType T, const FunctionDecl *FD) {
|
||||
if (T.isNull())
|
||||
return false;
|
||||
if (const auto *RecordT = T->getAs<RecordType>()) {
|
||||
const RecordDecl *RD = RecordT->getDecl();
|
||||
assert(RD);
|
||||
if (isAncestorDeclContextOf(FD, RD)) {
|
||||
assert(RD->getLexicalDeclContext() == RD->getDeclContext());
|
||||
return true;
|
||||
}
|
||||
if (const auto *RDTempl = dyn_cast<ClassTemplateSpecializationDecl>(RD))
|
||||
return llvm::count_if(RDTempl->getTemplateArgs().asArray(),
|
||||
[FD](const TemplateArgument &Arg) {
|
||||
return hasTypeDeclaredInsideFunction(
|
||||
Arg.getAsType(), FD);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
|
||||
QualType FromTy = D->getType();
|
||||
const auto *FromFPT = FromTy->getAs<FunctionProtoType>();
|
||||
assert(FromFPT && "Must be called on FunctionProtoType");
|
||||
if (const AutoType *AutoT =
|
||||
FromFPT->getReturnType()->getContainedAutoType()) {
|
||||
QualType DeducedT = AutoT->getDeducedType();
|
||||
if (const auto *RecordT =
|
||||
!DeducedT.isNull() ? DeducedT->getAs<RecordType>() : nullptr) {
|
||||
const RecordDecl *RD = RecordT->getDecl();
|
||||
assert(RD);
|
||||
if (isAncestorDeclContextOf(D, RD)) {
|
||||
assert(RD->getLexicalDeclContext() == RD->getDeclContext());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (const AutoType *AutoT = FromFPT->getReturnType()->getContainedAutoType())
|
||||
return hasTypeDeclaredInsideFunction(AutoT->getDeducedType(), D);
|
||||
if (const auto *TypedefT = FromFPT->getReturnType()->getAs<TypedefType>()) {
|
||||
const TypedefNameDecl *TD = TypedefT->getDecl();
|
||||
assert(TD);
|
||||
|
|
|
@ -6319,6 +6319,61 @@ TEST_P(ASTImporterOptionSpecificTestBase,
|
|||
|
||||
struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {};
|
||||
|
||||
TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside1) {
|
||||
Decl *FromTU = getTuDecl(
|
||||
R"(
|
||||
template<class> struct Tmpl {};
|
||||
auto foo() {
|
||||
struct X {};
|
||||
return Tmpl<X>();
|
||||
}
|
||||
)",
|
||||
Lang_CXX14, "input0.cc");
|
||||
FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
|
||||
FromTU, functionDecl(hasName("foo")));
|
||||
|
||||
FunctionDecl *To = Import(From, Lang_CXX14);
|
||||
EXPECT_TRUE(To);
|
||||
EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
|
||||
}
|
||||
|
||||
TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside2) {
|
||||
Decl *FromTU = getTuDecl(
|
||||
R"(
|
||||
template<class> struct Tmpl {};
|
||||
auto foo() {
|
||||
struct X {};
|
||||
return Tmpl<Tmpl<X>>();
|
||||
}
|
||||
)",
|
||||
Lang_CXX14, "input0.cc");
|
||||
FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
|
||||
FromTU, functionDecl(hasName("foo")));
|
||||
|
||||
FunctionDecl *To = Import(From, Lang_CXX14);
|
||||
EXPECT_TRUE(To);
|
||||
EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
|
||||
}
|
||||
|
||||
TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTypedefDeclaredInside) {
|
||||
Decl *FromTU = getTuDecl(
|
||||
R"(
|
||||
template<class> struct Tmpl {};
|
||||
auto foo() {
|
||||
struct X {};
|
||||
using x_type = X;
|
||||
return Tmpl<x_type>();
|
||||
}
|
||||
)",
|
||||
Lang_CXX14, "input0.cc");
|
||||
FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
|
||||
FromTU, functionDecl(hasName("foo")));
|
||||
|
||||
FunctionDecl *To = Import(From, Lang_CXX14);
|
||||
EXPECT_TRUE(To);
|
||||
EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
|
||||
}
|
||||
|
||||
TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) {
|
||||
Decl *FromTU = getTuDecl(
|
||||
R"(
|
||||
|
|
Loading…
Reference in a new issue