Skip to content

Commit a6a237f

Browse files
author
Anastasia Stulova
committed
[OpenCL] Added addrspace_cast operator in C++ mode.
This operator is intended for casting between pointers to objects in different address spaces and follows similar logic as const_cast in C++. Tags: #clang Differential Revision: https://reviews.llvm.org/D60193
1 parent f997370 commit a6a237f

32 files changed

+298
-71
lines changed

clang/include/clang-c/Index.h

+27-23
Original file line numberDiff line numberDiff line change
@@ -2052,58 +2052,62 @@ enum CXCursorKind {
20522052
*/
20532053
CXCursor_CXXFunctionalCastExpr = 128,
20542054

2055+
/** OpenCL's addrspace_cast<> expression.
2056+
*/
2057+
CXCursor_CXXAddrspaceCastExpr = 129,
2058+
20552059
/** A C++ typeid expression (C++ [expr.typeid]).
20562060
*/
2057-
CXCursor_CXXTypeidExpr = 129,
2061+
CXCursor_CXXTypeidExpr = 130,
20582062

20592063
/** [C++ 2.13.5] C++ Boolean Literal.
20602064
*/
2061-
CXCursor_CXXBoolLiteralExpr = 130,
2065+
CXCursor_CXXBoolLiteralExpr = 131,
20622066

20632067
/** [C++0x 2.14.7] C++ Pointer Literal.
20642068
*/
2065-
CXCursor_CXXNullPtrLiteralExpr = 131,
2069+
CXCursor_CXXNullPtrLiteralExpr = 132,
20662070

20672071
/** Represents the "this" expression in C++
20682072
*/
2069-
CXCursor_CXXThisExpr = 132,
2073+
CXCursor_CXXThisExpr = 133,
20702074

20712075
/** [C++ 15] C++ Throw Expression.
20722076
*
20732077
* This handles 'throw' and 'throw' assignment-expression. When
20742078
* assignment-expression isn't present, Op will be null.
20752079
*/
2076-
CXCursor_CXXThrowExpr = 133,
2080+
CXCursor_CXXThrowExpr = 134,
20772081

20782082
/** A new expression for memory allocation and constructor calls, e.g:
20792083
* "new CXXNewExpr(foo)".
20802084
*/
2081-
CXCursor_CXXNewExpr = 134,
2085+
CXCursor_CXXNewExpr = 135,
20822086

20832087
/** A delete expression for memory deallocation and destructor calls,
20842088
* e.g. "delete[] pArray".
20852089
*/
2086-
CXCursor_CXXDeleteExpr = 135,
2090+
CXCursor_CXXDeleteExpr = 136,
20872091

20882092
/** A unary expression. (noexcept, sizeof, or other traits)
20892093
*/
2090-
CXCursor_UnaryExpr = 136,
2094+
CXCursor_UnaryExpr = 137,
20912095

20922096
/** An Objective-C string literal i.e. @"foo".
20932097
*/
2094-
CXCursor_ObjCStringLiteral = 137,
2098+
CXCursor_ObjCStringLiteral = 138,
20952099

20962100
/** An Objective-C \@encode expression.
20972101
*/
2098-
CXCursor_ObjCEncodeExpr = 138,
2102+
CXCursor_ObjCEncodeExpr = 139,
20992103

21002104
/** An Objective-C \@selector expression.
21012105
*/
2102-
CXCursor_ObjCSelectorExpr = 139,
2106+
CXCursor_ObjCSelectorExpr = 140,
21032107

21042108
/** An Objective-C \@protocol expression.
21052109
*/
2106-
CXCursor_ObjCProtocolExpr = 140,
2110+
CXCursor_ObjCProtocolExpr = 141,
21072111

21082112
/** An Objective-C "bridged" cast expression, which casts between
21092113
* Objective-C pointers and C pointers, transferring ownership in the process.
@@ -2112,7 +2116,7 @@ enum CXCursorKind {
21122116
* NSString *str = (__bridge_transfer NSString *)CFCreateString();
21132117
* \endcode
21142118
*/
2115-
CXCursor_ObjCBridgedCastExpr = 141,
2119+
CXCursor_ObjCBridgedCastExpr = 142,
21162120

21172121
/** Represents a C++0x pack expansion that produces a sequence of
21182122
* expressions.
@@ -2127,7 +2131,7 @@ enum CXCursorKind {
21272131
* }
21282132
* \endcode
21292133
*/
2130-
CXCursor_PackExpansionExpr = 142,
2134+
CXCursor_PackExpansionExpr = 143,
21312135

21322136
/** Represents an expression that computes the length of a parameter
21332137
* pack.
@@ -2139,7 +2143,7 @@ enum CXCursorKind {
21392143
* };
21402144
* \endcode
21412145
*/
2142-
CXCursor_SizeOfPackExpr = 143,
2146+
CXCursor_SizeOfPackExpr = 144,
21432147

21442148
/* Represents a C++ lambda expression that produces a local function
21452149
* object.
@@ -2153,37 +2157,37 @@ enum CXCursorKind {
21532157
* }
21542158
* \endcode
21552159
*/
2156-
CXCursor_LambdaExpr = 144,
2160+
CXCursor_LambdaExpr = 145,
21572161

21582162
/** Objective-c Boolean Literal.
21592163
*/
2160-
CXCursor_ObjCBoolLiteralExpr = 145,
2164+
CXCursor_ObjCBoolLiteralExpr = 146,
21612165

21622166
/** Represents the "self" expression in an Objective-C method.
21632167
*/
2164-
CXCursor_ObjCSelfExpr = 146,
2168+
CXCursor_ObjCSelfExpr = 147,
21652169

21662170
/** OpenMP 4.0 [2.4, Array Section].
21672171
*/
2168-
CXCursor_OMPArraySectionExpr = 147,
2172+
CXCursor_OMPArraySectionExpr = 148,
21692173

21702174
/** Represents an @available(...) check.
21712175
*/
2172-
CXCursor_ObjCAvailabilityCheckExpr = 148,
2176+
CXCursor_ObjCAvailabilityCheckExpr = 149,
21732177

21742178
/**
21752179
* Fixed point literal
21762180
*/
2177-
CXCursor_FixedPointLiteral = 149,
2181+
CXCursor_FixedPointLiteral = 150,
21782182

21792183
/** OpenMP 5.0 [2.1.4, Array Shaping].
21802184
*/
2181-
CXCursor_OMPArrayShapingExpr = 150,
2185+
CXCursor_OMPArrayShapingExpr = 151,
21822186

21832187
/**
21842188
* OpenMP 5.0 [2.1.6 Iterators]
21852189
*/
2186-
CXCursor_OMPIteratorExpr = 151,
2190+
CXCursor_OMPIteratorExpr = 152,
21872191

21882192
CXCursor_LastExpr = CXCursor_OMPIteratorExpr,
21892193

clang/include/clang/AST/ExprCXX.h

+38-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,8 @@ class CXXRewrittenBinaryOperator : public Expr {
366366
/// This abstract class is inherited by all of the classes
367367
/// representing "named" casts: CXXStaticCastExpr for \c static_cast,
368368
/// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for
369-
/// reinterpret_cast, and CXXConstCastExpr for \c const_cast.
369+
/// reinterpret_cast, CXXConstCastExpr for \c const_cast and
370+
/// CXXAddrspaceCastExpr for addrspace_cast (in OpenCL).
370371
class CXXNamedCastExpr : public ExplicitCastExpr {
371372
private:
372373
// the location of the casting op
@@ -412,6 +413,7 @@ class CXXNamedCastExpr : public ExplicitCastExpr {
412413
case CXXDynamicCastExprClass:
413414
case CXXReinterpretCastExprClass:
414415
case CXXConstCastExprClass:
416+
case CXXAddrspaceCastExprClass:
415417
return true;
416418
default:
417419
return false;
@@ -569,6 +571,41 @@ class CXXConstCastExpr final
569571
}
570572
};
571573

574+
/// A C++ addrspace_cast expression (currently only enabled for OpenCL).
575+
///
576+
/// This expression node represents a cast between pointers to objects in
577+
/// different address spaces e.g.,
578+
/// \c addrspace_cast<global int*>(PtrToGenericInt).
579+
///
580+
/// A addrspace_cast can cast address space type qualifiers but does not change
581+
/// the underlying value.
582+
class CXXAddrspaceCastExpr final
583+
: public CXXNamedCastExpr,
584+
private llvm::TrailingObjects<CXXAddrspaceCastExpr, CXXBaseSpecifier *> {
585+
CXXAddrspaceCastExpr(QualType ty, ExprValueKind VK, CastKind Kind, Expr *op,
586+
TypeSourceInfo *writtenTy, SourceLocation l,
587+
SourceLocation RParenLoc, SourceRange AngleBrackets)
588+
: CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0,
589+
writtenTy, l, RParenLoc, AngleBrackets) {}
590+
591+
explicit CXXAddrspaceCastExpr(EmptyShell Empty)
592+
: CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0) {}
593+
594+
public:
595+
friend class CastExpr;
596+
friend TrailingObjects;
597+
598+
static CXXAddrspaceCastExpr *
599+
Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind,
600+
Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L,
601+
SourceLocation RParenLoc, SourceRange AngleBrackets);
602+
static CXXAddrspaceCastExpr *CreateEmpty(const ASTContext &Context);
603+
604+
static bool classof(const Stmt *T) {
605+
return T->getStmtClass() == CXXAddrspaceCastExprClass;
606+
}
607+
};
608+
572609
/// A call to a literal operator (C++11 [over.literal])
573610
/// written as a user-defined literal (C++11 [lit.ext]).
574611
///

clang/include/clang/AST/RecursiveASTVisitor.h

+4
Original file line numberDiff line numberDiff line change
@@ -2355,6 +2355,10 @@ DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
23552355
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
23562356
})
23572357

2358+
DEF_TRAVERSE_STMT(CXXAddrspaceCastExpr, {
2359+
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2360+
})
2361+
23582362
DEF_TRAVERSE_STMT(CXXConstCastExpr, {
23592363
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
23602364
})

clang/include/clang/Basic/DiagnosticParseKinds.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ def err_friend_decl_defines_type : Error<
833833
"cannot define a type in a friend declaration">;
834834
def err_missing_whitespace_digraph : Error<
835835
"found '<::' after a "
836-
"%select{template name|const_cast|dynamic_cast|reinterpret_cast|static_cast}0"
836+
"%select{template name|addrspace_cast|const_cast|dynamic_cast|reinterpret_cast|static_cast}0"
837837
" which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?">;
838838

839839
def ext_defaulted_deleted_function : ExtWarn<

clang/include/clang/Basic/DiagnosticSemaKinds.td

+17-17
Original file line numberDiff line numberDiff line change
@@ -4221,13 +4221,13 @@ def err_ovl_no_conversion_in_cast : Error<
42214221
"cannot convert %1 to %2 without a conversion operator">;
42224222
def err_ovl_no_viable_conversion_in_cast : Error<
42234223
"no matching conversion for %select{|static_cast|reinterpret_cast|"
4224-
"dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2">;
4224+
"dynamic_cast|C-style cast|functional-style cast|}0 from %1 to %2">;
42254225
def err_ovl_ambiguous_conversion_in_cast : Error<
42264226
"ambiguous conversion for %select{|static_cast|reinterpret_cast|"
4227-
"dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2">;
4227+
"dynamic_cast|C-style cast|functional-style cast|}0 from %1 to %2">;
42284228
def err_ovl_deleted_conversion_in_cast : Error<
42294229
"%select{|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
4230-
"functional-style cast}0 from %1 to %2 uses deleted function">;
4230+
"functional-style cast|}0 from %1 to %2 uses deleted function">;
42314231
def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;
42324232
def err_ref_init_ambiguous : Error<
42334233
"reference initialization of type %0 with initializer of type %1 is ambiguous">;
@@ -6843,34 +6843,34 @@ def err_bad_cstyle_cast_overload : Error<
68436843

68446844

68456845
def err_bad_cxx_cast_generic : Error<
6846-
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
6847-
"functional-style cast}0 from %1 to %2 is not allowed">;
6846+
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|"
6847+
"C-style cast|functional-style cast|addrspace_cast}0 from %1 to %2 is not allowed">;
68486848
def err_bad_cxx_cast_unrelated_class : Error<
68496849
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
6850-
"functional-style cast}0 from %1 to %2, which are not related by "
6850+
"functional-style cast|}0 from %1 to %2, which are not related by "
68516851
"inheritance, is not allowed">;
68526852
def note_type_incomplete : Note<"%0 is incomplete">;
68536853
def err_bad_cxx_cast_rvalue : Error<
68546854
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
6855-
"functional-style cast}0 from rvalue to reference type %2">;
6855+
"functional-style cast|addrspace_cast}0 from rvalue to reference type %2">;
68566856
def err_bad_cxx_cast_bitfield : Error<
68576857
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
6858-
"functional-style cast}0 from bit-field lvalue to reference type %2">;
6858+
"functional-style cast|}0 from bit-field lvalue to reference type %2">;
68596859
def err_bad_cxx_cast_qualifiers_away : Error<
68606860
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
6861-
"functional-style cast}0 from %1 to %2 casts away qualifiers">;
6861+
"functional-style cast|}0 from %1 to %2 casts away qualifiers">;
68626862
def err_bad_cxx_cast_addr_space_mismatch : Error<
6863-
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
6864-
"functional-style cast}0 from %1 to %2 converts between mismatching address"
6863+
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|"
6864+
"C-style cast|functional-style cast|addrspace_cast}0 from %1 to %2 converts between mismatching address"
68656865
" spaces">;
68666866
def ext_bad_cxx_cast_qualifiers_away_incoherent : ExtWarn<
68676867
"ISO C++ does not allow "
68686868
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
6869-
"functional-style cast}0 from %1 to %2 because it casts away qualifiers, "
6869+
"functional-style cast|}0 from %1 to %2 because it casts away qualifiers, "
68706870
"even though the source and destination types are unrelated">,
68716871
SFINAEFailure, InGroup<DiagGroup<"cast-qual-unrelated">>;
68726872
def err_bad_const_cast_dest : Error<
6873-
"%select{const_cast||||C-style cast|functional-style cast}0 to %2, "
6873+
"%select{const_cast||||C-style cast|functional-style cast|}0 to %2, "
68746874
"which is not a reference, pointer-to-object, or pointer-to-data-member">;
68756875
def ext_cast_fn_obj : Extension<
68766876
"cast between pointer-to-function and pointer-to-object is an extension">;
@@ -6883,13 +6883,13 @@ def warn_cxx98_compat_cast_fn_obj : Warning<
68836883
def err_bad_reinterpret_cast_small_int : Error<
68846884
"cast from pointer to smaller type %2 loses information">;
68856885
def err_bad_cxx_cast_vector_to_scalar_different_size : Error<
6886-
"%select{||reinterpret_cast||C-style cast|}0 from vector %1 "
6886+
"%select{||reinterpret_cast||C-style cast||}0 from vector %1 "
68876887
"to scalar %2 of different size">;
68886888
def err_bad_cxx_cast_scalar_to_vector_different_size : Error<
6889-
"%select{||reinterpret_cast||C-style cast|}0 from scalar %1 "
6889+
"%select{||reinterpret_cast||C-style cast||}0 from scalar %1 "
68906890
"to vector %2 of different size">;
68916891
def err_bad_cxx_cast_vector_to_vector_different_size : Error<
6892-
"%select{||reinterpret_cast||C-style cast|}0 from vector %1 "
6892+
"%select{||reinterpret_cast||C-style cast||}0 from vector %1 "
68936893
"to vector %2 of different size">;
68946894
def warn_bad_cxx_cast_nested_pointer_addr_space : Warning<
68956895
"%select{reinterpret_cast|C-style cast}0 from %1 to %2 "
@@ -6906,7 +6906,7 @@ def err_bad_static_cast_pointer_nonpointer : Error<
69066906
def err_bad_static_cast_member_pointer_nonmp : Error<
69076907
"cannot cast from type %1 to member pointer type %2">;
69086908
def err_bad_cxx_cast_member_pointer_size : Error<
6909-
"cannot %select{||reinterpret_cast||C-style cast|}0 from member pointer "
6909+
"cannot %select{||reinterpret_cast||C-style cast||}0 from member pointer "
69106910
"type %1 to member pointer type %2 of different size">;
69116911
def err_bad_reinterpret_cast_reference : Error<
69126912
"reinterpret_cast of a %0 to %1 needs its address, which is not allowed">;

clang/include/clang/Basic/StmtNodes.td

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ def CXXStaticCastExpr : StmtNode<CXXNamedCastExpr>;
120120
def CXXDynamicCastExpr : StmtNode<CXXNamedCastExpr>;
121121
def CXXReinterpretCastExpr : StmtNode<CXXNamedCastExpr>;
122122
def CXXConstCastExpr : StmtNode<CXXNamedCastExpr>;
123+
def CXXAddrspaceCastExpr : StmtNode<CXXNamedCastExpr>;
123124
def CXXFunctionalCastExpr : StmtNode<ExplicitCastExpr>;
124125
def CXXTypeidExpr : StmtNode<Expr>;
125126
def UserDefinedLiteral : StmtNode<CallExpr>;

clang/include/clang/Basic/TokenKinds.def

+3-2
Original file line numberDiff line numberDiff line change
@@ -574,12 +574,13 @@ KEYWORD(__builtin_astype , KEYOPENCLC | KEYOPENCLCXX)
574574
KEYWORD(vec_step , KEYOPENCLC | KEYALTIVEC | KEYZVECTOR)
575575
#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX)
576576
#include "clang/Basic/OpenCLImageTypes.def"
577+
KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX)
578+
// C++ for OpenCL s2.3.1: addrspace_cast operator
579+
KEYWORD(addrspace_cast , KEYOPENCLCXX)
577580

578581
// OpenMP Type Traits
579582
KEYWORD(__builtin_omp_required_simd_align, KEYALL)
580583

581-
KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX)
582-
583584
// Borland Extensions.
584585
KEYWORD(__pascal , KEYALL)
585586

clang/include/clang/Sema/Sema.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -5710,7 +5710,8 @@ class Sema final {
57105710
void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
57115711
bool IsDereference, SourceRange Range);
57125712

5713-
/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
5713+
/// ActOnCXXNamedCast - Parse
5714+
/// {dynamic,static,reinterpret,const,addrspace}_cast's.
57145715
ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
57155716
tok::TokenKind Kind,
57165717
SourceLocation LAngleBracketLoc,

clang/include/clang/Serialization/ASTBitCodes.h

+3
Original file line numberDiff line numberDiff line change
@@ -1791,6 +1791,9 @@ namespace serialization {
17911791
/// A CXXConstCastExpr record.
17921792
EXPR_CXX_CONST_CAST,
17931793

1794+
/// A CXXAddrspaceCastExpr record.
1795+
EXPR_CXX_ADDRSPACE_CAST,
1796+
17941797
/// A CXXFunctionalCastExpr record.
17951798
EXPR_CXX_FUNCTIONAL_CAST,
17961799

clang/lib/AST/Expr.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -1711,12 +1711,13 @@ bool CastExpr::CastConsistency() const {
17111711
auto Ty = getType();
17121712
auto SETy = getSubExpr()->getType();
17131713
assert(getValueKindForType(Ty) == Expr::getValueKindForType(SETy));
1714-
if (isRValue()) {
1714+
if (isRValue() && !Ty->isDependentType() && !SETy->isDependentType()) {
17151715
Ty = Ty->getPointeeType();
17161716
SETy = SETy->getPointeeType();
17171717
}
1718-
assert(!Ty.isNull() && !SETy.isNull() &&
1719-
Ty.getAddressSpace() != SETy.getAddressSpace());
1718+
assert((Ty->isDependentType() || SETy->isDependentType()) ||
1719+
(!Ty.isNull() && !SETy.isNull() &&
1720+
Ty.getAddressSpace() != SETy.getAddressSpace()));
17201721
goto CheckNoBasePath;
17211722
}
17221723
// These should not have an inheritance path.
@@ -3205,6 +3206,7 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
32053206
case ObjCBridgedCastExprClass:
32063207
case CXXDynamicCastExprClass:
32073208
case CXXReinterpretCastExprClass:
3209+
case CXXAddrspaceCastExprClass:
32083210
case CXXConstCastExprClass: {
32093211
const CastExpr *CE = cast<CastExpr>(this);
32103212

@@ -3496,6 +3498,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
34963498
case CXXStaticCastExprClass:
34973499
case CXXReinterpretCastExprClass:
34983500
case CXXConstCastExprClass:
3501+
case CXXAddrspaceCastExprClass:
34993502
case CXXFunctionalCastExprClass:
35003503
case BuiltinBitCastExprClass: {
35013504
// While volatile reads are side-effecting in both C and C++, we treat them

0 commit comments

Comments
 (0)