Skip to content

Add clang patch to support template parameters for as_type #430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 16, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
From 52dbb306a00d7ce7becad0c7245bc439998eceb4 Mon Sep 17 00:00:00 2001
From: Haonan Yang <[email protected]>
Date: Tue, 16 May 2023 12:57:47 +0800
Subject: [PATCH] [OpenCL] Support template parameters for as_type

Implement the TreeTransform for AsTypeExpr. Split `BuildAsTypeExpr`
out of `ActOnAsTypeExpr`, such that we can call the Build method from
the TreeTransform.

Fixes PR47979.
---
clang/include/clang/Sema/Sema.h | 3 +++
clang/lib/Sema/SemaExpr.cpp | 24 +++++++++++++--------
clang/lib/Sema/TreeTransform.h | 9 +++++++-
clang/test/SemaOpenCLCXX/template-astype.cl | 23 ++++++++++++++++++++
4 files changed, 49 insertions(+), 10 deletions(-)
create mode 100644 clang/test/SemaOpenCLCXX/template-astype.cl

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 2530a2776373..9cca5f2b1bf1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5558,6 +5558,9 @@ public:
ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy,
SourceLocation BuiltinLoc,
SourceLocation RParenLoc);
+ ExprResult BuildAsTypeExpr(Expr *E, QualType DestTy,
+ SourceLocation BuiltinLoc,
+ SourceLocation RParenLoc);

//===---------------------------- C++ Features --------------------------===//

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ae8508d6c601..4dfdb7870374 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6493,24 +6493,30 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
ExecConfig, IsExecConfig);
}

-/// ActOnAsTypeExpr - create a new asType (bitcast) from the arguments.
+/// Parse a __builtin_astype expression.
///
/// __builtin_astype( value, dst type )
///
ExprResult Sema::ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy,
SourceLocation BuiltinLoc,
SourceLocation RParenLoc) {
+ QualType DstTy = GetTypeFromParser(ParsedDestTy);
+ return BuildAsTypeExpr(E, DstTy, BuiltinLoc, RParenLoc);
+}
+
+/// Create a new AsTypeExpr node (bitcast) from the arguments.
+ExprResult Sema::BuildAsTypeExpr(Expr *E, QualType DestTy,
+ SourceLocation BuiltinLoc,
+ SourceLocation RParenLoc) {
ExprValueKind VK = VK_RValue;
ExprObjectKind OK = OK_Ordinary;
- QualType DstTy = GetTypeFromParser(ParsedDestTy);
QualType SrcTy = E->getType();
- if (Context.getTypeSize(DstTy) != Context.getTypeSize(SrcTy))
- return ExprError(Diag(BuiltinLoc,
- diag::err_invalid_astype_of_different_size)
- << DstTy
- << SrcTy
- << E->getSourceRange());
- return new (Context) AsTypeExpr(E, DstTy, VK, OK, BuiltinLoc, RParenLoc);
+ if (!SrcTy->isDependentType() &&
+ Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy))
+ return ExprError(
+ Diag(BuiltinLoc, diag::err_invalid_astype_of_different_size)
+ << DestTy << SrcTy << E->getSourceRange());
+ return new (Context) AsTypeExpr(E, DestTy, VK, OK, BuiltinLoc, RParenLoc);
}

/// ActOnConvertVectorExpr - create a new convert-vector expression from the
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 3c68f9458e58..abdc3d12101e 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -13821,7 +13821,14 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
- llvm_unreachable("Cannot transform asType expressions yet");
+ ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
+ if (SrcExpr.isInvalid())
+ return ExprError();
+
+ QualType Type = getDerived().TransformType(E->getType());
+
+ return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
+ E->getRParenLoc());
}

template<typename Derived>
diff --git a/clang/test/SemaOpenCLCXX/template-astype.cl b/clang/test/SemaOpenCLCXX/template-astype.cl
new file mode 100644
index 000000000000..efb93412cb20
--- /dev/null
+++ b/clang/test/SemaOpenCLCXX/template-astype.cl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fdeclare-opencl-builtins -finclude-default-header %s -cl-std=clc++ -verify
+
+// Test as_type, which is defined in terms of __builtin_astype.
+template <typename T>
+auto templated_astype(T x) {
+ return as_int2(x);
+ // expected-error@-1{{invalid reinterpretation: sizes of 'int2' (vector of 2 'int' values) and '__private int' must match}}
+}
+
+auto test_long(long x) { return templated_astype(x); }
+
+auto neg_test_int(int x) { return templated_astype(x); }
+// expected-note@-1{{in instantiation of function template specialization 'templated_astype<int>' requested here}}
+
+auto test_short4(short4 x) { return templated_astype(x); }
+
+// Test __builtin_astype.
+template <typename T>
+auto templated_builtin_astype(T x) {
+ return __builtin_astype(x, int2);
+}
+
+auto test_builtin(char8 x) { return templated_builtin_astype(x); }
--
2.31.1