diff --git a/README.md b/README.md index d7257eee0..4c0f3d770 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,11 @@ The C frontend is currently parse-only. It supports: compatible top-level redeclaration merging. - Pointer, array, function, and parenthesized declarator shapes, including function pointer typedefs/parameters and parameter adjustment metadata. -- Project include/index facts through `parse_c_project(...)`. +- Project include/index facts through `parse_c_project(...)`, with includes + recorded non-recursively: only explicitly supplied files or files below an + explicitly supplied directory are parsed. +- Raw mutually exclusive function alternatives preserved for later semantic + selection rather than collapsed into one signature. C semantic IR conversion, C `.pyi` generation, and C wrap-readiness are still intentionally disabled until the C semantic layer is implemented. @@ -74,8 +78,8 @@ Public API entrypoints include: - `x2py.parse_fortran_file(source_or_path, filename=None, macro_defines=None, encoding="utf-8") -> FortranFile` - `x2py.parse_fortran_project(files, encoding="utf-8") -> FortranProject` -- `c_parser.parse_c_file(source_or_path, filename=None, macro_defines=None, include_dirs=None, preprocessing="raw", encoding="utf-8") -> CFile` -- `c_parser.parse_c_project(files, include_dirs=None, macro_defines=None, preprocessing="raw", encoding="utf-8") -> CProject` +- `x2py.parse_c_file(source_or_path, filename=None, macro_defines=None, include_dirs=None, preprocessing="raw", encoding="utf-8") -> CFile` +- `x2py.parse_c_project(files, include_dirs=None, macro_defines=None, preprocessing="raw", encoding="utf-8") -> CProject` - `x2py.fortran_file_to_semantic_modules(parsed_file, standalone_module_name=None) -> list[SemanticModule]` - `x2py.assess_semantic_wrap_readiness(semantic_ir, source=None) -> dict` - `x2py.assess_pyi_wrap_readiness(path_or_paths, encoding="utf-8") -> dict` @@ -611,7 +615,7 @@ types with `class` stubs, literal compile-time constants with ### Example 3: parse C from Python ```python -from c_parser import parse_c_file, parse_c_project +from x2py import parse_c_file, parse_c_project header = parse_c_file("include/api.h") print("functions:", [fn.name for fn in header.functions]) @@ -622,9 +626,11 @@ print("include graph:", project.include_graph) print("header/source pairs:", project.header_source_pairs) ``` -The C Python API is intentionally imported from `c_parser` while the C frontend -stabilizes. C semantic conversion will be added through the semantic layer in a -future phase. +The same C entrypoints remain available from `c_parser`. Includes are recorded +as project facts and are not recursively parsed; supply every header that +should contribute declarations (or supply its containing directory). C +semantic conversion will be added through the semantic layer in a future +phase. ## Running tests diff --git a/c_parser/models.py b/c_parser/models.py index bb35e5532..47d344d93 100644 --- a/c_parser/models.py +++ b/c_parser/models.py @@ -82,13 +82,23 @@ def c_model_to_dict(obj: Any, _seen: set[int] | None = None) -> Any: and f.name == "original_source_paths" and not getattr(obj, f.name) ) + or ( + isinstance(obj, CFunction) + and f.name == "condition_set" + and not getattr(obj, f.name) + ) + or ( + isinstance(obj, CProject) + and f.name == "conditional_function_variants" + and not getattr(obj, f.name) + ) ) } if isinstance(obj, list): return [c_model_to_dict(v, _seen) for v in obj] if isinstance(obj, dict): return {k: c_model_to_dict(v, _seen) for k, v in obj.items()} - if isinstance(obj, set): + if isinstance(obj, (set, frozenset)): return sorted(c_model_to_dict(v, _seen) for v in obj) return obj @@ -391,6 +401,7 @@ class CFunction: start: CSourceLocation | None = None end: CSourceLocation | None = None declaration_locations: list[CSourceLocation] = field(default_factory=list) + condition_set: frozenset[str] = field(default_factory=frozenset) origin: str | None = None @property @@ -561,6 +572,7 @@ class CProject: system_includes: dict[str, set[str]] = field(default_factory=dict) unresolved_includes: dict[str, set[str]] = field(default_factory=dict) header_source_pairs: dict[str, set[str]] = field(default_factory=dict) + conditional_function_variants: dict[str, list[CFunction]] = field(default_factory=dict) diagnostics: list[CDiagnostic] = field(default_factory=list) def to_dict(self) -> dict[str, Any]: diff --git a/c_parser/parser.py b/c_parser/parser.py index 8234e562b..220afe1dc 100644 --- a/c_parser/parser.py +++ b/c_parser/parser.py @@ -117,6 +117,9 @@ ) _CXX_DECLARATION_KEYWORDS = {"using", "namespace", "template", "class"} _CXX_ACCESS_SPECIFIERS = {"public", "private", "protected"} +_RAW_CONDITIONAL_DIRECTIVE_RE = re.compile( + r"^\s*#\s*(?Pif|ifdef|ifndef|elif|else|endif)\b" +) _PRIMITIVE_WORDS = { "void", "char", @@ -365,6 +368,7 @@ def visit_file( filename, function_like_macros=function_like_macro_names, object_like_macros=object_like_macro_names, + condition_sets_by_line=self._raw_conditional_condition_sets(source), ) parsed.functions = functions parsed.structs = structs @@ -410,7 +414,12 @@ def visit_project( preprocessing: str = "raw", encoding: str = "utf-8", ) -> CProject: - """Parse a mapping, file list, single file, or directory into a `CProject`.""" + """Parse explicit project inputs without recursively parsing includes. + + A directory input explicitly supplies all supported source files below + that directory. Include directives are recorded and resolved as graph + facts where possible, but they never cause another file to be opened. + """ if isinstance(files, Mapping): parsed_files = { name: self.visit_file( @@ -675,6 +684,51 @@ def _append_declaration_location( if location is not None and location not in locations: locations.append(location) + @staticmethod + def _raw_conditional_condition_sets(source: str) -> dict[int, frozenset[str]]: + """Track unselected raw preprocessor alternatives by physical line.""" + conditions_by_line: dict[int, frozenset[str]] = {} + condition_stack: list[tuple[int, int]] = [] + group_counter = 0 + for line_number, line in enumerate(source.splitlines(), start=1): + match = _RAW_CONDITIONAL_DIRECTIVE_RE.match(line) + if match is None: + conditions_by_line[line_number] = frozenset( + f"g{group_id}:b{branch_id}" + for group_id, branch_id in condition_stack + ) + continue + + directive = match.group("directive") + if directive in {"if", "ifdef", "ifndef"}: + group_counter += 1 + condition_stack.append((group_counter, 0)) + elif directive in {"elif", "else"} and condition_stack: + group_id, branch_id = condition_stack.pop() + condition_stack.append((group_id, branch_id + 1)) + elif directive == "endif" and condition_stack: + condition_stack.pop() + return conditions_by_line + + @staticmethod + def _functions_are_mutually_exclusive(left: CFunction, right: CFunction) -> bool: + """Return whether two raw function facts are in alternative branches.""" + if ( + not left.condition_set + or not right.condition_set + or left.source_location is None + or right.source_location is None + or left.source_location.filename != right.source_location.filename + ): + return False + branches: dict[str, str] = {} + for token in left.condition_set | right.condition_set: + group, _, branch = token.partition(":") + if group in branches and branches[group] != branch: + return True + branches[group] = branch + return False + # ------------------------------------------------------------------ # Redeclaration compatibility and normalization # ------------------------------------------------------------------ @@ -771,43 +825,48 @@ def _deduplicate_functions( diagnostics: list[CDiagnostic], ) -> list[CFunction]: """Merge compatible functions and report duplicate/conflicting ones.""" - by_name: dict[str, CFunction] = {} - order: list[str] = [] + normalized: list[CFunction] = [] for function in functions: - existing = by_name.get(function.name) - if existing is None: - by_name[function.name] = function - order.append(function.name) + overlapping = [ + index + for index, existing in enumerate(normalized) + if existing.name == function.name + and not self._functions_are_mutually_exclusive(existing, function) + ] + if not overlapping: + normalized.append(function) continue - if not self._functions_compatible(existing, function): - diagnostics.append( - self._redeclaration_diagnostic( - "C_CONFLICTING_FUNCTION_DECLARATION", - f"Conflicting declarations for function {function.name!r}.", - function.source_location, - "function", - function.name, + for index in overlapping: + existing = normalized[index] + if not self._functions_compatible(existing, function): + diagnostics.append( + self._redeclaration_diagnostic( + "C_CONFLICTING_FUNCTION_DECLARATION", + f"Conflicting declarations for function {function.name!r}.", + function.source_location, + "function", + function.name, + ) ) - ) - continue + continue - if existing.is_definition and function.is_definition: - diagnostics.append( - self._redeclaration_diagnostic( - "C_DUPLICATE_FUNCTION_DEFINITION", - f"Duplicate definition for function {function.name!r}.", - function.source_location, - "function", - function.name, + if existing.is_definition and function.is_definition: + diagnostics.append( + self._redeclaration_diagnostic( + "C_DUPLICATE_FUNCTION_DEFINITION", + f"Duplicate definition for function {function.name!r}.", + function.source_location, + "function", + function.name, + ) ) - ) - continue + continue - by_name[function.name] = self._merge_function_declaration(existing, function) + normalized[index] = self._merge_function_declaration(existing, function) - return [by_name[name] for name in order] + return normalized def _is_variable_definition(self, variable: CVariable) -> bool: """Return whether a file-scope variable has an initializer.""" @@ -1018,6 +1077,17 @@ def _normalize_redeclarations(self, parsed: CFile) -> None: parsed.typedefs = self._deduplicate_typedefs(parsed.typedefs, parsed.diagnostics) parsed.variables = self._deduplicate_variables(parsed.variables, parsed.diagnostics) parsed.functions = self._deduplicate_functions(parsed.functions, parsed.diagnostics) + function_counts: dict[str, int] = {} + for function in parsed.functions: + function_counts[function.name] = function_counts.get(function.name, 0) + 1 + variant_names = { + function.name + for function in parsed.functions + if function_counts[function.name] > 1 + } + for function in parsed.functions: + if function.name not in variant_names: + function.condition_set = frozenset() def _end_location(self, segment: CTopLevelSegment) -> CSourceLocation: """Return the original end location for a top-level segment.""" @@ -2366,6 +2436,7 @@ def _parse_translation_unit( function_like_macros: set[str] | None = None, object_like_macros: set[str] | None = None, use_linemarkers: bool = False, + condition_sets_by_line: Mapping[int, frozenset[str]] | None = None, ) -> tuple[ list[CFunction], list[CStruct], @@ -2398,6 +2469,7 @@ def _parse_translation_unit( function_like_names = function_like_macros or set() object_like_names = object_like_macros or set() + condition_sets = condition_sets_by_line or {} for segment in split_top_level_c_source( source, filename=filename, @@ -2432,6 +2504,11 @@ def _parse_translation_unit( else: enums.append(aggregate) functions.extend(parsed_functions) + for function in parsed_functions: + function.condition_set = condition_sets.get( + segment.original_start_line, + frozenset(), + ) typedefs.extend(parsed_typedefs) variables.extend(parsed_variables) diagnostics.extend(parsed_diagnostics) @@ -2443,6 +2520,10 @@ def _parse_translation_unit( diagnostics.append(self._declarator_diagnostic(segment, str(error))) continue if function is not None: + function.condition_set = condition_sets.get( + segment.original_start_line, + frozenset(), + ) functions.append(function) self._append_union_by_value_diagnostics(function, diagnostics) continue @@ -2461,6 +2542,11 @@ def _parse_translation_unit( segment ) functions.extend(parsed_functions) + for function in parsed_functions: + function.condition_set = condition_sets.get( + segment.original_start_line, + frozenset(), + ) typedefs.extend(parsed_typedefs) variables.extend(parsed_variables) for function in parsed_functions: @@ -2509,12 +2595,20 @@ def _build_project(self, parsed_files: dict[str, CFile]) -> CProject: self._index_file_includes(project, filename, file) self._index_header_source_pairs(project) resolve_project_types(project) - project.functions = { - function.name: function - for function in self._deduplicate_functions(all_functions, project.diagnostics) - } + normalized_functions = self._deduplicate_functions(all_functions, project.diagnostics) + functions_by_name: dict[str, list[CFunction]] = {} + for function in normalized_functions: + functions_by_name.setdefault(function.name, []).append(function) + for name, variants in functions_by_name.items(): + if len(variants) == 1: + project.functions[name] = variants[0] + else: + project.conditional_function_variants[name] = variants for function in project.functions.values(): self._append_union_by_value_diagnostics(function, project.diagnostics) + for variants in project.conditional_function_variants.values(): + for function in variants: + self._append_union_by_value_diagnostics(function, project.diagnostics) return project def _index_struct( @@ -2617,7 +2711,7 @@ def _index_file_includes( filename: str, file: CFile, ) -> None: - """Populate include-graph, system-include, and unresolved-include sets.""" + """Populate include facts without extending the parsed input set.""" local_targets: set[str] = set() system_targets: set[str] = set() unresolved_targets: set[str] = set() diff --git a/docs/c_parser/c_parser_architecture.md b/docs/c_parser/c_parser_architecture.md index 2fba5e7e3..2d476d8e4 100644 --- a/docs/c_parser/c_parser_architecture.md +++ b/docs/c_parser/c_parser_architecture.md @@ -28,6 +28,8 @@ Implemented now: - `c_parser/` package exists and is included in package discovery. - `c_parser.models` defines JSON-stable parser dataclasses and `CParseError`. - `c_parser.parser` exposes `CParser`, `parse_c_file`, and `parse_c_project`. +- `x2py` re-exports `parse_c_file` and `parse_c_project`, matching its + Fortran file/project entrypoint style. - `c_parser.parser` keeps parser helpers on `CParser`, matching the Fortran parser's stateful class structure; module-level functions are limited to public entrypoints and small path helpers. @@ -78,6 +80,10 @@ Implemented now: declarations, preserves related declaration locations, and reports duplicate definitions or incompatible redeclarations as diagnostics. Local declarations inside function bodies remain out of scope because bodies are skipped. +- Raw same-name function alternatives in mutually exclusive conditional + branches retain Fortran-style `condition_set` identity; a project keeps + ambiguous alternatives in `conditional_function_variants` rather than + inventing one selected function. - `c_parser.cli` provides C-specific partial report formatting. - `x2py.cli` dispatches `--language c --parse` to the C parser path. - `x2py.c_type_probe` compiles and runs a generated C11 query for @@ -100,7 +106,7 @@ Deferred: - full typedef/tag resolution policy beyond basic project-level link-up and callback policy metadata, for example conflict diagnostics, active - conditional branches, and semantic wrappability decisions + semantic wrappability decisions - compiler attributes and alignment specifiers - broader compiler-family validation for preprocessing; parsed declarations already retain preprocessed origin and mapped source identity @@ -284,7 +290,8 @@ Current and planned responsibilities: - `c_parser/type_resolver.py` - Resolves tag and typedef references, typedef chains/cycles, and aggregate references across parsed project files. - - Planned: safely fold simple compile-time constant expressions. + - Boundary: enum initializer expressions remain source text in the parser; + any target-aware evaluation belongs to later semantic conversion. - `c_parser/cli.py` - Implemented: report formatting and serialization helpers called by `x2py.cli` behind explicit C flags. @@ -319,9 +326,10 @@ class CParser: def visit_project(...): ... ``` -These entrypoints are exposed from `c_parser`, not re-exported from -`x2py.__init__`. Keeping the API under `c_parser` avoids making the top-level -x2py API promise stable C behavior before the frontend matures. +These entrypoints are exposed from both `c_parser` and `x2py.__init__`, using +the same top-level file/project invocation pattern already provided for +Fortran. C semantic conversion remains unavailable despite the parse API +export. ## Core Model Families @@ -371,8 +379,10 @@ Declaration objects are separate from the type components: locations; there is no separate field class. - `CFunction` has `name`, `result_type`, named `parameters`, storage and function specifiers, `is_variadic`, prototype style, and source/definition - locations plus related declaration locations. Its `type` property builds the - corresponding nameless `CFunctionType`. + locations plus related declaration locations. Raw alternative declarations + can also carry `condition_set` tokens such as `g1:b0`, matching the + Fortran parser's conditional-sibling identity convention. Its `type` + property builds the corresponding nameless `CFunctionType`. - `CParameter` has a source name, written `declared_type`, and effective `type`; outer array parameters and direct function parameters adjust to pointer `type` values while their source form is retained. @@ -432,6 +442,7 @@ Declaration objects are separate from the type components: - `system_includes` - `unresolved_includes` - `header_source_pairs` + - `conditional_function_variants` - `diagnostics` Serialization uses `"model"` to identify concrete `CType` nodes; `"type"` is @@ -441,9 +452,8 @@ spellings, such as `"const"`. Reused aggregate/typedef objects serialize as references to avoid cycles. Future parser phases can deepen symbol links, duplicate/conflict diagnostics, -conditional region ownership, and project diagnostics when the corresponding -behavior lands. Additions should be documented and tested with stable -serialization expectations. +and project diagnostics when the corresponding behavior lands. Additions +should be documented and tested with stable serialization expectations. ## Grammar-Style Parsing Strategy @@ -546,6 +556,9 @@ Raw-source mode target: - Record function-like macros as unsupported or deferred metadata. - Record conditional directive presence as metadata only when needed for provenance. +- Preserve same-name function declarations from mutually exclusive raw + conditional branches as separate `condition_set` variants; do not select an + active branch in raw mode. - Parse ordinary declarations only when they are visible without macro expansion. - Mark function-like wrappers and object-like declaration-prefix regions as @@ -599,7 +612,7 @@ graphs. Current behavior: - `parse_c_project` accepts mappings, explicit paths, and directories. -- Directory mode currently discovers `.c` and `.h` files only. +- Directory mode discovers `.c`, `.h`, and `.i` files. - Returned `CProject` objects contain `CFile` parser models with raw include, macro, metadata diagnostics, and supported declarations populated per file. - Basic project-level indexes are populated for parsed functions, typedefs, @@ -608,6 +621,15 @@ Current behavior: are recorded separately. Unresolved quoted includes remain diagnostics rather than hard failures, and include cycles are represented as graph edges without recursive traversal. +- Included local or system files are never recursively parsed, even when a + local path can be resolved. The parser reads only explicit mapping/file + inputs or supported files below an explicit directory, matching the + Fortran policy of recording imports/includes without loading them. +- Generated headers and direct `.i` inputs follow that explicit-input rule; + compiler linemarkers record origins rather than introducing project files. +- Project and include-graph keys are input/path keys. There is no C module-key + namespace; a graph edge uses a parsed project-file key when one matches and + otherwise retains its external path/target fact. - Likely header/source pairs are reported by matching stems and direct source includes. - Basic cross-file typedef and struct/union/enum tag references are linked to @@ -618,9 +640,6 @@ Current behavior: Planned behavior after project-resolution phases: -- Collect `.c`, `.h`, and `.i` files from explicit paths or - directories. -- Parse headers and sources into `CFile` models. - Deepen include graph behavior where normalized paths are ambiguous. - Deepen duplicate/conflict diagnostics. - Track duplicate symbols by C namespace: diff --git a/docs/c_parser/c_parser_cli_workflow.md b/docs/c_parser/c_parser_cli_workflow.md index 18cd23f3f..293c8d211 100644 --- a/docs/c_parser/c_parser_cli_workflow.md +++ b/docs/c_parser/c_parser_cli_workflow.md @@ -2,8 +2,9 @@ Status: C parser partial subset plus raw directive metadata implemented. The CLI command shape exists and parse reports can include raw includes, simple -macros, `#undef` and conditional directive provenance, top-level -redeclaration diagnostics, project include/index metadata, diagnostics, +macros, `#undef` and conditional directive provenance, raw conditional +function variants, top-level redeclaration diagnostics, project include/index +metadata, diagnostics, variables, typedefs, aggregate declarations, function prototypes, prototype-style metadata, and function-definition signatures with start/end locations. Declarator output can @@ -29,8 +30,11 @@ python -m x2py path/to/api.h --language c --parse --out report.json python -m x2py path/to/api.h --language c --parse --preprocess compiler --compiler clang-18 -I include -D API_EXPORT= --std c11 ``` -The C parser accepts explicit `.c` and `.h` files, plus directories in explicit -C mode. Directory scanning in C mode only collects `.c` and `.h` files. +The C parser accepts explicit `.c`, `.h`, and direct `.i` files, plus +directories in explicit C mode. Directory scanning in C mode collects those +three source forms. It does not recursively parse headers mentioned by +includes; as on the Fortran path, an imported/included source is parsed only +when the user supplied it or supplied a directory containing it. Auto-detection is deferred, so omitting `--language` keeps the current Fortran behavior. @@ -54,7 +58,11 @@ source. `parse_c_project(...)` additionally populates project-level include/index fields such as `include_graph`, `system_includes`, `unresolved_includes`, `functions_by_file`, `enum_constants`, and `header_source_pairs`. Those fields require project -context; a single-file parse only records the local file facts. +context; a single-file parse only records the local file facts. If raw +conditional branches expose incompatible alternatives of one function, +`CFunction.condition_set` records the alternatives and +`CProject.conditional_function_variants` retains them outside the unique +function index. The object class distinguishes declarations (`CFunction`, `CVariable`, `CTypedef`, `CStruct`, `CUnion`, or `CEnum`), and incomplete tag declarations set `is_incomplete=True`. @@ -139,14 +147,8 @@ Rationale: - It lets Fortran remain the default during the long C parser stabilization period. -Optional short alias, not implemented: - -```bash -x2py --parse-c -``` - -The short alias is convenient, but should be secondary. If added, it should be -implemented as a strict alias for `--language c --parse`. +No separate `--parse-c` alias is provided. `--language c --parse` is the +single shared language-selection form. Auto-detection should be later: @@ -413,7 +415,12 @@ marked through `macro_dependencies` without being parsed as expanded declarations. Local quoted includes are resolved relative to the current file or configured include dirs when possible; unresolved local includes produce `C_UNRESOLVED_INCLUDE` diagnostics instead -of hard failures. +of hard failures. Resolution records an edge; it does not make the included +file a parser input. System includes are recorded but neither searched nor +parsed recursively. Generated headers follow the same explicit-input rule. +Raw same-name functions in mutually exclusive conditional branches carry +`condition_set` branch tokens and are retained as alternatives rather than +misdiagnosed as incompatible redeclarations. Raw mode must not claim support for macro-generated declarations. If macros affect function names, types, parameters, attributes, storage classes, calling @@ -462,6 +469,11 @@ Declaration/directive records include `source_location`; diagnostics use `location`. Concrete type components preserve `source_text` rather than their own source-location object: +`condition_set` is emitted only for raw same-name `CFunction` alternatives +that survive normalization. For project-model JSON, +`conditional_function_variants` is emitted only when those alternatives +cannot be represented by one unique `functions` entry. + ```text source_location: { filename: str | null, @@ -561,7 +573,7 @@ The active CLI/parser tests cover the current partial subset: - Existing Fortran CLI tests still pass unchanged. - `python -m x2py --help` lists `--language`. - `python -m x2py --language c --parse` is accepted. -- `python -m x2py --parse-c` is not implemented. +- No `--parse-c` alias is provided; C uses `--language c --parse`. - `--language c --parse --json` emits stable partial-parser JSON with raw include/macro metadata and supported declarations when present. - `--language c --parse --out report.json` writes JSON and suppresses stdout. @@ -570,7 +582,8 @@ The active CLI/parser tests cover the current partial subset: - raw comment stripping, line-continuation folding, top-level splitting, include collection, simple macro collection, function-like macro diagnostics, object-like macro declaration-prefix deferral, - conditional non-selection, simple declarations, variables, typedefs, + conditional non-selection and mutually exclusive function variants, simple + declarations, variables, typedefs, parenthesized declarators, function pointer typedefs/parameters, recursive declarator combinations, concrete declaration objects, aggregate definitions/members/enumerators, incomplete struct/union tags, and function diff --git a/docs/c_parser/c_parser_reference.md b/docs/c_parser/c_parser_reference.md index 19c8b8e5f..eb844b606 100644 --- a/docs/c_parser/c_parser_reference.md +++ b/docs/c_parser/c_parser_reference.md @@ -37,7 +37,9 @@ Supported source forms: Project input accepts explicit files and directories in explicit C mode. Directory scanning in C mode discovers C source/header inputs without changing -Fortran's default directory behavior. +Fortran's default directory behavior. Project parsing does not recursively +parse files named by C includes: as with Fortran recorded imports/includes, +only user-supplied files or files beneath a user-supplied directory are parsed. ## Current Status @@ -46,6 +48,8 @@ Implemented: - `c_parser` package - typed C parser models for partial parse reports and raw metadata - `CParser`, `parse_c_file`, and `parse_c_project` +- top-level `x2py.parse_c_file` and `x2py.parse_c_project` exports alongside + the `c_parser` package entrypoints - `CParseError` with compiler-style diagnostic formatting - explicit `x2py --language c --parse` output - C JSON partial output and `--out` behavior @@ -54,6 +58,9 @@ Implemented: lightweight token source locations - top-level source splitting that tracks braces, parentheses, brackets, and string/character literals +- raw conditional same-name function alternatives retain Fortran-style + `condition_set` branch identity rather than being diagnosed as conflicting + redeclarations - raw `#include` collection for quoted and system includes - simple object-like `#define` macro collection - function-like macro metadata with unsupported diagnostics @@ -100,10 +107,12 @@ Implemented: explicit C mode, while leaving Fortran directory scanning unchanged - include resolution for quoted includes relative to the current file and configured include directories, unresolved include tracking, system include - tracking, cycle-safe include graph construction, and header/source pairing + tracking, cycle-safe include graph construction, and header/source pairing, + without recursive include parsing - project indexes for functions, file-scope variables, typedefs, struct tags, union tags, enum tags, enum constants, macros/constants, and functions by - file + file; raw conditional alternatives that cannot occupy one unique function + index entry are retained in `conditional_function_variants` - basic cross-file typedef chain and struct/union/enum tag resolution, with typedef-cycle diagnostics and unresolved references preserved for later diagnostics @@ -184,6 +193,9 @@ Raw-source mode means source normalization plus directive metadata: - record conditional and pragma directives as raw provenance metadata, including OpenMP declaration pragmas such as `#pragma omp declare simd` and `#pragma omp declare target` +- retain mutually exclusive same-name function declarations as alternatives + with `CFunction.condition_set` branch identity, matching the Fortran + parser's unselected-branch convention - record function-like macros as metadata with unsupported/deferred diagnostics - record function-like wrappers and object-like declaration prefixes as macro-dependency metadata without claiming they were parsed @@ -286,10 +298,12 @@ assumptions. ## Public API -Implemented module-level entrypoints: +Implemented top-level and package entrypoints: ```python -from c_parser import parse_c_file, parse_c_project +from x2py import parse_c_file, parse_c_project +# Equivalent parser-package imports remain available: +# from c_parser import parse_c_file, parse_c_project ``` Implemented signatures: @@ -395,12 +409,13 @@ declaration. Duplicate initialized variables, duplicate function definitions, duplicate complete tag definitions, and incompatible top-level redeclarations produce diagnostics. Local declarations inside function bodies are ignored because body contents are intentionally skipped. -Re-export from `x2py` is still deferred; users should import from `c_parser`. +`x2py` exports the C file/project entrypoints in the same style as the +Fortran entrypoints. The typed C parser package remains importable directly. Example: parse one header from Python. ```python -from c_parser import parse_c_file +from x2py import parse_c_file parsed = parse_c_file("include/api.h") print([function.name for function in parsed.functions]) @@ -410,7 +425,7 @@ print([typedef.name for typedef in parsed.typedefs]) Example: parse a small project with include directories. ```python -from c_parser import parse_c_project +from x2py import parse_c_project project = parse_c_project(["src/api.c", "include/api.h"], include_dirs=["include"]) print(project.include_graph) @@ -433,6 +448,18 @@ macros, declarations, diagnostics, and unresolved typedef/tag references. A project parse sees multiple files together and can populate include graphs, system include records, unresolved include sets, functions by file, enum constants, likely header/source pairs, and basic cross-file typedef/tag links. +An include edge is metadata only: a resolved local or system header is not +parsed unless it is also supplied as a project input or falls beneath a +directory input. Generated headers and direct `.i` streams follow that same +explicit-input rule. Include-graph keys use project input/path identity; they +are not module keys. + +When raw input declares incompatible versions of the same function in +alternative `#if`/`#else` branches, each `CFunction` retains a `condition_set` +such as `{"g1:b0"}` or `{"g1:b1"}`. A `CProject` stores such alternatives in +`conditional_function_variants` rather than claiming that one variant is the +unique `functions` entry. Compiler-preprocessed input contains the selected +configuration and therefore does not need this ambiguity representation. `macro_defines` is reserved for future compiler-assisted preprocessing configuration. It must not mean that raw mode evaluates C preprocessor @@ -453,13 +480,8 @@ x2py path/to/api.h --language c --parse --json x2py path/to/api.h --language c --parse --out report.json ``` -Optional alias, not implemented: - -```bash -x2py path/to/api.h --parse-c -``` - -Auto-detection should come later, after the frontend is stable. +There is no separate `--parse-c` alias: `--language c --parse` is the shared +language-selection form. Auto-detection remains deferred. ## Current JSON Output @@ -511,6 +533,10 @@ JSON compatibility rules: - emit references for reused aggregate or typedef objects rather than recursive JSON cycles - preserve unknown or unresolved information rather than dropping it silently +- emit `condition_set` only for retained raw conditional function alternatives, + and + emit project `conditional_function_variants` only when a unique function + index would discard those alternatives - keep model fields stable enough for golden fixture testing - document every intentional schema break @@ -591,7 +617,8 @@ public entrypoints, empty model serialization, CLI discovery, JSON/output-file behavior, unsupported C stages, comment stripping, line-continuation folding, top-level splitting, include collection, simple macro collection, macro-shaped declaration deferral, raw conditional branch non-selection and provenance, -macro-dependency metadata, project include/index behavior, simple declarations, +mutually exclusive function variant retention, macro-dependency metadata, +explicit-input/non-recursive project include behavior, simple declarations, variables, typedefs, top-level redeclaration diagnostics, recursive declarator composition, aggregate definitions, members, enums, simple function prototypes/definitions, function-definition start/end locations, JSON golden @@ -643,7 +670,7 @@ declarations. | Capability | C example | Current parser boundary | Needed behavior | | --- | --- | --- | --- | -| Typedef/tag resolution | `typedef unsigned long size_t; size_t count(void);` and `struct state { int id; }; void step(struct state *s);` | Basic project parsing links typedef chains and struct/union/enum tag references while preserving unresolved objects when context is absent. | Deepen conflict and generated-header policy for broader projects. | +| Typedef/tag resolution | `typedef unsigned long size_t; size_t count(void);` and `struct state { int id; }; void step(struct state *s);` | Basic project parsing links typedef chains and struct/union/enum tag references while preserving unresolved objects when context is absent. | Deepen conflict policy for broader projects; included/generated files are parsed only when supplied as project inputs. | | Preprocessed declarations | `#define API(ret) ret` followed by `API(int) run(void);` | Raw mode records macro metadata and does not claim the expanded declaration; compiler or `.i` mode parses expanded declarations, maps locations through `#line` markers, and records `origin="preprocessed"`; x2py-generated streams also record their recipe. | Broaden fixture-driven extension and compiler-family coverage. | | Additional extension families | `int run(void) __attribute__((visibility("default")));` | Known attribute/alignment forms are diagnosed; broader compiler extensions are not modeled. | Add fixture-driven support or a focused diagnostic for each required extension family. | @@ -702,8 +729,9 @@ active projects with Fatal diagnostic goldens are regenerated with `C_PARSER_UPDATE_GOLDENS=1 PYTHONPATH=. pytest -q tests/parser/c/test_c_error_fixture_suite.py`. The standalone generator modules remain available for targeted refreshes. -Until include-expanded parsing is implemented, a paired project records the -source-to-header include edge but parses the `.c` and `.h` members separately. +By policy, a paired project records source-to-header include edges but parses +each supplied `.c`, `.h`, or `.i` member separately; include traversal is not +a parser input-discovery mechanism. STB is treated as a family of independent single-file libraries: each top-level `.h` or `.c` input generates its own one-file project golden rather diff --git a/docs/x2py_checklist.md b/docs/x2py_checklist.md index 827761c98..f721551c6 100644 --- a/docs/x2py_checklist.md +++ b/docs/x2py_checklist.md @@ -18,34 +18,47 @@ Language scope is stated in each section or subsection heading: ## Step 1: C Parser Frontend Cleanup -- [ ] Keep existing C parser behavior unchanged unless a future task explicitly - requires shared infrastructure changes. -- [ ] Keep wrappability assessment in the semantic layer, not inside parser - packages. -- [ ] Split `CParser` internals into smaller visitor/helper classes only if the - class grows past what remains readable. -- [ ] Decide whether macros belong only in `CFile.macros` or also in project - symbol indexes. -- [ ] If `--parse-c` is added, make it an alias for `--language c --parse` and - add CLI tests for the alias. -- [ ] Allow same function under mutually exclusive preprocessor branches. -- [ ] Make C parser diagnostics report "no functions found" only when - appropriate. -- [ ] Safely fold simple enum integer expressions, or document the exact - boundary for preserving expression text. -- [ ] Decide how much enum expression folding is safe without compiler - semantics. -- [ ] Decide whether unions map to semantic IR at all in v1. -- [ ] Feed C standard-type probe reports into C semantic conversion once the - C semantic converter exists. +- [x] Keep C parsing source-faithful and parse-only. Unsupported syntax and + unresolved parser facts may produce diagnostics; wrapper readiness and + policy remain semantic-layer work. +- [x] Keep `CParser` as the current grammar-shaped visitor/helper class; no + readability-driven class split is needed for the implemented parser + surface. +- [x] Store macros on each `CFile` and index their recorded project facts in + `CProject.macros`. +- [x] Use the shared CLI spelling `--language c --parse`; do not add a separate + `--parse-c` spelling while it would only duplicate that path. +- [x] Expose `parse_c_file` and `parse_c_project` from `x2py` as well as from + `c_parser`, matching the Fortran public entrypoint style. +- [x] Preserve same-name function variants in mutually exclusive raw + preprocessor branches. `CFunction.condition_set` uses the Fortran-style + `gN:bN` branch tokens; ambiguous project names are retained in + `CProject.conditional_function_variants` instead of being collapsed into + one `CProject.functions` entry. +- [x] Keep "no functions found" out of parser diagnostics. Whether a source + has no wrappable public API is a Step 4 semantic-readiness decision. +- [x] Preserve enum initializer expression text in parser models rather than + folding it without compiler semantics. Later semantic conversion may + evaluate expressions only with an explicit safe/target-aware policy. +- [x] Preserve `CUnion` source facts in the parser; whether a union maps to + semantic IR or blocks wrapping is deferred to C semantic conversion. ## Step 2: C Project And Include Policy -- [ ] Decide whether project parsing should parse all included system headers - when they are found locally. -- [ ] Decide how to handle generated headers. -- [ ] Decide whether include graph keys should be path-keyed, module-keyed, or - both. +- [x] Parse only inputs given by the user: explicit mapping entries, explicit + file paths, or supported files discovered below an explicit directory. + Quoted and system includes are recorded as dependency facts; they do not + cause recursive parsing even when a matching header is locally available. + This is the same non-recursive policy used for Fortran recorded + imports/includes. +- [x] Treat generated headers and direct `.i` inputs like other sources: parse + them only when explicitly supplied or discovered below an explicitly + supplied directory. Compiler-preprocessed streams remain supported input; + their linemarkers record origins but do not add recursively parsed files. +- [x] Key C project files and include-graph edges by input/path identity, not + module identity. An edge uses an already parsed project-file key where + one matches; otherwise it retains the resolved path or written include + target as an external dependency fact. ## Step 3: Shared Semantic Model Foundation (Fortran And C) @@ -175,6 +188,8 @@ Language scope is stated in each section or subsection heading: - [ ] Create `semantics/c2ir.py`. - [ ] Implement `CToIRConverter`. - [ ] Mirror the visitor style of `FortranToIRConverter`. +- [ ] Accept C standard-type probe reports as target context for converting + standard-header aliases and opaque handles once `CToIRConverter` exists. - [ ] Add compatibility helpers such as `c_file_to_semantic_modules`. - [ ] Add `c_function_to_semantic_function`. - [ ] Add `c_struct_to_semantic_class` where appropriate. diff --git a/tests/parser/c/fixtures/stb/stb_image.json b/tests/parser/c/fixtures/stb/stb_image.json index 8f49e0b91..9816493a8 100644 --- a/tests/parser/c/fixtures/stb/stb_image.json +++ b/tests/parser/c/fixtures/stb/stb_image.json @@ -39,7 +39,54 @@ "column": 1, "source_line": "}" }, - "declaration_locations": [] + "declaration_locations": [], + "condition_set": [ + "g17:b0", + "g49:b0", + "g50:b0", + "g51:b0" + ] + }, + { + "name": "stbi__cpuid3", + "result_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int" + }, + "parameters": [], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_image.h", + "line": 739, + "column": 1, + "source_line": "static int stbi__cpuid3(void)" + }, + "start": { + "filename": "stb/stb_image.h", + "line": 739, + "column": 1, + "source_line": "static int stbi__cpuid3(void)" + }, + "end": { + "filename": "stb/stb_image.h", + "line": 748, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g17:b0", + "g49:b0", + "g50:b0", + "g51:b1" + ] }, { "name": "stbi__sse2_available", @@ -74,7 +121,54 @@ "column": 1, "source_line": "}" }, - "declaration_locations": [] + "declaration_locations": [], + "condition_set": [ + "g17:b0", + "g49:b0", + "g50:b0", + "g52:b0" + ] + }, + { + "name": "stbi__sse2_available", + "result_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int" + }, + "parameters": [], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_image.h", + "line": 765, + "column": 1, + "source_line": "static int stbi__sse2_available(void)" + }, + "start": { + "filename": "stb/stb_image.h", + "line": 765, + "column": 1, + "source_line": "static int stbi__sse2_available(void)" + }, + "end": { + "filename": "stb/stb_image.h", + "line": 771, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g17:b0", + "g49:b0", + "g50:b1", + "g53:b0" + ] }, { "name": "stbi__refill_buffer", @@ -33185,32 +33279,6 @@ "unit_kind": "typedef", "unit_name": "stbi__int32" }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'stbi__cpuid3'.", - "severity": "error", - "location": { - "filename": "stb/stb_image.h", - "line": 739, - "column": 1, - "source_line": "static int stbi__cpuid3(void)" - }, - "unit_kind": "function", - "unit_name": "stbi__cpuid3" - }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'stbi__sse2_available'.", - "severity": "error", - "location": { - "filename": "stb/stb_image.h", - "line": 765, - "column": 1, - "source_line": "static int stbi__sse2_available(void)" - }, - "unit_kind": "function", - "unit_name": "stbi__sse2_available" - }, { "code": "C_DUPLICATE_FUNCTION_DEFINITION", "message": "Duplicate definition for function 'stbi__idct_simd'.", @@ -33228,76 +33296,6 @@ } }, "functions": { - "stbi__cpuid3": { - "name": "stbi__cpuid3", - "result_type": { - "model": "CInt", - "qualifiers": [], - "source_text": "int" - }, - "parameters": [], - "storage": [ - "static" - ], - "specifiers": [], - "is_variadic": false, - "is_definition": true, - "prototype_style": "prototype", - "source_location": { - "filename": "stb/stb_image.h", - "line": 732, - "column": 1, - "source_line": "static int stbi__cpuid3(void)" - }, - "start": { - "filename": "stb/stb_image.h", - "line": 732, - "column": 1, - "source_line": "static int stbi__cpuid3(void)" - }, - "end": { - "filename": "stb/stb_image.h", - "line": 737, - "column": 1, - "source_line": "}" - }, - "declaration_locations": [] - }, - "stbi__sse2_available": { - "name": "stbi__sse2_available", - "result_type": { - "model": "CInt", - "qualifiers": [], - "source_text": "int" - }, - "parameters": [], - "storage": [ - "static" - ], - "specifiers": [], - "is_variadic": false, - "is_definition": true, - "prototype_style": "prototype", - "source_location": { - "filename": "stb/stb_image.h", - "line": 754, - "column": 1, - "source_line": "static int stbi__sse2_available(void)" - }, - "start": { - "filename": "stb/stb_image.h", - "line": 754, - "column": 1, - "source_line": "static int stbi__sse2_available(void)" - }, - "end": { - "filename": "stb/stb_image.h", - "line": 758, - "column": 1, - "source_line": "}" - }, - "declaration_locations": [] - }, "stbi__refill_buffer": { "name": "stbi__refill_buffer", "result_type": { @@ -55471,6 +55469,8 @@ "functions_by_file": { "stb/stb_image.h": [ "stbi__cpuid3", + "stbi__cpuid3", + "stbi__sse2_available", "stbi__sse2_available", "stbi__refill_buffer", "stbi__start_mem", @@ -55820,6 +55820,176 @@ "header_source_pairs": { "stb/stb_image.h": [] }, + "conditional_function_variants": { + "stbi__cpuid3": [ + { + "name": "stbi__cpuid3", + "result_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int" + }, + "parameters": [], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_image.h", + "line": 732, + "column": 1, + "source_line": "static int stbi__cpuid3(void)" + }, + "start": { + "filename": "stb/stb_image.h", + "line": 732, + "column": 1, + "source_line": "static int stbi__cpuid3(void)" + }, + "end": { + "filename": "stb/stb_image.h", + "line": 737, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g17:b0", + "g49:b0", + "g50:b0", + "g51:b0" + ] + }, + { + "name": "stbi__cpuid3", + "result_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int" + }, + "parameters": [], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_image.h", + "line": 739, + "column": 1, + "source_line": "static int stbi__cpuid3(void)" + }, + "start": { + "filename": "stb/stb_image.h", + "line": 739, + "column": 1, + "source_line": "static int stbi__cpuid3(void)" + }, + "end": { + "filename": "stb/stb_image.h", + "line": 748, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g17:b0", + "g49:b0", + "g50:b0", + "g51:b1" + ] + } + ], + "stbi__sse2_available": [ + { + "name": "stbi__sse2_available", + "result_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int" + }, + "parameters": [], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_image.h", + "line": 754, + "column": 1, + "source_line": "static int stbi__sse2_available(void)" + }, + "start": { + "filename": "stb/stb_image.h", + "line": 754, + "column": 1, + "source_line": "static int stbi__sse2_available(void)" + }, + "end": { + "filename": "stb/stb_image.h", + "line": 758, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g17:b0", + "g49:b0", + "g50:b0", + "g52:b0" + ] + }, + { + "name": "stbi__sse2_available", + "result_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int" + }, + "parameters": [], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_image.h", + "line": 765, + "column": 1, + "source_line": "static int stbi__sse2_available(void)" + }, + "start": { + "filename": "stb/stb_image.h", + "line": 765, + "column": 1, + "source_line": "static int stbi__sse2_available(void)" + }, + "end": { + "filename": "stb/stb_image.h", + "line": 771, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g17:b0", + "g49:b0", + "g50:b1", + "g53:b0" + ] + } + ] + }, "diagnostics": [ { "code": "C_UNSUPPORTED_FUNCTION_LIKE_MACRO", @@ -57511,32 +57681,6 @@ "unit_kind": "typedef", "unit_name": "stbi__int32" }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'stbi__cpuid3'.", - "severity": "error", - "location": { - "filename": "stb/stb_image.h", - "line": 739, - "column": 1, - "source_line": "static int stbi__cpuid3(void)" - }, - "unit_kind": "function", - "unit_name": "stbi__cpuid3" - }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'stbi__sse2_available'.", - "severity": "error", - "location": { - "filename": "stb/stb_image.h", - "line": 765, - "column": 1, - "source_line": "static int stbi__sse2_available(void)" - }, - "unit_kind": "function", - "unit_name": "stbi__sse2_available" - }, { "code": "C_DUPLICATE_FUNCTION_DEFINITION", "message": "Duplicate definition for function 'stbi__idct_simd'.", diff --git a/tests/parser/c/fixtures/stb/stb_truetype.json b/tests/parser/c/fixtures/stb/stb_truetype.json index 526b8f7eb..98e8a33c5 100644 --- a/tests/parser/c/fixtures/stb/stb_truetype.json +++ b/tests/parser/c/fixtures/stb/stb_truetype.json @@ -6125,7 +6125,200 @@ "column": 1, "source_line": "}" }, - "declaration_locations": [] + "declaration_locations": [], + "condition_set": [ + "g22:b0", + "g28:b0" + ] + }, + { + "name": "stbtt__new_active", + "result_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__active_edge", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__active_edge" + } + ] + }, + "parameters": [ + { + "name": "hh", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__hheap *hh", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__hheap" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__hheap *hh", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__hheap" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "e", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "off_x", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "start_point", + "type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float start_point" + }, + "declared_type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float start_point" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "userdata", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_truetype.h", + "line": 2857, + "column": 1, + "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" + }, + "start": { + "filename": "stb/stb_truetype.h", + "line": 2857, + "column": 1, + "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" + }, + "end": { + "filename": "stb/stb_truetype.h", + "line": 2873, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g22:b0", + "g28:b1" + ] }, { "name": "stbtt__fill_active_edges", @@ -6476,7 +6669,11 @@ "column": 1, "source_line": "}" }, - "declaration_locations": [] + "declaration_locations": [], + "condition_set": [ + "g22:b0", + "g29:b0" + ] }, { "name": "stbtt__handle_clipped_edge", @@ -7101,7 +7298,7 @@ "declaration_locations": [] }, { - "name": "stbtt__sort_edges_ins_sort", + "name": "stbtt__rasterize_sorted_edges", "result_type": { "model": "CVoid", "qualifiers": [], @@ -7109,11 +7306,52 @@ }, "parameters": [ { - "name": "p", + "name": "result", "type": { "model": "CComposedType", "qualifiers": [], - "source_text": "stbtt__edge *p", + "source_text": "stbtt__bitmap *result", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CTypedef", + "qualifiers": [], + "source_text": "stbtt__bitmap", + "name": "stbtt__bitmap", + "type": null, + "source_location": null, + "declaration_locations": [] + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__bitmap *result", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__bitmap" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "e", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", "components": [ { "model": "CPointer", @@ -7128,7 +7366,7 @@ "declared_type": { "model": "CComposedType", "qualifiers": [], - "source_text": "stbtt__edge *p", + "source_text": "stbtt__edge *e", "components": [ { "model": "CPointer", @@ -7157,25 +7395,199 @@ }, "source_location": null, "callback_policy": null - } - ], - "storage": [ - "static" - ], - "specifiers": [], - "is_variadic": false, - "is_definition": true, - "prototype_style": "prototype", - "source_location": { - "filename": "stb/stb_truetype.h", - "line": 3399, - "column": 1, - "source_line": "static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)" - }, - "start": { - "filename": "stb/stb_truetype.h", - "line": 3399, - "column": 1, + }, + { + "name": "vsubsample", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int vsubsample" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int vsubsample" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "off_x", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "off_y", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_y" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_y" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "userdata", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_truetype.h", + "line": 3297, + "column": 1, + "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" + }, + "start": { + "filename": "stb/stb_truetype.h", + "line": 3297, + "column": 1, + "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" + }, + "end": { + "filename": "stb/stb_truetype.h", + "line": 3392, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g22:b0", + "g29:b1" + ] + }, + { + "name": "stbtt__sort_edges_ins_sort", + "result_type": { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + }, + "parameters": [ + { + "name": "p", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *p", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *p", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "n", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_truetype.h", + "line": 3399, + "column": 1, + "source_line": "static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)" + }, + "start": { + "filename": "stb/stb_truetype.h", + "line": 3399, + "column": 1, "source_line": "static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)" }, "end": { @@ -14869,32 +15281,6 @@ }, "unit_kind": "function", "unit_name": "main" - }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'stbtt__new_active'.", - "severity": "error", - "location": { - "filename": "stb/stb_truetype.h", - "line": 2857, - "column": 1, - "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" - }, - "unit_kind": "function", - "unit_name": "stbtt__new_active" - }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'stbtt__rasterize_sorted_edges'.", - "severity": "error", - "location": { - "filename": "stb/stb_truetype.h", - "line": 3297, - "column": 1, - "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" - }, - "unit_kind": "function", - "unit_name": "stbtt__rasterize_sorted_edges" } ] } @@ -19728,30 +20114,20 @@ }, "declaration_locations": [] }, - "stbtt__new_active": { - "name": "stbtt__new_active", + "stbtt__fill_active_edges": { + "name": "stbtt__fill_active_edges", "result_type": { - "model": "CComposedType", + "model": "CVoid", "qualifiers": [], - "source_text": "stbtt__active_edge", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "stbtt__active_edge" - } - ] + "source_text": "void" }, "parameters": [ { - "name": "hh", + "name": "scanline", "type": { "model": "CComposedType", "qualifiers": [], - "source_text": "stbtt__hheap *hh", + "source_text": "unsigned char *scanline", "components": [ { "model": "CPointer", @@ -19759,14 +20135,16 @@ "source_text": "" }, { - "reference": "stbtt__hheap" + "model": "CUnsignedChar", + "qualifiers": [], + "source_text": "unsigned char" } ] }, "declared_type": { "model": "CComposedType", "qualifiers": [], - "source_text": "stbtt__hheap *hh", + "source_text": "unsigned char *scanline", "components": [ { "model": "CPointer", @@ -19774,19 +20152,36 @@ "source_text": "" }, { - "reference": "stbtt__hheap" + "model": "CUnsignedChar", + "qualifiers": [], + "source_text": "unsigned char" } ] }, "source_location": null, "callback_policy": null }, + { + "name": "len", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int len" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int len" + }, + "source_location": null, + "callback_policy": null + }, { "name": "e", "type": { "model": "CComposedType", "qualifiers": [], - "source_text": "stbtt__edge *e", + "source_text": "stbtt__active_edge *e", "components": [ { "model": "CPointer", @@ -19794,14 +20189,14 @@ "source_text": "" }, { - "reference": "stbtt__edge" + "reference": "stbtt__active_edge" } ] }, "declared_type": { "model": "CComposedType", "qualifiers": [], - "source_text": "stbtt__edge *e", + "source_text": "stbtt__active_edge *e", "components": [ { "model": "CPointer", @@ -19809,7 +20204,7 @@ "source_text": "" }, { - "reference": "stbtt__edge" + "reference": "stbtt__active_edge" } ] }, @@ -19817,70 +20212,16 @@ "callback_policy": null }, { - "name": "off_x", + "name": "max_weight", "type": { "model": "CInt", "qualifiers": [], - "source_text": "int off_x" + "source_text": "int max_weight" }, "declared_type": { "model": "CInt", "qualifiers": [], - "source_text": "int off_x" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "start_point", - "type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float start_point" - }, - "declared_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float start_point" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "userdata", - "type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "void *userdata", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "model": "CVoid", - "qualifiers": [], - "source_text": "void" - } - ] - }, - "declared_type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "void *userdata", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "model": "CVoid", - "qualifiers": [], - "source_text": "void" - } - ] + "source_text": "int max_weight" }, "source_location": null, "callback_policy": null @@ -19895,26 +20236,26 @@ "prototype_style": "prototype", "source_location": { "filename": "stb/stb_truetype.h", - "line": 2835, + "line": 2882, "column": 1, - "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" + "source_line": "static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)" }, "start": { "filename": "stb/stb_truetype.h", - "line": 2835, + "line": 2882, "column": 1, - "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" + "source_line": "static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)" }, "end": { "filename": "stb/stb_truetype.h", - "line": 2855, + "line": 2922, "column": 1, "source_line": "}" }, "declaration_locations": [] }, - "stbtt__fill_active_edges": { - "name": "stbtt__fill_active_edges", + "stbtt__handle_clipped_edge": { + "name": "stbtt__handle_clipped_edge", "result_type": { "model": "CVoid", "qualifiers": [], @@ -19926,7 +20267,7 @@ "type": { "model": "CComposedType", "qualifiers": [], - "source_text": "unsigned char *scanline", + "source_text": "float *scanline", "components": [ { "model": "CPointer", @@ -19934,16 +20275,16 @@ "source_text": "" }, { - "model": "CUnsignedChar", + "model": "CFloat", "qualifiers": [], - "source_text": "unsigned char" + "source_text": "float" } ] }, "declared_type": { "model": "CComposedType", "qualifiers": [], - "source_text": "unsigned char *scanline", + "source_text": "float *scanline", "components": [ { "model": "CPointer", @@ -19951,9 +20292,9 @@ "source_text": "" }, { - "model": "CUnsignedChar", + "model": "CFloat", "qualifiers": [], - "source_text": "unsigned char" + "source_text": "float" } ] }, @@ -19961,16 +20302,16 @@ "callback_policy": null }, { - "name": "len", + "name": "x", "type": { "model": "CInt", "qualifiers": [], - "source_text": "int len" + "source_text": "int x" }, "declared_type": { "model": "CInt", "qualifiers": [], - "source_text": "int len" + "source_text": "int x" }, "source_location": null, "callback_policy": null @@ -20011,16 +20352,61 @@ "callback_policy": null }, { - "name": "max_weight", + "name": "x0", "type": { - "model": "CInt", + "model": "CFloat", "qualifiers": [], - "source_text": "int max_weight" + "source_text": "float x0" }, "declared_type": { - "model": "CInt", + "model": "CFloat", "qualifiers": [], - "source_text": "int max_weight" + "source_text": "float x0" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "y0", + "type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float y0" + }, + "declared_type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float y0" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "x1", + "type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float x1" + }, + "declared_type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float x1" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "y1", + "type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float y1" + }, + "declared_type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float y1" }, "source_location": null, "callback_policy": null @@ -20035,197 +20421,73 @@ "prototype_style": "prototype", "source_location": { "filename": "stb/stb_truetype.h", - "line": 2882, + "line": 3028, "column": 1, - "source_line": "static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)" + "source_line": "static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1)" }, "start": { "filename": "stb/stb_truetype.h", - "line": 2882, + "line": 3028, "column": 1, - "source_line": "static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)" + "source_line": "static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1)" }, "end": { "filename": "stb/stb_truetype.h", - "line": 2922, + "line": 3063, "column": 1, "source_line": "}" }, "declaration_locations": [] }, - "stbtt__rasterize_sorted_edges": { - "name": "stbtt__rasterize_sorted_edges", + "stbtt__sized_trapezoid_area": { + "name": "stbtt__sized_trapezoid_area", "result_type": { - "model": "CVoid", + "model": "CFloat", "qualifiers": [], - "source_text": "void" + "source_text": "float" }, "parameters": [ { - "name": "result", - "type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "stbtt__bitmap *result", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "stbtt__bitmap" - } - ] - }, - "declared_type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "stbtt__bitmap *result", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "stbtt__bitmap" - } - ] - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "e", - "type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "stbtt__edge *e", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "stbtt__edge" - } - ] - }, - "declared_type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "stbtt__edge *e", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "stbtt__edge" - } - ] - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "n", + "name": "height", "type": { - "model": "CInt", + "model": "CFloat", "qualifiers": [], - "source_text": "int n" + "source_text": "float height" }, "declared_type": { - "model": "CInt", + "model": "CFloat", "qualifiers": [], - "source_text": "int n" + "source_text": "float height" }, "source_location": null, "callback_policy": null }, { - "name": "vsubsample", + "name": "top_width", "type": { - "model": "CInt", + "model": "CFloat", "qualifiers": [], - "source_text": "int vsubsample" + "source_text": "float top_width" }, "declared_type": { - "model": "CInt", + "model": "CFloat", "qualifiers": [], - "source_text": "int vsubsample" + "source_text": "float top_width" }, "source_location": null, "callback_policy": null }, { - "name": "off_x", + "name": "bottom_width", "type": { - "model": "CInt", + "model": "CFloat", "qualifiers": [], - "source_text": "int off_x" + "source_text": "float bottom_width" }, "declared_type": { - "model": "CInt", + "model": "CFloat", "qualifiers": [], - "source_text": "int off_x" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "off_y", - "type": { - "model": "CInt", - "qualifiers": [], - "source_text": "int off_y" - }, - "declared_type": { - "model": "CInt", - "qualifiers": [], - "source_text": "int off_y" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "userdata", - "type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "void *userdata", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "model": "CVoid", - "qualifiers": [], - "source_text": "void" - } - ] - }, - "declared_type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "void *userdata", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "model": "CVoid", - "qualifiers": [], - "source_text": "void" - } - ] + "source_text": "float bottom_width" }, "source_location": null, "callback_policy": null @@ -20240,177 +20502,103 @@ "prototype_style": "prototype", "source_location": { "filename": "stb/stb_truetype.h", - "line": 2924, + "line": 3065, "column": 1, - "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" + "source_line": "static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width)" }, "start": { "filename": "stb/stb_truetype.h", - "line": 2924, + "line": 3065, "column": 1, - "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" + "source_line": "static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width)" }, "end": { "filename": "stb/stb_truetype.h", - "line": 3022, + "line": 3070, "column": 1, "source_line": "}" }, "declaration_locations": [] }, - "stbtt__handle_clipped_edge": { - "name": "stbtt__handle_clipped_edge", + "stbtt__position_trapezoid_area": { + "name": "stbtt__position_trapezoid_area", "result_type": { - "model": "CVoid", + "model": "CFloat", "qualifiers": [], - "source_text": "void" + "source_text": "float" }, "parameters": [ { - "name": "scanline", - "type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "float *scanline", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "model": "CFloat", - "qualifiers": [], - "source_text": "float" - } - ] - }, - "declared_type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "float *scanline", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "model": "CFloat", - "qualifiers": [], - "source_text": "float" - } - ] - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "x", - "type": { - "model": "CInt", - "qualifiers": [], - "source_text": "int x" - }, - "declared_type": { - "model": "CInt", - "qualifiers": [], - "source_text": "int x" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "e", + "name": "height", "type": { - "model": "CComposedType", + "model": "CFloat", "qualifiers": [], - "source_text": "stbtt__active_edge *e", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "stbtt__active_edge" - } - ] + "source_text": "float height" }, "declared_type": { - "model": "CComposedType", + "model": "CFloat", "qualifiers": [], - "source_text": "stbtt__active_edge *e", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "stbtt__active_edge" - } - ] + "source_text": "float height" }, "source_location": null, "callback_policy": null }, { - "name": "x0", + "name": "tx0", "type": { "model": "CFloat", "qualifiers": [], - "source_text": "float x0" + "source_text": "float tx0" }, "declared_type": { "model": "CFloat", "qualifiers": [], - "source_text": "float x0" + "source_text": "float tx0" }, "source_location": null, "callback_policy": null }, { - "name": "y0", + "name": "tx1", "type": { "model": "CFloat", "qualifiers": [], - "source_text": "float y0" + "source_text": "float tx1" }, "declared_type": { "model": "CFloat", "qualifiers": [], - "source_text": "float y0" + "source_text": "float tx1" }, "source_location": null, "callback_policy": null }, { - "name": "x1", + "name": "bx0", "type": { "model": "CFloat", "qualifiers": [], - "source_text": "float x1" + "source_text": "float bx0" }, "declared_type": { "model": "CFloat", "qualifiers": [], - "source_text": "float x1" + "source_text": "float bx0" }, "source_location": null, "callback_policy": null }, { - "name": "y1", + "name": "bx1", "type": { "model": "CFloat", "qualifiers": [], - "source_text": "float y1" + "source_text": "float bx1" }, "declared_type": { "model": "CFloat", "qualifiers": [], - "source_text": "float y1" + "source_text": "float bx1" }, "source_location": null, "callback_policy": null @@ -20425,26 +20613,26 @@ "prototype_style": "prototype", "source_location": { "filename": "stb/stb_truetype.h", - "line": 3028, + "line": 3072, "column": 1, - "source_line": "static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1)" + "source_line": "static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1)" }, "start": { "filename": "stb/stb_truetype.h", - "line": 3028, + "line": 3072, "column": 1, - "source_line": "static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1)" + "source_line": "static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1)" }, "end": { "filename": "stb/stb_truetype.h", - "line": 3063, + "line": 3075, "column": 1, "source_line": "}" }, "declaration_locations": [] }, - "stbtt__sized_trapezoid_area": { - "name": "stbtt__sized_trapezoid_area", + "stbtt__sized_triangle_area": { + "name": "stbtt__sized_triangle_area", "result_type": { "model": "CFloat", "qualifiers": [], @@ -20467,31 +20655,16 @@ "callback_policy": null }, { - "name": "top_width", - "type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float top_width" - }, - "declared_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float top_width" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "bottom_width", + "name": "width", "type": { "model": "CFloat", "qualifiers": [], - "source_text": "float bottom_width" + "source_text": "float width" }, "declared_type": { "model": "CFloat", "qualifiers": [], - "source_text": "float bottom_width" + "source_text": "float width" }, "source_location": null, "callback_policy": null @@ -20506,230 +20679,53 @@ "prototype_style": "prototype", "source_location": { "filename": "stb/stb_truetype.h", - "line": 3065, + "line": 3077, "column": 1, - "source_line": "static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width)" + "source_line": "static float stbtt__sized_triangle_area(float height, float width)" }, "start": { "filename": "stb/stb_truetype.h", - "line": 3065, + "line": 3077, "column": 1, - "source_line": "static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width)" + "source_line": "static float stbtt__sized_triangle_area(float height, float width)" }, "end": { "filename": "stb/stb_truetype.h", - "line": 3070, + "line": 3080, "column": 1, "source_line": "}" }, "declaration_locations": [] }, - "stbtt__position_trapezoid_area": { - "name": "stbtt__position_trapezoid_area", + "stbtt__fill_active_edges_new": { + "name": "stbtt__fill_active_edges_new", "result_type": { - "model": "CFloat", + "model": "CVoid", "qualifiers": [], - "source_text": "float" + "source_text": "void" }, "parameters": [ { - "name": "height", + "name": "scanline", "type": { - "model": "CFloat", + "model": "CComposedType", "qualifiers": [], - "source_text": "float height" + "source_text": "float *scanline", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] }, "declared_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float height" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "tx0", - "type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float tx0" - }, - "declared_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float tx0" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "tx1", - "type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float tx1" - }, - "declared_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float tx1" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "bx0", - "type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float bx0" - }, - "declared_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float bx0" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "bx1", - "type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float bx1" - }, - "declared_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float bx1" - }, - "source_location": null, - "callback_policy": null - } - ], - "storage": [ - "static" - ], - "specifiers": [], - "is_variadic": false, - "is_definition": true, - "prototype_style": "prototype", - "source_location": { - "filename": "stb/stb_truetype.h", - "line": 3072, - "column": 1, - "source_line": "static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1)" - }, - "start": { - "filename": "stb/stb_truetype.h", - "line": 3072, - "column": 1, - "source_line": "static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1)" - }, - "end": { - "filename": "stb/stb_truetype.h", - "line": 3075, - "column": 1, - "source_line": "}" - }, - "declaration_locations": [] - }, - "stbtt__sized_triangle_area": { - "name": "stbtt__sized_triangle_area", - "result_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float" - }, - "parameters": [ - { - "name": "height", - "type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float height" - }, - "declared_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float height" - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "width", - "type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float width" - }, - "declared_type": { - "model": "CFloat", - "qualifiers": [], - "source_text": "float width" - }, - "source_location": null, - "callback_policy": null - } - ], - "storage": [ - "static" - ], - "specifiers": [], - "is_variadic": false, - "is_definition": true, - "prototype_style": "prototype", - "source_location": { - "filename": "stb/stb_truetype.h", - "line": 3077, - "column": 1, - "source_line": "static float stbtt__sized_triangle_area(float height, float width)" - }, - "start": { - "filename": "stb/stb_truetype.h", - "line": 3077, - "column": 1, - "source_line": "static float stbtt__sized_triangle_area(float height, float width)" - }, - "end": { - "filename": "stb/stb_truetype.h", - "line": 3080, - "column": 1, - "source_line": "}" - }, - "declaration_locations": [] - }, - "stbtt__fill_active_edges_new": { - "name": "stbtt__fill_active_edges_new", - "result_type": { - "model": "CVoid", - "qualifiers": [], - "source_text": "void" - }, - "parameters": [ - { - "name": "scanline", - "type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "float *scanline", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "model": "CFloat", - "qualifiers": [], - "source_text": "float" - } - ] - }, - "declared_type": { - "model": "CComposedType", + "model": "CComposedType", "qualifiers": [], "source_text": "float *scanline", "components": [ @@ -25377,115 +25373,919 @@ "column": 4, "source_line": " #include " } - } - }, - "functions_by_file": { - "stb/stb_truetype.h": [ - "my_stbtt_initfont", - "my_stbtt_print", - "main", - "stbtt__buf_get8", - "stbtt__buf_peek8", - "stbtt__buf_seek", - "stbtt__buf_skip", - "stbtt__buf_get", - "stbtt__new_buf", - "stbtt__buf_range", - "stbtt__cff_get_index", - "stbtt__cff_int", - "stbtt__cff_skip_operand", - "stbtt__dict_get", - "stbtt__dict_get_ints", - "stbtt__cff_index_count", - "stbtt__cff_index_get", - "ttUSHORT", - "ttSHORT", - "ttULONG", - "ttLONG", - "stbtt__isfont", - "stbtt__find_table", - "stbtt_GetFontOffsetForIndex_internal", - "stbtt_GetNumberOfFonts_internal", - "stbtt__get_subrs", - "stbtt__get_svg", - "stbtt_InitFont_internal", - "stbtt_setvertex", - "stbtt__GetGlyfOffset", - "stbtt__GetGlyphInfoT2", - "stbtt__close_shape", - "stbtt__GetGlyphShapeTT", - "stbtt__track_vertex", - "stbtt__csctx_v", - "stbtt__csctx_close_shape", - "stbtt__csctx_rmove_to", - "stbtt__csctx_rline_to", - "stbtt__csctx_rccurve_to", - "stbtt__get_subr", - "stbtt__cid_get_glyph_subrs", - "stbtt__run_charstring", - "stbtt__GetGlyphShapeT2", - "stbtt__GetGlyphKernInfoAdvance", - "stbtt__GetCoverageIndex", - "stbtt__GetGlyphClass", - "stbtt__GetGlyphGPOSInfoAdvance", - "stbtt__hheap_alloc", - "stbtt__hheap_free", - "stbtt__hheap_cleanup", - "stbtt__new_active", - "stbtt__fill_active_edges", - "stbtt__rasterize_sorted_edges", - "stbtt__handle_clipped_edge", - "stbtt__sized_trapezoid_area", - "stbtt__position_trapezoid_area", - "stbtt__sized_triangle_area", - "stbtt__fill_active_edges_new", - "stbtt__sort_edges_ins_sort", - "stbtt__sort_edges_quicksort", - "stbtt__sort_edges", - "stbtt__rasterize", - "stbtt__add_point", - "stbtt__tesselate_curve", - "stbtt__tesselate_cubic", - "stbtt_FlattenCurves", - "stbtt_BakeFontBitmap_internal", - "stbrp_init_target", - "stbrp_pack_rects", - "stbtt__h_prefilter", - "stbtt__v_prefilter", - "stbtt__oversample_shift", - "stbtt__ray_intersect_bezier", - "equal", - "stbtt__compute_crossings_x", - "stbtt__cuberoot", - "stbtt__solve_cubic", - "stbtt__CompareUTF8toUTF16_bigendian_prefix", - "stbtt_CompareUTF8toUTF16_bigendian_internal", - "stbtt__matchpair", - "stbtt__matches", - "stbtt_FindMatchingFont_internal" - ] - }, - "enum_constants": {}, - "include_graph": { - "stb/stb_truetype.h": [ - "stb/stb_truetype.h" - ] - }, - "system_includes": { - "stb/stb_truetype.h": [ - "assert.h", - "math.h", - "stdio.h", - "stdlib.h", - "string.h" + } + }, + "functions_by_file": { + "stb/stb_truetype.h": [ + "my_stbtt_initfont", + "my_stbtt_print", + "main", + "stbtt__buf_get8", + "stbtt__buf_peek8", + "stbtt__buf_seek", + "stbtt__buf_skip", + "stbtt__buf_get", + "stbtt__new_buf", + "stbtt__buf_range", + "stbtt__cff_get_index", + "stbtt__cff_int", + "stbtt__cff_skip_operand", + "stbtt__dict_get", + "stbtt__dict_get_ints", + "stbtt__cff_index_count", + "stbtt__cff_index_get", + "ttUSHORT", + "ttSHORT", + "ttULONG", + "ttLONG", + "stbtt__isfont", + "stbtt__find_table", + "stbtt_GetFontOffsetForIndex_internal", + "stbtt_GetNumberOfFonts_internal", + "stbtt__get_subrs", + "stbtt__get_svg", + "stbtt_InitFont_internal", + "stbtt_setvertex", + "stbtt__GetGlyfOffset", + "stbtt__GetGlyphInfoT2", + "stbtt__close_shape", + "stbtt__GetGlyphShapeTT", + "stbtt__track_vertex", + "stbtt__csctx_v", + "stbtt__csctx_close_shape", + "stbtt__csctx_rmove_to", + "stbtt__csctx_rline_to", + "stbtt__csctx_rccurve_to", + "stbtt__get_subr", + "stbtt__cid_get_glyph_subrs", + "stbtt__run_charstring", + "stbtt__GetGlyphShapeT2", + "stbtt__GetGlyphKernInfoAdvance", + "stbtt__GetCoverageIndex", + "stbtt__GetGlyphClass", + "stbtt__GetGlyphGPOSInfoAdvance", + "stbtt__hheap_alloc", + "stbtt__hheap_free", + "stbtt__hheap_cleanup", + "stbtt__new_active", + "stbtt__new_active", + "stbtt__fill_active_edges", + "stbtt__rasterize_sorted_edges", + "stbtt__handle_clipped_edge", + "stbtt__sized_trapezoid_area", + "stbtt__position_trapezoid_area", + "stbtt__sized_triangle_area", + "stbtt__fill_active_edges_new", + "stbtt__rasterize_sorted_edges", + "stbtt__sort_edges_ins_sort", + "stbtt__sort_edges_quicksort", + "stbtt__sort_edges", + "stbtt__rasterize", + "stbtt__add_point", + "stbtt__tesselate_curve", + "stbtt__tesselate_cubic", + "stbtt_FlattenCurves", + "stbtt_BakeFontBitmap_internal", + "stbrp_init_target", + "stbrp_pack_rects", + "stbtt__h_prefilter", + "stbtt__v_prefilter", + "stbtt__oversample_shift", + "stbtt__ray_intersect_bezier", + "equal", + "stbtt__compute_crossings_x", + "stbtt__cuberoot", + "stbtt__solve_cubic", + "stbtt__CompareUTF8toUTF16_bigendian_prefix", + "stbtt_CompareUTF8toUTF16_bigendian_internal", + "stbtt__matchpair", + "stbtt__matches", + "stbtt_FindMatchingFont_internal" + ] + }, + "enum_constants": {}, + "include_graph": { + "stb/stb_truetype.h": [ + "stb/stb_truetype.h" + ] + }, + "system_includes": { + "stb/stb_truetype.h": [ + "assert.h", + "math.h", + "stdio.h", + "stdlib.h", + "string.h" + ] + }, + "unresolved_includes": { + "stb/stb_truetype.h": [] + }, + "header_source_pairs": { + "stb/stb_truetype.h": [] + }, + "conditional_function_variants": { + "stbtt__new_active": [ + { + "name": "stbtt__new_active", + "result_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__active_edge", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__active_edge" + } + ] + }, + "parameters": [ + { + "name": "hh", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__hheap *hh", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__hheap" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__hheap *hh", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__hheap" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "e", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "off_x", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "start_point", + "type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float start_point" + }, + "declared_type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float start_point" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "userdata", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_truetype.h", + "line": 2835, + "column": 1, + "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" + }, + "start": { + "filename": "stb/stb_truetype.h", + "line": 2835, + "column": 1, + "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" + }, + "end": { + "filename": "stb/stb_truetype.h", + "line": 2855, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g22:b0", + "g28:b0" + ] + }, + { + "name": "stbtt__new_active", + "result_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__active_edge", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__active_edge" + } + ] + }, + "parameters": [ + { + "name": "hh", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__hheap *hh", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__hheap" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__hheap *hh", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__hheap" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "e", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "off_x", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "start_point", + "type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float start_point" + }, + "declared_type": { + "model": "CFloat", + "qualifiers": [], + "source_text": "float start_point" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "userdata", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_truetype.h", + "line": 2857, + "column": 1, + "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" + }, + "start": { + "filename": "stb/stb_truetype.h", + "line": 2857, + "column": 1, + "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" + }, + "end": { + "filename": "stb/stb_truetype.h", + "line": 2873, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g22:b0", + "g28:b1" + ] + } + ], + "stbtt__rasterize_sorted_edges": [ + { + "name": "stbtt__rasterize_sorted_edges", + "result_type": { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + }, + "parameters": [ + { + "name": "result", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__bitmap *result", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__bitmap" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__bitmap *result", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__bitmap" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "e", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "n", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "vsubsample", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int vsubsample" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int vsubsample" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "off_x", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "off_y", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_y" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_y" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "userdata", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_truetype.h", + "line": 2924, + "column": 1, + "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" + }, + "start": { + "filename": "stb/stb_truetype.h", + "line": 2924, + "column": 1, + "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" + }, + "end": { + "filename": "stb/stb_truetype.h", + "line": 3022, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g22:b0", + "g29:b0" + ] + }, + { + "name": "stbtt__rasterize_sorted_edges", + "result_type": { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + }, + "parameters": [ + { + "name": "result", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__bitmap *result", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__bitmap" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__bitmap *result", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__bitmap" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "e", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "stbtt__edge *e", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "stbtt__edge" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "n", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "vsubsample", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int vsubsample" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int vsubsample" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "off_x", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_x" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "off_y", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_y" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int off_y" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "userdata", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "void *userdata", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + } + ] + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_truetype.h", + "line": 3297, + "column": 1, + "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" + }, + "start": { + "filename": "stb/stb_truetype.h", + "line": 3297, + "column": 1, + "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" + }, + "end": { + "filename": "stb/stb_truetype.h", + "line": 3392, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g22:b0", + "g29:b1" + ] + } ] }, - "unresolved_includes": { - "stb/stb_truetype.h": [] - }, - "header_source_pairs": { - "stb/stb_truetype.h": [] - }, "diagnostics": [ { "code": "C_UNSUPPORTED_FUNCTION_LIKE_MACRO", @@ -26656,32 +27456,6 @@ }, "unit_kind": "function", "unit_name": "main" - }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'stbtt__new_active'.", - "severity": "error", - "location": { - "filename": "stb/stb_truetype.h", - "line": 2857, - "column": 1, - "source_line": "static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)" - }, - "unit_kind": "function", - "unit_name": "stbtt__new_active" - }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'stbtt__rasterize_sorted_edges'.", - "severity": "error", - "location": { - "filename": "stb/stb_truetype.h", - "line": 3297, - "column": 1, - "source_line": "static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)" - }, - "unit_kind": "function", - "unit_name": "stbtt__rasterize_sorted_edges" } ] } diff --git a/tests/parser/c/fixtures/stb/stb_vorbis.json b/tests/parser/c/fixtures/stb/stb_vorbis.json index d21dacff5..4dab52f36 100644 --- a/tests/parser/c/fixtures/stb/stb_vorbis.json +++ b/tests/parser/c/fixtures/stb/stb_vorbis.json @@ -8610,7 +8610,153 @@ "column": 1, "source_line": "}" }, - "declaration_locations": [] + "declaration_locations": [], + "condition_set": [ + "g13:b0", + "g72:b0" + ] + }, + { + "name": "inverse_mdct_slow", + "result_type": { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + }, + "parameters": [ + { + "name": "buffer", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "n", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "f", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "vorb *f", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "vorb" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "vorb *f", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "vorb" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "blocktype", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int blocktype" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int blocktype" + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_vorbis.c", + "line": 2312, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" + }, + "start": { + "filename": "stb/stb_vorbis.c", + "line": 2312, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" + }, + "end": { + "filename": "stb/stb_vorbis.c", + "line": 2329, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g13:b0", + "g72:b1" + ] }, { "name": "dct_iv_slow", @@ -8700,6 +8846,148 @@ }, "declaration_locations": [] }, + { + "name": "inverse_mdct_slow", + "result_type": { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + }, + "parameters": [ + { + "name": "buffer", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "n", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "f", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "vorb *f", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "vorb" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "vorb *f", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "vorb" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "blocktype", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int blocktype" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int blocktype" + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_vorbis.c", + "line": 2350, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" + }, + "start": { + "filename": "stb/stb_vorbis.c", + "line": 2350, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" + }, + "end": { + "filename": "stb/stb_vorbis.c", + "line": 2361, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g13:b0", + "g72:b2" + ] + }, { "name": "mdct_init", "result_type": { @@ -21721,32 +22009,6 @@ "unit_kind": "typedef", "unit_name": "YTYPE" }, - { - "code": "C_CONFLICTING_FUNCTION_DECLARATION", - "message": "Conflicting declarations for function 'inverse_mdct_slow'.", - "severity": "error", - "location": { - "filename": "stb/stb_vorbis.c", - "line": 2312, - "column": 1, - "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" - }, - "unit_kind": "function", - "unit_name": "inverse_mdct_slow" - }, - { - "code": "C_CONFLICTING_FUNCTION_DECLARATION", - "message": "Conflicting declarations for function 'inverse_mdct_slow'.", - "severity": "error", - "location": { - "filename": "stb/stb_vorbis.c", - "line": 2350, - "column": 1, - "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" - }, - "unit_kind": "function", - "unit_name": "inverse_mdct_slow" - }, { "code": "C_DUPLICATE_FUNCTION_DEFINITION", "message": "Duplicate definition for function 'inverse_mdct'.", @@ -26644,94 +26906,6 @@ }, "declaration_locations": [] }, - "inverse_mdct_slow": { - "name": "inverse_mdct_slow", - "result_type": { - "model": "CVoid", - "qualifiers": [], - "source_text": "void" - }, - "parameters": [ - { - "name": "buffer", - "type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "float *buffer", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "model": "CFloat", - "qualifiers": [], - "source_text": "float" - } - ] - }, - "declared_type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "float *buffer", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "model": "CFloat", - "qualifiers": [], - "source_text": "float" - } - ] - }, - "source_location": null, - "callback_policy": null - }, - { - "name": "n", - "type": { - "model": "CInt", - "qualifiers": [], - "source_text": "int n" - }, - "declared_type": { - "model": "CInt", - "qualifiers": [], - "source_text": "int n" - }, - "source_location": null, - "callback_policy": null - } - ], - "storage": [], - "specifiers": [], - "is_variadic": false, - "is_definition": true, - "prototype_style": "prototype", - "source_location": { - "filename": "stb/stb_vorbis.c", - "line": 2289, - "column": 1, - "source_line": "void inverse_mdct_slow(float *buffer, int n)" - }, - "start": { - "filename": "stb/stb_vorbis.c", - "line": 2289, - "column": 1, - "source_line": "void inverse_mdct_slow(float *buffer, int n)" - }, - "end": { - "filename": "stb/stb_vorbis.c", - "line": 2309, - "column": 1, - "source_line": "}" - }, - "declaration_locations": [] - }, "dct_iv_slow": { "name": "dct_iv_slow", "result_type": { @@ -35986,7 +36160,9 @@ "residue_decode", "decode_residue", "inverse_mdct_slow", + "inverse_mdct_slow", "dct_iv_slow", + "inverse_mdct_slow", "mdct_init", "mdct_clear", "mdct_backward", @@ -36100,6 +36276,386 @@ "stb/stb_vorbis.c": [] }, "header_source_pairs": {}, + "conditional_function_variants": { + "inverse_mdct_slow": [ + { + "name": "inverse_mdct_slow", + "result_type": { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + }, + "parameters": [ + { + "name": "buffer", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "n", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_vorbis.c", + "line": 2289, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n)" + }, + "start": { + "filename": "stb/stb_vorbis.c", + "line": 2289, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n)" + }, + "end": { + "filename": "stb/stb_vorbis.c", + "line": 2309, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g13:b0", + "g72:b0" + ] + }, + { + "name": "inverse_mdct_slow", + "result_type": { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + }, + "parameters": [ + { + "name": "buffer", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "n", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "f", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "vorb *f", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "vorb" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "vorb *f", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "vorb" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "blocktype", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int blocktype" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int blocktype" + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_vorbis.c", + "line": 2312, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" + }, + "start": { + "filename": "stb/stb_vorbis.c", + "line": 2312, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" + }, + "end": { + "filename": "stb/stb_vorbis.c", + "line": 2329, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g13:b0", + "g72:b1" + ] + }, + { + "name": "inverse_mdct_slow", + "result_type": { + "model": "CVoid", + "qualifiers": [], + "source_text": "void" + }, + "parameters": [ + { + "name": "buffer", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "float *buffer", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CFloat", + "qualifiers": [], + "source_text": "float" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "n", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int n" + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "f", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "vorb *f", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "vorb" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "vorb *f", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "vorb" + } + ] + }, + "source_location": null, + "callback_policy": null + }, + { + "name": "blocktype", + "type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int blocktype" + }, + "declared_type": { + "model": "CInt", + "qualifiers": [], + "source_text": "int blocktype" + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "stb/stb_vorbis.c", + "line": 2350, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" + }, + "start": { + "filename": "stb/stb_vorbis.c", + "line": 2350, + "column": 1, + "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" + }, + "end": { + "filename": "stb/stb_vorbis.c", + "line": 2361, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g13:b0", + "g72:b2" + ] + } + ] + }, "diagnostics": [ { "code": "C_UNSUPPORTED_FUNCTION_LIKE_MACRO", @@ -36673,32 +37229,6 @@ "unit_kind": "typedef", "unit_name": "YTYPE" }, - { - "code": "C_CONFLICTING_FUNCTION_DECLARATION", - "message": "Conflicting declarations for function 'inverse_mdct_slow'.", - "severity": "error", - "location": { - "filename": "stb/stb_vorbis.c", - "line": 2312, - "column": 1, - "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" - }, - "unit_kind": "function", - "unit_name": "inverse_mdct_slow" - }, - { - "code": "C_CONFLICTING_FUNCTION_DECLARATION", - "message": "Conflicting declarations for function 'inverse_mdct_slow'.", - "severity": "error", - "location": { - "filename": "stb/stb_vorbis.c", - "line": 2350, - "column": 1, - "source_line": "void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)" - }, - "unit_kind": "function", - "unit_name": "inverse_mdct_slow" - }, { "code": "C_DUPLICATE_FUNCTION_DEFINITION", "message": "Duplicate definition for function 'inverse_mdct'.", diff --git a/tests/parser/c/fixtures/tinyexpr/tinyexpr.json b/tests/parser/c/fixtures/tinyexpr/tinyexpr.json index dc68ca1b8..c1b735458 100644 --- a/tests/parser/c/fixtures/tinyexpr/tinyexpr.json +++ b/tests/parser/c/fixtures/tinyexpr/tinyexpr.json @@ -2013,7 +2013,100 @@ "column": 1, "source_line": "}" }, - "declaration_locations": [] + "declaration_locations": [], + "condition_set": [ + "g5:b0" + ] + }, + { + "name": "factor", + "result_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "te_expr", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "model": "CTypedef", + "qualifiers": [], + "source_text": "te_expr", + "name": "te_expr", + "type": null, + "source_location": null, + "declaration_locations": [] + } + ] + }, + "parameters": [ + { + "name": "s", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "state *s", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "state" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "state *s", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "state" + } + ] + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "tinyexpr/tinyexpr.c", + "line": 503, + "column": 1, + "source_line": "static te_expr *factor(state *s) {" + }, + "start": { + "filename": "tinyexpr/tinyexpr.c", + "line": 503, + "column": 1, + "source_line": "static te_expr *factor(state *s) {" + }, + "end": { + "filename": "tinyexpr/tinyexpr.c", + "line": 522, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g5:b1" + ] }, { "name": "term", @@ -3470,19 +3563,6 @@ }, "unit_kind": "macro", "unit_name": "M" - }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'factor'.", - "severity": "error", - "location": { - "filename": "tinyexpr/tinyexpr.c", - "line": 503, - "column": 1, - "source_line": "static te_expr *factor(state *s) {" - }, - "unit_kind": "function", - "unit_name": "factor" } ] }, @@ -5136,87 +5216,6 @@ }, "declaration_locations": [] }, - "factor": { - "name": "factor", - "result_type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "te_expr", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "te_expr" - } - ] - }, - "parameters": [ - { - "name": "s", - "type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "state *s", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "state" - } - ] - }, - "declared_type": { - "model": "CComposedType", - "qualifiers": [], - "source_text": "state *s", - "components": [ - { - "model": "CPointer", - "qualifiers": [], - "source_text": "" - }, - { - "reference": "state" - } - ] - }, - "source_location": null, - "callback_policy": null - } - ], - "storage": [ - "static" - ], - "specifiers": [], - "is_variadic": false, - "is_definition": true, - "prototype_style": "prototype", - "source_location": { - "filename": "tinyexpr/tinyexpr.c", - "line": 448, - "column": 1, - "source_line": "static te_expr *factor(state *s) {" - }, - "start": { - "filename": "tinyexpr/tinyexpr.c", - "line": 448, - "column": 1, - "source_line": "static te_expr *factor(state *s) {" - }, - "end": { - "filename": "tinyexpr/tinyexpr.c", - "line": 501, - "column": 1, - "source_line": "}" - }, - "declaration_locations": [] - }, "term": { "name": "term", "result_type": { @@ -6189,6 +6188,7 @@ "power", "base", "factor", + "factor", "term", "te_eval", "optimize", @@ -6327,6 +6327,178 @@ "tinyexpr/tinyexpr.c" ] }, + "conditional_function_variants": { + "factor": [ + { + "name": "factor", + "result_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "te_expr", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "te_expr" + } + ] + }, + "parameters": [ + { + "name": "s", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "state *s", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "state" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "state *s", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "state" + } + ] + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "tinyexpr/tinyexpr.c", + "line": 448, + "column": 1, + "source_line": "static te_expr *factor(state *s) {" + }, + "start": { + "filename": "tinyexpr/tinyexpr.c", + "line": 448, + "column": 1, + "source_line": "static te_expr *factor(state *s) {" + }, + "end": { + "filename": "tinyexpr/tinyexpr.c", + "line": 501, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g5:b0" + ] + }, + { + "name": "factor", + "result_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "te_expr", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "te_expr" + } + ] + }, + "parameters": [ + { + "name": "s", + "type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "state *s", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "state" + } + ] + }, + "declared_type": { + "model": "CComposedType", + "qualifiers": [], + "source_text": "state *s", + "components": [ + { + "model": "CPointer", + "qualifiers": [], + "source_text": "" + }, + { + "reference": "state" + } + ] + }, + "source_location": null, + "callback_policy": null + } + ], + "storage": [ + "static" + ], + "specifiers": [], + "is_variadic": false, + "is_definition": true, + "prototype_style": "prototype", + "source_location": { + "filename": "tinyexpr/tinyexpr.c", + "line": 503, + "column": 1, + "source_line": "static te_expr *factor(state *s) {" + }, + "start": { + "filename": "tinyexpr/tinyexpr.c", + "line": 503, + "column": 1, + "source_line": "static te_expr *factor(state *s) {" + }, + "end": { + "filename": "tinyexpr/tinyexpr.c", + "line": 522, + "column": 1, + "source_line": "}" + }, + "declaration_locations": [], + "condition_set": [ + "g5:b1" + ] + } + ] + }, "diagnostics": [ { "code": "C_UNSUPPORTED_FUNCTION_LIKE_MACRO", @@ -6445,19 +6617,6 @@ "unit_kind": "macro", "unit_name": "M" }, - { - "code": "C_DUPLICATE_FUNCTION_DEFINITION", - "message": "Duplicate definition for function 'factor'.", - "severity": "error", - "location": { - "filename": "tinyexpr/tinyexpr.c", - "line": 503, - "column": 1, - "source_line": "static te_expr *factor(state *s) {" - }, - "unit_kind": "function", - "unit_name": "factor" - }, { "code": "C_UNSUPPORTED_DECLARATOR", "message": "Unsupported declarator syntax after parsed type layers: '\"C\"'.", diff --git a/tests/parser/c/test_c_lexer_preprocessor.py b/tests/parser/c/test_c_lexer_preprocessor.py index b3f53a168..85d29d57a 100644 --- a/tests/parser/c/test_c_lexer_preprocessor.py +++ b/tests/parser/c/test_c_lexer_preprocessor.py @@ -199,6 +199,55 @@ def test_raw_conditional_directives_do_not_select_active_branches(): ] +def test_raw_mode_keeps_incompatible_function_variants_from_alternative_branches(): + from c_parser import parse_c_file + + parsed = parse_c_file( + """ +#ifdef USE_FLOAT +float scale(float value); +#else +double scale(double value); +#endif +""", + filename="conditional_signature.h", + preprocessing="raw", + ) + + assert [fn.name for fn in parsed.functions] == ["scale", "scale"] + assert [fn.condition_set for fn in parsed.functions] == [ + frozenset({"g1:b0"}), + frozenset({"g1:b1"}), + ] + assert not any( + diag.code == "C_CONFLICTING_FUNCTION_DECLARATION" + for diag in parsed.diagnostics + ) + assert parsed.to_dict()["functions"][0]["condition_set"] == ["g1:b0"] + + +def test_raw_mode_does_not_treat_independent_conditional_groups_as_exclusive(): + from c_parser import parse_c_file + + parsed = parse_c_file( + """ +#ifdef USE_FLOAT +float scale(float value); +#endif +#ifdef USE_DOUBLE +double scale(double value); +#endif +""", + filename="overlapping_signatures.h", + preprocessing="raw", + ) + + assert any( + diag.code == "C_CONFLICTING_FUNCTION_DECLARATION" + for diag in parsed.diagnostics + ) + + def test_raw_mode_records_pragmas_as_metadata_without_hiding_declarations(): from c_parser import parse_c_file diff --git a/tests/parser/c/test_c_project_resolution.py b/tests/parser/c/test_c_project_resolution.py index 1e2bbfab9..573fea1ca 100644 --- a/tests/parser/c/test_c_project_resolution.py +++ b/tests/parser/c/test_c_project_resolution.py @@ -39,6 +39,40 @@ def test_project_resolves_quoted_includes_through_include_dirs(tmp_path: Path): assert project.unresolved_includes[str(api)] == set() +def test_project_records_local_include_without_recursively_parsing_resolved_header(tmp_path: Path): + from c_parser import parse_c_project + + include_dir = tmp_path / "generated" + include_dir.mkdir() + generated = include_dir / "generated_types.h" + api = tmp_path / "api.h" + generated.write_text("typedef int generated_int;\n", encoding="utf-8") + api.write_text('#include "generated_types.h"\nint run(void);\n', encoding="utf-8") + + project = parse_c_project([api], include_dirs=[include_dir]) + + assert set(project.files) == {str(api)} + assert project.files[str(api)].includes[0].resolved_path == str(generated) + assert project.include_graph[str(api)] == {str(generated)} + assert "generated_int" not in project.typedefs + + +def test_project_records_system_include_without_searching_or_parsing_local_copy(tmp_path: Path): + from c_parser import parse_c_project + + local_system_header = tmp_path / "stddef.h" + api = tmp_path / "api.h" + local_system_header.write_text("typedef unsigned long size_t;\n", encoding="utf-8") + api.write_text("#include \nint run(void);\n", encoding="utf-8") + + project = parse_c_project([api], include_dirs=[tmp_path]) + + assert set(project.files) == {str(api)} + assert project.files[str(api)].includes[0].resolved_path is None + assert project.system_includes[str(api)] == {"stddef.h"} + assert "size_t" not in project.typedefs + + def test_parse_c_project_directory_discovers_preprocessed_i_files(tmp_path: Path): from c_parser import parse_c_project @@ -61,6 +95,34 @@ def test_parse_c_project_directory_discovers_preprocessed_i_files(tmp_path: Path assert generated.to_dict()["functions"][0]["origin"] == "preprocessed" +def test_project_retains_mutually_exclusive_function_variants_out_of_unique_index(): + from c_parser import parse_c_project + + project = parse_c_project( + { + "api.h": """ +#ifdef API_V2 +int configure(int option); +#else +double configure(double option); +#endif +""" + } + ) + + assert "configure" not in project.functions + assert [fn.condition_set for fn in project.conditional_function_variants["configure"]] == [ + frozenset({"g1:b0"}), + frozenset({"g1:b1"}), + ] + assert not any( + diag.code == "C_CONFLICTING_FUNCTION_DECLARATION" + for diag in project.diagnostics + ) + payload = project.to_dict() + assert payload["conditional_function_variants"]["configure"][0]["condition_set"] == ["g1:b0"] + + def test_project_indexes_functions_by_file_and_enum_constants(tmp_path: Path): from c_parser import parse_c_project diff --git a/tests/parser/c/test_c_public_api_skeleton.py b/tests/parser/c/test_c_public_api_skeleton.py index 25e82cbb1..b146871dd 100644 --- a/tests/parser/c/test_c_public_api_skeleton.py +++ b/tests/parser/c/test_c_public_api_skeleton.py @@ -16,6 +16,17 @@ def test_parse_c_file_accepts_inline_source_and_returns_typed_model(): assert [fn.name for fn in parsed.functions] == ["add"] +def test_x2py_exports_c_file_and_project_entrypoints_like_fortran(): + from x2py import CFile, CProject, parse_c_file, parse_c_project + + parsed = parse_c_file("int add(int left, int right);\n", filename="api.h") + project = parse_c_project({"api.h": "int add(int left, int right);\n"}) + + assert isinstance(parsed, CFile) + assert isinstance(project, CProject) + assert "add" in project.functions + + def test_parse_c_file_accepts_path_input_and_preserves_filename(tmp_path: Path): from c_parser import parse_c_file diff --git a/x2py/__init__.py b/x2py/__init__.py index 5f25e1c52..e0fbbce9e 100644 --- a/x2py/__init__.py +++ b/x2py/__init__.py @@ -2,6 +2,8 @@ from importlib import import_module +from c_parser.models import CFile, CParseError, CProject +from c_parser.parser import parse_c_file, parse_c_project from fortran_parser.models import ( FortranArgument, FortranBlockData, @@ -44,6 +46,9 @@ def __getattr__(name: str): raise AttributeError(f"module 'x2py' has no attribute {name!r}") __all__ = ( + "CFile", + "CParseError", + "CProject", "FortranTypeProbeError", "FortranTypeProbeReport", "FortranArgument", @@ -68,6 +73,8 @@ def __getattr__(name: str): "fortran_module_to_semantic_module", "load_pyi_file", "main", + "parse_c_file", + "parse_c_project", "parse_fortran_file", "parse_fortran_project", "parse_pyi_text",