Skip to content

Commit 66adf93

Browse files
committed
Only compile unittests in root modules
1 parent 44d849e commit 66adf93

File tree

5 files changed

+56
-60
lines changed

5 files changed

+56
-60
lines changed

src/dmd/astbase.d

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,21 @@ struct ASTBase
14411441
srcfile = new File(srcfilename);
14421442
}
14431443

1444+
/**
1445+
A root module is one that will be compiled all the way to object code.
1446+
*/
1447+
final bool isRoot() const
1448+
{
1449+
return true;
1450+
}
1451+
1452+
/**
1453+
Called by the parser after the module declaration has been determined.
1454+
*/
1455+
final void afterModuleDeclaration()
1456+
{
1457+
}
1458+
14441459
override void accept(Visitor v)
14451460
{
14461461
v.visit(this);

src/dmd/dmodule.d

Lines changed: 26 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -292,10 +292,10 @@ extern (C++) final class Module : Package
292292
extern (C++) static __gshared Dsymbols deferred3; // deferred Dsymbol's needing semantic3() run on them
293293
extern (C++) static __gshared uint dprogress; // progress resolving the deferred list
294294
/**
295-
* A callback function that is called once an imported module is
296-
* parsed. If the callback returns true, then it tells the
297-
* frontend that the driver intends on compiling the import.
298-
*/
295+
A callback function that is called when a module is loaded as soon as its
296+
module declaration has been parsed. If the callback returns true, then it tells the
297+
frontend that the driver intends on compiling the import.
298+
*/
299299
extern (C++) static __gshared bool function(Module mod) onImport;
300300

301301
static void _init()
@@ -369,14 +369,8 @@ extern (C++) final class Module : Package
369369
Dsymbol searchCacheSymbol; // cached value of search
370370
int searchCacheFlags; // cached flags
371371

372-
/**
373-
* A root module is one that will be compiled all the way to
374-
* object code. This field holds the root module that caused
375-
* this module to be loaded. If this module is a root module,
376-
* then it will be set to `this`. This is used to determine
377-
* ownership of template instantiation.
378-
*/
379372
Module importedFrom;
373+
bool isCompiledImport;
380374

381375
Dsymbols* decldefs; // top level declarations for this Module
382376

@@ -515,41 +509,6 @@ extern (C++) final class Module : Package
515509
message("import %s", buf.peekString());
516510
}
517511
m = m.parse();
518-
519-
// Call onImport here because if the module is going to be compiled then we
520-
// need to determine it early because it affects semantic analysis. This is
521-
// being done after parsing the module so the full module name can be taken
522-
// from whatever was declared in the file.
523-
524-
//!!!!!!!!!!!!!!!!!!!!!!!
525-
// Workaround for bug in dmd version 2.068.2 platform Darwin_64_32.
526-
// This is the compiler version that the autotester uses, and this code
527-
// has been carefully crafted using trial and error to prevent a seg fault
528-
// bug that occurs with that version of the compiler. Note, this segfault
529-
// does not occur on the next version of dmd, namely, version 2.069.0. If
530-
// the autotester upgrades to that version, then this workaround can be removed.
531-
//!!!!!!!!!!!!!!!!!!!!!!!
532-
version(OSX)
533-
{
534-
if (!m.isRoot() && onImport)
535-
{
536-
auto onImportResult = onImport(m);
537-
if(onImportResult)
538-
{
539-
m.importedFrom = m;
540-
assert(m.isRoot());
541-
}
542-
}
543-
}
544-
else
545-
{
546-
if (!m.isRoot() && onImport && onImport(m))
547-
{
548-
m.importedFrom = m;
549-
assert(m.isRoot());
550-
}
551-
}
552-
553512
Target.loadModule(m);
554513
return m;
555514
}
@@ -1288,9 +1247,28 @@ extern (C++) final class Module : Package
12881247
return false;
12891248
}
12901249

1291-
bool isRoot()
1250+
/**
1251+
A root module is one that will be compiled all the way to object code.
1252+
*/
1253+
final bool isRoot() const
1254+
{
1255+
return this.importedFrom == this || isCompiledImport;
1256+
}
1257+
1258+
/**
1259+
Called by the parser after the module declaration has been determined.
1260+
*/
1261+
final void afterModuleDeclaration()
12921262
{
1293-
return this.importedFrom == this;
1263+
// Call onImport here because if the module is going to be compiled then we
1264+
// need to determine it early because it affects whether unittests will be parsed
1265+
// and semantic analysis. This is being done right after parsing the module delclaration
1266+
// so the full module name can be taken from whatever was declared in the file.
1267+
if (!isRoot() && Module.onImport && Module.onImport(this))
1268+
{
1269+
isCompiledImport = true;
1270+
assert(isRoot());
1271+
}
12941272
}
12951273

12961274
// true if the module source file is directly

src/dmd/glue.d

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -752,8 +752,17 @@ void FuncDeclaration_toObjFile(FuncDeclaration fd, bool multiobj)
752752
if (!fd.fbody)
753753
return;
754754

755+
// Find module m for this function
756+
Module m = null;
757+
for (Dsymbol p = fd.parent; p; p = p.parent)
758+
{
759+
m = p.isModule();
760+
if (m)
761+
break;
762+
}
763+
755764
UnitTestDeclaration ud = fd.isUnitTestDeclaration();
756-
if (ud && !global.params.useUnitTests)
765+
if (ud && (!global.params.useUnitTests || !m.isRoot))
757766
return;
758767

759768
if (multiobj && !fd.isStaticDtorDeclaration() && !fd.isStaticCtorDeclaration())
@@ -886,15 +895,6 @@ void FuncDeclaration_toObjFile(FuncDeclaration fd, bool multiobj)
886895
symtab_t *symtabsave = cstate.CSpsymtab;
887896
cstate.CSpsymtab = &f.Flocsym;
888897

889-
// Find module m for this function
890-
Module m = null;
891-
for (Dsymbol p = fd.parent; p; p = p.parent)
892-
{
893-
m = p.isModule();
894-
if (m)
895-
break;
896-
}
897-
898898
Dsymbols deferToObj; // write these to OBJ file later
899899
Array!(elem*) varsInScope;
900900
Label*[void*] labels = null;

src/dmd/module.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class Module : public Package
101101
// i.e. a module that will be taken all the
102102
// way to an object file
103103
Module *importedFrom;
104+
bool isCompiledImport;
104105

105106
Dsymbols *decldefs; // top level declarations for this Module
106107

@@ -144,7 +145,7 @@ class Module : public Package
144145
static void clearCache();
145146
int imports(Module *m);
146147

147-
bool isRoot() { return this->importedFrom == this; }
148+
bool isRoot() const { return this->importedFrom == this || this->isCompiledImport; }
148149
// true if the module source file is directly
149150
// listed in command line.
150151
bool isCoreModule(Identifier *ident);

src/dmd/parse.d

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ final class Parser(AST) : Lexer
377377
}
378378
}
379379

380+
mod.afterModuleDeclaration();
381+
380382
decldefs = parseDeclDefs(0, &lastDecl);
381383
if (token.value != TOK.endOfFile)
382384
{
@@ -547,7 +549,7 @@ final class Parser(AST) : Lexer
547549
break;
548550
}
549551
case TOK.unittest_:
550-
if (global.params.useUnitTests || global.params.doDocComments || global.params.doHdrGeneration)
552+
if ( (global.params.useUnitTests || global.params.doDocComments || global.params.doHdrGeneration) && mod.isRoot)
551553
{
552554
s = parseUnitTest(pAttrs);
553555
if (*pLastDecl)

0 commit comments

Comments
 (0)