Skip to content

Commit 8fdf38f

Browse files
committed
Move enums to main object
1 parent d97e6b9 commit 8fdf38f

21 files changed

+191
-186
lines changed

bindgen/ir/Enum.cpp

+29-37
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,30 @@ Enum::Enum(std::string name, std::string type,
1313
: PrimitiveType(std::move(type)), LocatableType(std::move(location)),
1414
name(std::move(name)), enumerators(std::move(enumerators)) {}
1515

16-
bool Enum::isAnonymous() const { return name.empty(); }
17-
18-
std::string Enum::getDefinition() {
19-
return " type " + getTypeAlias() + " = " + PrimitiveType::str() + "\n";
20-
}
21-
22-
llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Enum &e) {
23-
for (auto enumerator : e.enumerators) {
24-
std::string enumeratorName;
25-
if (!e.name.empty()) {
26-
enumeratorName = "enum_" + e.name + "_" + enumerator.getName();
27-
} else {
28-
enumeratorName = "enum_" + enumerator.getName();
29-
}
30-
s << " final val " << enumeratorName;
31-
std::string type;
32-
if (e.isAnonymous()) {
33-
type = e.getType();
34-
} else {
35-
type = "enum_" + e.name;
36-
}
37-
s << ": " << type << " = " << std::to_string(enumerator.getValue());
38-
39-
if (e.getType() == "native.CLong") {
40-
s << "L";
41-
} else if (e.getType() == "native.CUnsignedInt") {
42-
s << ".toUInt";
43-
} else if (e.getType() == "native.CUnsignedLong") {
44-
s << "L.toULong";
45-
}
46-
s << "\n";
16+
std::string Enum::getEnumerators() const {
17+
std::stringstream s;
18+
std::string typeCastSuffix = getTypeCastSuffix();
19+
std::string type = getTypeAlias();
20+
s << " object " << type << " {\n";
21+
for (auto enumerator : enumerators) {
22+
s << " final val " << enumerator.getName();
23+
s << ": " << type << " = " << std::to_string(enumerator.getValue())
24+
<< typeCastSuffix << "\n";
4725
}
48-
return s;
26+
s << " }\n";
27+
return s.str();
4928
}
5029

51-
std::string Enum::getName() const { return name; }
52-
53-
std::string Enum::getTypeAlias() const {
54-
assert(!isAnonymous());
55-
return "enum_" + name;
30+
std::string Enum::getTypeCastSuffix() const {
31+
std::string primitiveType = PrimitiveType::getType();
32+
if (primitiveType == "native.CLong") {
33+
return "L";
34+
} else if (primitiveType == "native.CUnsignedInt") {
35+
return ".toUInt";
36+
} else if (primitiveType == "native.CUnsignedLong") {
37+
return "L.toULong";
38+
}
39+
return "";
5640
}
5741

5842
std::string Enum::str(const LocationManager &locationManager) const {
@@ -61,3 +45,11 @@ std::string Enum::str(const LocationManager &locationManager) const {
6145
}
6246
return getTypeAlias();
6347
}
48+
49+
std::string Enum::getTypeAlias() const { return "enum_" + name; }
50+
51+
std::string Enum::getDefinition() const {
52+
return " type " + getTypeAlias() + " = " + PrimitiveType::str() + "\n";
53+
}
54+
55+
std::string Enum::getName() const { return name; }

bindgen/ir/Enum.h

+13-8
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,26 @@ class Enum : public PrimitiveType, public LocatableType {
2525
std::vector<Enumerator> enumerators,
2626
std::shared_ptr<Location> location);
2727

28-
bool isAnonymous() const;
28+
/**
29+
* @return a string that contains all enumerators.
30+
* If enum is not anonymous then enumerators are inside an object
31+
* with the same name as enum type.
32+
*/
33+
std::string getEnumerators() const;
2934

30-
std::string getDefinition();
35+
std::string str(const LocationManager &locationManager) const override;
3136

3237
std::string getName() const;
3338

34-
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Enum &e);
35-
36-
std::string getTypeAlias() const;
37-
38-
std::string str(const LocationManager &locationManager) const override;
39+
std::string getDefinition() const;
3940

4041
private:
41-
std::string name; // might be empty
42+
std::string name; // non-empty
4243
std::vector<Enumerator> enumerators;
44+
45+
std::string getTypeCastSuffix() const;
46+
47+
std::string getTypeAlias() const;
4348
};
4449

4550
#endif // SCALA_NATIVE_BINDGEN_ENUM_H

bindgen/ir/IR.cpp

+9-20
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ std::shared_ptr<Enum> IR::addEnum(std::string name, const std::string &type,
2727
std::shared_ptr<Location> location) {
2828
std::shared_ptr<Enum> e = std::make_shared<Enum>(
2929
std::move(name), type, std::move(enumerators), std::move(location));
30-
3130
enums.push_back(e);
32-
3331
return e;
3432
}
3533

@@ -122,8 +120,9 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
122120

123121
for (const auto &e : ir.enums) {
124122
visitedTypes.clear();
125-
if (!e->isAnonymous() && ir.shouldOutput(e, visitedTypes)) {
123+
if (ir.shouldOutput(e, visitedTypes)) {
126124
s << e->getDefinition();
125+
s << e->getEnumerators() << "\n";
127126
}
128127
}
129128

@@ -184,25 +183,10 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
184183
s << "}\n\n";
185184
}
186185

187-
if (ir.shouldOutputType(ir.enums) || ir.hasHelperMethods()) {
186+
if (ir.hasHelperMethods()) {
188187
s << "import " << objectName << "._\n\n";
189188
}
190189

191-
if (ir.shouldOutputType(ir.enums)) {
192-
s << "object " << ir.libName << "Enums {\n";
193-
194-
std::string sep = "";
195-
for (const auto &e : ir.enums) {
196-
visitedTypes.clear();
197-
if (ir.shouldOutput(e, visitedTypes)) {
198-
s << sep << *e;
199-
sep = "\n";
200-
}
201-
}
202-
203-
s << "}\n\n";
204-
}
205-
206190
if (ir.hasHelperMethods()) {
207191
s << "object " << ir.libName << "Helpers {\n";
208192

@@ -443,7 +427,12 @@ std::shared_ptr<TypeDef> IR::getTypeDefWithName(const std::string &name) const {
443427
}
444428

445429
std::shared_ptr<Enum> IR::getEnumWithName(const std::string &name) const {
446-
return getDeclarationWithName(enums, name);
430+
for (const auto &e : enums) {
431+
if (e->getName() == name) {
432+
return e;
433+
}
434+
}
435+
return nullptr;
447436
}
448437

449438
template <typename T>

bindgen/visitor/TreeVisitor.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,16 @@ bool TreeVisitor::VisitEnumDecl(clang::EnumDecl *enumDecl) {
7474
std::string scalaType = typeTranslator.getTypeFromTypeMap(
7575
enumDecl->getIntegerType().getUnqualifiedType().getAsString());
7676

77+
std::shared_ptr<Location> location = typeTranslator.getLocation(enumDecl);
78+
if (name.empty()) {
79+
name = "anonymous_" + std::to_string(anonymousEnumId++);
80+
}
7781
std::shared_ptr<Enum> e =
78-
ir.addEnum(name, scalaType, std::move(enumerators),
79-
typeTranslator.getLocation(enumDecl));
82+
ir.addEnum(name, scalaType, std::move(enumerators), location);
8083

8184
if (typedefName) {
85+
/* add alias here because in VisitTypedefDecl it will be difficult to
86+
* match typedef with enum */
8287
ir.addTypeDef(name, e, typeTranslator.getLocation(typedefName));
8388
}
8489

bindgen/visitor/TreeVisitor.h

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class TreeVisitor : public clang::RecursiveASTVisitor<TreeVisitor> {
1010
clang::ASTContext *astContext;
1111
TypeTranslator typeTranslator;
1212
IR &ir;
13+
uint anonymousEnumId = 0;
1314

1415
bool isAliasForAnonymousEnum(clang::TypedefDecl *tpdef) const;
1516

tests/samples/CustomNames.scala

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ import scala.scalanative.native._
66
@native.link("bindgentests")
77
@native.extern
88
object CustomNames {
9+
type enum_enumWithTypedef = native.CUnsignedInt
10+
object enum_enumWithTypedef {
11+
final val CONST: enum_enumWithTypedef = 0.toUInt
12+
}
13+
14+
type EnumWithTypedef = enum_enumWithTypedef
915
type page = native.CStruct2[native.CString, native.Ptr[Byte]]
1016
type book = native.CStruct1[native.Ptr[page]]
1117
type MY_INT = native.CInt

tests/samples/Enum.scala

+31-24
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,40 @@ import scala.scalanative.native._
77
@native.extern
88
object Enum {
99
type enum_days = native.CUnsignedInt
10-
type enum_bigValues = native.CUnsignedLong
11-
type enum_negativeValues = native.CInt
12-
type enum_bigNegativeValues = native.CLong
13-
def get_WEDNESDAY(): enum_days = native.extern
14-
def check_BIG_NEG_A(big_neg_a: enum_bigNegativeValues): native.CString = native.extern
15-
}
10+
object enum_days {
11+
final val MONDAY: enum_days = 0.toUInt
12+
final val TUESDAY: enum_days = 200.toUInt
13+
final val WEDNESDAY: enum_days = 201.toUInt
14+
final val THURSDAY: enum_days = 4.toUInt
15+
final val FRIDAY: enum_days = 5.toUInt
16+
final val SATURDAY: enum_days = 3.toUInt
17+
final val SUNDAY: enum_days = 4.toUInt
18+
}
1619

17-
import Enum._
18-
19-
object EnumEnums {
20-
final val enum_days_MONDAY: enum_days = 0.toUInt
21-
final val enum_days_TUESDAY: enum_days = 200.toUInt
22-
final val enum_days_WEDNESDAY: enum_days = 201.toUInt
23-
final val enum_days_THURSDAY: enum_days = 4.toUInt
24-
final val enum_days_FRIDAY: enum_days = 5.toUInt
25-
final val enum_days_SATURDAY: enum_days = 3.toUInt
26-
final val enum_days_SUNDAY: enum_days = 4.toUInt
20+
type enum_bigValues = native.CUnsignedLong
21+
object enum_bigValues {
22+
final val BIG_A: enum_bigValues = 10000000000L.toULong
23+
final val BIG_B: enum_bigValues = 1L.toULong
24+
}
2725

28-
final val enum_bigValues_BIG_A: enum_bigValues = 10000000000L.toULong
29-
final val enum_bigValues_BIG_B: enum_bigValues = 1L.toULong
26+
type enum_anonymous_0 = native.CUnsignedInt
27+
object enum_anonymous_0 {
28+
final val ANON_A: enum_anonymous_0 = 0.toUInt
29+
final val ANON_B: enum_anonymous_0 = 1.toUInt
30+
}
3031

31-
final val enum_ANON_A: native.CUnsignedInt = 0.toUInt
32-
final val enum_ANON_B: native.CUnsignedInt = 1.toUInt
32+
type enum_negativeValues = native.CInt
33+
object enum_negativeValues {
34+
final val NEG_A: enum_negativeValues = -1
35+
final val NEG_B: enum_negativeValues = -2
36+
}
3337

34-
final val enum_negativeValues_NEG_A: enum_negativeValues = -1
35-
final val enum_negativeValues_NEG_B: enum_negativeValues = -2
38+
type enum_bigNegativeValues = native.CLong
39+
object enum_bigNegativeValues {
40+
final val BIG_NEG_A: enum_bigNegativeValues = -10000000000L
41+
final val BIG_NEG_B: enum_bigNegativeValues = -1L
42+
}
3643

37-
final val enum_bigNegativeValues_BIG_NEG_A: enum_bigNegativeValues = -10000000000L
38-
final val enum_bigNegativeValues_BIG_NEG_B: enum_bigNegativeValues = -1L
44+
def get_WEDNESDAY(): enum_days = native.extern
45+
def check_BIG_NEG_A(big_neg_a: enum_bigNegativeValues): native.CString = native.extern
3946
}

tests/samples/Extern.scala

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import scala.scalanative.native._
77
@native.extern
88
object Extern {
99
type enum_mode = native.CUnsignedInt
10+
object enum_mode {
11+
final val SYSTEM: enum_mode = 0.toUInt
12+
final val USER: enum_mode = 1.toUInt
13+
}
14+
1015
type struct_version = native.CStruct3[native.CInt, native.CInt, native.CInt]
1116
val forty_two: native.CInt = native.extern
1217
val version: native.CString = native.extern
@@ -16,11 +21,6 @@ object Extern {
1621

1722
import Extern._
1823

19-
object ExternEnums {
20-
final val enum_mode_SYSTEM: enum_mode = 0.toUInt
21-
final val enum_mode_USER: enum_mode = 1.toUInt
22-
}
23-
2424
object ExternHelpers {
2525

2626
implicit class struct_version_ops(val p: native.Ptr[struct_version]) extends AnyVal {

tests/samples/IncludesHeader.scala

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import scala.scalanative.native._
77
@native.extern
88
object IncludesHeader {
99
type enum_semester = native.CUnsignedInt
10+
object enum_semester {
11+
final val AUTUMN: enum_semester = 0.toUInt
12+
final val SPRING: enum_semester = 1.toUInt
13+
}
14+
1015
type size = native.CInt
1116
type struct_metadata = native.CStruct2[native.CUnsignedInt, native.CString]
1217
type metadata = struct_metadata
@@ -17,11 +22,6 @@ object IncludesHeader {
1722

1823
import IncludesHeader._
1924

20-
object IncludesHeaderEnums {
21-
final val enum_semester_AUTUMN: enum_semester = 0.toUInt
22-
final val enum_semester_SPRING: enum_semester = 1.toUInt
23-
}
24-
2525
object IncludesHeaderHelpers {
2626

2727
implicit class struct_metadata_ops(val p: native.Ptr[struct_metadata]) extends AnyVal {

tests/samples/PrivateMembers.scala

+16-11
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,23 @@ import scala.scalanative.native._
77
@native.extern
88
object PrivateMembers {
99
type enum___privateEnum = native.CUnsignedInt
10+
object enum___privateEnum {
11+
final val A: enum___privateEnum = 0.toUInt
12+
final val B: enum___privateEnum = 1.toUInt
13+
}
14+
1015
type enum_enumWithPrivateMembers = native.CUnsignedInt
16+
object enum_enumWithPrivateMembers {
17+
final val __C: enum_enumWithPrivateMembers = 0.toUInt
18+
final val D: enum_enumWithPrivateMembers = 1.toUInt
19+
}
20+
21+
type enum_anonymous_0 = native.CUnsignedInt
22+
object enum_anonymous_0 {
23+
final val __E: enum_anonymous_0 = 0.toUInt
24+
final val F: enum_anonymous_0 = 1.toUInt
25+
}
26+
1127
type pid_t = native.CInt
1228
type __private_type = native.CInt
1329
type struct_structWithPrivateType = native.CStruct2[native.CInt, __private_type]
@@ -26,17 +42,6 @@ object PrivateMembers {
2642

2743
import PrivateMembers._
2844

29-
object PrivateMembersEnums {
30-
final val enum___privateEnum_A: enum___privateEnum = 0.toUInt
31-
final val enum___privateEnum_B: enum___privateEnum = 1.toUInt
32-
33-
final val enum_enumWithPrivateMembers___C: enum_enumWithPrivateMembers = 0.toUInt
34-
final val enum_enumWithPrivateMembers_D: enum_enumWithPrivateMembers = 1.toUInt
35-
36-
final val enum___E: native.CUnsignedInt = 0.toUInt
37-
final val enum_F: native.CUnsignedInt = 1.toUInt
38-
}
39-
4045
object PrivateMembersHelpers {
4146

4247
implicit class struct_structWithPrivateType_ops(val p: native.Ptr[struct_structWithPrivateType]) extends AnyVal {

tests/samples/ReuseBindings.h

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ struct usesImportedEnum {
1616
void readBook(struct book *book);
1717

1818
myInt getMyInt();
19+
enumWithTypedef getEnum();

tests/samples/ReuseBindings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"names": {
66
"struct book": "book",
77
"struct page": "page",
8-
"myInt": "MY_INT"
8+
"myInt": "MY_INT",
9+
"enumWithTypedef": "EnumWithTypedef"
910
}
1011
}
1112
}

tests/samples/ReuseBindings.scala

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ object ReuseBindings {
1313
def returnTypedef_point(): native.Ptr[org.scalanative.bindgen.samples.Struct.point] = native.extern
1414
def readBook(book: native.Ptr[org.scalanative.bindgen.samples.CustomNames.book]): Unit = native.extern
1515
def getMyInt(): org.scalanative.bindgen.samples.CustomNames.MY_INT = native.extern
16+
def getEnum(): org.scalanative.bindgen.samples.CustomNames.EnumWithTypedef = native.extern
1617
}
1718

1819
import ReuseBindings._

0 commit comments

Comments
 (0)