-
-
Save alexandrumc/01c8f00e41e15ba6a541f164fd931ff3 to your computer and use it in GitHub Desktop.
DLang - semantic analysis on imports
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module x; | |
import y; | |
/* | |
Semantic analysis 1 = only TOP-LEVEL declarations are analyzed | |
By TOP-LEVEL declarations I understand: - functions (the header of the function, the parameters and the return type; | |
*the body IS NOT included*) | |
- global variables (templates instantiations included) | |
- struct/classes/templates declarations | |
Semantic analysis 2 = solves the things that couldn't be solved in Semantic 1 (more complicated things) | |
(ex. templates definitions and instantiations, classes, structs etc.) | |
Semantic analysis 3 = the final analysis and the most complete and invasive one. | |
- e.g. the bodies of the functions and some properties of the templates that weren't solved in semantic 1 and semantic 2 | |
- THE MOST IMPORTANT THING: the code on which semantic 3 is performed GETS A CHANCE TO BE GENERATED. | |
Now is important to understand how semantic analysis works *on imports*: | |
- Firstly, only semantic analysis 1 is done on imports. | |
- observation 1: as I mentioned before, in semantic1 the bodies of functions are not included, so that's why | |
there won't be an error for 'WrongCodeThatPassesLexicalAnalysis' (see y.d below) (both "dmd -c x.d" and | |
"dmd -c -unittest x.d" will work) | |
- observation 2: most of version(unittest) {} blocks are at the TOP-LEVEL; that means "dmd -c -unittest x.d" will trigger | |
semantic 1 on every statement that's present inside a version block (Phobos, druntime included) -> overhead | |
- observation 2.1 : there are still many version (unittest) in the Phobos library. | |
I thought that Steven’s PR removed everything, but then I verified myself and | |
I realized it’s not true. I tried to replace them automatically using | |
sed -i version(unittest)/ version(somethingElse)/g but this didn’t work | |
and resulted in different errors while recompiling Phobos. | |
The conclusion is that we must remove one version block at a time | |
because the code inside each version() {} has to be understood and moved correctly. | |
There are version (unittest) {} blocks even in the druntime, and they are | |
semantic analyzed (when we use -unittest) even if there are 0 import statements. | |
- After the semantic 1 finishes, semantic analysis 2 will begin its job on the statements that couldn't be handled by semantic1 | |
- Now, very important, BY DEFAULT THERE IS NO semantic3 done on non-root modules => no semantic3 on imports that are not | |
also passed as command-line arguments. | |
e.g. "dmd -c x.d" won't trigger semantic3 on y.d because y is not a root module; | |
Now, again, very important: the special behaviour done when -unittest switch is used can be summed up as follows: | |
"-unittest is activating semantic analysis 3 on non-root modules (i.e. imports not given in the command line) | |
by considering them root modules" | |
Why? Because some templates from non-root modules might need code generation. Why again? | |
All the answers are here: https://wiki.dlang.org/Template_Instantiation_Strategy | |
*/ | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module y; | |
struct S(T) | |
{ | |
T something; | |
void method() {}; | |
} | |
unittest | |
{ | |
WrongCodeThatPassesLexicalAnalysis; | |
} | |
version (unittest) | |
{ | |
import std.uni; | |
import std.regex; | |
// other imports | |
// template instantiations, other things... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment