<div><div class="gmail_extra"><div class="gmail_quote">On 21 Sep 2016 3:11 pm, "Manman via cfe-dev" <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="quoted-text"><br>
> On Sep 21, 2016, at 10:48 AM, Tim Prince via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br>
><br>
> Hi everyone,<br>
><br>
> The modules documentation (<a href="http://clang.llvm.org/docs/Modules.html#macros" rel="noreferrer" target="_blank">http://clang.llvm.org/docs/<wbr>Modules.html#macros</a>) says this about importing multiple definitions of the same macro:<br>
><br>
>> For example, suppose:<br>
>>  - <stdio.h> defines a macro getc (and exports its #define)<br>
>>  - <cstdio> imports the <stdio.h> module and undefines the macro (and exports its #undef)<br>
>> The #undef overrides the #define, and a source file that imports both modules in any order will not see getc defined as a macro.<br>
<br>
</div>In this specific case, #undef in cstdio overrides the #define in the imported <stdio.h> module.<br>
See the document:<br>
        • A #define X or #undef X directive overrides all definitions of X that are visible at the point of the directive.<br>
        • A #define or #undef directive is active if it is visible and no visible directive overrides it.<br>
<div class="quoted-text"><br>
><br>
> I've been writing some test cases, and I've confirmed this behavior in a trivial test case. However, when I import two modules that both define a macro, that macro still seems to be defined even in the presence of another macro that #undef's it.<br>
<br>
</div>The module has 3 macros, the macro owned by Module.UndefFoo overrides the macro in Module.DefineFoo. The set of macros a given macro overrides depends on the order in your module map file, I think. That is why the macro in RedefineFoo is still active.</blockquote></div></div></div><div><br></div><div>Right. In the default mode, names defined in an earlier header in a top-level module are visible in later headers within that top-level module, so the order matters. (With -fmodules-local-submodule-visibility, this name leakage is turned off and each submodule starts with a clean slate, but that's not well supported in C yet.)</div><div><br></div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="quoted-text">
> Here are two test cases that demonstrate the divergent behavior:<br>
><br>
>> $ cat undef.c<br>
>> #include "Module/UndefFoo.h"<br>
</div>>> #include "Module/DefineFoo.h”<br>
<br>
Since the macro from Module.DefineFoo is overridden, FOO is undefined.<br>
<div class="quoted-text">>><br>
>> #ifdef FOO<br>
>> #error FOO was defined<br>
>> #endif<br>
>> $ cat redef-undef.c<br>
>> #include "Module/UndefFoo.h"<br>
>> #include "Module/DefineFoo.h"<br>
</div>>> #include "Module/RedefineFoo.h”<br>
The macro from RedefineFoo is active, and FOO is defined here.<br>
<br>
Manman<br>
<div class="elided-text"><br>
>><br>
>> #ifdef FOO<br>
>> #error FOO was defined<br>
>> #endif<br>
>> $<br>
><br>
> And here's the contents of the module itself:<br>
><br>
>> $ ls Module/<br>
>> DefineFoo.h  module.modulemap  RedefineFoo.h  UndefFoo.h<br>
>> $ cat Module/module.modulemap<br>
>> module Module {<br>
>>  module DefineFoo {<br>
>>    header "DefineFoo.h"<br>
>>  }<br>
>>  module UndefFoo {<br>
>>    header "UndefFoo.h"<br>
>>  }<br>
>>  module RedefineFoo {<br>
>>    header "RedefineFoo.h"<br>
>>  }<br>
>> }<br>
>> $ cat Module/DefineFoo.h<br>
>> #define FOO 1<br>
>> $ cat Module/RedefineFoo.h<br>
>> #define FOO 1<br>
>> $ cat Module/UndefFoo.h<br>
>> #undef FOO<br>
>> $<br>
><br>
> Now, when I run these test cases:<br>
><br>
>> $ /opt/pkg/clang-3.9.0/bin/clang -fmodules -c undef.c<br>
>> $ /opt/pkg/clang-3.9.0/bin/clang -fmodules -c redef-undef.c<br>
>> redef-undef.c:6:2: error: FOO was defined<br>
>> #error FOO was defined<br>
>> ^<br>
>> 1 error generated.<br>
>> $<br>
><br>
> The documentation seems to suggest that the latter case should also pass without errors. Is this inconsistency a bug or is there some subtlety I'm missing here?<br>
><br>
> Thanks!<br>
> - Tim<br>
> ______________________________<wbr>_________________<br>
> cfe-dev mailing list<br>
> <a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
<br>
______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
</div></blockquote></div><br></div></div>