<!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: 24em;}
@media only screen and (min-width: 360px)
{
  body {min-width: 24em;}
}

/*
 * 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. */

/*
 * 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;
}

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

#content
{
  max-width: 50em;
  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;}


/* Wording style. */

.w p
{
  line-height: 1.5em;
}

.w code
{
  background-color: inherit;
  border-radius: none;
  padding: 0;
  font-weight: bold;
}

.w pre
{
  background-color: inherit;
  border-radius: none;
  padding: 0;
  margin: 1em 0 1em 0; /* Same as plain pre. */
}

.w sub
{
  font-size: 80%;
  font-style: italic;
}

.w-new
{
  color: #080;
  text-decoration: underline;
}

.w-add
{
  background: #cfc;
  color: #000;
  text-decoration: underline;
}

.w-del
{
  background: #fcc;
  color: #000;
  text-decoration: line-through;
}

.w-ins
{
  margin-top: 3em;
  color: #e50;
}
  </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/P1703R1">P1703R1</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-07-19</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="history">Revision History</h2>

  <p><b>R1</b> &#8211; Add the <a href="#wording">Wording</a> section.</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="#wording">Wording</a></td></tr>
    <tr><th>6</th><td><a href="#qna">Questions and Answers</a>
      <table class="toc">
        <tr><th>6.1</th><td><a href="#qna-who">Who will be in Cologne to
present this paper?</a></td></tr>
        <tr><th>6.2</th><td><a href="#qna-impl">Is there implementation
experience?</a></td></tr>
        <tr><th>6.3</th><td><a href="#qna-usage">Is there usage
experience?</a></td></tr>
        <tr><th>6.4</th><td><a href="#qna-ship">What shipping vehicle do you
target with this proposal?</a></td></tr>
      </table>
    </td></tr>
    <tr><th>7</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="wording">5 Wording</h2>

  <div class="note">
  <p>Note that according to the direction given at the Cologne meeting, this
  section extends the original proposal of this paper to all (module and
  header unit) imports.</p>
  </div>


  <div class="w-ins">
  <p>In [lex.pptoken]:</p>
  </div>

  <div class="w">
  <pre class="w-bnf">
<i>preprocessing-token:</i>
    <i>header-name</i>
    <span class="w-add"><i>import-keyword</i></span>
    ...</pre>

  <dl>
  <dt>(3.3)</dt><dd>

Otherwise, the next preprocessing token is the longest sequence of characters
that could constitute a preprocessing token, even if that would cause further
lexical analysis to fail, except that a <i>header-name</i> ([lex.header]) is only
formed

  <dl>
  <dt>(3.3.1)</dt><dd>
<span class="w-del">within a <code>#include</code> directive ([cpp.include]),</span><br/>
<span class="w-add">after the <code>include</code> or <code>import</code> preprocessing token in a <code>#include</code> ([cpp.include]) or <code>import</code> ([cpp.import]) directive, or</span>
  </dd>

  <dt>(3.3.2)</dt><dd>
within a <i>has-include-expression</i><span class="w-del">, or</span><span class="w-add">.</span>
  </dd>

  <dt><span class="w-del">(3.3.3)</span></dt><dd>
<span class="w-del"> outside of any preprocessing directive, if applying phase
4 of translation to the sequence of preprocessing tokens produced thus far is
valid and results in an <i>import-seq</i> ([cpp.module]).</span>
  </dd>

  </dl>
  </dd>
  </dl>

  Insert new paragraph 4:

  <dl>
  <dt>4</dt><dd><span class="w-add">
The <i>import-keyword</i> is produced by processing an
<code>import</code> directive ([cpp.import]) and has no
associated grammar productions.</span>
  </dd>
  </dl>

  </div>



  <div class="w-ins">
  <p>In [basic.link]:</p>
  </div>

  <div class="w">
  <dl>
  <dt>3</dt><dd>

A token sequence beginning
with <code>export</code><sub>opt</sub> <code>module</code>
<span class="w-del">or <code>export</code><sub>opt</sub> <code>import</code></span> and not immediately
followed by <code>::</code> is never interpreted as the <i>declaration</i> of a
<i>top-level-declaration</i>.

  </dd>
  </dl>
  </div>



  <div class="w-ins">
  <p>In [cpp]:</p>
  </div>

  <div class="w">
  <dl>
  <dt>1</dt><dd>
A preprocessing directive consists of a sequence of preprocessing tokens that satisfies the following constraints:
The first token in the sequence<span class="w-add">, referred to as a <i>directive-introducing token</i>,</span>
is a <code>#</code> preprocessing token<span class="w-add">, an <code>import</code> preprocessing token, or an <code>export</code> preprocessing token
immediately followed by an <code>import</code> preprocessing token,</span>

that (at the start of translation phase 4)
either <span class="w-del">is</span><span class="w-add">begins with</span> the
first character in the source file (optionally after white space containing no
new-line characters) or follows white space containing at least one new-line
character.

The last token in the sequence is the first new-line character that follows
the first token in the sequence.<sup>144</sup> A new-line character ends the
preprocessing directive even if it occurs within what would otherwise be an
invocation of a function-like macro.

  <pre class="w-bnf">
  ...
<i>control-line</i>:
    <code>#</code> <code>include</code> <i>pp-tokens</i> <i>new-line</i>
    <span class="w-add"><code>export</code><sub>opt</sub> <code>import</code> <i>pp-tokens</i> <i>new-line</i></span>
    ...</pre>
  </dd>

  <dt>4</dt><dd>
The only white-space characters that shall appear between preprocessing tokens
within a preprocessing directive (from just after
the <span class="w-del">introducing <code>#</code>
preprocessing</span><span class="w-add">directive-introducing</span> token
through just before the terminating new-line character) are space and
horizontal-tab (including spaces that have replaced comments or possibly other
white-space characters in translation phase 3).
  </dd>

  </dl>
  </div>


  <div class="w-ins">
  <p>In [cpp.include]:</p>
  </div>

  <div class="w">
  <dl>
  <dt>7</dt><dd>

If the header identified by the <i>header-name</i> denotes an importable
header ([module.import]), the <span class="w-add"><code>#include</code></span>
preprocessing directive is instead replaced by
<span class="w-del"><i>the preprocessing-tokens</i></span>
<span class="w-add">an <code>import</code> directive ([cpp.import]) of the form</span>

  <pre class="w-bnf">
  <code>import</code> <i>header-name</i> <code>;</code> <span class="w-add"><i>new-line</i></span></pre>
  </dd>
  </dl>
  </div>


  <div class="w-ins">
  <p>Rename [cpp.module] "Header units" to [cpp.import] "Header unit
    importation" and change order so that it appears immediately after
    [cpp.include] "Source file inclusion".</p>

  <p>Move the <i>pp-balanced-token-seq</i> and associated productions to [cpp.glob.frag].</p>

  <p>In [cpp.import] (previously [cpp.module]):</p>
  </div>

  <div class="w">

  <pre class="w-bnf"><span class="w-del">
<i>import-seq</i>:
    <i>top-level-token-seq</i><sub>opt</sub> <code>export</code><sub>opt</sub> <code>import</code>

<i>top-level-token-seq</i>:
    any <i>pp-balanced-token-seq</i> ending in <code>;</code> or <code>}</code></span>

<i>pp-import</i>:<span class="w-del">
    <code>import</code> <i>header-name</i> <i>pp-import-suffix</i><sub>opt</sub> <code>;</code>
    <code>import</code> <i>header-name-tokens</i> <i>pp-import-suffix</i><sub>opt</sub> <code>;</code></span><span class="w-add">
    <code>export</code><sub>opt</sub> <code>import</code> <i>header-name</i> <i>pp-tokens</i><sub>opt</sub> <code>;</code> <i>new-line</i>
    <code>export</code><sub>opt</sub> <code>import</code> <i>header-name-tokens</i> <i>pp-tokens</i><sub>opt</sub> <code>;</code> <i>new-line</i>
    <code>export</code><sub>opt</sub> <code>import</code> <i>pp-tokens</i> <code>;</code> <i>new-line</i></span>

<span class="w-del"><i>pp-import-suffix</i>:
	<i>pp-import-suffix-token</i>
	<i>pp-import-suffix</i> <i>pp-import-suffix-token</i>

<i>pp-import-suffix-token</i>:
	any <i>pp-balanced-token</i> other than <code>;</code></span>
  </pre>
  <dl>

  <dt>1</dt>
  <dd>
 <span class="w-add">
The preprocessing tokens after the <code>import</code> preprocessing token in
the <code>import</code> <i>control-line</i> are processed just as in normal text (i.e.,
each identifier currently defined as a macro name is replaced by its
replacement list of preprocessing tokens).
 </span>

<span class="w-del">A sequence of <i>preprocessing-tokens</i></span>
<span class="w-add">An <code>import</code> directive</span>
matching the <span class="w-add">first
two</span> form<span class="w-add">s</span> of a <i>pp-import</i> instructs
the preprocessor to import macros from the header unit ([module.import])
denoted by the <i>header-name</i>.

<span class="w-del">A <i>pp-import</i> is only recognized when
the sequence of tokens produced by phase 4 of translation
up to the <code>import</code> token forms an <i>import-seq</i>, and
the <code>import</code> token is not within the <i>header-name-tokens</i>
or <i>pp-import-suffix</i> of another <i>pp-import</i>.
The <code>;</code> <i>preprocessing-token</i> terminating a <i>pp-import</i>
shall not have been produced by macro replacement ([cpp.replace]).</span>

The point of macro import for
<span class="w-del">a</span>
<span class="w-add">the first two forms of</span>
<i>pp-import</i> is immediately after the <span class="w-del">;</span><span class="w-add"><i>new-line</i></span>
terminating the <i>pp-import</i>.

<span class="w-add">The last form of <i>pp-import</i> is only considered if
the first two forms did not match.</span>
  </dd>

  <dt>2</dt>
  <dd>
<span class="w-add">In all three forms of <i>pp-import</i>
the <code>import</code> token is replaced by the <i>import-keyword</i>
token. Additionally,</span>
<span class="w-del">In</span><span class="w-add">in</span>
the second form of <i>pp-import</i>, a <i>header-name</i> token is formed
as if the <i>header-name-tokens</i> were the <i>pp-tokens</i> of
a <code>#include</code> directive. The <i>header-name-tokens</i> are replaced
by the <i>header-name</i> token. [<i>Note</i>: This ensures that imports are treated
consistently by the preprocessor and later phases of translation. &#8212; <i>end
note</i>]
  </dd>
  </dl>
  </div>

  <div class="w-ins">
  <p>In [module.import]:</p>
  </div>

  <div class="w">
  <pre class="w-bnf">
<i>module-import-declaration:</i>
    <code>export</code><sub>opt</sub> <span class="w-del"><code>import</code></span><span class="w-add"><i>import-keyword</i></span> <i>module-name</i> <i>attribute-specifier-seq</i><sub>opt</sub> <code>;</code>
    <code>export</code><sub>opt</sub> <span class="w-del"><code>import</code></span><span class="w-add"><i>import-keyword</i></span> <i>module-partition</i> <i>attribute-specifier-seq</i><sub>opt</sub> <code>;</code>
    <code>export</code><sub>opt</sub> <span class="w-del"><code>import</code></span><span class="w-add"><i>import-keyword</i></span> <i>header-name</i> <i>attribute-specifier-seq</i><sub>opt</sub> <code>;</code></pre>
  </div>

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

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

  <p>Boris Kolpackov</p>

  <h3 id="qna-impl">6.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">6.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">6.4 What shipping vehicle do you target with this
  proposal?</h3>

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

  <h2 id="ack">7 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>
