Skip to content

Support custom types#303

Open
davispuh wants to merge 4 commits into
jacob-carlborg:masterfrom
davispuh:types
Open

Support custom types#303
davispuh wants to merge 4 commits into
jacob-carlborg:masterfrom
davispuh:types

Conversation

@davispuh

Copy link
Copy Markdown

Consider C code like:

#define FIELD_PTR(Record, TYPE, Field) ((TYPE *)&((Record)->Field))

Currently dstep is not able to parse such macro definition because cast's TYPE is not known at definition time but will be only known at usage time. So such definitions are just ignored.

This PR implements support for custom types that doesn't need to be known at definition time.
Note that it's not trivial to determine where (SYMBOL) is cast with a type or simply a parameter/value so after parsing we use fixCasts to try to fix these places with correct usage.

We also repurpose CXTypeKind.unexposed for these custom type definitions.

With this PR result for such macro definition will be:

extern (D) auto FIELD_PTR(T0, T1, T2)(auto ref T0 Record, auto ref T1 TYPE, auto ref T2 Field)
{
    return cast(TYPE*) &(Record.Field);
}

Note that this change has a side effect that definitions like:

#define __unused  __attribute__((__unused__))
#define CONST  const
#define STATIC  static

Will be converted to:

enum __unused = __attribute__(__unused__);
enum CONST = const;
enum STATIC = static;

While previously they were simply dropped.
But I consider this to be wanted change to convert as much code as possible and I will submit another PR that will comment out invalid code.

Copilot AI review requested due to automatic review settings March 19, 2026 18:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends dstep’s macro parsing and type translation to support “custom” type placeholders (types not known at macro definition time) by representing them as CXTypeKind.unexposed and post-processing ambiguous cast-like patterns.

Changes:

  • Update type translation helpers to take a full clang.Type and emit unexposed type spellings when no declaration is available.
  • Extend macro type-name parsing to optionally accept arbitrary identifiers as type-names in cast/sizeof contexts.
  • Add a fixCasts post-pass to rewrite some ambiguous (SYMBOL) <unary-op> ... parses into binary operator expressions when SYMBOL matches a macro parameter.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
dstep/translator/Type.d Adjusts low-level type translation to accept Type and emit spelling for unexposed when needed for custom-type macros.
dstep/translator/MacroParser.d Adds “any type” parsing in cast/sizeof, accepts keywords as identifiers in primary expressions, and introduces fixCasts post-processing.
Comments suppressed due to low confidence (1)

dstep/translator/MacroParser.d:981

  • parseCastExpr now calls parseTypeName(..., anyType=true), which will treat any identifier in parentheses as a type (via CXTypeKind.unexposed). This makes patterns like (bar)(a) parse as a cast to the unknown type bar instead of a function call bar(a), regressing existing behavior (there are unit tests for translating (bar)(a) as a call). Consider tightening the heuristic: only accept an unexposed identifier as a type in cast context when it can be proven to be a type (e.g., present in the type table) or when it matches a macro type-parameter, and otherwise fall back to parsing as a parenthesized expression/call.
Expression parseCastExpr(ref Token[] tokens, Cursor[string] table, bool defined)
{
    auto local = tokens;

    if (!accept!("(")(local, TokenKind.punctuation))
        return parseUnaryExpr(tokens, table, defined);

    Type type = parseTypeName(local, table, true);

    if (!type.isValid)
        return parseUnaryExpr(tokens, table, defined);

    if (!accept!(")")(local, TokenKind.punctuation))
        return parseUnaryExpr(tokens, table, defined);


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread dstep/translator/MacroParser.d
Comment thread dstep/translator/MacroParser.d
Comment thread dstep/translator/MacroParser.d
@davispuh

Copy link
Copy Markdown
Author

Improved this PR and added tests. Also rebased it on top of #304 so that PR is included here aswell.

@davispuh

Copy link
Copy Markdown
Author

I included additional commit in this PR to also support compiler types like __SIZE_TYPE__ so:

#define FOO __SIZE_TYPE__

would become

alias FOO = size_t;

@davispuh davispuh force-pushed the types branch 2 times, most recently from 418f3c3 to c082709 Compare July 4, 2026 00:00
davispuh added 4 commits July 4, 2026 03:00
Consider C header like:
```
 #define va_copy __builtin_va_copy
 #define ALIGNOF(TYPE)  _Alignof (TYPE)
 #define __unused  __attribute__((__unused__))
 #define __noreturn  __attribute__((__noreturn__))
 #define STATIC_ASSERT  _Static_assert
 #define CONST  const
 #define STATIC  static
 #define __volatile  volatile
```

This commit implements commenting out such compiler builtins with `// FIXME:` prefix.
Consider C code like:
```c
 #define FIELD_PTR(Record, TYPE, Field) ((TYPE *)&((Record)->Field))
```

Currently dstep is not able to parse such macro definition because cast's TYPE is not known at definition time
but will be only known at usage time. So such definitions are just ignored.

This commit implements support for custom types that doesn't need to be known at definition time.
Note that it's not trivial to determine where (SYMBOL) is cast with a type or simply a parameter/value
so after parsing we use `fixCasts` to try to fix these places with correct usage.
@davispuh

davispuh commented Jul 4, 2026

Copy link
Copy Markdown
Author

Found some issues so now I significantly improved this PR and seems it's working correctly in all cases. I added bunch of additional tests aswell and also included #307 here so that could have proper support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants