Skip to content
Merged
Show file tree
Hide file tree
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
38 changes: 37 additions & 1 deletion cgen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ def get_decl_pair(self):
class MaybeUnused(NestedDeclarator):
def get_decl_pair(self):
sub_tp, sub_decl = self.subdecl.get_decl_pair()
return sub_tp, ("%s __attribute__ ((unused))" % sub_decl)
return sub_tp, ("(%s __attribute__ ((unused)))" % sub_decl)

mapper_method = "map_maybe_unused"

Expand All @@ -296,6 +296,16 @@ def __init__(self, subdecl):

def get_decl_pair(self):
sub_tp, sub_decl = self.subdecl.get_decl_pair()

if not isinstance(self.subdecl, (Pointer, POD, Value)):
# declarator might "change direction"
# (e.g. include an array declarator)
#
# Note that * binds less strongly than [], so these
# parentheses might not be necessary. Nonetheless,
# we insert them for clarity.
sub_decl = "(%s)" % sub_decl

return sub_tp, ("*%s" % sub_decl)

def struct_maker_code(self, data):
Expand All @@ -313,6 +323,16 @@ def alignment_requirement(self):
class RestrictPointer(Pointer):
def get_decl_pair(self):
sub_tp, sub_decl = self.subdecl.get_decl_pair()

if not isinstance(self.subdecl, (Pointer, POD, Value)):
# declarator might "change direction"
# (e.g. include an array declarator)
#
# Note that * binds less strongly than [], so these
# parentheses might not be necessary. Nonetheless,
# we insert them for clarity.
sub_decl = "(%s)" % sub_decl

return sub_tp, ("*__restrict__ %s" % sub_decl)

mapper_method = "map_restrict_pointer"
Expand All @@ -321,6 +341,16 @@ def get_decl_pair(self):
class Reference(Pointer):
def get_decl_pair(self):
sub_tp, sub_decl = self.subdecl.get_decl_pair()

if not isinstance(self.subdecl, (Pointer, POD, Value)):
# declarator might "change direction"
# (e.g. include an array declarator)
#
# Note that * binds less strongly than [], so these
# parentheses might not be necessary. Nonetheless,
# we insert them for clarity.
sub_decl = "(%s)" % sub_decl

return sub_tp, ("&%s" % sub_decl)

mapper_method = "map_reference"
Expand All @@ -337,6 +367,12 @@ def get_decl_pair(self):
count_str = ""
else:
count_str = str(self.count)

if not isinstance(self.subdecl, (POD, Value, ArrayOf)):
# declarator might "change direction"
# (e.g. include a pointer declarator)
sub_decl = "(%s)" % sub_decl

return sub_tp, ("%s[%s]" % (sub_decl, count_str))

def struct_maker_code(self, name):
Expand Down
20 changes: 19 additions & 1 deletion test/test_cgen.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import sys

from cgen import (
POD, Struct, FunctionBody, FunctionDeclaration,
For, If, Assign, Value, Block, ArrayOf, Comment,
Template)
Template, Pointer)
import numpy as np


Expand Down Expand Up @@ -46,3 +48,19 @@ def test_cgen():
print(s)
print(f_body)
print(t_decl)


def test_ptr_to_array():
t1 = Pointer(ArrayOf(Pointer(POD(np.float32, "xxx")), 2))
assert str(t1) == "float *((*xxx)[2]);"

t2 = Pointer(Pointer(ArrayOf(POD(np.float32, "yyy"), 2)))
assert str(t2) == "float **(yyy[2]);"


if __name__ == "__main__":
if len(sys.argv) > 1:
exec(sys.argv[1])
else:
from pytest import main
main([__file__])