Skip to content

Add clang patch to support template parameters for as_type #429

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 2be38bbf7362ee0338bc3e7a415c2e95301a6f73 Mon Sep 17 00:00:00 2001
From: haonanya <[email protected]>
Date: Tue, 16 May 2023 13:57:11 +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 128e0c197a8a..6b891bc7266d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4798,6 +4798,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 d8869ffe945a..74d4a7ddb6e2 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5703,24 +5703,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 69939d0c4cc6..da0c8cd4d524 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12661,7 +12661,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..ed6bba49b32a
--- /dev/null
+++ b/clang/test/SemaOpenCLCXX/template-astype.cl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -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 '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.17.1