[clang] [Clang][ASTImporter] Implement AST import for CXXParenListInitExpr, SubstNonTypeTemplateParmPackExpr, PseudoObjectExpr (PR #160904)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 21 02:27:58 PDT 2025
https://github.com/ganenkokb-yandex updated https://github.com/llvm/llvm-project/pull/160904
>From 3558472186bac6b676217dd8002c1a01f051605c Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Thu, 25 Sep 2025 18:11:46 +0300
Subject: [PATCH 1/7] Implement VisitSubstNonTypeTemplateParmPackExpr
---
clang/lib/AST/ASTImporter.cpp | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index bf51c3e42719c..72d9383cd63ee 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -696,6 +696,8 @@ namespace clang {
ExpectedStmt VisitCXXFoldExpr(CXXFoldExpr *E);
ExpectedStmt VisitRequiresExpr(RequiresExpr* E);
ExpectedStmt VisitConceptSpecializationExpr(ConceptSpecializationExpr* E);
+ ExpectedStmt
+ VisitSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr *E);
// Helper for chaining together multiple imports. If an error is detected,
// subsequent imports will return default constructed nodes, so that failure
@@ -9273,6 +9275,21 @@ ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
const_cast<ImplicitConceptSpecializationDecl *>(CSD), &Satisfaction);
}
+ExpectedStmt ASTNodeImporter::VisitSubstNonTypeTemplateParmPackExpr(
+ SubstNonTypeTemplateParmPackExpr *E) {
+ Error Err = Error::success();
+ auto ToType = importChecked(Err, E->getType());
+ auto ToNameLoc = importChecked(Err, E->getParameterPackLocation());
+ auto ToArgPack = importChecked(Err, E->getArgumentPack());
+ auto ToAssociatedDecl = importChecked(Err, E->getAssociatedDecl());
+ if (Err)
+ return std::move(Err);
+
+ return new (Importer.getToContext()) SubstNonTypeTemplateParmPackExpr(
+ ToType, E->getValueKind(), ToNameLoc, ToArgPack, ToAssociatedDecl,
+ E->getIndex(), E->getFinal());
+}
+
Error ASTNodeImporter::ImportOverriddenMethods(CXXMethodDecl *ToMethod,
CXXMethodDecl *FromMethod) {
Error ImportErrors = Error::success();
>From 5158012b4ea1f2bb23cabb46da6b231048e909e5 Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Thu, 25 Sep 2025 18:13:07 +0300
Subject: [PATCH 2/7] Implement VisitPseudoObjectExpr
---
clang/lib/AST/ASTImporter.cpp | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 72d9383cd63ee..1699414bd2b31 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -698,6 +698,7 @@ namespace clang {
ExpectedStmt VisitConceptSpecializationExpr(ConceptSpecializationExpr* E);
ExpectedStmt
VisitSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr *E);
+ ExpectedStmt VisitPseudoObjectExpr(PseudoObjectExpr *E);
// Helper for chaining together multiple imports. If an error is detected,
// subsequent imports will return default constructed nodes, so that failure
@@ -9290,6 +9291,21 @@ ExpectedStmt ASTNodeImporter::VisitSubstNonTypeTemplateParmPackExpr(
E->getIndex(), E->getFinal());
}
+ExpectedStmt ASTNodeImporter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+ SmallVector<Expr *, 4> ToSemantics(E->getNumSemanticExprs());
+ if (Error Err = ImportContainerChecked(E->semantics(), ToSemantics))
+ return std::move(Err);
+ Expr *ToSynt = nullptr;
+ if (const Expr *FromSynt = E->getSyntacticForm()) {
+ if (auto ToSyntOrErr = import(FromSynt))
+ ToSynt = *ToSyntOrErr;
+ else
+ return ToSyntOrErr.takeError();
+ }
+ return PseudoObjectExpr::Create(Importer.getToContext(), ToSynt, ToSemantics,
+ E->getResultExprIndex());
+}
+
Error ASTNodeImporter::ImportOverriddenMethods(CXXMethodDecl *ToMethod,
CXXMethodDecl *FromMethod) {
Error ImportErrors = Error::success();
>From 34ab8be30869ad6700160ef8747931c0246485a9 Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Thu, 25 Sep 2025 18:14:29 +0300
Subject: [PATCH 3/7] Implement VisitCXXParenListInitExpr
---
clang/lib/AST/ASTImporter.cpp | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 1699414bd2b31..2c2ff6aac2bf5 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -699,6 +699,7 @@ namespace clang {
ExpectedStmt
VisitSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr *E);
ExpectedStmt VisitPseudoObjectExpr(PseudoObjectExpr *E);
+ ExpectedStmt VisitCXXParenListInitExpr(CXXParenListInitExpr *E);
// Helper for chaining together multiple imports. If an error is detected,
// subsequent imports will return default constructed nodes, so that failure
@@ -9306,6 +9307,24 @@ ExpectedStmt ASTNodeImporter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
E->getResultExprIndex());
}
+ExpectedStmt
+ASTNodeImporter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
+ Error Err = Error::success();
+ auto ToType = importChecked(Err, E->getType());
+ auto ToInitLoc = importChecked(Err, E->getInitLoc());
+ auto ToBeginLoc = importChecked(Err, E->getBeginLoc());
+ auto ToEndLoc = importChecked(Err, E->getEndLoc());
+ if (Err)
+ return std::move(Err);
+
+ SmallVector<Expr *, 4> ToArgs(E->getInitExprs().size());
+ if (Error Err = ImportContainerChecked(E->getInitExprs(), ToArgs))
+ return std::move(Err);
+ return CXXParenListInitExpr::Create(Importer.getToContext(), ToArgs, ToType,
+ E->getUserSpecifiedInitExprs().size(),
+ ToInitLoc, ToBeginLoc, ToEndLoc);
+}
+
Error ASTNodeImporter::ImportOverriddenMethods(CXXMethodDecl *ToMethod,
CXXMethodDecl *FromMethod) {
Error ImportErrors = Error::success();
>From 60cb0a1239a67a8c41b509ecde41ee9a007627d0 Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Fri, 10 Oct 2025 18:34:52 +0300
Subject: [PATCH 4/7] Add tests for VisitSubstNonTypeTemplateParmPackExpr
---
clang/unittests/AST/ASTImporterTest.cpp | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 4c7ea5e338a13..74c14f208a381 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -3300,6 +3300,22 @@ TEST_P(ImportExpr, ConceptNestedNonInstantiationDependentRequirement) {
conceptDecl(has(requiresExpr(has(requiresExprBodyDecl())))));
}
+TEST_P(ImportExpr, ImportSubstNonTypeTemplateParmPackExpr) {
+ MatchVerifier<Decl> Verifier;
+ const char *Code = R"(
+ template<auto ...> struct X {};
+ template<typename ...> struct Z {};
+
+ template<int ...N> struct E {
+ template<int ...M> using B = Z<X<N, M>...>;
+ template<int M1, int M2> E(B<M1, M2>);
+ };
+ using declToImport = E<1, 3>;
+ )";
+ testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
+ typedefNameDecl(hasName("declToImport")));
+}
+
class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase {
public:
static constexpr auto DefaultCode = R"(
>From ad94079560fa1ff61e81def934eb77553a7c57bd Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Mon, 13 Oct 2025 12:35:54 +0300
Subject: [PATCH 5/7] Add test for VisitCXXParenListInitExpr
---
clang/unittests/AST/ASTImporterTest.cpp | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 74c14f208a381..5b1a2aefd9fbd 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -3316,6 +3316,23 @@ TEST_P(ImportExpr, ImportSubstNonTypeTemplateParmPackExpr) {
typedefNameDecl(hasName("declToImport")));
}
+
+TEST_P(ImportExpr, ImportCXXParenListInitExpr) {
+ MatchVerifier<Decl> Verifier;
+ const char *Code = R"(
+ struct Node {
+ int val;
+ double d;
+ };
+ template <int N> struct Container {
+ Node* create() { return new Node(N, 3.14); }
+ };
+ using declToImport = Container<42>;
+ )";
+ testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
+ typedefNameDecl(hasName("declToImport")));
+}
+
class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase {
public:
static constexpr auto DefaultCode = R"(
>From 87765e445a5a0db53ac3a5f08bc8f12e0b92d08b Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Mon, 13 Oct 2025 14:21:38 +0300
Subject: [PATCH 6/7] Add test for VisitPseudoObjectExpr
---
clang/unittests/AST/ASTImporterTest.cpp | 38 ++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 5b1a2aefd9fbd..7e11355144a1f 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -3316,7 +3316,6 @@ TEST_P(ImportExpr, ImportSubstNonTypeTemplateParmPackExpr) {
typedefNameDecl(hasName("declToImport")));
}
-
TEST_P(ImportExpr, ImportCXXParenListInitExpr) {
MatchVerifier<Decl> Verifier;
const char *Code = R"(
@@ -3333,6 +3332,43 @@ TEST_P(ImportExpr, ImportCXXParenListInitExpr) {
typedefNameDecl(hasName("declToImport")));
}
+TEST_P(ImportExpr, ImportPseudoObjectExpr) {
+ MatchVerifier<Decl> Verifier;
+ const char *Code = R"(
+ namespace std {
+ struct strong_ordering {
+ int n;
+ constexpr operator int() const { return n; }
+ static const strong_ordering less, equal, greater;
+ };
+ constexpr strong_ordering strong_ordering::less{-1},
+ strong_ordering::equal{0}, strong_ordering::greater{1};
+ }
+
+ struct A {
+ std::strong_ordering operator<=>(const A&) const;
+ };
+ struct B {
+ bool operator==(const B&) const;
+ bool operator<(const B&) const;
+ };
+
+ template<typename T> struct Cmp : T {
+ std::strong_ordering operator<=>(const Cmp&) const = default;
+ };
+
+ void use(...);
+ void declToImport() {
+ use(
+ Cmp<A>() <=> Cmp<A>(),
+ Cmp<B>() <=> Cmp<B>()
+ );
+ }
+ )";
+ testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
+ functionDecl(hasName("declToImport")));
+}
+
class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase {
public:
static constexpr auto DefaultCode = R"(
>From 61674a3e80cd2aa9dd9427566280996579d40046 Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Tue, 14 Oct 2025 19:02:19 +0300
Subject: [PATCH 7/7] Code review
Skip null check in VisitPseudoObjectExpr
Fix bad naming in VisitConceptSpecializationExpr
Simplify test for ImportCXXParenListInitExpr
---
clang/lib/AST/ASTImporter.cpp | 18 +++++++-----------
clang/unittests/AST/ASTImporterTest.cpp | 7 ++-----
2 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 2c2ff6aac2bf5..735f3157b694e 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -9281,14 +9281,14 @@ ExpectedStmt ASTNodeImporter::VisitSubstNonTypeTemplateParmPackExpr(
SubstNonTypeTemplateParmPackExpr *E) {
Error Err = Error::success();
auto ToType = importChecked(Err, E->getType());
- auto ToNameLoc = importChecked(Err, E->getParameterPackLocation());
+ auto ToPackLoc = importChecked(Err, E->getParameterPackLocation());
auto ToArgPack = importChecked(Err, E->getArgumentPack());
auto ToAssociatedDecl = importChecked(Err, E->getAssociatedDecl());
if (Err)
return std::move(Err);
return new (Importer.getToContext()) SubstNonTypeTemplateParmPackExpr(
- ToType, E->getValueKind(), ToNameLoc, ToArgPack, ToAssociatedDecl,
+ ToType, E->getValueKind(), ToPackLoc, ToArgPack, ToAssociatedDecl,
E->getIndex(), E->getFinal());
}
@@ -9296,15 +9296,11 @@ ExpectedStmt ASTNodeImporter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
SmallVector<Expr *, 4> ToSemantics(E->getNumSemanticExprs());
if (Error Err = ImportContainerChecked(E->semantics(), ToSemantics))
return std::move(Err);
- Expr *ToSynt = nullptr;
- if (const Expr *FromSynt = E->getSyntacticForm()) {
- if (auto ToSyntOrErr = import(FromSynt))
- ToSynt = *ToSyntOrErr;
- else
- return ToSyntOrErr.takeError();
- }
- return PseudoObjectExpr::Create(Importer.getToContext(), ToSynt, ToSemantics,
- E->getResultExprIndex());
+ auto ToSyntOrErr = import(E->getSyntacticForm());
+ if (!ToSyntOrErr)
+ return ToSyntOrErr.takeError();
+ return PseudoObjectExpr::Create(Importer.getToContext(), *ToSyntOrErr,
+ ToSemantics, E->getResultExprIndex());
}
ExpectedStmt
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 7e11355144a1f..3cab4c600b1b1 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -3323,13 +3323,10 @@ TEST_P(ImportExpr, ImportCXXParenListInitExpr) {
int val;
double d;
};
- template <int N> struct Container {
- Node* create() { return new Node(N, 3.14); }
- };
- using declToImport = Container<42>;
+ Node* declToImport() { return new Node(2, 3.14); }
)";
testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
- typedefNameDecl(hasName("declToImport")));
+ functionDecl(hasName("declToImport")));
}
TEST_P(ImportExpr, ImportPseudoObjectExpr) {
More information about the cfe-commits
mailing list