From 3680c4065d33f3b894380b6c4939b8638944c69f Mon Sep 17 00:00:00 2001 From: John Ernberg Date: Wed, 22 Oct 2025 12:42:40 +0200 Subject: [PATCH] nala: Rework PRIMITIVE_TYPES check The old check wasn't appropriate as the order of qualifiers isn't enforced by pycparser nor C compilers, yet Nala enforced the order. This is a problem with stdatomic.h which contains instances of "short unsigned int", a type not recognized by Nala. Instead just check that all qualifiers and the core types are common, leaving the qualifier validation to pycarser and the compiler. Utilize a set for this. Encapsulate the PRIMITIVE_TYPES list in a method and call that instead of implementing the set check everywhere. This results in some changes to is_primitive_type_pointer and is_primitive_type_pointer_type to no longer take a types argument, instead they call the new is_primitive_type method as necessary. --- nala/generator.py | 1 - nala/inspect.py | 66 +++++++++++++++-------------------------------- 2 files changed, 21 insertions(+), 46 deletions(-) diff --git a/nala/generator.py b/nala/generator.py index 75747a2..6354a9f 100644 --- a/nala/generator.py +++ b/nala/generator.py @@ -9,7 +9,6 @@ from pycparser import c_ast from pycparser.c_generator import CGenerator -from .inspect import PRIMITIVE_TYPES from .inspect import VaList from .inspect import PrimitiveType from .inspect import is_struct_or_union diff --git a/nala/inspect.py b/nala/inspect.py index b26ecc0..e9a386d 100644 --- a/nala/inspect.py +++ b/nala/inspect.py @@ -137,40 +137,6 @@ def rename_parameters(function_declaration, param_names): return function_declaration -PRIMITIVE_TYPES = [ - 'char', - 'signed char', - 'unsigned char', - 'short', - 'short int', - 'signed short', - 'signed short int', - 'unsigned short', - 'unsigned short int', - 'int', - 'signed', - 'signed int', - 'unsigned', - 'unsigned int', - 'long', - 'long int', - 'signed long', - 'signed long int', - 'unsigned long', - 'unsigned long int', - 'long unsigned int', - 'long long', - 'long long int', - 'signed long long', - 'signed long long int', - 'unsigned long long', - 'unsigned long long int', - 'long long unsigned int', - 'float', - 'double', - 'long double' -] - LINEMARKER = re.compile(r'^# \d+ "((?:\\.|[^\\"])*)"((?: [1234])*)$') TOKENS = { @@ -281,25 +247,35 @@ def is_fixed_array(type_): return False -def is_primitive_type_pointer_type(type_, types): +def is_primitive_type(type_): + PRIMITIVE_TYPES = set([ + 'char', 'signed', 'unsigned', + 'short', 'int', 'long', + 'float', 'double', + ]) + + if isinstance(type_, c_ast.IdentifierType): + return set(type_.names) <= PRIMITIVE_TYPES + + return False + + +def is_primitive_type_pointer_type(type_): if isinstance(type_, c_ast.IdentifierType): - return ' '.join(type_.names) in types + return is_primitive_type(type_) if isinstance(type_, c_ast.TypeDecl): - return is_primitive_type_pointer_type(type_.type, types) + return is_primitive_type_pointer_type(type_.type) return False -def is_primitive_type_pointer(type_, types=None): - if types is None: - types = PRIMITIVE_TYPES - +def is_primitive_type_pointer(type_): if isinstance(type_, c_ast.TypeDecl): - return is_primitive_type_pointer(type_.type, types) + return is_primitive_type_pointer(type_.type) if isinstance(type_, c_ast.PtrDecl): - return is_primitive_type_pointer_type(type_.type, types) + return is_primitive_type_pointer_type(type_.type) return False @@ -410,7 +386,7 @@ def resolve_type(self, type_): if isinstance(type_, c_ast.IdentifierType): name = ' '.join(type_.names) - if name in PRIMITIVE_TYPES or name == '_Bool': + if is_primitive_type(type_) or name == '_Bool': return PrimitiveType(name) elif name == '__builtin_va_list': return VaList() @@ -439,7 +415,7 @@ def expand_type(self, type_): if isinstance(type_, c_ast.IdentifierType): name = ' '.join(type_.names) - if name in PRIMITIVE_TYPES: + if is_primitive_type(type_): pass elif name in ['__builtin_va_list', 'void', '_Bool']: pass