Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture

This chapter explains how ROUP is organised internally and where to look when modifying the parser or the public bindings.

High level view

source text
   │
   ▼
lexer (`src/lexer.rs`)
   │  ─ token stream with language specific helpers
   ▼
parser (`src/parser/`)
   │  ─ builds an intermediate representation (IR)
   ▼
IR (`src/ir/`)
   │  ├─ used directly by Rust callers
   │  └─ converted into the C API data structures
   ▼
C bindings (`src/c_api.rs`)

The lexer normalises whitespace, line continuations, sentinel comments, and language specific keywords before the parser consumes the token stream. The parser modules mirror the OpenMP structure: directives, clauses, helper enumerations, and validation passes. Rust callers typically work with the IR structures directly, while C and C++ consumers receive stable C structs exposed through the FFI layer.

Unsafe code boundaries

The vast majority of the project uses safe Rust. The only unsafe blocks live inside src/c_api.rs where pointers cross the FFI boundary. Each function performs explicit null checks and documents its expectations. When modifying or adding FFI functions, keep the following rules in mind:

  • Convert raw pointers to Rust types as late as possible and convert back only when returning values to the caller.
  • Maintain ownership invariants: the caller is responsible for freeing values returned by constructors and must not free borrowed data.
  • Update the generated C constants header whenever the exported structs or enums change.

Generated constants and headers

The build script (build.rs) parses portions of src/c_api.rs using syn to produce src/roup_constants.h (also emitted to OUT_DIR). This keeps the OpenMP and OpenACC directive/clause tables in sync with the Rust implementation.

Compatibility layers

  • compat/ompparser/ mirrors the original ompparser API, forwarding calls through the ROUP C API and converting the resulting structures back into the expected C++ types. The CMake tests in the ompparser submodule validate parity.
  • compat/accparser/ provides the same drop-in experience for accparser with ROUP_ACC_* constants and the upstream ctest suite.

Testing

Integration tests live under tests/ and cover keyword registration, parser round-trips, language specific behaviour, and helper utilities. Running cargo test executes the Rust suites, while test.sh orchestrates the full project matrix including compatibility and documentation builds.