<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <meta name="title" content="Recognizing Header Unit Imports Requires Full Preprocessing"/>

  <title>Recognizing Header Unit Imports Requires Full Preprocessing</title>

  <style type="text/css">

html
{
  font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
  font-weight: normal;
  font-size: 18px;
  line-height: 1.4em;
  letter-spacing: 0.01em;

  color: #292929;
}

body {margin: 0;} /* There is non-0 default margin for body. */

/* See notes on what's going on here. */
body {min-width: 17em;}
@media only screen and (min-width: 360px)
{
  body {min-width: 19em;}
}

/*
 * Header (optional).
 */

#header-bar
{
  width: 100%;

  background: rgba(0, 0, 0, 0.04);
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);

  padding: .4em 0 .42em 0;
  margin: 0 0 1.4em 0;
}

#header
{
  /* Same as in #content. */
  max-width: 41em;
  margin: 0 auto 0 auto;
  padding: 0 .4em 0 .4em;

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;

  width: 100%;
  display: table;
  border: none;
  border-collapse: collapse;
}

#header-logo, #header-menu
{
  display: table-cell;
  border: none;
  padding: 0;
  vertical-align: middle;
}

#header-logo {text-align: left;}
#header-menu {text-align: right;}

/* These overlap with #header's margin because of border collapsing. */
#header-logo {padding-left: .4em;}
#header-menu {padding-right: .4em;}

#header-logo a
{
  color: #000;
  text-decoration: none;
  outline: none;
}
#header-logo a:visited {color: #000;}
#header-logo a:hover, #header-logo a:active {color: #000;}

#header-menu a
{
  font-size: 0.889em;
  line-height: 1.4em;
  text-align: right;
  margin-left: 1.2em;
  white-space: nowrap;
  letter-spacing: 0;
}

#header-menu a
{
  color: #000;
  outline: none;
}
#header-menu a:visited {color: #000;}
#header-menu a:hover, #header-menu a:active
{
  color: #3870c0;
  text-decoration: none;
}

/* Flexbox-based improvements though the above works reasonably well. */
#header-menu-body
{
  width: 100%;

  display: -webkit-inline-flex;
  display: inline-flex;

  -webkit-flex-flow: row wrap;
  flex-flow: row wrap;

  -webkit-justify-content: flex-end;
  justify-content: flex-end;
}

/* Whether we want it (and at which point) depends on the size of the menu. */
/*
@media only screen and (max-width: 567px)
{
  #header-menu-body
  {
    -webkit-flex-direction: column;
    flex-direction: column;
  }
}
*/

/*
 * Content.
 */

#content
{
  max-width: 41em;
  margin: 0 auto 0 auto;
  padding: 0 .4em 0 .4em; /* Space between text and browser frame. */

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

/*
 * Footer (optional).
 */

#footer
{
  color: #767676;
  font-size: 0.7223em;
  line-height: 1.3em;
  margin: 2.2em 0 1em 0;
  text-align: center;
}

#footer a
{
  color: #767676;
  text-decoration: underline;
}
#footer a:visited {color: #767676;}
#footer a:hover, #footer a:active {color: #3870c0;}

/* Screen size indicator in the footer. The before/after content is in case
   we don't have any content in the footer. Margin is to actually see the
   border separate from the browser frame. */

/*
#footer:before {content: "\A0";}
#footer:after {content: "\A0";}

#footer
{
  border-left: 1px solid;
  border-right: 1px solid;
  margin-left: 1px;
  margin-right: 1px;
}

@media only screen and (max-width: 359px)
{
  #footer {border-color: red;}
}

@media only screen and (min-width: 360px) and (max-width: 567px)
{
  #footer {border-color: orange;}
}

@media only screen and (min-width: 568px) and (max-width: 1023px)
{
  #footer {border-color: blue;}
}

@media only screen and (min-width: 1024px)
{
  #footer {border-color: green;}
}
*/

/*
 * Common elements.
 */

p, li, dd {text-align: justify;}
.code {text-align: left;} /* Manually aligned. */
pre {text-align: left;}   /* If it is inside li/dd. */

/* Notes. */

.note
{
  color: #606060;
}

div.note
{
  margin: 2em 0 2em 0; /* The same top/bottom margings as pre box. */

  padding-left: 0.5em;
  border: 0.25em;
  border-left-style: solid;
  border-color: #808080;

  page-break-inside: avoid;
}

div.note :first-child {margin-top:    0;}
div.note :last-child  {margin-bottom: 0;}

span.note::before {content: "[Note: "}
span.note::after  {content: "]"}

/* Links. */
a
{
  color: #3870c0;
  /*color: #4078c0;*/
  text-decoration: none;
}

a:hover, a:active
{
/*color: #006fbf;*/
/*color: #0087e7;*/
  text-decoration: underline;
}

a:visited
{
/*color: #003388;*/
  color: #00409c;
}

/* Standard paragraph. */

p, pre {margin: 1em 0 1em 0;}

/* Standard lists. */
ul, ol, dl {margin: 1em 0 1em 0;}
ul li, ol li {margin: 0 0 .4em 0;}
ul li {list-style-type: circle;}
dl dt {margin: 0 0 0 0;}
dl dd {margin: 0 0 .6em 1.8em;}

code, pre
{
  font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 0.92em;
  letter-spacing: 0;
}

pre {white-space: pre-wrap;}

@media only screen and (max-width: 567px)
{
  pre {word-break: break-all;}
}

/* Use page rather than system font settings. */
input
{
  font-family: inherit;
  font-weight: inherit;
  font-size:   inherit;
  line-height: inherit;
}

pre
{
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 0.2em;
  padding: .8em .4em .8em .4em;
  margin: 2em -.4em 2em -.4em; /* Use margins of #content. */
}

code
{
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 0.2em;
  padding: .2em .32em .18em .32em;
}

/*
code::before
{
  letter-spacing: -0.2em;
  content: "\00a0";
}

code::after
{
  letter-spacing: -0.2em;
  content: "\00a0";
}
*/


/* Bases:
 *
 * common.css
 * pre-box.css
 * code-box.css
 *
 */

#content
{
  max-width: 43.6em;
  padding-left: 3em; /* Reserve for headings. */
}

h1
{
  font-weight: normal;
  font-size: 2em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -1.4em;
}

h1.preface
{
  margin-left: -.56em;
}

h2
{
  font-weight: normal;
  font-size: 1.556em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -.8em;
}

h3
{
  font-weight: normal;
  font-size: 1.3em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -.2em;
}

/* Title page */

#titlepage {
  margin: 0 0 4em 0;
  border-bottom: 1px solid black;
}

#titlepage .title {
  font-weight: normal;
  font-size: 2.333em;
  line-height: 1.4em;
  letter-spacing: 0;
  text-align: center;
  margin: 2em 0 2em 0;
}

#titlepage p {
  font-size: 0.889em;
  line-height: 1.4em;
  margin: 2em 0 .6em 0;
}

table.toc
{
  border-style      : none;
  border-collapse   : separate;
  border-spacing    : 0;

  margin            : 0.2em 0 0.2em 0;
  padding           : 0 0 0 0;
}

table.toc tr
{
  padding           : 0 0 0 0;
  margin            : 0 0 0 0;
}

table.toc * td, table.toc * th {
  border-style      : none;
  margin            : 0 0 0 0;
  vertical-align    : top;
}

table.toc * th
{
  font-weight       : normal;
  padding           : 0 0.8em 0 0;
  text-align        : left;
  white-space       : nowrap;
}

table.toc * table.toc th
{
  padding-left      : 1em;
}

table.toc * td
{
  padding           : 0 0 0 0;
  text-align        : left;
}

table.toc * td.preface
{
  padding-left      : 1.35em;
}


#titlepage .title
{
  font-size: 2em;
}

/*
 * Property list table.
 */
.proplist
{
  width: calc(100%); /* Fill the page. */

  table-layout: fixed;

  border: none;
  border-spacing: 0 0;
}

.proplist th, .proplist td {padding: .1em 0 .1em 0;}

.proplist th
{
  font-weight: normal;
  text-align: left;

  width: 7em;
}
.proplist th:after {content: ":";}

/*
 * Before/after table.
 */
.proplist
{
  width: calc(100%); /* Fill the page. */

  table-layout: fixed;

  border: none;
  border-spacing: 0 0;
}

.proplist th, .proplist td {padding: .1em 0 .1em 0;}

/*
 * Before/after table.
 */
.ba
{
  width: calc(100%); /* Fill the page. */
  table-layout: fixed;

  border: none;
  border-spacing: 0 0;

  margin: 2em 0 2em 0;
}

.ba th, .ba td {padding: 0;}

.ba th
{
  text-align: left;
  border-bottom: 1px solid #666666;
}

.ba td pre {margin: .5em 0 .5em 0;}

.ba .b {width: 50%; padding-right: 1em;}
.ba .a {width: 50%; padding-left:  1em;}
  </style>

</head>
<body>
<div id="content">

  <div id="titlepage">
    <div class="title">Recognizing Header Unit Imports Requires Full Preprocessing</div>

    <table class="proplist">
      <tbody>
	<tr><th>Document</th><td><a href="https://wg21.link/P1703R0">P1703R0</a></td></tr>
	<tr><th>Audience</th><td>SG2, EWG</td></tr>
	<tr><th>Authors</th><td>Boris Kolpackov (Code Synthesis)</td></tr>
	<tr><th>Reply-To</th><td>boris@codesynthesis.com</td></tr>
	<tr><th>Date</th><td>2019-06-17</td></tr>
      </tbody>
    </table>
  </div>
  <h2 id="abstract">Abstract</h2>

  <p><i>Currently, recognizing header unit imports requires full preprocessing
  which is problematic for dependency scanning and partial preprocessing. This
  paper proposes changes that will allow handling such imports with the same
  degree of preprocessing as <code>#include</code> directives.</i></p>

  <h2 id="toc">Contents</h2>

  <table class="toc">
    <tr><th>1</th><td><a href="#background">Background</a></td></tr>
    <tr><th>2</th><td><a href="#proposal">Proposal</a></td></tr>
    <tr><th>3</th><td><a href="#tony-tables">Before/After Tables ("Tony
Tables")</a>
      <table class="toc">
        <tr><th>3.1</th><td><a href="#tony-tables-affected">Affected Use
Cases</a></td></tr>
        <tr><th>3.2</th><td><a href="#tony-tables-unaffected">Unaffected Use
Cases</a></td></tr>
        <tr><th>3.3</th><td><a href="#tony-tables-unsupported">Unsupported Use
Cases</a></td></tr>
      </table>
    </td></tr>
    <tr><th>4</th><td><a href="#discussion">Discussion</a>
      <table class="toc">
        <tr><th>4.1</th><td><a
href="#discuss-context-sensitive">Context-Sensitive Keywords</a></td></tr>
        <tr><th>4.2</th><td><a href="#discuss-one-line">One Line
Requirement</a></td></tr>
      </table>
    </td></tr>
    <tr><th>5</th><td><a href="#qna">Questions and Answers</a>
      <table class="toc">
        <tr><th>5.1</th><td><a href="#qna-who">Who will be in Cologne to
present this paper?</a></td></tr>
        <tr><th>5.2</th><td><a href="#qna-impl">Is there implementation
experience?</a></td></tr>
        <tr><th>5.3</th><td><a href="#qna-usage">Is there usage
experience?</a></td></tr>
        <tr><th>5.4</th><td><a href="#qna-ship">What shipping vehicle do you
target with this proposal?</a></td></tr>
      </table>
    </td></tr>
    <tr><th>6</th><td><a href="#ack">Acknowledgments</a></td></tr>
  </table>

  <h2 id="background">1 Background</h2>

  <p>With the current wording, recognizing a header unit <code>import</code>
  declaration requires performing macros replacement and tokenization of every
  line in a translation unit. As a representative example, consider the
  following line:</p>

<pre>MYDECL <span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;int&gt;</span><span style="color:#000000">;</span>
</pre>

  <p>Whether this is a header unit importation or something else depends on
  what <code>MYDECL</code> expands to. Compare:</p>

<pre><span style="color:#008200">#define MYDECL int x;</span>

MYDECL <span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;int&gt;</span><span style="color:#000000">;</span>
</pre>

  <p>And:</p>

<pre><span style="color:#0057ae; font-weight:bold">template</span> <span style="color:#000000">&lt;</span><span style="color:#0057ae; font-weight:bold">typename</span><span style="color:#000000">&gt;</span> <span style="color:#0057ae; font-weight:bold">class</span> import<span style="color:#000000">;</span>
<span style="color:#008200">#define MYDECL using x =</span>

MYDECL import <span style="color:#000000">&lt;</span><span style="color:#0057ae">int</span><span style="color:#000000">&gt;;</span>
</pre>

  <div class="note">
  <p>While the second example is contrived, it is valid (again, according to
  the current wording) because <code>import</code> is a context-sensitive
  keyword.</p>
  </div>

  <p>Requiring such full macro replacement is at a minimum wasteful for header
  dependency scanning but also may not be something that tools other than
  compilers can easily and correctly do.</p>

  <p>Additionally, several implementations provide support for partial
  preprocessing (GCC's <code>-fdirectives-only</code> and Clang's
  <code>-frewrite-includes</code>) and this requirement is in conflict with
  the essence of that functionality.</p>

  <p>More specifically, GCC is currently unable to support header unit imports
  in its <code>-M</code> (dependency scanning) and
  <code>-fdirectives-only</code> (partial preprocessing) modes because in
  these modes it does not perform macro replacement in non-directive
  lines.</p>

  <p>While Clang currently performs full preprocessing in its <code>-M</code>
  and <code>-frewrite-includes</code> modes, there is agreement that it's not
  ideal for it to be impossible to correctly extract dependencies without full
  preprocessing.</p>

  <p>Finally, consulting with the developers of <code>clang-scan-deps</code>
  (a Clang-based tool for fast dependency extraction) revealed that this
  requirement would be problematic for their implementation.</p>

  <h2 id="proposal">2 Proposal</h2>

  <p>We propose to further restrict header unit import declarations so that
  they can be recognized and handled with the same degree of preprocessing as
  <code>#include</code> directives.</p>

  <p>Specifically, we propose recognizing a declaration as a header unit
  import if, additionally to restrictions in <a
  href="http://eel.is/c++draft/cpp#module-1">[cpp.module.1]</a>:</p>

  <ol>
  <li>It starts with the <code>import</code> token or <code>export
  import</code> token sequence that have not been produced by macro
  replacement.</li>

  <li>Followed, after macro replacement, by <a
  href="http://eel.is/c++draft/cpp#nt:header-name-tokens"><i>header-name-tokens</i></a>.</li>

  <li>The entire, single, and only declaration is on one line.</li>
  </ol>

  <p>We believe this should not detract much from usability because header
  imports are replacing <code>#include</code> directives where we have the
  same restrictions.</p>

  <h2 id="tony-tables">3 Before/After Tables ("Tony Tables")</h2>

  <h3 id="tony-tables-affected">3.1 Affected Use Cases</h3>

  <table class='ba'>
  <tbody>
    <tr><th class='b'>before</th><th class='a'>after</th></tr>
    <tr><td class='b'><pre><span style="color:#0057ae">int</span> x<span style="color:#000000">;</span> <span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span> <span style="color:#0057ae">int</span> y<span style="color:#000000">;</span>


</pre></td><td class='a'><pre><span style="color:#0057ae">int</span> x<span style="color:#000000">;</span>
<span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span>
<span style="color:#0057ae">int</span> y<span style="color:#000000">;</span>
</pre></td></tr>
  </tbody>
</table>


<table class='ba'>
  <tbody>
    <tr><th class='b'>before</th><th class='a'>after</th></tr>
    <tr><td class='b'><pre><span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span> <span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;set&gt;</span><span style="color:#000000">;</span>

</pre></td><td class='a'><pre><span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span>
<span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;set&gt;</span><span style="color:#000000">;</span>
</pre></td></tr>
  </tbody>
</table>


<table class='ba'>
  <tbody>
    <tr><th class='b'>before</th><th class='a'>after</th></tr>
    <tr><td class='b'><pre><span style="color:#0057ae; font-weight:bold">export</span>
<span style="color:#0057ae; font-weight:bold">import</span>
<span style="color:#000000">&lt;</span>map<span style="color:#000000">&gt;;</span>
</pre></td><td class='a'><pre><span style="color:#0057ae; font-weight:bold">export import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span>


</pre></td></tr>
  </tbody>
</table>


<table class='ba'>
  <tbody>
    <tr><th class='b'>before</th><th class='a'>after</th></tr>
    <tr><td class='b'><pre><span style="color:#008200">#ifdef MAYBE_EXPORT</span>
<span style="color:#0057ae; font-weight:bold">export</span>
<span style="color:#008200">#endif</span>
<span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span>

</pre></td><td class='a'><pre><span style="color:#008200">#ifdef MAYBE_EXPORT</span>
<span style="color:#0057ae; font-weight:bold">export import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span>
<span style="color:#008200">#else</span>
<span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span>
<span style="color:#008200">#endif</span>
</pre></td></tr>
  </tbody>
</table>


<table class='ba'>
  <tbody>
    <tr><th class='b'>before</th><th class='a'>after</th></tr>
    <tr><td class='b'><pre><span style="color:#008200">#define MAYBE_EXPORT export</span>
MAYBE_EXPORT <span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span>




</pre></td><td class='a'><pre><span style="color:#008200">#define MAYBE_EXPORT</span>
<span style="color:#008200">#ifdef MAYBE_EXPORT</span>
<span style="color:#0057ae; font-weight:bold">export import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span>
<span style="color:#008200">#else</span>
<span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&lt;map&gt;</span><span style="color:#000000">;</span>
<span style="color:#008200">#endif</span>
</pre></td></tr>
  </tbody>
</table>

  <h3 id="tony-tables-unaffected">3.2 Unaffected Use Cases</h3>

  <p>Header unit names are still macro-expanded (similar to
  <code>#include</code>):</p>

<pre><span style="color:#008200">#define MYMODULE &lt;map&gt;</span>
<span style="color:#0057ae; font-weight:bold">import</span> MYMODULE<span style="color:#000000">;</span>
</pre>

  <p>Normal module imports are unaffected:</p>

<pre><span style="color:#0057ae; font-weight:bold">import</span> std<span style="color:#000000">.</span>set<span style="color:#000000">;</span> <span style="color:#0057ae; font-weight:bold">using</span> int_set <span style="color:#000000">=</span> std<span style="color:#000000">::</span>set<span style="color:#000000">&lt;</span><span style="color:#0057ae">int</span><span style="color:#000000">&gt;;</span>
</pre>

  <h3 id="tony-tables-unsupported">3.3 Unsupported Use Cases</h3>

  <p>With the proposed change the following will no longer be possible:</p>

<pre><span style="color:#008200">#define MYIMPORT(x) import x</span>
MYIMPORT<span style="color:#000000">(&lt;</span>set<span style="color:#000000">&gt;);</span>
</pre>

  <p>Note also that the following is already impossible (because neither
  <code>#include</code> nor <code>import</code>'s closing <code>;</code> can
  be the result of macro replacement):</p>

<pre><span style="color:#008200">#define IMPORT_OR_INCLUDE(x) ???</span>
IMPORT_OR_INCLUDE<span style="color:#000000">(&lt;</span>set<span style="color:#000000">&gt;)</span>
</pre>

  <h2 id="discussion">4 Discussion</h2>

  <h3 id="discuss-context-sensitive">4.1 Context-Sensitive Keywords</h3>

  <p>The proposed change does not fit well with the context-sensitive modules
  keywords semantics. In the current wording, the context is "wide" taking
  into account (after macro expansion) previous lines as well as
  <code>{}</code>-nesting.  The following examples illustrate the problem:</p>

<pre><span style="color:#008200">#define MYDECL using x =</span>
MYDECL
import <span style="color:#000000">&lt;</span><span style="color:#0057ae">int</span><span style="color:#000000">&gt;;</span>
</pre>

<pre>BEGIN_NAMESPACE

<span style="color:#0057ae; font-weight:bold">template</span><span style="color:#000000">&lt;&gt;</span> <span style="color:#0057ae; font-weight:bold">class</span>
import<span style="color:#000000">&lt;</span><span style="color:#0057ae">int</span><span style="color:#000000">&gt;;</span>

END_NAMESPACE
</pre>

  <p>Our proposed resolution is to adjust context-sensitivity for header unit
  imports to be based solely on the declaration itself. The fact that import
  should be at the beginning of the line followed by <a
  href="http://eel.is/c++draft/cpp#nt:header-name-tokens"><i>header-name-tokens</i></a>
  and terminated with <code>;</code> already makes the "pattern" fairly
  constrained. We could not think of any plausible use-cases for
  <code>"</code> while <code>&lt;</code> all seem to boil down to multi-line
  template-related declarations. And all such cases are easily fixed either by
  adjusting newlines or with <code>::</code>-qualification. For example:</p>

<table class='ba'>
  <tbody>
    <tr><th class='b'>before</th><th class='a'>after</th></tr>
    <tr><td class='b'><pre><span style="color:#0057ae; font-weight:bold">using</span> x <span style="color:#000000">=</span>
<span style="color:#0057ae; font-weight:bold">import</span><span style="color:#008200">&lt;int&gt;</span><span style="color:#000000">;</span>

<span style="color:#0057ae; font-weight:bold">template</span><span style="color:#000000">&lt;&gt;</span> <span style="color:#0057ae; font-weight:bold">class</span>
<span style="color:#0057ae; font-weight:bold">import</span><span style="color:#008200">&lt;int&gt;</span><span style="color:#000000">;</span>
</pre></td><td class='a'><pre><span style="color:#0057ae; font-weight:bold">using</span> x <span style="color:#000000">=</span>
<span style="color:#000000">::</span>import<span style="color:#000000">&lt;</span><span style="color:#0057ae">int</span><span style="color:#000000">&gt;;</span>

<span style="color:#0057ae; font-weight:bold">template</span><span style="color:#000000">&lt;&gt;</span>
<span style="color:#0057ae; font-weight:bold">class</span> import<span style="color:#000000">&lt;</span><span style="color:#0057ae">int</span><span style="color:#000000">&gt;;</span>
</pre></td></tr>
  </tbody>
</table>

  <div class="note">
  <p>Doing a search for <code>import&#160;&lt;</code> on <a
  href="https://codesearch.isocpp.org">https://codesearch.isocpp.org</a>
  yielded 2562 matches which unfortunately also included
  <code>#import&#160;&lt;...</code> directives. Doing a search for
  <code>#import&#160;&lt;</code> produced 2540 matches. From this we can
  conclude (though, without seeing the actual code, with low degree of
  certainty), that there are 20 occurrences of the
  <code>import&#160;&lt;</code> token sequence, however, not necessarily at
  the beginning of the line. We've managed to track at least some of these 20
  matches to the Boost.Metaparse library with none of the occurrences being
  problematic.</p>
  </div>

  <h3 id="discuss-one-line">4.2 One Line Requirement</h3>

  <p>Requiring the entire header unit <code>import</code> declaration to be on
  a single line is not strictly necessary. The benefit of this restriction is
  the simplification of tools that may then be able to reuse the same code to
  handle both <code>#include</code> directives and header unit
  <code>import</code> declarations (at least we found this to be the case for
  GCC). However, the ability to split the declaration across multiple lines
  could be beneficial in the presence of attributes. For example (courtesy of
  Richard Smith):</p>

<pre><span style="color:#0057ae; font-weight:bold">import</span> <span style="color:#008200">&quot;foo.h&quot;</span>
  <span style="color:#000000">[[</span>clang<span style="color:#000000">::</span>import_macros<span style="color:#000000">(</span>FOO<span style="color:#000000">,</span> BAR<span style="color:#000000">,</span> BAZ<span style="color:#000000">,</span> QUUX<span style="color:#000000">),</span>
    clang<span style="color:#000000">::</span>wrap_in_namespace<span style="color:#000000">(</span>foo_namespace<span style="color:#000000">)]];</span>
</pre>

  <h2 id="qna">5 Questions and Answers</h2>

  <h3 id="qna-who">5.1 Who will be in Cologne to present this paper?</h3>

  <p>Boris Kolpackov</p>

  <h3 id="qna-impl">5.2 Is there implementation experience?</h3>

  <p>Yes, an implementation is available in the <a
  href="https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/boris/c%2B%2B-modules-ex"><code>boris/c++-modules-ex</code></a>
  GCC branch. This includes working <code>-fdirectives-only</code> mode.</p>

  <p>One encouraging result of implementing the proposed change was the
  relative ease of generalizing the <code>#include</code> directive handling
  code in the GCC preprocessor (<code>libcpp</code>) and module mapper to also
  handle header unit imports.</p>

  <h3 id="qna-usage">5.3 Is there usage experience?</h3>

  <p>Yes, the <a href="https://build2.org"><code>build2</code> build
  system</a> implements support for header unit importation relying on this
  functionality.</p>

  <h3 id="qna-ship">5.4 What shipping vehicle do you target with this
  proposal?</h3>

  <p>The same as C++ Modules, presumably C++20.</p>

  <h2 id="ack">6 Acknowledgments</h2>

  <p>To our knowledge this issue was first discovered and documented (in the
  GCC manual) by Nathan Sidwell.</p>

  <p>Thanks to Nathan Sidwell, Richard Smith, Gabriel Dos Reis, Alex Lorenz,
  Michael Spencer, Cameron DaCamara, David Stone, and Ben Boeckel for
  discussions regarding this issue and for feedback on earlier drafts of this
  paper.</p>

</div>

</body>
</html>
