@@ -6068,161 +6068,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
6068
6068
*/
6069
6069
final bool needsCodegen ()
6070
6070
{
6071
- // Now -allInst is just for the backward compatibility.
6072
- if (global.params.allInst)
6073
- {
6074
- // printf("%s minst = %s, enclosing (%s).isNonRoot = %d\n",
6075
- // toPrettyChars(), minst ? minst.toChars() : NULL,
6076
- // enclosing ? enclosing.toPrettyChars() : NULL, enclosing && enclosing.inNonRoot());
6077
- if (enclosing)
6078
- {
6079
- /* https://issues.dlang.org/show_bug.cgi?id=14588
6080
- * If the captured context is not a function
6081
- * (e.g. class), the instance layout determination is guaranteed,
6082
- * because the semantic/semantic2 pass will be executed
6083
- * even for non-root instances.
6084
- */
6085
- if (! enclosing.isFuncDeclaration())
6086
- return true ;
6087
-
6088
- /* https://issues.dlang.org/show_bug.cgi?id=14834
6089
- * If the captured context is a function,
6090
- * this excessive instantiation may cause ODR violation, because
6091
- * -allInst and others doesn't guarantee the semantic3 execution
6092
- * for that function.
6093
- *
6094
- * If the enclosing is also an instantiated function,
6095
- * we have to rely on the ancestor's needsCodegen() result.
6096
- */
6097
- if (TemplateInstance ti = enclosing.isInstantiated())
6098
- return ti.needsCodegen();
6099
-
6100
- /* https://issues.dlang.org/show_bug.cgi?id=13415
6101
- * If and only if the enclosing scope needs codegen,
6102
- * this nested templates would also need code generation.
6103
- */
6104
- return ! enclosing.inNonRoot();
6105
- }
6106
- return true ;
6107
- }
6108
-
6109
- if (! minst)
6110
- {
6111
- // If this is a speculative instantiation,
6112
- // 1. do codegen if ancestors really needs codegen.
6113
- // 2. become non-speculative if siblings are not speculative
6114
-
6115
- TemplateInstance tnext = this .tnext;
6116
- TemplateInstance tinst = this .tinst;
6117
- // At first, disconnect chain first to prevent infinite recursion.
6118
- this .tnext = null ;
6119
- this .tinst = null ;
6120
-
6121
- // Determine necessity of tinst before tnext.
6122
- if (tinst && tinst.needsCodegen())
6123
- {
6124
- minst = tinst.minst; // cache result
6125
- assert (minst);
6126
- assert (minst.isRoot() || minst.rootImports());
6127
- return true ;
6128
- }
6129
- if (tnext && (tnext.needsCodegen() || tnext.minst))
6130
- {
6131
- minst = tnext.minst; // cache result
6132
- assert (minst);
6133
- return minst.isRoot() || minst.rootImports();
6134
- }
6135
-
6136
- // Elide codegen because this is really speculative.
6137
- return false ;
6138
- }
6139
-
6140
- /* Even when this is reached to the codegen pass,
6141
- * a non-root nested template should not generate code,
6142
- * due to avoid ODR violation.
6143
- */
6144
- if (enclosing && enclosing.inNonRoot())
6145
- {
6146
- if (tinst)
6147
- {
6148
- auto r = tinst.needsCodegen();
6149
- minst = tinst.minst; // cache result
6150
- return r;
6151
- }
6152
- if (tnext)
6153
- {
6154
- auto r = tnext.needsCodegen();
6155
- minst = tnext.minst; // cache result
6156
- return r;
6157
- }
6158
- return false ;
6159
- }
6160
-
6161
- if (true )// global.params.useUnitTests)
6162
- {
6163
- // Prefer instantiations from root modules, to maximize link-ability.
6164
- if (minst.isRoot())
6165
- return true ;
6166
-
6167
- TemplateInstance tnext = this .tnext;
6168
- TemplateInstance tinst = this .tinst;
6169
- this .tnext = null ;
6170
- this .tinst = null ;
6171
-
6172
- if (tinst && tinst.needsCodegen())
6173
- {
6174
- minst = tinst.minst; // cache result
6175
- assert (minst);
6176
- assert (minst.isRoot() || minst.rootImports());
6177
- return true ;
6178
- }
6179
- if (tnext && tnext.needsCodegen())
6180
- {
6181
- minst = tnext.minst; // cache result
6182
- assert (minst);
6183
- assert (minst.isRoot() || minst.rootImports());
6184
- return true ;
6185
- }
6186
-
6187
- // https://issues.dlang.org/show_bug.cgi?id=2500 case
6188
- if (false )// minst.rootImports())
6189
- return true ;
6190
-
6191
- // Elide codegen because this is not included in root instances.
6192
- return false ;
6193
- }
6194
- else
6195
- {
6196
- // Prefer instantiations from non-root module, to minimize object code size.
6197
-
6198
- /* If a TemplateInstance is ever instantiated by non-root modules,
6199
- * we do not have to generate code for it,
6200
- * because it will be generated when the non-root module is compiled.
6201
- *
6202
- * But, if the non-root 'minst' imports any root modules, it might still need codegen.
6203
- *
6204
- * The problem is if A imports B, and B imports A, and both A
6205
- * and B instantiate the same template, does the compilation of A
6206
- * or the compilation of B do the actual instantiation?
6207
- *
6208
- * See https://issues.dlang.org/show_bug.cgi?id=2500.
6209
- */
6210
- if (! minst.isRoot() && ! minst.rootImports())
6211
- return false ;
6212
-
6213
- TemplateInstance tnext = this .tnext;
6214
- this .tnext = null ;
6215
-
6216
- if (tnext && ! tnext.needsCodegen() && tnext.minst)
6217
- {
6218
- minst = tnext.minst; // cache result
6219
- assert (! minst.isRoot());
6220
- return false ;
6221
- }
6222
-
6223
- // Do codegen because this is not included in non-root instances.
6224
- return true ;
6225
- }
6071
+ return minst && minst.isRoot();
6226
6072
}
6227
6073
6228
6074
/* *********************************************
@@ -7165,9 +7011,14 @@ extern (C++) class TemplateInstance : ScopeDsymbol
7165
7011
}
7166
7012
*/
7167
7013
7168
- if (! mi)
7014
+ if (! mi || ! mi.isRoot() )
7169
7015
return null ;
7170
7016
7017
+ // skip if a sibling has already been added
7018
+ for (auto sibling = primaryInst; sibling; sibling = sibling.tnext)
7019
+ if (sibling.memberOf is mi)
7020
+ return null ;
7021
+
7171
7022
/+ +
7172
7023
//printf("%s.appendToModuleMember() enclosing = %s mi = %s\n",
7173
7024
// toPrettyChars(),
@@ -7228,10 +7079,20 @@ extern (C++) class TemplateInstance : ScopeDsymbol
7228
7079
Dsymbols* a = mi.members;
7229
7080
a.push(this );
7230
7081
memberOf = mi;
7231
- if (mi.semanticRun >= PASS .semantic2done && mi.isRoot())
7232
- Module.addDeferredSemantic2(this );
7233
- if (mi.semanticRun >= PASS .semantic3done && mi.isRoot())
7234
- Module.addDeferredSemantic3(this );
7082
+ if (! primaryInst)
7083
+ {
7084
+ if (mi.semanticRun >= PASS .semantic2done)
7085
+ Module.addDeferredSemantic2(this );
7086
+ if (mi.semanticRun >= PASS .semantic3done)
7087
+ Module.addDeferredSemantic3(this );
7088
+ }
7089
+ else if (! primaryInst.memberOf || ! primaryInst.memberOf.isRoot())
7090
+ {
7091
+ // printf(".: deferredSemantic for non-root primaryInst: %s\n", primaryInst.toChars());
7092
+ Module.addDeferredSemantic2(primaryInst);
7093
+ Module.addDeferredSemantic3(primaryInst);
7094
+ primaryInst.memberOf = mi; // HACK
7095
+ }
7235
7096
return a;
7236
7097
}
7237
7098
0 commit comments