Skip to content

Commit f48b4c9

Browse files
committed
Improve conversion of PostfixExpressions . and ->
1 parent 392939b commit f48b4c9

File tree

7 files changed

+236
-50
lines changed

7 files changed

+236
-50
lines changed

src/cppconv/dwriter/conditioncode.d

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ struct ConditionalCodeWrapper
153153
return false;
154154
}
155155

156-
void checkTree(Tree tree, bool allowNonArrayPPIf)
156+
void checkTree(Tree tree, bool allowNonArrayPPIf,
157+
scope bool delegate(Tree) shouldDescent = null)
157158
in(!active)
158159
{
159160
if (allowNonArrayPPIfSet)
@@ -171,24 +172,29 @@ struct ConditionalCodeWrapper
171172
alwaysUseMixin = true;
172173
}
173174
}
174-
if (tree.nodeType == NodeType.array)
175+
if (tree.nodeType == NodeType.array
176+
|| (tree.nodeType == NodeType.nonterminal && shouldDescent !is null && shouldDescent(tree)))
175177
{
176178
foreach (c; tree.childs)
177-
checkTree(c, allowNonArrayPPIf);
179+
checkTree(c, allowNonArrayPPIf, shouldDescent);
178180
}
179181
}
180182

181-
void checkTree(Tree[] trees, bool allowNonArrayPPIf)
183+
void checkTree(Tree[] trees, bool allowNonArrayPPIf,
184+
scope bool delegate(Tree) shouldDescent = null)
182185
in(!active)
183186
{
184187
foreach (c; trees)
185-
checkTree(c, allowNonArrayPPIf);
188+
checkTree(c, allowNonArrayPPIf, shouldDescent);
186189
}
187190

188191
void changeCurrentCondition(ref CodeWriter code,
189192
immutable(Formula)* condition, StringType stringType)
190193
in(active)
191194
{
195+
if (!alwaysUseMixin && conditionMapPrefix.entries.length == 1
196+
&& conditionMapSuffix.entries.length == 1)
197+
return;
192198
if (condition !is currentCondition || stringType != currentStringType)
193199
{
194200
if (currentStringType != StringType.none)
@@ -361,8 +367,9 @@ struct ConditionalCodeWrapper
361367
active = false;
362368
}
363369

364-
void writeTree(ref CodeWriter code, scope void delegate(Tree,
365-
immutable(Formula)*) F, Tree tree, immutable(Formula)* condition)
370+
void writeTree(ref CodeWriter code,
371+
scope void delegate(Tree, immutable(Formula)*) F,
372+
Tree tree, immutable(Formula)* condition)
366373
in(active)
367374
{
368375
if (!tree.isValid)
@@ -417,10 +424,31 @@ struct ConditionalCodeWrapper
417424
writeTree(code, F, c);
418425
}
419426

420-
void writeString(ref CodeWriter code, string s)
427+
void writeString(ref CodeWriter code, string s, immutable(Formula)* condition = null)
421428
in(active)
422429
{
423-
changeCurrentCondition(code, firstCondition, StringType.string);
430+
if (condition is null)
431+
condition = firstCondition;
432+
if (!alwaysUseMixin && conditionMapPrefix.entries.length == 1
433+
&& conditionMapSuffix.entries.length == 1)
434+
{
435+
}
436+
else
437+
changeCurrentCondition(code, condition, StringType.string);
438+
code.write(s);
439+
}
440+
441+
void writeCode(ref CodeWriter code, string s, immutable(Formula)* condition = null)
442+
in(active)
443+
{
444+
if (condition is null)
445+
condition = firstCondition;
446+
if (!alwaysUseMixin && conditionMapPrefix.entries.length == 1
447+
&& conditionMapSuffix.entries.length == 1)
448+
{
449+
}
450+
else
451+
changeCurrentCondition(code, condition, StringType.code);
424452
code.write(s);
425453
}
426454
}

src/cppconv/dwriter/treecode.d

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,48 +1775,57 @@ void parseTreeToDCode(T)(ref CodeWriter code, DWriterData data, T tree, immutabl
17751775
{
17761776
auto codeWrapper = ConditionalCodeWrapper(condition, data);
17771777

1778+
immutable(Formula)* conditionIsArray = semantic.logicSystem.false_;
17781779
foreach (combination; iterateCombinations())
17791780
{
17801781
IteratePPVersions ppVersion = IteratePPVersions(combination,
1781-
semantic.logicSystem, condition);
1782-
Appender!string app;
1782+
semantic.logicSystem, condition, null, semantic.mergedTreeDatas);
17831783

17841784
auto t = chooseType(semantic.extraInfo(tree.childs[0]).type, ppVersion, true);
17851785

17861786
if (t.kind == TypeKind.array)
1787-
app.put("[0]");
1787+
conditionIsArray = semantic.logicSystem.or(conditionIsArray, ppVersion.condition);
1788+
}
1789+
1790+
bool shouldDescent(Tree tree)
1791+
{
1792+
return tree.nonterminalID == nonterminalIDFor!"SimpleTemplateId";
1793+
}
17881794

1789-
app.put(".");
1795+
codeWrapper.checkTree(tree.childs, false, &shouldDescent);
17901796

1791-
void buildSuffix(Tree tree, ref IteratePPVersions ppVersion)
1797+
void onTree(Tree tree, immutable(Formula)* condition2)
1798+
{
1799+
if (tree.nonterminalID == nonterminalIDFor!"SimpleTemplateId")
17921800
{
1793-
if (tree.nodeType == NodeType.token)
1794-
{
1795-
if (tree.content.length)
1796-
{
1797-
app.put(replaceKeywords(tree.content));
1798-
}
1799-
}
1800-
else
1801-
{
1802-
foreach (c; tree.childs)
1803-
iteratePPVersions!buildSuffix(c, ppVersion);
1804-
}
1801+
codeWrapper.writeTree(code, &onTree, tree.childs[0], condition2);
1802+
codeWrapper.writeCode(code, "!(", condition2);
1803+
skipToken(code, data, tree.childs[1]);
1804+
codeWrapper.writeTree(code, &onTree, tree.childs[2], condition2);
1805+
codeWrapper.writeCode(code, ")", condition2);
1806+
skipToken(code, data, tree.childs[3]);
1807+
return;
1808+
}
1809+
parseTreeToDCode(code, data, tree, condition2, currentScope);
1810+
if (tree.location.context !is null)
1811+
{
1812+
writeComments(code, data, data.sourceTokenManager.collectTokens(tree.location.end));
1813+
writeComments(code, data,
1814+
data.sourceTokenManager.collectTokensUntilLineEnd(tree.location.end,
1815+
condition2));
18051816
}
1806-
1807-
foreach (c; tree.childs[2 .. $])
1808-
iteratePPVersions!buildSuffix(c, ppVersion);
1809-
1810-
codeWrapper.add("", app.data, ppVersion.condition);
18111817
}
18121818

18131819
codeWrapper.begin(code, condition);
1814-
parseTreeToDCode(code, data, tree.childs[0], condition, currentScope);
1815-
if (data.sourceTokenManager.tokensLeft.data.length > 0)
1816-
writeComments(code, data, tree.childs[1].start);
1820+
1821+
codeWrapper.writeTree(code, &onTree, tree.childs[0]);
1822+
if (!conditionIsArray.isFalse)
1823+
codeWrapper.writeString(code, "[0]", conditionIsArray);
1824+
skipToken(code, data, tree.childs[1]);
1825+
codeWrapper.writeCode(code, ".");
1826+
foreach (c; tree.childs[2 .. $])
1827+
codeWrapper.writeTree(code, &onTree, c);
18171828
codeWrapper.end(code, condition);
1818-
if (data.sourceTokenManager.tokensLeft.data.length > 0)
1819-
writeComments(code, data, tree.end, true);
18201829
}
18211830
else if (auto match = tree.matchTreePattern!q{
18221831
Designator(".", *)
@@ -2080,7 +2089,18 @@ void parseTreeToDCode(T)(ref CodeWriter code, DWriterData data, T tree, immutabl
20802089
}
20812090
else
20822091
{
2083-
string name = declarationNameToCode(e.data, data, contextScope, newCondition);
2092+
string name;
2093+
size_t indexInParentExpr = indexInParent;
2094+
Tree parentExpr = parent;
2095+
while (parentExpr.nonterminalID == nonterminalIDFor!"SimpleTemplateId")
2096+
parentExpr = getRealParent(parentExpr, semantic, &indexInParentExpr);
2097+
if (parentExpr.nonterminalID == nonterminalIDFor!"PostfixExpression"
2098+
&& parentExpr.childs[1].nodeType == NodeType.token
2099+
&& parentExpr.childs[1].content.among(".", "->")
2100+
&& indexInParentExpr == parentExpr.childs.length - 1)
2101+
name = chooseDeclarationName(e.data, data);
2102+
else
2103+
name = declarationNameToCode(e.data, data, contextScope, newCondition);
20842104
if (e.data !in data.fileByDecl && realId.conditionAll !is null)
20852105
newCondition = logicSystem.and(newCondition, realId.conditionAll.negated);
20862106
realId.addReplace(newCondition, name, logicSystem);

tests/single/test119.d

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,14 @@ int function(git_config_backend*, git_config_level_t level, const(git_repository
5353

5454
int git_config_file_open(git_config_backend* cfg, uint level, const(git_repository)* repo)
5555
{
56-
return mixin(q{cfg
56+
return mixin(q{cfg.
5757
}
58-
~ ((defined!"_WIN32") ? "._open" : ".open"))(cfg, cast(git_config_level_t) (level), repo);
58+
~ (defined!"_WIN32" ? q{
59+
/+ open +/_open
60+
}:"")
61+
~ (!defined!"_WIN32" ? q{
62+
open
63+
}:"")
64+
)(cfg, cast(git_config_level_t) (level), repo);
5965
}
6066

tests/single/test388.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
struct S
3+
{
4+
template<class T>
5+
bool f()
6+
{
7+
return true;
8+
}
9+
template<class T>
10+
S *f2()
11+
{
12+
return this;
13+
}
14+
};
15+
16+
#ifdef DEF
17+
#define NAME f
18+
#else
19+
#define NAME f2
20+
#endif
21+
22+
#ifdef DEF
23+
#define NAME2 p
24+
#else
25+
#define NAME2 arr
26+
#endif
27+
28+
int main()
29+
{
30+
S x;
31+
S arr[2];
32+
S *p = &x;
33+
x.f<S>();
34+
p->f<S>();
35+
arr->f<S>();
36+
x.f2<S>()->f<S>();
37+
x.NAME<S>();
38+
NAME2->f<S>();
39+
return 0;
40+
}

tests/single/test388.d

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
2+
module test388;
3+
4+
import config;
5+
import cppconvhelpers;
6+
7+
struct S
8+
{
9+
/+ template<class T> +/
10+
bool f(T)()
11+
{
12+
return true;
13+
}
14+
/+ template<class T> +/
15+
S* f2(T)()
16+
{
17+
return &this;
18+
}
19+
}
20+
21+
/+ #ifdef DEF
22+
#define NAME f
23+
#else
24+
#define NAME f2
25+
#endif +/
26+
27+
static if (defined!"DEF")
28+
{
29+
/+ #define NAME2 p +/
30+
enum NAME2 = q{p};
31+
}
32+
static if (!defined!"DEF")
33+
{
34+
/+ #define NAME2 arr +/
35+
enum NAME2 = q{arr};
36+
}
37+
38+
int main()
39+
{
40+
S x;
41+
S[2] arr;
42+
S* p = &x;
43+
x.f!(S)();
44+
p.f!(S)();
45+
arr[0].f!(S)();
46+
x.f2!(S)().f!(S)();
47+
mixin(q{x.
48+
}
49+
~ (defined!"DEF" ? q{
50+
/+ NAME +/f
51+
}:"")
52+
~ (!defined!"DEF" ? q{
53+
f2
54+
}:"")
55+
~ q{
56+
!(S)
57+
}
58+
)();
59+
mixin(q{
60+
}
61+
~ (defined!"DEF" ? q{
62+
mixin(NAME2)
63+
}:"")
64+
~ (!defined!"DEF" ? q{
65+
mixin(NAME2)
66+
}:"")
67+
~ (!defined!"DEF" ? "[0]":"")
68+
~ q{
69+
.f!(S)
70+
}
71+
)();
72+
return 0;
73+
}
74+

tests/single/test94.d

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,14 @@ struct S
2727

2828
int f(S* s)
2929
{
30-
return mixin(q{s
30+
return mixin(q{s.
3131
}
32-
~ ((defined!"DEF") ? ".x" : ".y"));
32+
~ (defined!"DEF" ? q{
33+
/+ i +/x
34+
}:"")
35+
~ (!defined!"DEF" ? q{
36+
y
37+
}:"")
38+
);
3339
}
3440

tests/single/testdefines51.d

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,31 @@ void function(const(char)* s) write;
2828

2929
void f1(S* x)
3030
{
31-
mixin(q{x
32-
}
33-
~ ((defined!"DEF") ? ".write_impl" : ".write")) = mixin((defined!"DEF") ? q{
34-
& write
35-
} : q{
31+
mixin(q{x.
32+
}
33+
~ (defined!"DEF" ? q{
34+
/+ write +/write_impl
35+
}:"")
36+
~ (!defined!"DEF" ? q{
37+
write
38+
}:"")
39+
) = mixin((defined!"DEF") ? q{
40+
& write
41+
} : q{
3642
&write
37-
});
43+
});
3844
}
3945

4046
void f2(S* x, const(char)* str)
4147
{
42-
mixin(q{x
43-
}
44-
~ ((defined!"DEF") ? ".write_impl" : ".write"))(str);
48+
mixin(q{x.
49+
}
50+
~ (defined!"DEF" ? q{
51+
/+ write +/write_impl
52+
}:"")
53+
~ (!defined!"DEF" ? q{
54+
write
55+
}:"")
56+
)(str);
4557
}
4658

0 commit comments

Comments
 (0)