Support custom types#303
Conversation
There was a problem hiding this comment.
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.Typeand emitunexposedtype spellings when no declaration is available. - Extend macro type-name parsing to optionally accept arbitrary identifiers as type-names in
cast/sizeofcontexts. - Add a
fixCastspost-pass to rewrite some ambiguous(SYMBOL) <unary-op> ...parses into binary operator expressions whenSYMBOLmatches 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
parseCastExprnow callsparseTypeName(..., anyType=true), which will treat any identifier in parentheses as a type (viaCXTypeKind.unexposed). This makes patterns like(bar)(a)parse as a cast to the unknown typebarinstead of a function callbar(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.
|
Improved this PR and added tests. Also rebased it on top of #304 so that PR is included here aswell. |
|
I included additional commit in this PR to also support compiler types like #define FOO __SIZE_TYPE__would become alias FOO = size_t; |
418f3c3 to
c082709
Compare
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.
|
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. |
Consider C code like:
Currently
dstepis not able to parse such macro definition because cast'sTYPEis 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 usefixCaststo try to fix these places with correct usage.We also repurpose
CXTypeKind.unexposedfor these custom type definitions.With this PR result for such macro definition will be:
Note that this change has a side effect that definitions like:
Will be converted to:
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.