[clang] [Clang][ASTImporter] Implement AST import for CXXParenListInitExpr, SubstNonTypeTemplateParmPackExpr, PseudoObjectExpr (PR #160904)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 14 09:02:44 PDT 2025
https://github.com/ganenkokb-yandex updated https://github.com/llvm/llvm-project/pull/160904
>From c66a8cd53799cae624b4155adc6f5d419636d654 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 f43fa8c90ad3b..46b101206b4aa 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
@@ -9274,6 +9276,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 2227fb8ab75db6be0215c77c72a5c25ee8ff7b33 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 46b101206b4aa..521a0b17a3778 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
@@ -9291,6 +9292,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 ced227201888a89e67518a1815b8f2eb55ca4652 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 521a0b17a3778..cb4bc4e6f41fb 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
@@ -9307,6 +9308,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 2b965111255f53f81a6981e64d73c250f727fd5d 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 e7160bcf2e0c2..72192abeb59e0 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 bfa402edfd5e17b56383c718b29e5a1cd5874eec 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 72192abeb59e0..41659f3fcfdd0 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 2194a6a4a102dc34571e085e3652ded956ec18c8 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 41659f3fcfdd0..a60ea9622e8e6 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 3f343d7cd9d5a84542c58a91bda0937792ad0aef 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 cb4bc4e6f41fb..7b9c7e4abff82 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -9282,14 +9282,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());
}
@@ -9297,15 +9297,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 a60ea9622e8e6..a9bfcc296d9b3 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