Skip to content

[SYCL] Add __builtin_num_fields and __builtin_field_type #3658

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 21 commits into from
Jun 4, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f5aac6b
Add __builtin_num_fields and __builtin_field_type.
AaronBallman Apr 29, 2021
0dfbb52
Add a test with bit-fields and anonymous bit-fields.
AaronBallman Apr 29, 2021
ca49643
Adding some missed bits for AST serialization.
AaronBallman Apr 29, 2021
a5771bc
Add a test that we can peer into an anonymous structure.
AaronBallman Apr 29, 2021
f80f305
Calculate the number of fields on the fly.
AaronBallman Apr 29, 2021
93c3ab6
Test for diagnostics more eagerly.
AaronBallman Apr 29, 2021
4f0ff13
Only rebuild during template instantiation if something changed.
AaronBallman Apr 29, 2021
5ec92c6
Disallow __builtin_field_type in an evaluated context.
AaronBallman Apr 29, 2021
d736e22
Add __builtin_num_bases and __builtin_base_type.
AaronBallman Apr 29, 2021
9f887d0
Add a test case for generic lambdas.
AaronBallman Apr 29, 2021
764bd2e
Fixing the formatting issues that are reasonable to fix.
AaronBallman Apr 29, 2021
60c6cf6
Fixing minor nits from the review.
AaronBallman Apr 30, 2021
82d9b57
Stop storing the field/base type.
AaronBallman Apr 30, 2021
fd6fb4b
Merge remote-tracking branch 'upstream/sycl' into sycl-builtin-fields
AaronBallman May 7, 2021
5df2a5b
Disable the kernel copyability checks from the FE.
AaronBallman May 7, 2021
9ff44d6
Merge remote-tracking branch 'upstream/sycl' into sycl-builtin-fields
AaronBallman May 26, 2021
4400173
Revert "Disable the kernel copyability checks from the FE."
AaronBallman May 26, 2021
3e10467
Updating based on review feedback.
AaronBallman Jun 2, 2021
ffe4032
Merge remote-tracking branch 'upstream/sycl' into sycl-builtin-fields
AaronBallman Jun 2, 2021
510357d
Diagnose a negative index
AaronBallman Jun 2, 2021
3827ebc
Merge remote-tracking branch 'upstream/sycl' into sycl-builtin-fields
AaronBallman Jun 4, 2021
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
9 changes: 9 additions & 0 deletions clang/include/clang/AST/ComputeDependence.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ class ObjCSubscriptRefExpr;
class ObjCIsaExpr;
class ObjCIndirectCopyRestoreExpr;
class ObjCMessageExpr;
class SYCLBuiltinNumFieldsExpr;
class SYCLBuiltinNumBasesExpr;
class SYCLBuiltinFieldTypeExpr;
class SYCLBuiltinBaseTypeExpr;

// The following functions are called from constructors of `Expr`, so they
// should not access anything beyond basic
Expand Down Expand Up @@ -192,5 +196,10 @@ ExprDependence computeDependence(ObjCIsaExpr *E);
ExprDependence computeDependence(ObjCIndirectCopyRestoreExpr *E);
ExprDependence computeDependence(ObjCMessageExpr *E);

ExprDependence computeDependence(SYCLBuiltinNumFieldsExpr *E);
ExprDependence computeDependence(SYCLBuiltinNumBasesExpr *E);
ExprDependence computeDependence(SYCLBuiltinFieldTypeExpr *E);
ExprDependence computeDependence(SYCLBuiltinBaseTypeExpr *E);

} // namespace clang
#endif
180 changes: 180 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -4902,6 +4902,186 @@ class BuiltinBitCastExpr final
}
};

/// Represents a __builtin_num_fields expression.
class SYCLBuiltinNumFieldsExpr : public Expr {
friend class ASTStmtReader;

SourceLocation Loc;
QualType SourceTy;

public:
SYCLBuiltinNumFieldsExpr(SourceLocation Loc, QualType SourceTy,
QualType RetTy)
: Expr(SYCLBuiltinNumFieldsExprClass, RetTy, VK_RValue, OK_Ordinary),
Loc(Loc), SourceTy(SourceTy) {
setDependence(computeDependence(this));
}

explicit SYCLBuiltinNumFieldsExpr(EmptyShell Empty)
: Expr(SYCLBuiltinNumFieldsExprClass, Empty) {}

QualType getSourceType() const { return SourceTy; }
unsigned getNumFields() const {
assert(!SourceTy->isDependentType());
assert(SourceTy->isRecordType());
const auto *RD = SourceTy->getAsRecordDecl();
assert(RD);
return static_cast<unsigned>(
std::distance(RD->field_begin(), RD->field_end()));
}

SourceLocation getBeginLoc() const { return Loc; }
SourceLocation getEndLoc() const { return Loc; }

SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }

child_range children() {
return child_range(child_iterator(), child_iterator());
}

const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}

static bool classof(const Stmt *T) {
return T->getStmtClass() == SYCLBuiltinNumFieldsExprClass;
}
};

/// Represents a __builtin_field_type expression. This does not actually return
/// the type itself (it would need to be a new type in the type system rather
/// than an expression to do that), but instead is a valueless expression of
/// the field's type. The expected usage is to use decltype to extract the
/// actual type information. This expression can only be used in an unevaluated
/// context.
class SYCLBuiltinFieldTypeExpr : public Expr {
friend class ASTStmtReader;

SourceLocation Loc;
QualType SourceTy;
Stmt *Index;

public:
SYCLBuiltinFieldTypeExpr(SourceLocation Loc, QualType SourceTy, Expr *Index,
QualType FieldTy, ExprValueKind ValueKind)
: Expr(SYCLBuiltinFieldTypeExprClass, FieldTy, ValueKind, OK_Ordinary),
Loc(Loc), SourceTy(SourceTy), Index(Index) {
setDependence(computeDependence(this));
}

explicit SYCLBuiltinFieldTypeExpr(EmptyShell Empty)
: Expr(SYCLBuiltinFieldTypeExprClass, Empty) {}

QualType getSourceType() const { return SourceTy; }

const Expr *getIndex() const { return static_cast<const Expr *>(Index); }
Expr *getIndex() { return static_cast<Expr *>(Index); }

SourceLocation getBeginLoc() const { return Loc; }
SourceLocation getEndLoc() const { return Loc; }

SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }

static bool classof(const Stmt *T) {
return T->getStmtClass() == SYCLBuiltinFieldTypeExprClass;
}

child_range children() { return child_range(&Index, &Index + 1); }

const_child_range children() const {
return const_child_range(&Index, &Index + 1);
}
};

/// Represents a __builtin_num_bases expression.
class SYCLBuiltinNumBasesExpr : public Expr {
friend class ASTStmtReader;

SourceLocation Loc;
QualType SourceTy;

public:
SYCLBuiltinNumBasesExpr(SourceLocation Loc, QualType SourceTy, QualType RetTy)
: Expr(SYCLBuiltinNumBasesExprClass, RetTy, VK_RValue, OK_Ordinary),
Loc(Loc), SourceTy(SourceTy) {
setDependence(computeDependence(this));
}

explicit SYCLBuiltinNumBasesExpr(EmptyShell Empty)
: Expr(SYCLBuiltinNumBasesExprClass, Empty) {}

QualType getSourceType() const { return SourceTy; }
unsigned getNumBases() const {
assert(!SourceTy->isDependentType());
assert(SourceTy->isRecordType());
const auto *RD = SourceTy->getAsCXXRecordDecl();
assert(RD);
return RD->getNumBases();
}

SourceLocation getBeginLoc() const { return Loc; }
SourceLocation getEndLoc() const { return Loc; }

SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }

child_range children() {
return child_range(child_iterator(), child_iterator());
}

const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}

static bool classof(const Stmt *T) {
return T->getStmtClass() == SYCLBuiltinNumBasesExprClass;
}
};

/// Represents a __builtin_base_type expression. This has the same behavior and
/// constraints as __builtin_field_type.
class SYCLBuiltinBaseTypeExpr : public Expr {
friend class ASTStmtReader;

SourceLocation Loc;
QualType SourceTy;
Stmt *Index;

public:
SYCLBuiltinBaseTypeExpr(SourceLocation Loc, QualType SourceTy, Expr *Index,
QualType BaseTy)
: Expr(SYCLBuiltinBaseTypeExprClass, BaseTy, VK_RValue, OK_Ordinary),
Loc(Loc), SourceTy(SourceTy), Index(Index) {
setDependence(computeDependence(this));
}

explicit SYCLBuiltinBaseTypeExpr(EmptyShell Empty)
: Expr(SYCLBuiltinBaseTypeExprClass, Empty) {}

QualType getSourceType() const { return SourceTy; }

const Expr *getIndex() const { return static_cast<const Expr *>(Index); }
Expr *getIndex() { return static_cast<Expr *>(Index); }

SourceLocation getBeginLoc() const { return Loc; }
SourceLocation getEndLoc() const { return Loc; }

SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }

static bool classof(const Stmt *T) {
return T->getStmtClass() == SYCLBuiltinBaseTypeExprClass;
}

child_range children() { return child_range(&Index, &Index + 1); }

const_child_range children() const {
return const_child_range(&Index, &Index + 1);
}
};

} // namespace clang

#endif // LLVM_CLANG_AST_EXPRCXX_H
14 changes: 14 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2359,6 +2359,20 @@ DEF_TRAVERSE_STMT(BuiltinBitCastExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
})

DEF_TRAVERSE_STMT(SYCLBuiltinFieldTypeExpr, {
TRY_TO(TraverseType(S->getSourceType()));
})
DEF_TRAVERSE_STMT(SYCLBuiltinBaseTypeExpr, {
TRY_TO(TraverseType(S->getSourceType()));
})

DEF_TRAVERSE_STMT(SYCLBuiltinNumFieldsExpr, {
TRY_TO(TraverseType(S->getSourceType()));
})
DEF_TRAVERSE_STMT(SYCLBuiltinNumBasesExpr, {
TRY_TO(TraverseType(S->getSourceType()));
})

template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
InitListExpr *S, DataRecursionQueue *Queue) {
Expand Down
15 changes: 15 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -11346,6 +11346,21 @@ def warn_sycl_kernel_too_big_args : Warning<
def err_sycl_virtual_types : Error<
"no class with a vtable can be used in a SYCL kernel or any code included in the kernel">;
def note_sycl_recursive_function_declared_here: Note<"function implemented using recursion declared here">;
def err_sycl_type_trait_requires_complete_type : Error<
"'%select{__builtin_num_fields|__builtin_field_type|__builtin_num_bases|"
"__builtin_base_type}0' requires a complete type">;
def err_sycl_type_trait_requires_record_type : Error<
"'%select{__builtin_num_fields|__builtin_field_type|__builtin_num_bases|"
"__builtin_base_type}0' requires a structure "
"or lambda type">;
def err_sycl_builtin_type_trait_index_out_of_range : Error<
"index %0 is greater than the number of %select{fields|bases}2 in type %1">;
def err_sycl_type_trait_requires_nonnegative_index : Error<
"'%select{__builtin_field_type|__builtin_base_type}0' requires a "
"non-negative index">;
def err_sycl_builtin_type_trait_evaluated : Error<
"'%select{__builtin_field_type|__builtin_base_type}0' cannot be used in an "
"evaluated context">;
def err_sycl_non_trivially_copy_ctor_dtor_type
: Error<"kernel parameter has non-trivially %select{copy "
"constructible|destructible}0 class/struct type %1">;
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/StmtNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ def ObjCBridgedCastExpr : StmtNode<ExplicitCastExpr>;
// CUDA Expressions.
def CUDAKernelCallExpr : StmtNode<CallExpr>;

// SYCL Extensions.
def SYCLBuiltinNumFieldsExpr : StmtNode<Expr>;
def SYCLBuiltinFieldTypeExpr : StmtNode<Expr>;
def SYCLBuiltinNumBasesExpr : StmtNode<Expr>;
def SYCLBuiltinBaseTypeExpr : StmtNode<Expr>;

// Clang Extensions.
def ShuffleVectorExpr : StmtNode<Expr>;
def ConvertVectorExpr : StmtNode<Expr>;
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,12 @@ TYPE_TRAIT_1(__has_unique_object_representations,
HasUniqueObjectRepresentations, KEYCXX)
KEYWORD(__underlying_type , KEYCXX)

// SYCL Type Traits
KEYWORD(__builtin_num_fields, KEYSYCL)
KEYWORD(__builtin_field_type, KEYSYCL)
KEYWORD(__builtin_num_bases, KEYSYCL)
KEYWORD(__builtin_base_type, KEYSYCL)

// Clang-only C++ Type Traits
TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)

Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3460,6 +3460,12 @@ class Parser : public CodeCompletionHandler {
ExprResult ParseArrayTypeTrait();
ExprResult ParseExpressionTrait();

/// SYCL Type Traits
// __builtin_num_fields, __builtin_num_bases
ExprResult ParseSYCLBuiltinNum();
// __builtin_field_type, __builtin_base_type
ExprResult ParseSYCLBuiltinType();

//===--------------------------------------------------------------------===//
// Preprocessor code-completion pass-through
void CodeCompleteDirective(bool InConditional) override;
Expand Down
22 changes: 22 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -13245,6 +13245,28 @@ class Sema final {
void ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc, MangleContext &MC);
void MarkDevices();

/// Get the number of fields or captures within the parsed type.
ExprResult ActOnSYCLBuiltinNumFieldsExpr(ParsedType PT);
ExprResult BuildSYCLBuiltinNumFieldsExpr(SourceLocation Loc,
QualType SourceTy);

/// Get a value based on the type of the given field number so that callers
/// can wrap it in a decltype() to get the actual type of the field.
ExprResult ActOnSYCLBuiltinFieldTypeExpr(ParsedType PT, Expr *Idx);
ExprResult BuildSYCLBuiltinFieldTypeExpr(SourceLocation Loc,
QualType SourceTy, Expr *Idx);

/// Get the number of base classes within the parsed type.
ExprResult ActOnSYCLBuiltinNumBasesExpr(ParsedType PT);
ExprResult BuildSYCLBuiltinNumBasesExpr(SourceLocation Loc,
QualType SourceTy);

/// Get a value based on the type of the given base number so that callers
/// can wrap it in a decltype() to get the actual type of the base class.
ExprResult ActOnSYCLBuiltinBaseTypeExpr(ParsedType PT, Expr *Idx);
ExprResult BuildSYCLBuiltinBaseTypeExpr(SourceLocation Loc, QualType SourceTy,
Expr *Idx);

/// Emit a diagnostic about the given attribute having a deprecated name, and
/// also emit a fixit hint to generate the new attribute name.
void DiagnoseDeprecatedAttribute(const ParsedAttr &A, StringRef NewScope,
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1965,6 +1965,12 @@ enum StmtCode {

// FixedPointLiteral
EXPR_FIXEDPOINT_LITERAL,

// SYCL
EXPR_SYCL_BUILTIN_NUM_FIELDS,
EXPR_SYCL_BUILTIN_FIELD_TYPE,
EXPR_SYCL_BUILTIN_NUM_BASES,
EXPR_SYCL_BUILTIN_BASE_TYPE,
};

/// The kinds of designators that can occur in a
Expand Down
24 changes: 24 additions & 0 deletions clang/lib/AST/ComputeDependence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,3 +842,27 @@ ExprDependence clang::computeDependence(ObjCMessageExpr *E) {
D |= A->getDependence();
return D;
}

ExprDependence clang::computeDependence(SYCLBuiltinNumFieldsExpr *E) {
return toExprDependence(E->getSourceType()->getDependence()) &
~ExprDependence::Type;
}

ExprDependence clang::computeDependence(SYCLBuiltinNumBasesExpr *E) {
return toExprDependence(E->getSourceType()->getDependence()) &
~ExprDependence::Type;
}

ExprDependence clang::computeDependence(SYCLBuiltinFieldTypeExpr *E) {
auto D = toExprDependence(E->getSourceType()->getDependence()) &
~ExprDependence::Type;
D |= E->getIndex()->getDependence();
return D;
}

ExprDependence clang::computeDependence(SYCLBuiltinBaseTypeExpr *E) {
auto D = toExprDependence(E->getSourceType()->getDependence()) &
~ExprDependence::Type;
D |= E->getIndex()->getDependence();
return D;
}
4 changes: 4 additions & 0 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3454,6 +3454,10 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case SourceLocExprClass:
case ConceptSpecializationExprClass:
case RequiresExprClass:
case SYCLBuiltinNumFieldsExprClass:
case SYCLBuiltinFieldTypeExprClass:
case SYCLBuiltinNumBasesExprClass:
case SYCLBuiltinBaseTypeExprClass:
// These never have a side-effect.
return false;

Expand Down
4 changes: 4 additions & 0 deletions clang/lib/AST/ExprClassification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::SourceLocExprClass:
case Expr::ConceptSpecializationExprClass:
case Expr::RequiresExprClass:
case Expr::SYCLBuiltinNumFieldsExprClass:
case Expr::SYCLBuiltinFieldTypeExprClass:
case Expr::SYCLBuiltinNumBasesExprClass:
case Expr::SYCLBuiltinBaseTypeExprClass:
return Cl::CL_PRValue;

case Expr::ConstantExprClass:
Expand Down
Loading