> On Jul 24, 2014, at 6:58 PM, Richard Smith <[email protected]> wrote:
> 
> On Thu, Jul 24, 2014 at 7:56 AM, Ben Langmuir <[email protected]> wrote:
> 
>> On Jul 16, 2014, at 3:42 PM, Richard Smith <[email protected]> wrote:
>> 
>> On Fri, Jul 11, 2014 at 8:42 AM, Ben Langmuir <[email protected]> wrote:
>> Hey RIchard,
>> 
>> Sorry to take so long to reply to this, but I am still interested in getting 
>> this stopgap into tree.
>> 
>> Sorry about the delay getting back to you!
>>  
>>> Please do not add a stopgap workaround to our stable and 
>>> backwards-compatible driver interface; just add it to -cc1 instead.
>> 
>> 
>> Sure.
>> 
>>> I don't see any relation between the flag's name and its functionality; 
>>> there seems to be no reason for this to be linked to the translation unit 
>>> being the implementation of any particular module (and if there were, 
>>> that's what -fmodule-name is for). Instead, I think what you're trying to 
>>> specify is that a particular module is included textually for this 
>>> compilation. Please pick a name that suggests that functionality instead.
>> 
>> 
>> In the abstract I agree with this, but the use case I have is only for TUs 
>> that are implementation files for a module and I know that is the only time 
>> that this flag will be used by our tools.  It is more useful for the 
>> diagnostic to say “don’t do this in the implementation of module Foo”, since 
>> that matches when the build system will be passing in this flag.  Given that 
>> this doesn’t go into the driver, is this still an issue? If not, I can 
>> update and commit this patch, or can post it again for review if you prefer 
>> :-)
>> 
>> I'm fine with this as a short-term cc1-only flag. Longer-term I think we 
>> need to evaluate whether we can make the import-of-same-module cases "just 
>> work" (I think we can), and I hope this becomes unnecessary at that point.
> 
> r213767
> 
>> 
>>> >>> What’s unexpected to me is that changing a header whose contents are 
>>> >>> not usually visible may still require rebuilding all of my .cpp files.
>>> >>> module Foo { module One { header “One.h” } module Two { header “Two.h” 
>>> >>> } }
>>> >>>
>>> >>> // One.cpp - I don’t want to rebuild when Two.h changes
>>> >>> #import <Foo/One.h>
>>> >>>
>>> >>> Do we agree that this is unnecessary if submodules cannot accidentally 
>>> >>> be affected by changes in other submodules they don’t import (and we 
>>> >>> have some way to get the set of dependency files for just the 
>>> >>> submodule)?
>>> >>
>>> >>
>>> >> No, I don't agree with that. One.cpp might inline some function 
>>> >> definitions from Two.h, for instance. Or it might fail to build because 
>>> >> it declares something that conflicts with something in Two.h.
>>> >
>>> >
>>> > I feel like I”m missing something - how is that different from One.cpp 
>>> > having conflicts with some completely different header or module that is 
>>> > not imported into that particular TU?
>>> 
>>> If you import any part of a module, you have the whole module as part of 
>>> your translation unit, even though only some of it might be visible. Thus 
>>> we will diagnose your declarations that conflict with unimported portions 
>>> of an imported module.
>>> 
>> 
>> Maybe we need to have this discussion on cfe-dev at some point.  I think we 
>> need a driver flag to control whether clang reports headers from unimported 
>> submodules as dependencies, which will allow users/build systems to make the 
>> tradeoff.  As for the default, I strongly feel we shouldn't penalize build 
>> performance for correct code in order to guarantee that these particular ODR 
>> violations get diagnosed in incremental builds.  A full rebuild will still 
>> see any diagnostics and the subset of errors that this affects are not being 
>> diagnosed today with headers, so we’re still improving.
>> 
>> Conversely, I think that we should provide a guarantee that incremental and 
>> full builds produce bit-for-bit identical results. As you say, it's a 
>> tradeoff, but note that this isn't just about ODR violation checking -- the 
>> incremental approach you're suggesting can generate wrong code in some cases 
>> (we can inline a function definition from the old version of Two.h) -- so if 
>> we want to support this partial-rebuild mode, we'll need to be /very/ 
>> careful that we don't pull in any information from an unimported submodule 
>> in that mode.
> 
> Maybe you can help me understand how this would come about.  In our 
> documentation we say:
> 
>> Modules are modeled as if each submodule were a separate translation unit, 
>> and a module import makes names from the other translation unit visible
> 
> 
> Here’s my understanding:
> If I don’t import the submodule containing “Two.h”, then I shouldn’t get its 
> definitions in my TU.
> 
> You get its definitions in your *program*. If you import any part of a 
> module, the entire module is part of your program. Example:

Okay, but that’s just more consistency checking, ins’t it?  If I import 
Module1.B, but not Module1.A (or Module2.C) I don’t want to see “f” in my 
exported symbols.

> 
> Module1.A:
> int f(int);
> 
> Module1.B:
> extern int n;
> 
> Module2.C:
> import Module1.B;
> void f(int); // error, conflicting return type
> 
> If I have an inline declaration for a function in Two, then I still need to 
> have a definition in my own TU because of inline.  If I have a non-inline 
> decl, then Two can’t have an inline decl and if it has a definition for the 
> function not marked inline then having that definition show up in my TU would 
> lead to multiple definitions if Two is imported somewhere else.
> 
> You can get into this situation with C++ templates. You might only be able to 
> see a declaration of a template, where another submodule provides a 
> definition that is hidden but still available for inlining. This doesn't 
> violate any language rule as long as there's an explicit instantiation of the 
> template somewhere.

If I don’t see a definition in my TU, how can I use the template in a way 
affected by inlining?  I may not have an instantiation of a template, but I 
still need to see its definition.  If its definition changes, that would 
require rebuilding the other TU that has the instantiation.  I’m probably being 
thick, but I still don’t see the issue here.


> You can also get into this situation with the C99 inline rules, where you 
> don't have to define an 'inline' function in every translation unit.

Did this change in C11, or am I misreading this?
6.7.4.7: For a function with external linkage, the following restrictions 
apply: If a function is declared with an inline function specifier, then it 
shall also be defined in the same translation unit.


Ben
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to