aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2020-04-12 12:19:13 -0500
committerGanesh Viswanathan <dev@genotrance.com>2020-04-12 12:19:13 -0500
commit9cd39600d43c90045b0da6873900881449e6d609 (patch)
tree9fd20983dd390b2177b8d471440521a43d17975d
parentecee58342ee53296eae98fcf4038e6f999b416a5 (diff)
downloadnimterop-9cd39600d43c90045b0da6873900881449e6d609.tar.gz
nimterop-9cd39600d43c90045b0da6873900881449e6d609.zip
Partly fix issue #183, lineTrace:on
-rw-r--r--config.nims1
-rw-r--r--nimterop/ast2.nim159
-rw-r--r--tests/include/tast2.h13
-rw-r--r--tests/tast2.nim7
4 files changed, 108 insertions, 72 deletions
diff --git a/config.nims b/config.nims
index 7e7a6e1..6b475de 100644
--- a/config.nims
+++ b/config.nims
@@ -10,6 +10,7 @@ when defined(Windows):
# Retain stackTrace for clear errors
switch("stackTrace", "on")
+switch("lineTrace", "on")
# Path to compiler
switch("path", "$nim")
diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim
index 7bb4520..ed7c2a9 100644
--- a/nimterop/ast2.nim
+++ b/nimterop/ast2.nim
@@ -495,7 +495,7 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode = nil): PNo
proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode
proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode
-proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode =
+iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode =
# Create nkIdentDefs tree for specified proc parameter or object field
#
# For proc, param should not be exported
@@ -520,8 +520,13 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn
# typ,
# nkEmpty()
# )
- result = newNode(nkIdentDefs)
-
+ #
+ # Iterator since structs can have multiple comma separated fields for the
+ # same type so can yield multiple results.
+ #
+ # struct ABC { int w, h; };
+ #
+ # This is not applicable for procs.
let
start = getStartAtom(node)
@@ -533,6 +538,9 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn
# Only for proc with no named param - create a param name based on offset
#
# int func(char, int);
+ var
+ result = newNode(nkIdentDefs)
+
if tname != "object":
let
pname = "a" & $(offset+1)
@@ -543,77 +551,88 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn
else:
# int func(void)
result = nil
+
+ yield result
else:
- let
- fdecl = node[start+1].firstChildInTree("function_declarator")
- afdecl = node[start+1].firstChildInTree("abstract_function_declarator")
- adecl = node[start+1].firstChildInTree("array_declarator")
- abst = node[start+1].getName() == "abstract_pointer_declarator"
- if fdecl.isNil and afdecl.isNil and adecl.isNil:
- if abst:
- # Only for proc with no named param with pointer type
+ for i in start+1 ..< node.len:
+ if node[i].getName() == "bitfield_clause":
+ continue
+
+ var
+ result = newNode(nkIdentDefs)
+
+ let
+ fdecl = node[i].firstChildInTree("function_declarator")
+ afdecl = node[i].firstChildInTree("abstract_function_declarator")
+ adecl = node[i].firstChildInTree("array_declarator")
+ abst = node[i].getName() == "abstract_pointer_declarator"
+ if fdecl.isNil and afdecl.isNil and adecl.isNil:
+ if abst:
+ # Only for proc with no named param with pointer type
+ # Create a param name based on offset
+ #
+ # int func(char *, int **);
+ let
+ pname = "a" & $(offset+1)
+ pident = nimState.getIdent(pname, tinfo, exported)
+ acount = node[i].getXCount("abstract_pointer_declarator")
+ result.add pident
+ result.add nimState.newPtrTree(acount, tident)
+ result.add newNode(nkEmpty)
+ else:
+ # Named param, simple type
+ let
+ (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name)
+ pident = nimState.getIdent(pname, pinfo, exported)
+
+ # Bitfield support - typedef struct { int field: 1; };
+ prident =
+ if node.len > i and node[i + 1].getName() == "bitfield_clause":
+ nimState.newPragmaExpr(node, pident, "bitsize",
+ newIntNode(nkIntLit, parseInt(nimState.getNodeVal(node[i + 1].getAtom()))))
+ else:
+ pident
+
+ count = node[i].getPtrCount()
+
+ result.add prident
+ if count > 0:
+ result.add nimState.newPtrTree(count, tident)
+ else:
+ result.add tident
+ result.add newNode(nkEmpty)
+ elif not fdecl.isNil:
+ # Named param, function pointer
+ let
+ (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name)
+ pident = nimState.getIdent(pname, pinfo, exported)
+ result.add pident
+ result.add nimState.getTypeProc(name, node[i], node[start])
+ result.add newNode(nkEmpty)
+ elif not afdecl.isNil:
+ # Only for proc with no named param with function pointer type
# Create a param name based on offset
#
- # int func(char *, int **);
+ # int func(int (*)(int *));
let
pname = "a" & $(offset+1)
pident = nimState.getIdent(pname, tinfo, exported)
- acount = node[start+1].getXCount("abstract_pointer_declarator")
+ procTy = nimState.getTypeProc(name, node[i], node[start])
result.add pident
- result.add nimState.newPtrTree(acount, tident)
+ result.add procTy
result.add newNode(nkEmpty)
- else:
- # Named param, simple type
+ elif not adecl.isNil:
+ # Named param, array type
let
- (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name)
+ (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name)
pident = nimState.getIdent(pname, pinfo, exported)
-
- # Bitfield support - typedef struct { int field: 1; };
- prident =
- if node.len > start+1 and node[start+2].getName() == "bitfield_clause":
- nimState.newPragmaExpr(node, pident, "bitsize",
- newIntNode(nkIntLit, parseInt(nimState.getNodeVal(node[start+2].getAtom()))))
- else:
- pident
-
- count = node[start+1].getPtrCount()
-
- result.add prident
- if count > 0:
- result.add nimState.newPtrTree(count, tident)
- else:
- result.add tident
+ result.add pident
+ result.add nimState.getTypeArray(node[i], node[start], name)
result.add newNode(nkEmpty)
- elif not fdecl.isNil:
- # Named param, function pointer
- let
- (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name)
- pident = nimState.getIdent(pname, pinfo, exported)
- result.add pident
- result.add nimState.getTypeProc(name, node[start+1], node[start])
- result.add newNode(nkEmpty)
- elif not afdecl.isNil:
- # Only for proc with no named param with function pointer type
- # Create a param name based on offset
- #
- # int func(int (*)(int *));
- let
- pname = "a" & $(offset+1)
- pident = nimState.getIdent(pname, tinfo, exported)
- procTy = nimState.getTypeProc(name, node[start+1], node[start])
- result.add pident
- result.add procTy
- result.add newNode(nkEmpty)
- elif not adecl.isNil:
- # Named param, array type
- let
- (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name)
- pident = nimState.getIdent(pname, pinfo, exported)
- result.add pident
- result.add nimState.getTypeArray(node[start+1], node[start], name)
- result.add newNode(nkEmpty)
- else:
- result = nil
+ else:
+ result = nil
+
+ yield result
proc newFormalParams(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode =
# Create nkFormalParams tree for specified params and return type
@@ -635,10 +654,9 @@ proc newFormalParams(nimState: NimState, name: string, node: TSNode, rtyp: PNode
for i in 0 ..< node.len:
if node[i].getName() == "parameter_declaration":
# Add nkIdentDefs for each param
- let
- param = nimState.newIdentDefs(name, node[i], i, exported = false)
- if not param.isNil:
- result.add param
+ for param in nimState.newIdentDefs(name, node[i], i, exported = false):
+ if not param.isNil:
+ result.add param
proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode =
# Create nkProcTy tree for specified proc type
@@ -674,10 +692,9 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode =
for i in 0 ..< node.len:
if node[i].getName() == "field_declaration":
# Add nkIdentDefs for each field
- let
- field = nimState.newIdentDefs(name, node[i], i, exported = true)
- if not field.isNil:
- result.add field
+ for field in nimState.newIdentDefs(name, node[i], i, exported = true):
+ if not field.isNil:
+ result.add field
proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) =
# Add a type of object
diff --git a/tests/include/tast2.h b/tests/include/tast2.h
index f4cd201..4854eb7 100644
--- a/tests/include/tast2.h
+++ b/tests/include/tast2.h
@@ -155,6 +155,12 @@ typedef struct {
int flags;
} BASS_DEVICEINFO;
+// Issue #183
+struct GPU_Target
+{
+ int w, *h;
+ char *x, y, **z;
+};
@@ -305,6 +311,13 @@ typedef struct {
int flags;
} BASS_DEVICEINFO;
+// Issue #183
+struct GPU_Target
+{
+ int w, *h;
+ char *x, y, **z;
+};
+
#endif
diff --git a/tests/tast2.nim b/tests/tast2.nim
index a88c29e..de0e743 100644
--- a/tests/tast2.nim
+++ b/tests/tast2.nim
@@ -356,4 +356,9 @@ assert func2 is proc (f1: cint; sfunc2: proc (f1: cint; ssfunc2: proc (f1: cint)
assert BASS_DEVICEINFO is object
testFields(BASS_DEVICEINFO, "name|driver|flags!cstring|cstring|cint")
-checkPragmas(BASS_DEVICEINFO, pHeaderImpBy) \ No newline at end of file
+checkPragmas(BASS_DEVICEINFO, pHeaderImpBy)
+
+# Issue #183
+assert GPU_Target is object
+testFields(GPU_Target, "w|h|x|y|z!cint|ptr cint|cstring|cchar|ptr cstring")
+checkPragmas(GPU_Target, pHeaderBy, istype = false) \ No newline at end of file