Skip to content

Commit 2d65ea8

Browse files
authored
Merge PR #160 from fix/dimeta-anon-structs
Generate hashed names for anon structs with llvm-dimeta
2 parents 717a560 + d3e9181 commit 2d65ea8

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

.codespellrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ check-hidden =
55
skip = */.git,*/build*,*/.codespellrc,*/install,*/lulesh,wrap.py,*.llin
66
quiet-level = 2
77
ignore-regex = ^#include <(?:stdio)\.h>$|DEPENDEES|\\endcode
8-
ignore-words-list = uint,files'
8+
ignore-words-list = uint,files',re-used

lib/passes/typegen/dimeta/DimetaTypeGen.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include "typelib/TypeDatabase.h"
1919
#include "typelib/TypeInterface.h"
2020

21+
#include "llvm/ADT/StringExtras.h"
22+
#include "llvm/Support/MD5.h"
23+
2124
#include <cassert>
2225
#include <cstddef>
2326
#include <cstdint>
@@ -108,6 +111,34 @@ dimeta::ArraySize vector_num_elements(const Type& type) {
108111
});
109112
}
110113

114+
std::string get_anon_struct_identifier(const dimeta::QualifiedCompound& compound) {
115+
llvm::MD5 compound_hash;
116+
if (compound.type.members.empty()) {
117+
LOG_WARNING("Anonymous struct has no members")
118+
}
119+
for (const auto& [member, offset, size] :
120+
llvm::zip(compound.type.members, compound.type.offsets, compound.type.sizes)) {
121+
compound_hash.update(member->name);
122+
compound_hash.update(offset);
123+
compound_hash.update(size);
124+
compound_hash.update(std::visit(overload{[&](const dimeta::QualifiedFundamental& member_fundamental) {
125+
return std::to_string(
126+
static_cast<int>(member_fundamental.type.encoding)) +
127+
std::to_string(static_cast<int>(member_fundamental.type.extent));
128+
},
129+
[&](const dimeta::QualifiedCompound& member_compound) {
130+
return get_anon_struct_identifier(member_compound);
131+
}},
132+
member->member));
133+
compound_hash.update("\0");
134+
}
135+
compound_hash.update(compound.type.extent);
136+
compound_hash.update("\0");
137+
llvm::MD5::MD5Result hash_result;
138+
compound_hash.final(hash_result);
139+
return "anonymous_compound_" + std::string(hash_result.digest().str());
140+
}
141+
111142
template <typename Type>
112143
dimeta::ArraySize array_size(const Type& type) {
113144
return detail::apply_func(type, [](const auto& t) -> dimeta::Extent {
@@ -130,6 +161,10 @@ std::string name_or_typedef_of(const Type& type) {
130161
const bool no_name = qual_type.type.name.empty();
131162
if constexpr (std::is_same_v<Type, typename dimeta::QualifiedCompound>) {
132163
const bool no_identifier = qual_type.type.identifier.empty();
164+
const bool no_typedef = qual_type.typedef_name.empty();
165+
if (no_identifier && no_name && no_typedef) {
166+
return get_anon_struct_identifier(qual_type);
167+
}
133168
if (no_identifier && no_name) {
134169
return qual_type.typedef_name;
135170
}

test/typemapping/06_anon_struct.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %c-to-llvm %s | %apply-typeart --typeart-stack=true
2+
// RUN: cat %tu_yaml | %filecheck %s
3+
4+
// REQUIRES: dimeta
5+
6+
struct {
7+
int dir;
8+
int length;
9+
float coeff;
10+
float forwback;
11+
} q_paths;
12+
13+
struct {
14+
int dir;
15+
float length;
16+
float coeff;
17+
float forwback;
18+
} q_paths_2;
19+
20+
struct {
21+
float dir;
22+
float length;
23+
float coeff;
24+
float forwback;
25+
} q_paths_3;
26+
27+
struct {
28+
struct {
29+
float dir;
30+
float length;
31+
float coeff;
32+
float forwback;
33+
} inner;
34+
} q_paths_4;
35+
36+
// CHECK-COUNT-4: name: anonymous_compound_{{[0-9a-z]+}}

0 commit comments

Comments
 (0)