Browse Source

Add Support for anonymous enums (having a type but no name)

master
heck 5 years ago
parent
commit
212724f4ee
  1. 2
      examples/lib/lib_synth_shed/synth_shed.c
  2. 2
      examples/lib/lib_synth_shed/synth_shed.h
  3. 2
      examples/lib/lib_test/typedefs.h
  4. 26
      pEpACIDgen/acid_yml.py
  5. 45
      pEpACIDgen/ast_2_acid.py
  6. 10
      pEpACIDgen/c_2_ast.py
  7. 15
      tests/test_pEpACIDgen.py

2
examples/lib/lib_synth_shed/synth_shed.c

@ -39,7 +39,7 @@ SYNTH_STATUS synth_set_osc_count(synth_t* synth, int osc_count) {
//SYNTH_STATUS synth_set_tech(synth_t* synth,
// tech_t tech);
const char* tech_to_string(const tech_t* const tech) {
const char* tech_to_string(const enum _tech* tech) {
assert(tech);
const char* ret = "unknown tech";
if (*tech == ANALOG) {

2
examples/lib/lib_synth_shed/synth_shed.h

@ -51,7 +51,7 @@ SYNTH_STATUS synth_set_osc_count(synth_t* synth, int osc_count);
//SYNTH_STATUS synth_set_tech(synth_t* synth,
// tech_t tech);
const char* tech_to_string(const tech_t* tech);
const char* tech_to_string(const enum _tech* tech);
const char* filtertype_to_string(const filtertype_t* filt);

2
examples/lib/lib_test/typedefs.h

@ -91,7 +91,7 @@ typedef enum E TE;
// TAE = typedef of an alias of an enum
typedef AE TAE;
// T_XE = anonymous without an alias is not a type, and cant be typedef'd
// TAXE = typedef of an anonymous enum
// TAXE = typedef of an anonymous enum alias
typedef AXE TAXE;

26
pEpACIDgen/acid_yml.py

@ -77,9 +77,7 @@ def _generate_structs(acid):
kind_main = "CursorKind.STRUCT_DECL"
def format_func_main(tmpl, item, subitems_str):
return tmpl.format(
name=item["name"],
subitems=subitems_str)
return tmpl.format(name=item["name"], subitems=subitems_str)
# Sub
tmpl_sub = ""
@ -87,9 +85,7 @@ def _generate_structs(acid):
kind_sub = "CursorKind.FIELD_DECL"
def format_func_sub(tmpl, item):
return tmpl.format(
type=item["type"],
name=item["name"])
return tmpl.format(type=item["type"], name=item["name"])
ret = _format(data_root, tmpl_main, kind_main, format_func_main, tmpl_sub, kind_sub, format_func_sub)
@ -108,9 +104,17 @@ def _generate_enums(acid):
kind_main = "CursorKind.ENUM_DECL"
def format_func_main(tmpl, item, subitems_str):
return tmpl.format(
name=item["name"],
subitems=subitems_str)
name = ""
if item["name"]:
name = item["name"]
else:
name = item["type"]
if name == "":
print(__file__," - warning: enum without a name or type extracted")
ret = tmpl.format(name=name, subitems=subitems_str)
return ret
# Sub
tmpl_sub = ""
@ -118,9 +122,7 @@ def _generate_enums(acid):
kind_sub = "CursorKind.ENUM_CONSTANT_DECL"
def format_func_sub(tmpl, item):
return tmpl.format(
name=item["name"],
value=item["value"])
return tmpl.format(name=item["name"], value=item["value"])
ret = _format(data_root, tmpl_main, kind_main, format_func_main, tmpl_sub, kind_sub, format_func_sub)

45
pEpACIDgen/ast_2_acid.py

@ -173,17 +173,15 @@ def _extract_typedef_decl(ast, name):
res = utils.recursive_query(ast, filter)
if res:
ret = res.pop()
if ret["utypekind"] == "Typedef":
ret = _extract_typedef_decl(ast, ret["utype"])
elif ret["utypekind"] == "Elaborated":
enum_decl = _extract_enum_decl(ast, ret["utype"])
struct_decl = _extract_struct_decl(ast, ret["utype"])
if enum_decl and struct_decl:
assert False, "duplicate types"
else:
ret = enum_decl or struct_decl
ress = res.pop()
if ress["utypekind"] == "Typedef" or ress["utypekind"] == "Elaborated":
ret = _extract_enum_decl(ast, ress["utype"])
if not ret:
ret = _extract_struct_decl(ast, ress["utype"])
if not ret:
ret = _extract_typedef_decl(ast, ress["utype"])
else:
ret = ress
return ret
@ -206,16 +204,32 @@ def _find_dup_types(data):
return (all_types, list(dups))
def remove_dup_types(types):
ret = []
for type in types:
dup = False
for i in ret:
if i["type"] == type["type"]:
dup = True
if not dup:
ret.append(type)
return ret
# TODO: Check for primitive type
def _remove_typedefs_of_primitive(types):
types_struct_enum = []
types_removed = []
for type in types:
if (type["kind"] == "CursorKind.TYPEDEF_DECL"):
pass
types_removed.append(type)
else:
types_struct_enum.append(type)
return types_struct_enum
return (types_struct_enum, types_removed)
def extract_acid_selectively(ast, var_names, function_names):
@ -246,7 +260,10 @@ def extract_acid_selectively(ast, var_names, function_names):
acid["typerefs_notfound"] += notfound
acid["types"] = _remove_typedefs_of_primitive(acid["types"])
(struct_enum_types, types_removed) = _remove_typedefs_of_primitive(acid["types"])
acid["types"] = struct_enum_types
acid["types_removed"] = types_removed
acid["types"] = remove_dup_types(acid["types"])
acid["type_names"] = _extract_type_names(acid["types"])
return acid

10
pEpACIDgen/c_2_ast.py

@ -53,6 +53,7 @@ class C2AST:
"type": "",
"file": "",
"is_definition": "",
"is_anonymous": "",
}
# generic info for all CursorKinds
@ -93,7 +94,15 @@ class C2AST:
if cursor.is_definition():
item["is_definition"] = cursor.is_definition()
item["is_anonymous"] = False
if cursor.is_anonymous():
item["is_anonymous"] = cursor.is_anonymous()
# ENUM specific info
# if cursor.kind == CursorKind.ENUM_DECL:
# if item["name"] == "":
# item["type"] = "enum " + item["type"]
# optional "value"
if cursor.kind == CursorKind.ENUM_CONSTANT_DECL:
item["value"] = cursor.enum_value
@ -103,6 +112,7 @@ class C2AST:
if cursor.kind == CursorKind.TYPEDEF_DECL:
item["utype"] = cursor.underlying_typedef_type.spelling
item["utypekind"] = cursor.underlying_typedef_type.kind.spelling
dont_recurse = True
# TYPE_REF specific info

15
tests/test_pEpACIDgen.py

@ -6,6 +6,7 @@ import re
import pytest
import pEpACIDgen
input()
# "type" - is the name of the type for which vars of all variations of this type exists
# (Variations being combinations of this type with qualifier alias and typedef,
# Which means that all variations resolve to the same underlying type)
@ -33,10 +34,10 @@ all_types.append({"type": ["E"],
"enum E"
]})
# all_types.append({"type": ["XE"],
# "requires": [
# "AXE"
# ]})
all_types.append({"type": ["XE"],
"requires": [
"AXE"
]})
all_types.append({"type": ["_PS"],
"requires": [
@ -174,7 +175,7 @@ def resolve_vars_and_funcs_to_acid(vars, funcs):
header_filename = "examples/lib/lib_test/lib_test.h"
libclang_path = "/opt/local/libexec/llvm-9.0/lib/libclang.dylib"
acidgen = pEpACIDgen.pEpACIDGen(libclang_path, header_filename, "test_pEpACIDgen")
header = acidgen.extract(vars, funcs)
header = acidgen.extract(vars, funcs, debug_ast=True, debug_acid=True, debug_yml=True)
return header["acid"]
@ -187,10 +188,10 @@ def check_expected_types_resolved(vars, funcs, type_names_expected):
assert len(cid["vars_notfound"]) == 0, "vars not found"
# Check on unresolved functions
assert len(cid["functions_notfound"]) == 0, "vars not found"
assert len(cid["functions_notfound"]) == 0, "functions not found"
# Check on unresolved typerefs
assert len(cid["typerefs_notfound"]) == 0, "vars not found"
assert len(cid["typerefs_notfound"]) == 0, "typerefs not found"
type_names = cid["type_names"]
# test for no dup types

Loading…
Cancel
Save