Skip to content

Commit 86d9bb3

Browse files
authored
Merge pull request #38 from kornilova-l/fix-underlying-type-of-enums
Fix underlying type of enums
2 parents a1aa78a + 32fc28b commit 86d9bb3

File tree

8 files changed

+95
-37
lines changed

8 files changed

+95
-37
lines changed

ir/Enum.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,60 @@
11
#include "Enum.h"
22
#include <sstream>
3-
#include <cassert>
43

5-
Enumerator::Enumerator(std::string name, uint64_t value)
4+
Enumerator::Enumerator(std::string name, int64_t value)
65
: name(std::move(name)), value(value) {}
76

87
std::string Enumerator::getName() {
98
return name;
109
}
1110

12-
uint64_t Enumerator::getValue() {
11+
int64_t Enumerator::getValue() {
1312
return value;
1413
}
1514

16-
Enum::Enum(std::string name, std::vector<Enumerator> enumerators)
17-
: name(std::move(name)), enumerators(std::move(enumerators)) {}
15+
Enum::Enum(std::string name, std::string type, std::vector<Enumerator> enumerators)
16+
: name(std::move(name)), type(std::move(type)), enumerators(std::move(enumerators)) {}
1817

1918
bool Enum::isAnonymous() const {
2019
return name.empty();
2120
}
2221

2322
TypeDef Enum::generateTypeDef() const {
2423
assert (!isAnonymous());
25-
return TypeDef("enum_" + name, "native.CInt");
24+
return TypeDef(getTypeName(), type);
2625
}
2726

2827
llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Enum &e) {
2928
for (auto enumerator : e.enumerators) {
3029
std::string enumeratorName;
3130
if (!e.name.empty()) {
32-
enumeratorName = "enum_" + e.name + "_" + enumerator.getName();
31+
enumeratorName = e.getTypeName() + "_" + enumerator.getName();
3332
} else {
3433
enumeratorName = "enum_" + enumerator.getName();
3534
}
36-
s << " final val " << enumeratorName << " = " << std::to_string(enumerator.getValue()) << "\n";
35+
s << " final val " << enumeratorName;
36+
std::string type;
37+
if (e.isAnonymous()) {
38+
type = e.type;
39+
} else {
40+
type = e.getTypeName();
41+
}
42+
s << ": " << type
43+
<< " = " << std::to_string(enumerator.getValue());
44+
45+
if (e.type == "native.CLong") {
46+
s << "L";
47+
} else if (e.type == "native.CUnsignedInt") {
48+
s << ".toUInt";
49+
} else if (e.type == "native.CUnsignedLong") {
50+
s << "L.toULong";
51+
}
52+
s << "\n";
3753
}
3854
return s;
3955
}
56+
57+
std::string Enum::getTypeName() const {
58+
assert(!isAnonymous());
59+
return "enum_" + name;
60+
}

ir/Enum.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,33 @@
99

1010
class Enumerator {
1111
public:
12-
Enumerator(std::string name, uint64_t value);
12+
Enumerator(std::string name, int64_t value);
1313

1414
std::string getName();
1515

16-
uint64_t getValue();
16+
int64_t getValue();
1717

1818
private:
1919
std::string name;
20-
uint64_t value;
20+
int64_t value;
2121
};
2222

2323

2424
class Enum {
2525
public:
26-
Enum(std::string name, std::vector<Enumerator> enumerators);
26+
Enum(std::string name, std::string type, std::vector<Enumerator> enumerators);
2727

2828
bool isAnonymous() const;
2929

3030
TypeDef generateTypeDef() const;
3131

32+
std::string getTypeName() const;
33+
3234
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Enum &e);
3335

3436
private:
3537
std::string name; // might be empty
38+
std::string type;
3639
std::vector<Enumerator> enumerators;
3740
};
3841

ir/IR.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ void IR::addTypeDef(std::string name, std::string type) {
1717
typeDefs.push_back(TypeDef(std::move(name), std::move(type)));
1818
}
1919

20-
void IR::addEnum(std::string name, std::vector<Enumerator> enumerators) {
21-
enums.push_back(Enum(std::move(name), std::move(enumerators)));
20+
void IR::addEnum(std::string name, std::string type, std::vector<Enumerator> enumerators) {
21+
enums.push_back(Enum(std::move(name), std::move(type), std::move(enumerators)));
2222
}
2323

2424
void IR::addStruct(std::string name, std::vector<Field> fields, uint64_t typeSize) {

ir/IR.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class IR {
1919

2020
void addTypeDef(std::string name, std::string type);
2121

22-
void addEnum(std::string name, std::vector<Enumerator> enumerators);
22+
void addEnum(std::string name, std::string type, std::vector<Enumerator> enumerators);
2323

2424
void addStruct(std::string name, std::vector<Field> fields, uint64_t typeSize);
2525

tests/samples/Enum.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,22 @@ enum days {
77
SATURDAY = 3,
88
SUNDAY // = 4
99
};
10+
11+
enum bigValues {
12+
BIG_A = 10000000000, // does not fit into int
13+
BIG_B = 1
14+
};
15+
16+
enum { // anonymous enum
17+
ANON_A, ANON_B
18+
};
19+
20+
enum negativeValues {
21+
NEG_A = -1,
22+
NEG_B = -2
23+
};
24+
25+
enum bigNegativeValues {
26+
BIG_NEG_A = -10000000000,
27+
BIG_NEG_B = -1
28+
};

tests/samples/Enum.scala

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,32 @@ import scala.scalanative.native.Nat._
55
@native.link("Enum")
66
@native.extern
77
object Enum {
8-
type enum_days = native.CInt
8+
type enum_days = native.CUnsignedInt
9+
type enum_bigValues = native.CUnsignedLong
10+
type enum_negativeValues = native.CInt
11+
type enum_bigNegativeValues = native.CLong
912
}
1013

1114
import Enum._
1215

1316
object EnumEnums {
14-
final val enum_days_MONDAY = 0
15-
final val enum_days_TUESDAY = 200
16-
final val enum_days_WEDNESDAY = 201
17-
final val enum_days_THURSDAY = 4
18-
final val enum_days_FRIDAY = 5
19-
final val enum_days_SATURDAY = 3
20-
final val enum_days_SUNDAY = 4
17+
final val enum_days_MONDAY: enum_days = 0.toUInt
18+
final val enum_days_TUESDAY: enum_days = 200.toUInt
19+
final val enum_days_WEDNESDAY: enum_days = 201.toUInt
20+
final val enum_days_THURSDAY: enum_days = 4.toUInt
21+
final val enum_days_FRIDAY: enum_days = 5.toUInt
22+
final val enum_days_SATURDAY: enum_days = 3.toUInt
23+
final val enum_days_SUNDAY: enum_days = 4.toUInt
24+
25+
final val enum_bigValues_BIG_A: enum_bigValues = 10000000000L.toULong
26+
final val enum_bigValues_BIG_B: enum_bigValues = 1L.toULong
27+
28+
final val enum_ANON_A: native.CUnsignedInt = 0.toUInt
29+
final val enum_ANON_B: native.CUnsignedInt = 1.toUInt
30+
31+
final val enum_negativeValues_NEG_A: enum_negativeValues = -1
32+
final val enum_negativeValues_NEG_B: enum_negativeValues = -2
33+
34+
final val enum_bigNegativeValues_BIG_NEG_A: enum_bigNegativeValues = -10000000000L
35+
final val enum_bigNegativeValues_BIG_NEG_B: enum_bigNegativeValues = -1L
2136
}

tests/samples/Typedef.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,21 @@ object Typedef {
99
type int2int = native.CFunctionPtr1[native.CInt, native.CInt]
1010
type day2string = native.CFunctionPtr1[enum_days, native.CString]
1111
type toggle = native.CFunctionPtr1[toggle_e, Unit]
12-
type enum_days = native.CInt
13-
type enum_toggle_e = native.CInt
12+
type enum_days = native.CUnsignedInt
13+
type enum_toggle_e = native.CUnsignedInt
1414
}
1515

1616
import Typedef._
1717

1818
object TypedefEnums {
19-
final val enum_days_MONDAY = 0
20-
final val enum_days_TUESDAY = 1
21-
final val enum_days_WEDNESDAY = 2
22-
final val enum_days_THURSDAY = 3
23-
final val enum_days_FRIDAY = 4
24-
final val enum_days_SATURDAY = 5
25-
final val enum_days_SUNDAY = 6
19+
final val enum_days_MONDAY: enum_days = 0.toUInt
20+
final val enum_days_TUESDAY: enum_days = 1.toUInt
21+
final val enum_days_WEDNESDAY: enum_days = 2.toUInt
22+
final val enum_days_THURSDAY: enum_days = 3.toUInt
23+
final val enum_days_FRIDAY: enum_days = 4.toUInt
24+
final val enum_days_SATURDAY: enum_days = 5.toUInt
25+
final val enum_days_SUNDAY: enum_days = 6.toUInt
2626

27-
final val enum_toggle_e_OFF = 0
28-
final val enum_toggle_e_ON = 1
27+
final val enum_toggle_e_OFF: enum_toggle_e = 0.toUInt
28+
final val enum_toggle_e_ON: enum_toggle_e = 1.toUInt
2929
}

visitor/TreeVisitor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ bool TreeVisitor::VisitEnumDecl(clang::EnumDecl *enumdecl) {
6363
std::vector<Enumerator> enumerators;
6464

6565
for (const clang::EnumConstantDecl *en : enumdecl->enumerators()) {
66-
uint64_t value = en->getInitVal().getLimitedValue();
67-
enumerators.push_back(Enumerator(en->getNameAsString(), value));
66+
int64_t value = en->getInitVal().getSExtValue();
67+
enumerators.emplace_back(en->getNameAsString(), value);
6868
}
6969

70-
ir->addEnum(name, enumerators);
70+
ir->addEnum(name, typeTranslator.Translate(enumdecl->getIntegerType()), enumerators);
7171

7272
return true;
7373
}

0 commit comments

Comments
 (0)