Skip to content

Commit ae94abd

Browse files
committed
Put members of enum class into separate scope
1 parent 58ec6ce commit ae94abd

File tree

6 files changed

+134
-22
lines changed

6 files changed

+134
-22
lines changed

src/cppconv/cppdeclaration.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ enum DeclarationFlags
344344
constExpr = 0x2000,
345345
templateSpecialization = 0x4000,
346346
templateParam = 0x8000,
347+
enumClass = 0x10000,
347348
}
348349

349350
struct DeclarationKey

src/cppconv/cppsemantic.d

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,15 @@ void analyzeClassSpecifier(Tree tree, ref IteratePPVersions ppVersion,
873873
iteratePPVersions!analyzeClassSpecifier(c, ppVersion, semantic, info);
874874
}
875875
}
876+
else if (tree.nonterminalID == ParserWrapper.nonterminalIDFor!"EnumKey")
877+
{
878+
assert(info.key.length == 0, text(info.key, " ", tree.childs[0].name));
879+
assert(tree.childs.length >= 1);
880+
assert(tree.childs[0].nodeType == NodeType.token);
881+
info.key = tree.childs[0].content;
882+
if (tree.childs.length >= 2)
883+
info.key ~= " " ~ tree.childs[1].content;
884+
}
876885
else if (tree.nonterminalID == ParserWrapper.nonterminalIDFor!"ClassKey")
877886
{
878887
assert(info.key.length == 0, text(info.key, " ", tree.childs[0].name));

src/cppconv/cppsemantic1.d

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,8 @@ void runSemantic(ref SemanticRunInfo semantic, ref Tree tree, Tree parent,
831831
runSemantic(semantic, c, tree, condition);
832832
}
833833

834+
bool isEnumClass;
835+
Scope enumClassScope;
834836
bool isTemplateSpecializationHere;
835837
foreach (combination; iterateCombinations())
836838
{
@@ -856,6 +858,9 @@ void runSemantic(ref SemanticRunInfo semantic, ref Tree tree, Tree parent,
856858
if (wrappperInfo.flags & DeclarationFlags.friend)
857859
continue;
858860

861+
if (classSpecifierInfo.key.among("enum class", "enum struct"))
862+
isEnumClass = true;
863+
859864
Tree parent2 = getRealParent(realParent, semantic);
860865
size_t parent3Index;
861866
Tree parent3 = getRealParent(parent2, semantic, &parent3Index);
@@ -930,7 +935,8 @@ void runSemantic(ref SemanticRunInfo semantic, ref Tree tree, Tree parent,
930935
}
931936
}
932937

933-
if (tree.nonterminalID == ParserWrapper.nonterminalIDFor!"ClassSpecifier")
938+
if (tree.nonterminalID == ParserWrapper.nonterminalIDFor!"ClassSpecifier"
939+
|| (tree.nonterminalID == ParserWrapper.nonterminalIDFor!"EnumSpecifier" && isEnumClass))
934940
{
935941
Scope classScope;
936942
if (tree !in targetScope.childScopeByTree)
@@ -945,37 +951,42 @@ void runSemantic(ref SemanticRunInfo semantic, ref Tree tree, Tree parent,
945951
classScope.scopeCondition = semantic.logicSystem.or(classScope.scopeCondition,
946952
instanceConditionHere);
947953
}
954+
if (tree.nonterminalID == ParserWrapper.nonterminalIDFor!"EnumSpecifier")
955+
enumClassScope = classScope;
948956
if (classSpecifierInfo.className !in targetScope.subScopes)
949957
targetScope.subScopes[classSpecifierInfo.className] = [];
950958
targetScope.subScopes[classSpecifierInfo.className].addOnce(
951959
targetScope.childScopeByTree[tree]);
952960
classScope.className.add(ppVersion.condition,
953961
classSpecifierInfo.className, semantic.logicSystem);
954962

955-
size_t startIndex = 0;
956-
foreach (s; templateScopes)
957-
startIndex = classScope.extraParentScopes.add(ppVersion.condition,
958-
ExtraScope(ExtraScopeType.template_, s), ppVersion.logicSystem, startIndex)
959-
+ 1;
960-
foreach (t; classSpecifierInfo.parentTypes)
963+
if (tree.nonterminalID == ParserWrapper.nonterminalIDFor!"ClassSpecifier")
961964
{
962-
t = chooseType(t, ppVersion, true);
963-
if (t.kind == TypeKind.record)
965+
size_t startIndex = 0;
966+
foreach (s; templateScopes)
967+
startIndex = classScope.extraParentScopes.add(ppVersion.condition,
968+
ExtraScope(ExtraScopeType.template_, s), ppVersion.logicSystem, startIndex)
969+
+ 1;
970+
foreach (t; classSpecifierInfo.parentTypes)
964971
{
965-
RecordType recordType = cast(RecordType) t.type;
972+
t = chooseType(t, ppVersion, true);
973+
if (t.kind == TypeKind.record)
974+
{
975+
RecordType recordType = cast(RecordType) t.type;
966976

967-
Scope scope_ = scopeForRecord(recordType, ppVersion, semantic);
977+
Scope scope_ = scopeForRecord(recordType, ppVersion, semantic);
968978

969-
if (scope_ !is null && scope_.tree !is tree)
970-
startIndex = classScope.extraParentScopes.add(ppVersion.condition,
971-
ExtraScope(ExtraScopeType.parentClass, scope_),
972-
ppVersion.logicSystem, startIndex) + 1;
979+
if (scope_ !is null && scope_.tree !is tree)
980+
startIndex = classScope.extraParentScopes.add(ppVersion.condition,
981+
ExtraScope(ExtraScopeType.parentClass, scope_),
982+
ppVersion.logicSystem, startIndex) + 1;
983+
}
973984
}
985+
if (classSpecifierInfo.namespaces.length && targetScope2 !is null)
986+
startIndex = classScope.extraParentScopes.add(ppVersion.condition,
987+
ExtraScope(ExtraScopeType.namespace, targetScope2),
988+
ppVersion.logicSystem, startIndex) + 1;
974989
}
975-
if (classSpecifierInfo.namespaces.length && targetScope2 !is null)
976-
startIndex = classScope.extraParentScopes.add(ppVersion.condition,
977-
ExtraScope(ExtraScopeType.namespace, targetScope2),
978-
ppVersion.logicSystem, startIndex) + 1;
979990
}
980991

981992
DeclarationKey dk;
@@ -992,6 +1003,8 @@ void runSemantic(ref SemanticRunInfo semantic, ref Tree tree, Tree parent,
9921003
dk.flags |= DeclarationFlags.friend;
9931004
if (targetScope.currentlyInsideParams)
9941005
dk.flags |= DeclarationFlags.templateParam;
1006+
if (isEnumClass)
1007+
dk.flags |= DeclarationFlags.enumClass;
9951008
dk.name = classSpecifierInfo.className;
9961009
dk.scope_ = targetScope;
9971010

@@ -1059,9 +1072,22 @@ void runSemantic(ref SemanticRunInfo semantic, ref Tree tree, Tree parent,
10591072
}
10601073
}
10611074

1062-
foreach (ref c; tree.childs[headChilds .. $])
1075+
if (tree.nonterminalID == ParserWrapper.nonterminalIDFor!"EnumSpecifier" && enumClassScope !is null)
10631076
{
1064-
runSemantic(semantic, c, tree, condition);
1077+
SemanticRunInfo semanticRun = semantic;
1078+
semanticRun.currentScope = enumClassScope;
1079+
1080+
foreach (ref c; tree.childs[headChilds .. $])
1081+
{
1082+
runSemantic(semanticRun, c, tree, condition);
1083+
}
1084+
}
1085+
else
1086+
{
1087+
foreach (ref c; tree.childs[headChilds .. $])
1088+
{
1089+
runSemantic(semantic, c, tree, condition);
1090+
}
10651091
}
10661092
}, (MatchNonterminals!("OriginalNamespaceDefinition")) {
10671093
string name = tree.childs[2].content;

src/cppconv/dwriter.d

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4473,7 +4473,17 @@ void parseTreeToDCode(T)(ref CodeWriter code, DWriterData data, T tree, immutabl
44734473
string declName = typeToCode(semantic.extraInfo(tree).type,
44744474
data, newCondition, contextScope, tree.location, [], codeType);
44754475

4476-
if (declName != "")
4476+
bool isEnumClass;
4477+
QualType enumType = chooseType(e.data.type2, ppVersion, true);
4478+
if (enumType.kind == TypeKind.record)
4479+
{
4480+
RecordType recordType = cast(RecordType) enumType.type;
4481+
foreach (e2; recordType.declarationSet.entries)
4482+
if (e2.data.flags & DeclarationFlags.enumClass)
4483+
isEnumClass = true;
4484+
}
4485+
4486+
if (declName != "" && !isEnumClass)
44774487
{
44784488
realId.add(newCondition,
44794489
declName ~ "." ~ replaceKeywords(tree.childs[0].content),

tests/single/test378.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class FileNotFound;
2+
3+
class QPdfDocument
4+
{
5+
public:
6+
enum class Status {
7+
Null,
8+
Loading,
9+
Ready,
10+
Unloading,
11+
Error
12+
};
13+
14+
enum class Error {
15+
None,
16+
Unknown,
17+
DataNotYetAvailable,
18+
FileNotFound,
19+
InvalidFileFormat,
20+
IncorrectPassword,
21+
UnsupportedSecurityScheme
22+
};
23+
24+
Error load();
25+
26+
Status status() const;
27+
};
28+
29+
QPdfDocument::Status s1 = QPdfDocument::Status::Ready;
30+
QPdfDocument::Error e1 = QPdfDocument::Error::Unknown;

tests/single/test378.d

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module test378;
2+
3+
import config;
4+
import cppconvhelpers;
5+
6+
extern(C++, class) struct FileNotFound;
7+
8+
extern(C++, class) struct QPdfDocument
9+
{
10+
public:
11+
enum /+ class +/ Status {
12+
Null,
13+
Loading,
14+
Ready,
15+
Unloading,
16+
Error
17+
}
18+
19+
enum /+ class +/ Error {
20+
None,
21+
Unknown,
22+
DataNotYetAvailable,
23+
FileNotFound,
24+
InvalidFileFormat,
25+
IncorrectPassword,
26+
UnsupportedSecurityScheme
27+
}
28+
29+
Error load();
30+
31+
Status status() const;
32+
}
33+
34+
__gshared QPdfDocument.Status s1 = QPdfDocument.Status.Ready;
35+
__gshared QPdfDocument.Error e1 = QPdfDocument.Error.Unknown;
36+

0 commit comments

Comments
 (0)