Skip to content

Commit

Permalink
Automatically register hyperobject struct members in C++
Browse files Browse the repository at this point in the history
  • Loading branch information
VoxSciurorum committed Dec 30, 2023
1 parent a5c8b8e commit cbf8108
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 22 deletions.
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -10593,8 +10593,8 @@ def incomplete_hyperobject : Error<
def nested_hyperobject : Error<
"type %0, which contains a hyperobject, may not be a hyperobject">;

def reducer_callbacks_not_allowed: Warning<
"reducer callbacks not implemented for structure members">,
def reducer_registration_not_implemented: Warning<
"reducer registration not implemented for structure members">,
InGroup<CilkIgnored>;

def err_invalid_reducer_callback : Error<
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/AST/DeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,12 @@ void CXXRecordDecl::addedMember(Decl *D) {
data().DefaultedCopyConstructorIsDeleted = true;
}

if (T->isHyperobjectType()) {
data().HasIrrelevantDestructor = false;
data().HasTrivialSpecialMembers &= ~SMF_Destructor;
data().HasTrivialSpecialMembersForCall &= ~SMF_Destructor;
}

if (!Field->hasInClassInitializer() && !Field->isMutable()) {
if (CXXRecordDecl *FieldType = T->getAsCXXRecordDecl()) {
if (FieldType->hasDefinition() && !FieldType->allowConstDefaultInit())
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18621,11 +18621,12 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
continue;
}

if (!FDTy->isDependentType()) {
// In C++ a constructor and destructor will be synthesized
// to register hyperobjects.
if (!CXXRecord && !FDTy->isDependentType()) {
if (const HyperobjectType *HT = FDTy->getAs<HyperobjectType>()) {
if (HT->hasCallbacks())
Diag(FD->getLocation(), diag::reducer_callbacks_not_allowed)
<< FD->getDeclName();
Diag(FD->getLocation(), diag::reducer_registration_not_implemented)
<< FD->getDeclName();
}
}

Expand Down
11 changes: 1 addition & 10 deletions clang/test/Cilk/222.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
// RUN: %clang_cc1 %s -x c++ -fopencilk -emit-llvm -verify -mllvm -use-opencilk-runtime-bc=false -mllvm -debug-abi-calls -o /dev/null
// expected-no-diagnostics
#define DEPTH 3
template<int N> struct R {
static void identity(void *);
static void reduce(void *, void *);
int get(int depth) { return depth <= 0 ? i : field.get(depth - 1); }
public:
R<N - 1> field;
// expected-note@-1{{in instantiation}}
// expected-note@-2{{in instantiation}}
// expected-note@-3{{in instantiation}}
int _Hyperobject(identity, reduce) i;
// expected-warning@-1{{reducer callbacks not implemented for structure members}}
// expected-warning@-2{{reducer callbacks not implemented for structure members}}
// expected-warning@-3{{reducer callbacks not implemented for structure members}}
};

template<> struct R<0> { int field; int get(int) { return field; } };

extern R<DEPTH> r;

int f() { return r.get(DEPTH / 2); }
// expected-note@-1{{in instantiation}}
// expected-note@-2{{in instantiation}}
// expected-note@-3{{in instantiation}}

4 changes: 2 additions & 2 deletions clang/test/Cilk/hyper-errors.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -fopencilk -verify -fsyntax-only -Werror=incompatible-function-pointer-types -Werror=int-conversion
// RUN: %clang_cc1 %s -x c++ -fopencilk -verify -fsyntax-only
struct C { int _Hyperobject c; };
// expected-warning@-1{{reducer registration not implemented for structure members}}
struct C _Hyperobject c; // expected-error{{type 'struct C', which contains a hyperobject, may not be a hyperobject}}
long _Hyperobject d; // expected-note{{previous definition}}
void f() {
Expand All @@ -17,7 +17,7 @@ extern void reduce(void *, void *), identity(void *);

struct D {
int _Hyperobject(identity, reduce) field;
// expected-warning@-1{{reducer callbacks not implemented for structure members}}
// expected-warning@-1{{reducer registration not implemented for structure members}}
};

int _Hyperobject(reduce, identity) h;
Expand Down
38 changes: 38 additions & 0 deletions clang/test/Cilk/hyper-errors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// RUN: %clang_cc1 %s -x c++ -fopencilk -verify -fsyntax-only
struct C { int _Hyperobject c; };
struct C _Hyperobject c; // expected-error{{type 'struct C', which contains a hyperobject, may not be a hyperobject}}
long _Hyperobject d; // expected-note{{previous definition}}
void f() {
extern int _Hyperobject d;
// expected-error@-1{{redeclaration of 'd' with a different type: 'int _Hyperobject' vs 'long _Hyperobject'}}
}
char _Hyperobject e; // expected-note{{previous definition}}
typedef long _Hyperobject long_h;
void g() {
extern long_h e; // expected-error{{redeclaration of 'e'}}
}

extern void reduce(void *, void *), identity(void *);

struct D {
int _Hyperobject(identity, reduce) field;
};

int _Hyperobject(reduce, identity) h;
// expected-error@-1{{incompatible function pointer types passing 'void (*)(void *, void *)' to parameter of type 'void (*)(void *)'}}
// expected-error@-2{{incompatible function pointer types passing 'void (*)(void *)' to parameter of type 'void (*)(void *, void *)'}}

int _Hyperobject(x) i; // expected-error{{use of undeclared identifier 'x'}}
int _Hyperobject(0) j; // expected-error{{hyperobject must have 0 or 2 callbacks}}
int _Hyperobject(0,0,0,0) k; // expected-error{{hyperobject must have 0 or 2 callbacks}}
int _Hyperobject(0, 1) x; // expected-error{{incompatible integer to pointer conversion passing 'int' to parameter of type 'void (*)(void *, void *)'}}

void function() {
int _Hyperobject(typo1, reduce) var1 = 0;
// expected-error@-1{{use of undeclared identifier 'typo1'}}
int _Hyperobject(typo2, typo3) var2 = 0;
// expected-error@-1{{use of undeclared identifier 'typo2'}}
// expected-error@-2{{use of undeclared identifier 'typo3'}}
int _Hyperobject(0, typo4) var3 = 0;
// expected-error@-1{{use of undeclared identifier 'typo4'}}
}
1 change: 1 addition & 0 deletions clang/test/Cilk/hyper-struct-assign.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 %s -fopencilk -verify -fsyntax-only

struct S { long _Hyperobject field; };
// expected-warning@-1{{reducer registration not implemented for structure members}}
extern struct S x, y;

struct S simple_assign(long val)
Expand Down
6 changes: 2 additions & 4 deletions clang/test/Cilk/hyper-template2.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
// RUN: %clang_cc1 %s -x c++ -fopencilk -verify -S -emit-llvm -disable-llvm-passes -o - | FileCheck %s
// RUN: %clang_cc1 %s -x c++ -fopencilk -S -emit-llvm -disable-llvm-passes -o - | FileCheck %s
template<typename VIEW>
struct reducer
{
static void identity(void *);
static void reduce(void *, void *);
char pad;
// Registration of structure members is not implemented.
VIEW _Hyperobject(identity, reduce) value;
// expected-warning@-1{{reducer callbacks not implemented}}
reducer();
~reducer();
};

// CHECK: call {{.+}} @_ZN7reducerIsEC1Ev
// CHECK: @_ZN7reducerIsED1Ev
reducer<short> r; // expected-note{{in instantiation}}
reducer<short> r;

// CHECK-LABEL: _Z1fv
// CHECK: call ptr @llvm.hyper.lookup
Expand Down

0 comments on commit cbf8108

Please sign in to comment.