Skip to content

Avoid collision between tag and typedef identifier#166

Merged
nunoplopes merged 2 commits into
Cpp2Rust:masterfrom
lucic71:tag-collision
Jun 3, 2026
Merged

Avoid collision between tag and typedef identifier#166
nunoplopes merged 2 commits into
Cpp2Rust:masterfrom
lucic71:tag-collision

Conversation

@lucic71

@lucic71 lucic71 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

C allows name collision between the following 2 declarations:

struct X {};
typedef enum {} X;

The 2 declarations live in different name spaces:

6.2.3 Name spaces of identifiers
[...] there are separate namespaces for various categories of identifiers, as follows:

  1. the tags of structures, unions, and enumerations (disambiguated by following any) of the keywords struct, union, or enum);
  2. all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants).

struct X {} lives in namespace 1 and typedef enum {} X lives in namespace 2.

We cannot translate both to X in the Rust code. We need to disambiguate between the 2 names. I chose to translate them as:

struct X {} -> X
typedef enum {} X -> X_enum

C++ does not have the name space rule for identifiers. I added the tag->getASTContext().getLangOpts().CPlusPlus check in DisambiguateAnonymousTag to avoid polluting the C++ generated files.

@nunoplopes nunoplopes merged commit d424cd1 into Cpp2Rust:master Jun 3, 2026
lucic71 added a commit to lucic71/cpp2rust that referenced this pull request Jun 4, 2026
C allows name collision between the following 2 declarations:

```c
struct X {};
typedef enum {} X;
```

The 2 declarations live in different name spaces:

6.2.3 Name spaces of identifiers
[...] there are separate namespaces for various categories of
identifiers, as follows:
1. the tags of structures, unions, and enumerations (disambiguated by
following any) of the keywords struct, union, or enum);
2. all other identifiers, called ordinary identifiers (declared in
ordinary declarators or as enumeration constants).

`struct X {}` lives in namespace 1 and `typedef enum {} X` lives in
namespace 2.

We cannot translate both to `X` in the Rust code. We need to
disambiguate between the 2 names. I chose to translate them as:

```
struct X {} -> X
typedef enum {} X -> X_enum
```

C++ does not have the name space rule for identifiers. I added the
`tag->getASTContext().getLangOpts().CPlusPlus` check in
DisambiguateAnonymousTag to avoid polluting the C++ generated files.

---------

Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
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