Modules TS: various problems

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Modules TS: various problems

Xin Wang via cfe-dev
I am trying to use the Modules TS implementation in Clang 5.0.0-svn305177.
My module interface file:

#include <string>

export module hello;

export namespace hello
{
  void say (const std::string& name);
}

Module implementation file:

#include <string>
#include <iostream>

module hello;

using namespace std;

namespace hello
{
  void
  say (const string& n)
  {
    cout << "Hello, " << n << '!' << endl;
  }
}

The problems:

1. It seems the .pcm file compiled from the interface file references
   said interface file. If I remove it after generating .pcm, then I get
   an error like this when compiling the implementation file:

   clang++-5.0 -std=c++1z -D__cpp_modules=201704 -fmodules-ts -fmodule-file=hello.a.pcm -o hello.a.o -c -x c++ hello.a.o.ii
   fatal error: malformed or corrupted AST file: 'could not find file '/home/boris/work/build2/hello/m/libmhello/libhello/hello.a.pcm.ii' referenced by AST file 'hello.a.pcm''

   The .pcm is produced with this command line:

   clang++-5.0 -std=c++1z -D__cpp_modules=201704 -fmodules-ts -o hello.a.pcm --precompile -Xclang -fmodules-codegen -Xclang -fmodules-debuginfo -x c++-module hello.a.pcm.ii

2. If I keep the source file, then I get errors along these lines (again,
   when compiling the implementation file):

   In file included from hello.cxx:3:
   In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/string:39:
   /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/bits/stringfwd.h:69:48: error: template parameter redefines default argument
     template<typename _CharT, typename _Traits = char_traits<_CharT>,
   /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/bits/stringfwd.h:69:48: note: previous default template argument defined here
     template<typename _CharT, typename _Traits = char_traits<_CharT>,

   The same code compiles fine with VC 15u3.

   If I get rid of the <string> inclusion from the interface file (and
   use const char* to pass the name), everything compiles fine.

Thanks,
Boris
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Modules TS: various problems

Xin Wang via cfe-dev


On Mon, Jun 19, 2017 at 6:45 AM Boris Kolpackov via cfe-dev <[hidden email]> wrote:
I am trying to use the Modules TS implementation in Clang 5.0.0-svn305177.
My module interface file:

#include <string>

export module hello;

export namespace hello
{
  void say (const std::string& name);
}

Module implementation file:

#include <string>
#include <iostream>

module hello;

using namespace std;

namespace hello
{
  void
  say (const string& n)
  {
    cout << "Hello, " << n << '!' << endl;
  }
}

The problems:

1. It seems the .pcm file compiled from the interface file references
   said interface file. If I remove it after generating .pcm, then I get
   an error like this when compiling the implementation file:

   clang++-5.0 -std=c++1z -D__cpp_modules=201704 -fmodules-ts -fmodule-file=hello.a.pcm -o hello.a.o -c -x c++ hello.a.o.ii
   fatal error: malformed or corrupted AST file: 'could not find file '/home/boris/work/build2/hello/m/libmhello/libhello/hello.a.pcm.ii' referenced by AST file 'hello.a.pcm''

   The .pcm is produced with this command line:

   clang++-5.0 -std=c++1z -D__cpp_modules=201704 -fmodules-ts -o hello.a.pcm --precompile -Xclang -fmodules-codegen -Xclang -fmodules-debuginfo -x c++-module hello.a.pcm.ii

This should be able to be addressed by using -Xclang -fmodules-embed-all-files (see https://reviews.llvm.org/rL253950 for some more info).

Perhaps Richard'll have ideas on the rest.
 
2. If I keep the source file, then I get errors along these lines (again,
   when compiling the implementation file):

   In file included from hello.cxx:3:
   In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/string:39:
   /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/bits/stringfwd.h:69:48: error: template parameter redefines default argument
     template<typename _CharT, typename _Traits = char_traits<_CharT>,
   /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/bits/stringfwd.h:69:48: note: previous default template argument defined here
     template<typename _CharT, typename _Traits = char_traits<_CharT>,

   The same code compiles fine with VC 15u3.

   If I get rid of the <string> inclusion from the interface file (and
   use const char* to pass the name), everything compiles fine.

Thanks,
Boris
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Modules TS: various problems

Xin Wang via cfe-dev
In reply to this post by Xin Wang via cfe-dev
On 19 June 2017 at 06:45, Boris Kolpackov via cfe-dev <[hidden email]> wrote:
I am trying to use the Modules TS implementation in Clang 5.0.0-svn305177.
My module interface file:

#include <string>

export module hello;

export namespace hello
{
  void say (const std::string& name);
}

Module implementation file:

#include <string>
#include <iostream>

module hello;

using namespace std;

namespace hello
{
  void
  say (const string& n)
  {
    cout << "Hello, " << n << '!' << endl;
  }
}

The problems:

1. It seems the .pcm file compiled from the interface file references
   said interface file. If I remove it after generating .pcm, then I get
   an error like this when compiling the implementation file:

   clang++-5.0 -std=c++1z -D__cpp_modules=201704 -fmodules-ts -fmodule-file=hello.a.pcm -o hello.a.o -c -x c++ hello.a.o.ii
   fatal error: malformed or corrupted AST file: 'could not find file '/home/boris/work/build2/hello/m/libmhello/libhello/hello.a.pcm.ii' referenced by AST file 'hello.a.pcm''

   The .pcm is produced with this command line:

   clang++-5.0 -std=c++1z -D__cpp_modules=201704 -fmodules-ts -o hello.a.pcm --precompile -Xclang -fmodules-codegen -Xclang -fmodules-debuginfo -x c++-module hello.a.pcm.ii

.pcm files are not a distribution format. You still need the module interface to be available at the point of use (Clang will use them to emit text snippets in diagnostics, as well as for some internal purposes where we avoid making copies of data that's present in a source file). As David notes, you can use -fmodules-embed-all-files to cause the input files to be embedded in the .pcm file.

2. If I keep the source file, then I get errors along these lines (again,
   when compiling the implementation file):

   In file included from hello.cxx:3:

This line number doesn't match the above code.
 
   In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/string:39:
   /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/bits/stringfwd.h:69:48: error: template parameter redefines default argument
     template<typename _CharT, typename _Traits = char_traits<_CharT>,
   /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/bits/stringfwd.h:69:48: note: previous default template argument defined here
     template<typename _CharT, typename _Traits = char_traits<_CharT>,

   The same code compiles fine with VC 15u3.

   If I get rid of the <string> inclusion from the interface file (and
   use const char* to pass the name), everything compiles fine.

I'm not surprised. Clang does not claim to fully implement the Modules TS yet; the implementation is incomplete. In particular, there is no support for the semantics of export declarations -- instead, we export everything declared within the module interface unit. As a result, you're importing the contents of <string> but not its include guards, so you will see redefinition errors for all definitions in that header.

If you want to experiment with Modules TS code using the standard library anyway, the easiest way to get the above code working would be to use a standard library implementation that provides a module map (for instance, build with -stdlib=libc++ -fmodules).

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Modules TS: various problems

Xin Wang via cfe-dev
Richard Smith <[hidden email]> writes:

> .pcm files are not a distribution format. You still need the module
> interface to be available at the point of use (Clang will use them to emit
> text snippets in diagnostics, as well as for some internal purposes where
> we avoid making copies of data that's present in a source file).

My source file is partially preprocessed (-frewrite-includes) and is
transient. More generally, this won't play nice with distributed
compilation or being able to move build directories around.


David Blaikie <[hidden email]> writes:

> This should be able to be addressed by using -Xclang
> -fmodules-embed-all-files [...]

Yes, this works, thanks.


Richard Smith <[hidden email]> writes:

> This line number doesn't match the above code.

Yes, my bad, I've killed a couple of irrelevant lines. It was the line
with '#include <string>'.


> I'm not surprised. Clang does not claim to fully implement the Modules TS
> yet; the implementation is incomplete. In particular, there is no support
> for the semantics of export declarations -- instead, we export everything
> declared within the module interface unit. As a result, you're importing
> the contents of <string> but not its include guards, so you will see
> redefinition errors for all definitions in that header.
>
> If you want to experiment with Modules TS code using the standard library
> anyway, the easiest way to get the above code working would be to use a
> standard library implementation that provides a module map (for instance,
> build with -stdlib=libc++ -fmodules).

Let me see if I understand how this will work: if I build libc++ modules,
then '#include <string>' directives will be treated by Clang as module
imports and this will prevent the imported std::string declarations from
being all-exported from my module?

Also, from your previous replies I pieced together that one can use the
import declaration to import "header modules". So, theoretically, I
should be able to replace my '#include <string>' with something like
'import std.core' provided I build an appropriate .pcm?

Thanks,
Boris
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Modules TS: various problems

Xin Wang via cfe-dev
Boris Kolpackov <[hidden email]> writes:

> So, theoretically, I should be able to replace my '#include <string>'
> with something like 'import std.core' provided I build an appropriate
> .pcm?

Actually, nothing prevents me from defining my own modules-ts std.core
module, even if I am using libstdc++:

// file: std-core.mxx -*- C++ -*-
export module std.core;

#include <string>
#include <iostream> // For compatibility with VC.

I was then able to replace '#include <string>' with 'import std.core'
and everything works except for one little niggle: for some reason
Clang insists that I import in the module's purview:

// file: hello.mxx -*- C++ -*-
export module hello;

import std.core;

export namespace hello
{
  void
  say (const std::string& name);
}

If I move import before the exporting module declaration:

// file: hello.mxx -*- C++ -*-
import std.core;

export module hello;

export namespace hello
{
  void
  say (const std::string& name); // line 9
}

Then I get this error:

hello.mxx:9:14: error: declaration of 'std' must be imported from module 'std.core' before it is required say (const std::string& name);
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/iostream:42:11: note: previous declaration is here namespace std _GLIBCXX_VISIBILITY(default)

VC is happy with either placement and my reading of the spec suggests
that it shouldn't matter (unlike #include). Or am I missing something
here?

Thanks,
Boris
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Modules TS: various problems

Xin Wang via cfe-dev
On 20 June 2017 at 05:29, Boris Kolpackov <[hidden email]> wrote:
Boris Kolpackov <[hidden email]> writes:

> So, theoretically, I should be able to replace my '#include <string>'
> with something like 'import std.core' provided I build an appropriate
> .pcm?

Actually, nothing prevents me from defining my own modules-ts std.core
module, even if I am using libstdc++:

// file: std-core.mxx -*- C++ -*-
export module std.core;

#include <string>
#include <iostream> // For compatibility with VC.

I was then able to replace '#include <string>' with 'import std.core'
and everything works except for one little niggle: for some reason
Clang insists that I import in the module's purview:

// file: hello.mxx -*- C++ -*-
export module hello;

import std.core;

export namespace hello
{
  void
  say (const std::string& name);
}

If I move import before the exporting module declaration:

// file: hello.mxx -*- C++ -*-
import std.core;

export module hello;

export namespace hello
{
  void
  say (const std::string& name); // line 9
}

Then I get this error:

hello.mxx:9:14: error: declaration of 'std' must be imported from module 'std.core' before it is required say (const std::string& name);
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/iostream:42:11: note: previous declaration is here namespace std _GLIBCXX_VISIBILITY(default)

VC is happy with either placement and my reading of the spec suggests
that it shouldn't matter (unlike #include). Or am I missing something
here?

This is another "implementation not finished yet" issue. What's happening here is that "export module hello;" enters a new module scope, and that new module scope does not (yet) inherit the set of imported modules from the global module scope. 

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Loading...