|
| 1 | +From 2be38bbf7362ee0338bc3e7a415c2e95301a6f73 Mon Sep 17 00:00:00 2001 |
| 2 | +From: haonanya < [email protected]> |
| 3 | +Date: Tue, 16 May 2023 13:57:11 +0800 |
| 4 | +Subject: [PATCH] [OpenCL] Support template parameters for as_type |
| 5 | + |
| 6 | +Implement the TreeTransform for AsTypeExpr. Split `BuildAsTypeExpr` |
| 7 | +out of `ActOnAsTypeExpr`, such that we can call the Build method from |
| 8 | +the TreeTransform. |
| 9 | + |
| 10 | +Fixes PR47979. |
| 11 | +--- |
| 12 | + clang/include/clang/Sema/Sema.h | 3 +++ |
| 13 | + clang/lib/Sema/SemaExpr.cpp | 24 +++++++++++++-------- |
| 14 | + clang/lib/Sema/TreeTransform.h | 9 +++++++- |
| 15 | + clang/test/SemaOpenCLCXX/template-astype.cl | 23 ++++++++++++++++++++ |
| 16 | + 4 files changed, 49 insertions(+), 10 deletions(-) |
| 17 | + create mode 100644 clang/test/SemaOpenCLCXX/template-astype.cl |
| 18 | + |
| 19 | +diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h |
| 20 | +index 128e0c197a8a..6b891bc7266d 100644 |
| 21 | +--- a/clang/include/clang/Sema/Sema.h |
| 22 | ++++ b/clang/include/clang/Sema/Sema.h |
| 23 | +@@ -4798,6 +4798,9 @@ public: |
| 24 | + ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, |
| 25 | + SourceLocation BuiltinLoc, |
| 26 | + SourceLocation RParenLoc); |
| 27 | ++ ExprResult BuildAsTypeExpr(Expr *E, QualType DestTy, |
| 28 | ++ SourceLocation BuiltinLoc, |
| 29 | ++ SourceLocation RParenLoc); |
| 30 | + |
| 31 | + //===---------------------------- C++ Features --------------------------===// |
| 32 | + |
| 33 | +diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp |
| 34 | +index d8869ffe945a..74d4a7ddb6e2 100644 |
| 35 | +--- a/clang/lib/Sema/SemaExpr.cpp |
| 36 | ++++ b/clang/lib/Sema/SemaExpr.cpp |
| 37 | +@@ -5703,24 +5703,30 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, |
| 38 | + ExecConfig, IsExecConfig); |
| 39 | + } |
| 40 | + |
| 41 | +-/// ActOnAsTypeExpr - create a new asType (bitcast) from the arguments. |
| 42 | ++/// Parse a __builtin_astype expression. |
| 43 | + /// |
| 44 | + /// __builtin_astype( value, dst type ) |
| 45 | + /// |
| 46 | + ExprResult Sema::ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, |
| 47 | + SourceLocation BuiltinLoc, |
| 48 | + SourceLocation RParenLoc) { |
| 49 | ++ QualType DstTy = GetTypeFromParser(ParsedDestTy); |
| 50 | ++ return BuildAsTypeExpr(E, DstTy, BuiltinLoc, RParenLoc); |
| 51 | ++} |
| 52 | ++ |
| 53 | ++/// Create a new AsTypeExpr node (bitcast) from the arguments. |
| 54 | ++ExprResult Sema::BuildAsTypeExpr(Expr *E, QualType DestTy, |
| 55 | ++ SourceLocation BuiltinLoc, |
| 56 | ++ SourceLocation RParenLoc) { |
| 57 | + ExprValueKind VK = VK_RValue; |
| 58 | + ExprObjectKind OK = OK_Ordinary; |
| 59 | +- QualType DstTy = GetTypeFromParser(ParsedDestTy); |
| 60 | + QualType SrcTy = E->getType(); |
| 61 | +- if (Context.getTypeSize(DstTy) != Context.getTypeSize(SrcTy)) |
| 62 | +- return ExprError(Diag(BuiltinLoc, |
| 63 | +- diag::err_invalid_astype_of_different_size) |
| 64 | +- << DstTy |
| 65 | +- << SrcTy |
| 66 | +- << E->getSourceRange()); |
| 67 | +- return new (Context) AsTypeExpr(E, DstTy, VK, OK, BuiltinLoc, RParenLoc); |
| 68 | ++ if (!SrcTy->isDependentType() && |
| 69 | ++ Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy)) |
| 70 | ++ return ExprError( |
| 71 | ++ Diag(BuiltinLoc, diag::err_invalid_astype_of_different_size) |
| 72 | ++ << DestTy << SrcTy << E->getSourceRange()); |
| 73 | ++ return new (Context) AsTypeExpr(E, DestTy, VK, OK, BuiltinLoc, RParenLoc); |
| 74 | + } |
| 75 | + |
| 76 | + /// ActOnConvertVectorExpr - create a new convert-vector expression from the |
| 77 | +diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h |
| 78 | +index 69939d0c4cc6..da0c8cd4d524 100644 |
| 79 | +--- a/clang/lib/Sema/TreeTransform.h |
| 80 | ++++ b/clang/lib/Sema/TreeTransform.h |
| 81 | +@@ -12661,7 +12661,14 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { |
| 82 | + template<typename Derived> |
| 83 | + ExprResult |
| 84 | + TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) { |
| 85 | +- llvm_unreachable("Cannot transform asType expressions yet"); |
| 86 | ++ ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr()); |
| 87 | ++ if (SrcExpr.isInvalid()) |
| 88 | ++ return ExprError(); |
| 89 | ++ |
| 90 | ++ QualType Type = getDerived().TransformType(E->getType()); |
| 91 | ++ |
| 92 | ++ return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(), |
| 93 | ++ E->getRParenLoc()); |
| 94 | + } |
| 95 | + |
| 96 | + template<typename Derived> |
| 97 | +diff --git a/clang/test/SemaOpenCLCXX/template-astype.cl b/clang/test/SemaOpenCLCXX/template-astype.cl |
| 98 | +new file mode 100644 |
| 99 | +index 000000000000..ed6bba49b32a |
| 100 | +--- /dev/null |
| 101 | ++++ b/clang/test/SemaOpenCLCXX/template-astype.cl |
| 102 | +@@ -0,0 +1,23 @@ |
| 103 | ++// RUN: %clang_cc1 -finclude-default-header %s -cl-std=clc++ -verify |
| 104 | ++ |
| 105 | ++// Test as_type, which is defined in terms of __builtin_astype. |
| 106 | ++template <typename T> |
| 107 | ++auto templated_astype(T x) { |
| 108 | ++ return as_int2(x); |
| 109 | ++ // expected-error@-1{{invalid reinterpretation: sizes of 'int2' (vector of 2 'int' values) and 'int' must match}} |
| 110 | ++} |
| 111 | ++ |
| 112 | ++auto test_long(long x) { return templated_astype(x); } |
| 113 | ++ |
| 114 | ++auto neg_test_int(int x) { return templated_astype(x); } |
| 115 | ++// expected-note@-1{{in instantiation of function template specialization 'templated_astype<int>' requested here}} |
| 116 | ++ |
| 117 | ++auto test_short4(short4 x) { return templated_astype(x); } |
| 118 | ++ |
| 119 | ++// Test __builtin_astype. |
| 120 | ++template <typename T> |
| 121 | ++auto templated_builtin_astype(T x) { |
| 122 | ++ return __builtin_astype(x, int2); |
| 123 | ++} |
| 124 | ++ |
| 125 | ++auto test_builtin(char8 x) { return templated_builtin_astype(x); } |
| 126 | +-- |
| 127 | +2.17.1 |
| 128 | + |
0 commit comments