@@ -498,52 +498,114 @@ private __gshared StringTable!(Symbol*) *stringTab;
498
498
/* ********************************************
499
499
* Figure out whether a data symbol should be dllimported
500
500
* Params:
501
- * var = declaration of the symbol
501
+ * symbl = declaration of the symbol
502
502
* Returns:
503
503
* true if symbol should be imported from a DLL
504
504
*/
505
- bool isDllImported (Dsymbol var )
505
+ bool isDllImported (Dsymbol symbl )
506
506
{
507
+ // Windows is the only platform which dmd supports, that uses the DllImport/DllExport scheme.
507
508
if (! (target.os & Target.OS .Windows))
508
509
return false ;
509
- if (var.isImportedSymbol())
510
+
511
+ // If function does not have a body, check to see if its marked as DllImport or is set to be exported.
512
+ // If a global variable has both export + extern, it is DllImport
513
+ if (symbl.isImportedSymbol())
510
514
return true ;
511
- if (driverParams.symImport == SymImport.none)
512
- return false ;
513
- if (auto vd = var.isDeclaration())
515
+
516
+ // Functions can go through the generated trampoline function.
517
+ // Not efficient, but it works.
518
+ if (symbl.isFuncDeclaration())
519
+ return false ; // can always jump through import table
520
+
521
+ // Global variables are allowed, but not TLS or read only memory.
522
+ if (auto vd = symbl.isDeclaration())
523
+ {
514
524
if (! vd.isDataseg() || vd.isThreadlocal())
515
525
return false ;
516
- if (var.isFuncDeclaration())
517
- return false ; // can always jump through import table
518
- if (auto tid = var.isTypeInfoDeclaration())
526
+ }
527
+
528
+ final switch (driverParams.symImport)
529
+ {
530
+ case SymImport.none:
531
+ // If DllImport overriding is disabled, do not change dllimport status.
532
+ return false ;
533
+
534
+ case SymImport.externalOnly:
535
+ // Only modules that are marked as out of binary will be DllImport
536
+ break ;
537
+
538
+ case SymImport.defaultLibsOnly:
539
+ case SymImport.all:
540
+ // If to access anything in druntime/phobos you need DllImport, verify against this.
541
+ break ;
542
+ }
543
+ const systemLibraryNeedDllImport = driverParams.symImport != SymImport.externalOnly;
544
+
545
+ // For TypeInfo's check to see if its in druntime and DllImport it
546
+ if (auto tid = symbl.isTypeInfoDeclaration())
519
547
{
548
+ // Built in TypeInfo's are defined in druntime
520
549
if (builtinTypeInfo(tid.tinfo))
521
- return true ;
550
+ return systemLibraryNeedDllImport;
551
+
552
+ // Convert TypeInfo to its symbol
522
553
if (auto ad = isAggregate(tid.type))
523
- var = ad;
554
+ symbl = ad;
524
555
}
525
- if (driverParams.symImport == SymImport.defaultLibsOnly)
556
+
526
557
{
527
- auto m = var.getModule();
558
+ // Filter the symbol based upon the module it is in.
559
+
560
+ auto m = symbl.getModule();
528
561
if (! m || ! m.md)
529
562
return false ;
530
- const id = m.md.packages.length ? m.md.packages[0 ] : null ;
531
- if (id && id != Id.core && id != Id.std)
532
- return false ;
533
- if (! id && m.md.id != Id.std && m.md.id != Id.object)
563
+
564
+ if (driverParams.symImport == SymImport.all || m.isExplicitlyOutOfBinary)
565
+ {
566
+ // If a module is specified as being out of binary (-extI), then it is allowed to be DllImport.
567
+ }
568
+ else if (driverParams.symImport == SymImport.externalOnly)
569
+ {
570
+ // Module is in binary, therefore not DllImport
534
571
return false ;
572
+ }
573
+ else if (systemLibraryNeedDllImport)
574
+ {
575
+ // Filter out all modules that are not in druntime/phobos if we are only doing default libs only
576
+
577
+ const id = m.md.packages.length ? m.md.packages[0 ] : null ;
578
+ if (id && id != Id.core && id != Id.std)
579
+ return false ;
580
+ if (! id && m.md.id != Id.std && m.md.id != Id.object)
581
+ return false ;
582
+ }
535
583
}
536
- else if (driverParams.symImport != SymImport.all)
537
- return false ;
538
- if (auto mod = var.isModule())
539
- return ! mod.isRoot(); // non-root ModuleInfo symbol
540
- if (var.inNonRoot())
584
+
585
+ // If symbol is a ModuleInfo, check to see if module is being compiled.
586
+ if (auto mod = symbl.isModule())
587
+ {
588
+ const isBeingCompiled = mod.isRoot();
589
+ return ! isBeingCompiled; // non-root ModuleInfo symbol
590
+ }
591
+
592
+ // Check to see if a template has been instatiated in current compilation,
593
+ // if it is defined in a external module, its DllImport.
594
+ if (symbl.inNonRoot())
541
595
return true ; // not instantiated, and defined in non-root
542
- if (auto ti = var.isInstantiated()) // && !defineOnDeclare(sym, false))
596
+
597
+ // If a template has been instatiated, only DllImport if it is codegen'ing
598
+ if (auto ti = symbl.isInstantiated()) // && !defineOnDeclare(sym, false))
543
599
return ! ti.needsCodegen(); // instantiated but potentially culled (needsCodegen())
544
- if (auto vd = var.isVarDeclaration())
600
+
601
+ // If a variable declaration and is extern
602
+ if (auto vd = symbl.isVarDeclaration())
603
+ {
604
+ // Shouldn't this be including an export check too???
545
605
if (vd.storage_class & STC .extern_)
546
606
return true ; // externally defined global variable
607
+ }
608
+
547
609
return false ;
548
610
}
549
611
0 commit comments