[www-releases] r356539 - Check in the 8.0.0 release
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 20 02:13:34 PDT 2019
Added: www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl5.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl5.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl5.html (added)
+++ www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl5.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,1371 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>5. Kaleidoscope: Extending the Language: Control Flow — LLVM 8 documentation</title>
+ <link rel="stylesheet" href="../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="6. Kaleidoscope: Extending the Language: User-defined Operators" href="OCamlLangImpl6.html" />
+ <link rel="prev" title="4. Kaleidoscope: Adding JIT and Optimizer Support" href="OCamlLangImpl4.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../index.html">
+ <img src="../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="OCamlLangImpl6.html" title="6. Kaleidoscope: Extending the Language: User-defined Operators"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="OCamlLangImpl4.html" title="4. Kaleidoscope: Adding JIT and Optimizer Support"
+ accesskey="P">previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-extending-the-language-control-flow">
+<h1>5. Kaleidoscope: Extending the Language: Control Flow<a class="headerlink" href="#kaleidoscope-extending-the-language-control-flow" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#chapter-5-introduction" id="id2">Chapter 5 Introduction</a></li>
+<li><a class="reference internal" href="#if-then-else" id="id3">If/Then/Else</a><ul>
+<li><a class="reference internal" href="#lexer-extensions-for-if-then-else" id="id4">Lexer Extensions for If/Then/Else</a></li>
+<li><a class="reference internal" href="#ast-extensions-for-if-then-else" id="id5">AST Extensions for If/Then/Else</a></li>
+<li><a class="reference internal" href="#parser-extensions-for-if-then-else" id="id6">Parser Extensions for If/Then/Else</a></li>
+<li><a class="reference internal" href="#llvm-ir-for-if-then-else" id="id7">LLVM IR for If/Then/Else</a></li>
+<li><a class="reference internal" href="#code-generation-for-if-then-else" id="id8">Code Generation for If/Then/Else</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#for-loop-expression" id="id9">âforâ Loop Expression</a><ul>
+<li><a class="reference internal" href="#lexer-extensions-for-the-for-loop" id="id10">Lexer Extensions for the âforâ Loop</a></li>
+<li><a class="reference internal" href="#ast-extensions-for-the-for-loop" id="id11">AST Extensions for the âforâ Loop</a></li>
+<li><a class="reference internal" href="#parser-extensions-for-the-for-loop" id="id12">Parser Extensions for the âforâ Loop</a></li>
+<li><a class="reference internal" href="#llvm-ir-for-the-for-loop" id="id13">LLVM IR for the âforâ Loop</a></li>
+<li><a class="reference internal" href="#code-generation-for-the-for-loop" id="id14">Code Generation for the âforâ Loop</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#full-code-listing" id="id15">Full Code Listing</a></li>
+</ul>
+</div>
+<div class="section" id="chapter-5-introduction">
+<h2><a class="toc-backref" href="#id2">5.1. Chapter 5 Introduction</a><a class="headerlink" href="#chapter-5-introduction" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to Chapter 5 of the â<a class="reference external" href="index.html">Implementing a language with
+LLVM</a>â tutorial. Parts 1-4 described the implementation of
+the simple Kaleidoscope language and included support for generating
+LLVM IR, followed by optimizations and a JIT compiler. Unfortunately, as
+presented, Kaleidoscope is mostly useless: it has no control flow other
+than call and return. This means that you canât have conditional
+branches in the code, significantly limiting its power. In this episode
+of âbuild that compilerâ, weâll extend Kaleidoscope to have an
+if/then/else expression plus a simple âforâ loop.</p>
+</div>
+<div class="section" id="if-then-else">
+<h2><a class="toc-backref" href="#id3">5.2. If/Then/Else</a><a class="headerlink" href="#if-then-else" title="Permalink to this headline">¶</a></h2>
+<p>Extending Kaleidoscope to support if/then/else is quite straightforward.
+It basically requires adding lexer support for this ânewâ concept to the
+lexer, parser, AST, and LLVM code emitter. This example is nice, because
+it shows how easy it is to âgrowâ a language over time, incrementally
+extending it as new ideas are discovered.</p>
+<p>Before we get going on âhowâ we add this extension, lets talk about
+âwhatâ we want. The basic idea is that we want to be able to write this
+sort of thing:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">x</span> <span class="o"><</span> <span class="mi">3</span> <span class="n">then</span>
+ <span class="mi">1</span>
+ <span class="k">else</span>
+ <span class="n">fib</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="n">fib</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">2</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>In Kaleidoscope, every construct is an expression: there are no
+statements. As such, the if/then/else expression needs to return a value
+like any other. Since weâre using a mostly functional form, weâll have
+it evaluate its conditional, then return the âthenâ or âelseâ value
+based on how the condition was resolved. This is very similar to the C
+â?:â expression.</p>
+<p>The semantics of the if/then/else expression is that it evaluates the
+condition to a boolean equality value: 0.0 is considered to be false and
+everything else is considered to be true. If the condition is true, the
+first subexpression is evaluated and returned, if the condition is
+false, the second subexpression is evaluated and returned. Since
+Kaleidoscope allows side-effects, this behavior is important to nail
+down.</p>
+<p>Now that we know what we âwantâ, lets break this down into its
+constituent pieces.</p>
+<div class="section" id="lexer-extensions-for-if-then-else">
+<h3><a class="toc-backref" href="#id4">5.2.1. Lexer Extensions for If/Then/Else</a><a class="headerlink" href="#lexer-extensions-for-if-then-else" title="Permalink to this headline">¶</a></h3>
+<p>The lexer extensions are straightforward. First we add new variants for
+the relevant tokens:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* control *)</span>
+<span class="o">|</span> <span class="nc">If</span> <span class="o">|</span> <span class="nc">Then</span> <span class="o">|</span> <span class="nc">Else</span> <span class="o">|</span> <span class="nc">For</span> <span class="o">|</span> <span class="nc">In</span>
+</pre></div>
+</div>
+<p>Once we have that, we recognize the new keywords in the lexer. This is
+pretty simple stuff:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="o">...</span>
+<span class="k">match</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">contents</span> <span class="n">buffer</span> <span class="k">with</span>
+<span class="o">|</span> <span class="s2">"def"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+<span class="o">|</span> <span class="s2">"extern"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+<span class="o">|</span> <span class="s2">"if"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">If</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+<span class="o">|</span> <span class="s2">"then"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Then</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+<span class="o">|</span> <span class="s2">"else"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Else</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+<span class="o">|</span> <span class="s2">"for"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+<span class="o">|</span> <span class="s2">"in"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+<span class="o">|</span> <span class="n">id</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="ast-extensions-for-if-then-else">
+<h3><a class="toc-backref" href="#id5">5.2.2. AST Extensions for If/Then/Else</a><a class="headerlink" href="#ast-extensions-for-if-then-else" title="Permalink to this headline">¶</a></h3>
+<p>To represent the new expression we add a new AST variant for it:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">type</span> <span class="n">expr</span> <span class="o">=</span>
+ <span class="o">...</span>
+ <span class="c">(* variant for if/then/else. *)</span>
+ <span class="o">|</span> <span class="nc">If</span> <span class="k">of</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span>
+</pre></div>
+</div>
+<p>The AST variant just has pointers to the various subexpressions.</p>
+</div>
+<div class="section" id="parser-extensions-for-if-then-else">
+<h3><a class="toc-backref" href="#id6">5.2.3. Parser Extensions for If/Then/Else</a><a class="headerlink" href="#parser-extensions-for-if-then-else" title="Permalink to this headline">¶</a></h3>
+<p>Now that we have the relevant tokens coming from the lexer and we have
+the AST node to build, our parsing logic is relatively straightforward.
+Next we add a new case for parsing a if-expression as a primary expression:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="k">rec</span> <span class="n">parse_primary</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">...</span>
+ <span class="c">(* ifexpr ::= 'if' expr 'then' expr 'else' expr *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">If</span><span class="o">;</span> <span class="n">c</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Then</span> <span class="o">??</span> <span class="s2">"expected 'then'"</span><span class="o">;</span> <span class="n">t</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Else</span> <span class="o">??</span> <span class="s2">"expected 'else'"</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">If</span> <span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="n">t</span><span class="o">,</span> <span class="n">e</span><span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="llvm-ir-for-if-then-else">
+<h3><a class="toc-backref" href="#id7">5.2.4. LLVM IR for If/Then/Else</a><a class="headerlink" href="#llvm-ir-for-if-then-else" title="Permalink to this headline">¶</a></h3>
+<p>Now that we have it parsing and building the AST, the final piece is
+adding LLVM code generation support. This is the most interesting part
+of the if/then/else example, because this is where it starts to
+introduce new concepts. All of the code above has been thoroughly
+described in previous chapters.</p>
+<p>To motivate the code we want to produce, lets take a look at a simple
+example. Consider:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">extern</span> <span class="n">foo</span><span class="p">();</span>
+<span class="n">extern</span> <span class="n">bar</span><span class="p">();</span>
+<span class="k">def</span> <span class="nf">baz</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">if</span> <span class="n">x</span> <span class="n">then</span> <span class="n">foo</span><span class="p">()</span> <span class="k">else</span> <span class="n">bar</span><span class="p">();</span>
+</pre></div>
+</div>
+<p>If you disable optimizations, the code youâll (soon) get from
+Kaleidoscope looks like this:</p>
+<div class="highlight-llvm notranslate"><div class="highlight"><pre><span></span><span class="k">declare</span> <span class="kt">double</span> <span class="vg">@foo</span><span class="p">()</span>
+
+<span class="k">declare</span> <span class="kt">double</span> <span class="vg">@bar</span><span class="p">()</span>
+
+<span class="k">define</span> <span class="kt">double</span> <span class="vg">@baz</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%x</span><span class="p">)</span> <span class="p">{</span>
+<span class="nl">entry:</span>
+ <span class="nv">%ifcond</span> <span class="p">=</span> <span class="k">fcmp</span> <span class="k">one</span> <span class="kt">double</span> <span class="nv">%x</span><span class="p">,</span> <span class="m">0.000000e+00</span>
+ <span class="k">br</span> <span class="k">i1</span> <span class="nv">%ifcond</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%then</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%else</span>
+
+<span class="nl">then:</span> <span class="c">; preds = %entry</span>
+ <span class="nv">%calltmp</span> <span class="p">=</span> <span class="k">call</span> <span class="kt">double</span> <span class="vg">@foo</span><span class="p">()</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%ifcont</span>
+
+<span class="nl">else:</span> <span class="c">; preds = %entry</span>
+ <span class="nv">%calltmp1</span> <span class="p">=</span> <span class="k">call</span> <span class="kt">double</span> <span class="vg">@bar</span><span class="p">()</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%ifcont</span>
+
+<span class="nl">ifcont:</span> <span class="c">; preds = %else, %then</span>
+ <span class="nv">%iftmp</span> <span class="p">=</span> <span class="k">phi</span> <span class="kt">double</span> <span class="p">[</span> <span class="nv">%calltmp</span><span class="p">,</span> <span class="nv">%then</span> <span class="p">],</span> <span class="p">[</span> <span class="nv">%calltmp1</span><span class="p">,</span> <span class="nv">%else</span> <span class="p">]</span>
+ <span class="k">ret</span> <span class="kt">double</span> <span class="nv">%iftmp</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>To visualize the control flow graph, you can use a nifty feature of the
+LLVM â<a class="reference external" href="http://llvm.org/cmds/opt.html">opt</a>â tool. If you put this LLVM
+IR into ât.llâ and run â<code class="docutils literal notranslate"><span class="pre">llvm-as</span> <span class="pre"><</span> <span class="pre">t.ll</span> <span class="pre">|</span> <span class="pre">opt</span> <span class="pre">-analyze</span> <span class="pre">-view-cfg</span></code>â, <a class="reference external" href="../ProgrammersManual.html#viewing-graphs-while-debugging-code">a
+window will pop up</a> and youâll
+see this graph:</p>
+<div class="figure align-center" id="id1">
+<img alt="Example CFG" src="../_images/LangImpl05-cfg.png" />
+<p class="caption"><span class="caption-text">Example CFG</span></p>
+</div>
+<p>Another way to get this is to call
+â<code class="docutils literal notranslate"><span class="pre">Llvm_analysis.view_function_cfg</span> <span class="pre">f</span></code>â or
+â<code class="docutils literal notranslate"><span class="pre">Llvm_analysis.view_function_cfg_only</span> <span class="pre">f</span></code>â (where <code class="docutils literal notranslate"><span class="pre">f</span></code> is a
+â<code class="docutils literal notranslate"><span class="pre">Function</span></code>â) either by inserting actual calls into the code and
+recompiling or by calling these in the debugger. LLVM has many nice
+features for visualizing various graphs.</p>
+<p>Getting back to the generated code, it is fairly simple: the entry block
+evaluates the conditional expression (âxâ in our case here) and compares
+the result to 0.0 with the â<code class="docutils literal notranslate"><span class="pre">fcmp</span> <span class="pre">one</span></code>â instruction (âoneâ is âOrdered
+and Not Equalâ). Based on the result of this expression, the code jumps
+to either the âthenâ or âelseâ blocks, which contain the expressions for
+the true/false cases.</p>
+<p>Once the then/else blocks are finished executing, they both branch back
+to the âifcontâ block to execute the code that happens after the
+if/then/else. In this case the only thing left to do is to return to the
+caller of the function. The question then becomes: how does the code
+know which expression to return?</p>
+<p>The answer to this question involves an important SSA operation: the
+<a class="reference external" href="http://en.wikipedia.org/wiki/Static_single_assignment_form">Phi
+operation</a>.
+If youâre not familiar with SSA, <a class="reference external" href="http://en.wikipedia.org/wiki/Static_single_assignment_form">the wikipedia
+article</a>
+is a good introduction and there are various other introductions to it
+available on your favorite search engine. The short version is that
+âexecutionâ of the Phi operation requires ârememberingâ which block
+control came from. The Phi operation takes on the value corresponding to
+the input control block. In this case, if control comes in from the
+âthenâ block, it gets the value of âcalltmpâ. If control comes from the
+âelseâ block, it gets the value of âcalltmp1â.</p>
+<p>At this point, you are probably starting to think âOh no! This means my
+simple and elegant front-end will have to start generating SSA form in
+order to use LLVM!â. Fortunately, this is not the case, and we strongly
+advise <em>not</em> implementing an SSA construction algorithm in your
+front-end unless there is an amazingly good reason to do so. In
+practice, there are two sorts of values that float around in code
+written for your average imperative programming language that might need
+Phi nodes:</p>
+<ol class="arabic simple">
+<li>Code that involves user variables: <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">1;</span> <span class="pre">x</span> <span class="pre">=</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">1;</span></code></li>
+<li>Values that are implicit in the structure of your AST, such as the
+Phi node in this case.</li>
+</ol>
+<p>In <a class="reference external" href="OCamlLangImpl7.html">Chapter 7</a> of this tutorial (âmutable
+variablesâ), weâll talk about #1 in depth. For now, just believe me that
+you donât need SSA construction to handle this case. For #2, you have
+the choice of using the techniques that we will describe for #1, or you
+can insert Phi nodes directly, if convenient. In this case, it is really
+really easy to generate the Phi node, so we choose to do it directly.</p>
+<p>Okay, enough of the motivation and overview, lets generate code!</p>
+</div>
+<div class="section" id="code-generation-for-if-then-else">
+<h3><a class="toc-backref" href="#id8">5.2.5. Code Generation for If/Then/Else</a><a class="headerlink" href="#code-generation-for-if-then-else" title="Permalink to this headline">¶</a></h3>
+<p>In order to generate code for this, we implement the <code class="docutils literal notranslate"><span class="pre">Codegen</span></code> method
+for <code class="docutils literal notranslate"><span class="pre">IfExprAST</span></code>:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="k">rec</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">...</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">If</span> <span class="o">(</span><span class="n">cond</span><span class="o">,</span> <span class="n">then_</span><span class="o">,</span> <span class="n">else_</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">cond</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">cond</span> <span class="k">in</span>
+
+ <span class="c">(* Convert condition to a bool by comparing equal to 0.0 *)</span>
+ <span class="k">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">cond_val</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">One</span> <span class="n">cond</span> <span class="n">zero</span> <span class="s2">"ifcond"</span> <span class="n">builder</span> <span class="k">in</span>
+</pre></div>
+</div>
+<p>This code is straightforward and similar to what we saw before. We emit
+the expression for the condition, then compare that value to zero to get
+a truth value as a 1-bit (bool) value.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Grab the first block so that we might later add the conditional branch</span>
+<span class="c"> * to it at the end of the function. *)</span>
+<span class="k">let</span> <span class="n">start_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+<span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="n">start_bb</span> <span class="k">in</span>
+
+<span class="k">let</span> <span class="n">then_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"then"</span> <span class="n">the_function</span> <span class="k">in</span>
+<span class="n">position_at_end</span> <span class="n">then_bb</span> <span class="n">builder</span><span class="o">;</span>
+</pre></div>
+</div>
+<p>As opposed to the <a class="reference external" href="LangImpl05.html">C++ tutorial</a>, we have to build our
+basic blocks bottom up since we canât have dangling BasicBlocks. We
+start off by saving a pointer to the first block (which might not be the
+entry block), which weâll need to build a conditional branch later. We
+do this by asking the <code class="docutils literal notranslate"><span class="pre">builder</span></code> for the current BasicBlock. The fourth
+line gets the current Function object that is being built. It gets this
+by the <code class="docutils literal notranslate"><span class="pre">start_bb</span></code> for its âparentâ (the function it is currently
+embedded into).</p>
+<p>Once it has that, it creates one block. It is automatically appended
+into the functionâs list of blocks.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Emit 'then' value. *)</span>
+<span class="n">position_at_end</span> <span class="n">then_bb</span> <span class="n">builder</span><span class="o">;</span>
+<span class="k">let</span> <span class="n">then_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">then_</span> <span class="k">in</span>
+
+<span class="c">(* Codegen of 'then' can change the current block, update then_bb for the</span>
+<span class="c"> * phi. We create a new name because one is used for the phi node, and the</span>
+<span class="c"> * other is used for the conditional branch. *)</span>
+<span class="k">let</span> <span class="n">new_then_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+</pre></div>
+</div>
+<p>We move the builder to start inserting into the âthenâ block. Strictly
+speaking, this call moves the insertion point to be at the end of the
+specified block. However, since the âthenâ block is empty, it also
+starts out by inserting at the beginning of the block. :)</p>
+<p>Once the insertion point is set, we recursively codegen the âthenâ
+expression from the AST.</p>
+<p>The final line here is quite subtle, but is very important. The basic
+issue is that when we create the Phi node in the merge block, we need to
+set up the block/value pairs that indicate how the Phi will work.
+Importantly, the Phi node expects to have an entry for each predecessor
+of the block in the CFG. Why then, are we getting the current block when
+we just set it to ThenBB 5 lines above? The problem is that the âThenâ
+expression may actually itself change the block that the Builder is
+emitting into if, for example, it contains a nested âif/then/elseâ
+expression. Because calling Codegen recursively could arbitrarily change
+the notion of the current block, we are required to get an up-to-date
+value for code that will set up the Phi node.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Emit 'else' value. *)</span>
+<span class="k">let</span> <span class="n">else_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"else"</span> <span class="n">the_function</span> <span class="k">in</span>
+<span class="n">position_at_end</span> <span class="n">else_bb</span> <span class="n">builder</span><span class="o">;</span>
+<span class="k">let</span> <span class="n">else_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">else_</span> <span class="k">in</span>
+
+<span class="c">(* Codegen of 'else' can change the current block, update else_bb for the</span>
+<span class="c"> * phi. *)</span>
+<span class="k">let</span> <span class="n">new_else_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+</pre></div>
+</div>
+<p>Code generation for the âelseâ block is basically identical to codegen
+for the âthenâ block.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Emit merge block. *)</span>
+<span class="k">let</span> <span class="n">merge_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"ifcont"</span> <span class="n">the_function</span> <span class="k">in</span>
+<span class="n">position_at_end</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">;</span>
+<span class="k">let</span> <span class="n">incoming</span> <span class="o">=</span> <span class="o">[(</span><span class="n">then_val</span><span class="o">,</span> <span class="n">new_then_bb</span><span class="o">);</span> <span class="o">(</span><span class="n">else_val</span><span class="o">,</span> <span class="n">new_else_bb</span><span class="o">)]</span> <span class="k">in</span>
+<span class="k">let</span> <span class="n">phi</span> <span class="o">=</span> <span class="n">build_phi</span> <span class="n">incoming</span> <span class="s2">"iftmp"</span> <span class="n">builder</span> <span class="k">in</span>
+</pre></div>
+</div>
+<p>The first two lines here are now familiar: the first adds the âmergeâ
+block to the Function object. The second changes the insertion
+point so that newly created code will go into the âmergeâ block. Once
+that is done, we need to create the PHI node and set up the block/value
+pairs for the PHI.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Return to the start block to add the conditional branch. *)</span>
+<span class="n">position_at_end</span> <span class="n">start_bb</span> <span class="n">builder</span><span class="o">;</span>
+<span class="n">ignore</span> <span class="o">(</span><span class="n">build_cond_br</span> <span class="n">cond_val</span> <span class="n">then_bb</span> <span class="n">else_bb</span> <span class="n">builder</span><span class="o">);</span>
+</pre></div>
+</div>
+<p>Once the blocks are created, we can emit the conditional branch that
+chooses between them. Note that creating new blocks does not implicitly
+affect the IRBuilder, so it is still inserting into the block that the
+condition went into. This is why we needed to save the âstartâ block.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Set a unconditional branch at the end of the 'then' block and the</span>
+<span class="c"> * 'else' block to the 'merge' block. *)</span>
+<span class="n">position_at_end</span> <span class="n">new_then_bb</span> <span class="n">builder</span><span class="o">;</span> <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">);</span>
+<span class="n">position_at_end</span> <span class="n">new_else_bb</span> <span class="n">builder</span><span class="o">;</span> <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+<span class="c">(* Finally, set the builder to the end of the merge block. *)</span>
+<span class="n">position_at_end</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+<span class="n">phi</span>
+</pre></div>
+</div>
+<p>To finish off the blocks, we create an unconditional branch to the merge
+block. One interesting (and very important) aspect of the LLVM IR is
+that it <a class="reference external" href="../LangRef.html#functionstructure">requires all basic blocks to be
+âterminatedâ</a> with a <a class="reference external" href="../LangRef.html#terminators">control flow
+instruction</a> such as return or branch.
+This means that all control flow, <em>including fall throughs</em> must be made
+explicit in the LLVM IR. If you violate this rule, the verifier will
+emit an error.</p>
+<p>Finally, the CodeGen function returns the phi node as the value computed
+by the if/then/else expression. In our example above, this returned
+value will feed into the code for the top-level function, which will
+create the return instruction.</p>
+<p>Overall, we now have the ability to execute conditional code in
+Kaleidoscope. With this extension, Kaleidoscope is a fairly complete
+language that can calculate a wide variety of numeric functions. Next up
+weâll add another useful expression that is familiar from non-functional
+languagesâ¦</p>
+</div>
+</div>
+<div class="section" id="for-loop-expression">
+<h2><a class="toc-backref" href="#id9">5.3. âforâ Loop Expression</a><a class="headerlink" href="#for-loop-expression" title="Permalink to this headline">¶</a></h2>
+<p>Now that we know how to add basic control flow constructs to the
+language, we have the tools to add more powerful things. Lets add
+something more aggressive, a âforâ expression:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">extern</span> <span class="n">putchard</span><span class="p">(</span><span class="n">char</span><span class="p">);</span>
+<span class="k">def</span> <span class="nf">printstar</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">i</span> <span class="o"><</span> <span class="n">n</span><span class="p">,</span> <span class="mf">1.0</span> <span class="ow">in</span>
+ <span class="n">putchard</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span> <span class="c1"># ascii 42 = '*'</span>
+
+<span class="c1"># print 100 '*' characters</span>
+<span class="n">printstar</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>This expression defines a new variable (âiâ in this case) which iterates
+from a starting value, while the condition (âi < nâ in this case) is
+true, incrementing by an optional step value (â1.0â in this case). If
+the step value is omitted, it defaults to 1.0. While the loop is true,
+it executes its body expression. Because we donât have anything better
+to return, weâll just define the loop as always returning 0.0. In the
+future when we have mutable variables, it will get more useful.</p>
+<p>As before, lets talk about the changes that we need to Kaleidoscope to
+support this.</p>
+<div class="section" id="lexer-extensions-for-the-for-loop">
+<h3><a class="toc-backref" href="#id10">5.3.1. Lexer Extensions for the âforâ Loop</a><a class="headerlink" href="#lexer-extensions-for-the-for-loop" title="Permalink to this headline">¶</a></h3>
+<p>The lexer extensions are the same sort of thing as for if/then/else:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="o">...</span> <span class="k">in</span> <span class="nn">Token</span><span class="p">.</span><span class="n">token</span> <span class="o">...</span>
+<span class="c">(* control *)</span>
+<span class="o">|</span> <span class="nc">If</span> <span class="o">|</span> <span class="nc">Then</span> <span class="o">|</span> <span class="nc">Else</span>
+<span class="o">|</span> <span class="nc">For</span> <span class="o">|</span> <span class="nn">In</span>
+
+<span class="p">...</span> <span class="n">in</span> <span class="nn">Lexer</span><span class="p">.</span><span class="n">lex_ident</span><span class="o">...</span>
+ <span class="k">match</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">contents</span> <span class="n">buffer</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="s2">"def"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"extern"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"if"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">If</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"then"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Then</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"else"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Else</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"for"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"in"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="n">id</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="ast-extensions-for-the-for-loop">
+<h3><a class="toc-backref" href="#id11">5.3.2. AST Extensions for the âforâ Loop</a><a class="headerlink" href="#ast-extensions-for-the-for-loop" title="Permalink to this headline">¶</a></h3>
+<p>The AST variant is just as simple. It basically boils down to capturing
+the variable name and the constituent expressions in the node.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">type</span> <span class="n">expr</span> <span class="o">=</span>
+ <span class="o">...</span>
+ <span class="c">(* variant for for/in. *)</span>
+ <span class="o">|</span> <span class="nc">For</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="n">option</span> <span class="o">*</span> <span class="n">expr</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="parser-extensions-for-the-for-loop">
+<h3><a class="toc-backref" href="#id12">5.3.3. Parser Extensions for the âforâ Loop</a><a class="headerlink" href="#parser-extensions-for-the-for-loop" title="Permalink to this headline">¶</a></h3>
+<p>The parser code is also fairly standard. The only interesting thing here
+is handling of the optional step value. The parser code handles it by
+checking to see if the second comma is present. If not, it sets the step
+value to null in the AST node:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="k">rec</span> <span class="n">parse_primary</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">...</span>
+ <span class="c">(* forexpr</span>
+<span class="c"> ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span> <span class="o">??</span> <span class="s2">"expected identifier after for"</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'='</span> <span class="o">??</span> <span class="s2">"expected '=' after for"</span><span class="o">;</span>
+ <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span>
+ <span class="n">start</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span> <span class="o">??</span> <span class="s2">"expected ',' after for"</span><span class="o">;</span>
+ <span class="n">end_</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">step</span> <span class="o">=</span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span><span class="o">;</span> <span class="n">step</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">Some</span> <span class="n">step</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">None</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="k">in</span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">body</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">For</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">end_</span><span class="o">,</span> <span class="n">step</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected 'in' after for"</span><span class="o">)</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected '=' after for"</span><span class="o">)</span>
+ <span class="k">end</span> <span class="n">stream</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="llvm-ir-for-the-for-loop">
+<h3><a class="toc-backref" href="#id13">5.3.4. LLVM IR for the âforâ Loop</a><a class="headerlink" href="#llvm-ir-for-the-for-loop" title="Permalink to this headline">¶</a></h3>
+<p>Now we get to the good part: the LLVM IR we want to generate for this
+thing. With the simple example above, we get this LLVM IR (note that
+this dump is generated with optimizations disabled for clarity):</p>
+<div class="highlight-llvm notranslate"><div class="highlight"><pre><span></span><span class="k">declare</span> <span class="kt">double</span> <span class="vg">@putchard</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span>
+
+<span class="k">define</span> <span class="kt">double</span> <span class="vg">@printstar</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%n</span><span class="p">)</span> <span class="p">{</span>
+<span class="nl">entry:</span>
+ <span class="c">; initial value = 1.0 (inlined into phi)</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%loop</span>
+
+<span class="nl">loop:</span> <span class="c">; preds = %loop, %entry</span>
+ <span class="nv">%i</span> <span class="p">=</span> <span class="k">phi</span> <span class="kt">double</span> <span class="p">[</span> <span class="m">1.000000e+00</span><span class="p">,</span> <span class="nv">%entry</span> <span class="p">],</span> <span class="p">[</span> <span class="nv">%nextvar</span><span class="p">,</span> <span class="nv">%loop</span> <span class="p">]</span>
+ <span class="c">; body</span>
+ <span class="nv">%calltmp</span> <span class="p">=</span> <span class="k">call</span> <span class="kt">double</span> <span class="vg">@putchard</span><span class="p">(</span><span class="kt">double</span> <span class="m">4.200000e+01</span><span class="p">)</span>
+ <span class="c">; increment</span>
+ <span class="nv">%nextvar</span> <span class="p">=</span> <span class="k">fadd</span> <span class="kt">double</span> <span class="nv">%i</span><span class="p">,</span> <span class="m">1.000000e+00</span>
+
+ <span class="c">; termination test</span>
+ <span class="nv">%cmptmp</span> <span class="p">=</span> <span class="k">fcmp</span> <span class="k">ult</span> <span class="kt">double</span> <span class="nv">%i</span><span class="p">,</span> <span class="nv">%n</span>
+ <span class="nv">%booltmp</span> <span class="p">=</span> <span class="k">uitofp</span> <span class="k">i1</span> <span class="nv">%cmptmp</span> <span class="k">to</span> <span class="kt">double</span>
+ <span class="nv">%loopcond</span> <span class="p">=</span> <span class="k">fcmp</span> <span class="k">one</span> <span class="kt">double</span> <span class="nv">%booltmp</span><span class="p">,</span> <span class="m">0.000000e+00</span>
+ <span class="k">br</span> <span class="k">i1</span> <span class="nv">%loopcond</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%loop</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%afterloop</span>
+
+<span class="nl">afterloop:</span> <span class="c">; preds = %loop</span>
+ <span class="c">; loop always returns 0.0</span>
+ <span class="k">ret</span> <span class="kt">double</span> <span class="m">0.000000e+00</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This loop contains all the same constructs we saw before: a phi node,
+several expressions, and some basic blocks. Lets see how this fits
+together.</p>
+</div>
+<div class="section" id="code-generation-for-the-for-loop">
+<h3><a class="toc-backref" href="#id14">5.3.5. Code Generation for the âforâ Loop</a><a class="headerlink" href="#code-generation-for-the-for-loop" title="Permalink to this headline">¶</a></h3>
+<p>The first part of Codegen is very simple: we just output the start
+expression for the loop value:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="k">rec</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">...</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">For</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">end_</span><span class="o">,</span> <span class="n">step</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* Emit the start code first, without 'variable' in scope. *)</span>
+ <span class="k">let</span> <span class="n">start_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">start</span> <span class="k">in</span>
+</pre></div>
+</div>
+<p>With this out of the way, the next step is to set up the LLVM basic
+block for the start of the loop body. In the case above, the whole loop
+body is one block, but remember that the body code itself could consist
+of multiple blocks (e.g. if it contains an if/then/else or a for/in
+expression).</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Make the new basic block for the loop header, inserting after current</span>
+<span class="c"> * block. *)</span>
+<span class="k">let</span> <span class="n">preheader_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+<span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="n">preheader_bb</span> <span class="k">in</span>
+<span class="k">let</span> <span class="n">loop_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"loop"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+<span class="c">(* Insert an explicit fall through from the current block to the</span>
+<span class="c"> * loop_bb. *)</span>
+<span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">loop_bb</span> <span class="n">builder</span><span class="o">);</span>
+</pre></div>
+</div>
+<p>This code is similar to what we saw for if/then/else. Because we will
+need it to create the Phi node, we remember the block that falls through
+into the loop. Once we have that, we create the actual block that starts
+the loop and create an unconditional branch for the fall-through between
+the two blocks.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Start insertion in loop_bb. *)</span>
+<span class="n">position_at_end</span> <span class="n">loop_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+<span class="c">(* Start the PHI node with an entry for start. *)</span>
+<span class="k">let</span> <span class="n">variable</span> <span class="o">=</span> <span class="n">build_phi</span> <span class="o">[(</span><span class="n">start_val</span><span class="o">,</span> <span class="n">preheader_bb</span><span class="o">)]</span> <span class="n">var_name</span> <span class="n">builder</span> <span class="k">in</span>
+</pre></div>
+</div>
+<p>Now that the âpreheaderâ for the loop is set up, we switch to emitting
+code for the loop body. To begin with, we move the insertion point and
+create the PHI node for the loop induction variable. Since we already
+know the incoming value for the starting value, we add it to the Phi
+node. Note that the Phi will eventually get a second value for the
+backedge, but we canât set it up yet (because it doesnât exist!).</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Within the loop, the variable is defined equal to the PHI node. If it</span>
+<span class="c"> * shadows an existing variable, we have to restore it, so save it</span>
+<span class="c"> * now. *)</span>
+<span class="k">let</span> <span class="n">old_val</span> <span class="o">=</span>
+ <span class="k">try</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">var_name</span><span class="o">)</span> <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="nc">None</span>
+<span class="k">in</span>
+<span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">variable</span><span class="o">;</span>
+
+<span class="c">(* Emit the body of the loop. This, like any other expr, can change the</span>
+<span class="c"> * current BB. Note that we ignore the value computed by the body, but</span>
+<span class="c"> * don't allow an error *)</span>
+<span class="n">ignore</span> <span class="o">(</span><span class="n">codegen_expr</span> <span class="n">body</span><span class="o">);</span>
+</pre></div>
+</div>
+<p>Now the code starts to get more interesting. Our âforâ loop introduces a
+new variable to the symbol table. This means that our symbol table can
+now contain either function arguments or loop variables. To handle this,
+before we codegen the body of the loop, we add the loop variable as the
+current value for its name. Note that it is possible that there is a
+variable of the same name in the outer scope. It would be easy to make
+this an error (emit an error and return null if there is already an
+entry for VarName) but we choose to allow shadowing of variables. In
+order to handle this correctly, we remember the Value that we are
+potentially shadowing in <code class="docutils literal notranslate"><span class="pre">old_val</span></code> (which will be None if there is no
+shadowed variable).</p>
+<p>Once the loop variable is set into the symbol table, the code
+recursively codegenâs the body. This allows the body to use the loop
+variable: any references to it will naturally find it in the symbol
+table.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Emit the step value. *)</span>
+<span class="k">let</span> <span class="n">step_val</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">step</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">step</span> <span class="o">-></span> <span class="n">codegen_expr</span> <span class="n">step</span>
+ <span class="c">(* If not specified, use 1.0. *)</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">1</span><span class="o">.</span><span class="mi">0</span>
+<span class="k">in</span>
+
+<span class="k">let</span> <span class="n">next_var</span> <span class="o">=</span> <span class="n">build_add</span> <span class="n">variable</span> <span class="n">step_val</span> <span class="s2">"nextvar"</span> <span class="n">builder</span> <span class="k">in</span>
+</pre></div>
+</div>
+<p>Now that the body is emitted, we compute the next value of the iteration
+variable by adding the step value, or 1.0 if it isnât present.
+â<code class="docutils literal notranslate"><span class="pre">next_var</span></code>â will be the value of the loop variable on the next
+iteration of the loop.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Compute the end condition. *)</span>
+<span class="k">let</span> <span class="n">end_cond</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">end_</span> <span class="k">in</span>
+
+<span class="c">(* Convert condition to a bool by comparing equal to 0.0. *)</span>
+<span class="k">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span> <span class="k">in</span>
+<span class="k">let</span> <span class="n">end_cond</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">One</span> <span class="n">end_cond</span> <span class="n">zero</span> <span class="s2">"loopcond"</span> <span class="n">builder</span> <span class="k">in</span>
+</pre></div>
+</div>
+<p>Finally, we evaluate the exit value of the loop, to determine whether
+the loop should exit. This mirrors the condition evaluation for the
+if/then/else statement.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Create the "after loop" block and insert it. *)</span>
+<span class="k">let</span> <span class="n">loop_end_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+<span class="k">let</span> <span class="n">after_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"afterloop"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+<span class="c">(* Insert the conditional branch into the end of loop_end_bb. *)</span>
+<span class="n">ignore</span> <span class="o">(</span><span class="n">build_cond_br</span> <span class="n">end_cond</span> <span class="n">loop_bb</span> <span class="n">after_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+<span class="c">(* Any new code will be inserted in after_bb. *)</span>
+<span class="n">position_at_end</span> <span class="n">after_bb</span> <span class="n">builder</span><span class="o">;</span>
+</pre></div>
+</div>
+<p>With the code for the body of the loop complete, we just need to finish
+up the control flow for it. This code remembers the end block (for the
+phi node), then creates the block for the loop exit (âafterloopâ). Based
+on the value of the exit condition, it creates a conditional branch that
+chooses between executing the loop again and exiting the loop. Any
+future code is emitted in the âafterloopâ block, so it sets the
+insertion position to it.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Add a new entry to the PHI node for the backedge. *)</span>
+<span class="n">add_incoming</span> <span class="o">(</span><span class="n">next_var</span><span class="o">,</span> <span class="n">loop_end_bb</span><span class="o">)</span> <span class="n">variable</span><span class="o">;</span>
+
+<span class="c">(* Restore the unshadowed variable. *)</span>
+<span class="k">begin</span> <span class="k">match</span> <span class="n">old_val</span> <span class="k">with</span>
+<span class="o">|</span> <span class="nc">Some</span> <span class="n">old_val</span> <span class="o">-></span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">old_val</span>
+<span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="bp">()</span>
+<span class="k">end</span><span class="o">;</span>
+
+<span class="c">(* for expr always returns 0.0. *)</span>
+<span class="n">const_null</span> <span class="n">double_type</span>
+</pre></div>
+</div>
+<p>The final code handles various cleanups: now that we have the
+â<code class="docutils literal notranslate"><span class="pre">next_var</span></code>â value, we can add the incoming value to the loop PHI
+node. After that, we remove the loop variable from the symbol table, so
+that it isnât in scope after the for loop. Finally, code generation of
+the for loop always returns 0.0, so that is what we return from
+<code class="docutils literal notranslate"><span class="pre">Codegen.codegen_expr</span></code>.</p>
+<p>With this, we conclude the âadding control flow to Kaleidoscopeâ chapter
+of the tutorial. In this chapter we added two control flow constructs,
+and used them to motivate a couple of aspects of the LLVM IR that are
+important for front-end implementors to know. In the next chapter of our
+saga, we will get a bit crazier and add <a class="reference external" href="OCamlLangImpl6.html">user-defined
+operators</a> to our poor innocent language.</p>
+</div>
+</div>
+<div class="section" id="full-code-listing">
+<h2><a class="toc-backref" href="#id15">5.4. Full Code Listing</a><a class="headerlink" href="#full-code-listing" title="Permalink to this headline">¶</a></h2>
+<p>Here is the complete code listing for our running example, enhanced with
+the if/then/else and for expressions.. To build this example, use:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># Compile</span>
+ocamlbuild toy.byte
+<span class="c1"># Run</span>
+./toy.byte
+</pre></div>
+</div>
+<p>Here is the code:</p>
+<dl class="docutils">
+<dt>_tags:</dt>
+<dd><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o"><</span><span class="p">{</span><span class="n">lexer</span><span class="p">,</span><span class="n">parser</span><span class="p">}</span><span class="o">.</span><span class="n">ml</span><span class="o">></span><span class="p">:</span> <span class="n">use_camlp4</span><span class="p">,</span> <span class="n">pp</span><span class="p">(</span><span class="n">camlp4of</span><span class="p">)</span>
+<span class="o"><*.</span><span class="p">{</span><span class="n">byte</span><span class="p">,</span><span class="n">native</span><span class="p">}</span><span class="o">></span><span class="p">:</span> <span class="n">g</span><span class="o">++</span><span class="p">,</span> <span class="n">use_llvm</span><span class="p">,</span> <span class="n">use_llvm_analysis</span>
+<span class="o"><*.</span><span class="p">{</span><span class="n">byte</span><span class="p">,</span><span class="n">native</span><span class="p">}</span><span class="o">></span><span class="p">:</span> <span class="n">use_llvm_executionengine</span><span class="p">,</span> <span class="n">use_llvm_target</span>
+<span class="o"><*.</span><span class="p">{</span><span class="n">byte</span><span class="p">,</span><span class="n">native</span><span class="p">}</span><span class="o">></span><span class="p">:</span> <span class="n">use_llvm_scalar_opts</span><span class="p">,</span> <span class="n">use_bindings</span>
+</pre></div>
+</div>
+</dd>
+<dt>myocamlbuild.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">open</span> <span class="nc">Ocamlbuild_plugin</span><span class="o">;;</span>
+
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_analysis"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_executionengine"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_target"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_scalar_opts"</span><span class="o">;;</span>
+
+<span class="n">flag</span> <span class="o">[</span><span class="s2">"link"</span><span class="o">;</span> <span class="s2">"ocaml"</span><span class="o">;</span> <span class="s2">"g++"</span><span class="o">]</span> <span class="o">(</span><span class="nc">S</span><span class="o">[</span><span class="nc">A</span><span class="s2">"-cc"</span><span class="o">;</span> <span class="nc">A</span><span class="s2">"g++"</span><span class="o">]);;</span>
+<span class="n">dep</span> <span class="o">[</span><span class="s2">"link"</span><span class="o">;</span> <span class="s2">"ocaml"</span><span class="o">;</span> <span class="s2">"use_bindings"</span><span class="o">]</span> <span class="o">[</span><span class="s2">"bindings.o"</span><span class="o">];;</span>
+</pre></div>
+</div>
+</dd>
+<dt>token.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Lexer Tokens</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="c">(* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of</span>
+<span class="c"> * these others for known things. *)</span>
+<span class="k">type</span> <span class="n">token</span> <span class="o">=</span>
+ <span class="c">(* commands *)</span>
+ <span class="o">|</span> <span class="nc">Def</span> <span class="o">|</span> <span class="nc">Extern</span>
+
+ <span class="c">(* primary *)</span>
+ <span class="o">|</span> <span class="nc">Ident</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">|</span> <span class="nc">Number</span> <span class="k">of</span> <span class="kt">float</span>
+
+ <span class="c">(* unknown *)</span>
+ <span class="o">|</span> <span class="nc">Kwd</span> <span class="k">of</span> <span class="kt">char</span>
+
+ <span class="c">(* control *)</span>
+ <span class="o">|</span> <span class="nc">If</span> <span class="o">|</span> <span class="nc">Then</span> <span class="o">|</span> <span class="nc">Else</span>
+ <span class="o">|</span> <span class="nc">For</span> <span class="o">|</span> <span class="nc">In</span>
+</pre></div>
+</div>
+</dd>
+<dt>lexer.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Lexer</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">let</span> <span class="k">rec</span> <span class="n">lex</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* Skip any whitespace. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">' '</span> <span class="o">|</span> <span class="sc">'\n'</span> <span class="o">|</span> <span class="sc">'\r'</span> <span class="o">|</span> <span class="sc">'\t'</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">lex</span> <span class="n">stream</span>
+
+ <span class="c">(* identifier: [a-zA-Z][a-zA-Z0-9] *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'A'</span> <span class="o">..</span> <span class="sc">'Z'</span> <span class="o">|</span> <span class="sc">'a'</span> <span class="o">..</span> <span class="sc">'z'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">buffer</span> <span class="o">=</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">create</span> <span class="mi">1</span> <span class="k">in</span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="n">stream</span>
+
+ <span class="c">(* number: [0-9.]+ *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'0'</span> <span class="o">..</span> <span class="sc">'9'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">buffer</span> <span class="o">=</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">create</span> <span class="mi">1</span> <span class="k">in</span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_number</span> <span class="n">buffer</span> <span class="n">stream</span>
+
+ <span class="c">(* Comment until end of line. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'#'</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="n">lex_comment</span> <span class="n">stream</span>
+
+ <span class="c">(* Otherwise, just return the character as its ascii value. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="n">c</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">c</span><span class="o">;</span> <span class="n">lex</span> <span class="n">stream</span> <span class="o">>]</span>
+
+ <span class="c">(* end of stream. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="o">[<</span> <span class="o">>]</span>
+
+<span class="ow">and</span> <span class="n">lex_number</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'0'</span> <span class="o">..</span> <span class="sc">'9'</span> <span class="o">|</span> <span class="sc">'.'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_number</span> <span class="n">buffer</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">stream</span><span class="o">=</span><span class="n">lex</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="o">(</span><span class="n">float_of_string</span> <span class="o">(</span><span class="nn">Buffer</span><span class="p">.</span><span class="n">contents</span> <span class="n">buffer</span><span class="o">));</span> <span class="n">stream</span> <span class="o">>]</span>
+
+<span class="ow">and</span> <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'A'</span> <span class="o">..</span> <span class="sc">'Z'</span> <span class="o">|</span> <span class="sc">'a'</span> <span class="o">..</span> <span class="sc">'z'</span> <span class="o">|</span> <span class="sc">'0'</span> <span class="o">..</span> <span class="sc">'9'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">stream</span><span class="o">=</span><span class="n">lex</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">match</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">contents</span> <span class="n">buffer</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="s2">"def"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"extern"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"if"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">If</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"then"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Then</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"else"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Else</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"for"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"in"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="n">id</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+
+<span class="ow">and</span> <span class="n">lex_comment</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'\n'</span><span class="o">);</span> <span class="n">stream</span><span class="o">=</span><span class="n">lex</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="n">c</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">lex_comment</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="o">[<</span> <span class="o">>]</span>
+</pre></div>
+</div>
+</dd>
+<dt>ast.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Abstract Syntax Tree (aka Parse Tree)</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="c">(* expr - Base type for all expression nodes. *)</span>
+<span class="k">type</span> <span class="n">expr</span> <span class="o">=</span>
+ <span class="c">(* variant for numeric literals like "1.0". *)</span>
+ <span class="o">|</span> <span class="nc">Number</span> <span class="k">of</span> <span class="kt">float</span>
+
+ <span class="c">(* variant for referencing a variable, like "a". *)</span>
+ <span class="o">|</span> <span class="nc">Variable</span> <span class="k">of</span> <span class="kt">string</span>
+
+ <span class="c">(* variant for a binary operator. *)</span>
+ <span class="o">|</span> <span class="nc">Binary</span> <span class="k">of</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span>
+
+ <span class="c">(* variant for function calls. *)</span>
+ <span class="o">|</span> <span class="nc">Call</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="n">expr</span> <span class="kt">array</span>
+
+ <span class="c">(* variant for if/then/else. *)</span>
+ <span class="o">|</span> <span class="nc">If</span> <span class="k">of</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span>
+
+ <span class="c">(* variant for for/in. *)</span>
+ <span class="o">|</span> <span class="nc">For</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="n">option</span> <span class="o">*</span> <span class="n">expr</span>
+
+<span class="c">(* proto - This type represents the "prototype" for a function, which captures</span>
+<span class="c"> * its name, and its argument names (thus implicitly the number of arguments the</span>
+<span class="c"> * function takes). *)</span>
+<span class="k">type</span> <span class="n">proto</span> <span class="o">=</span> <span class="nc">Prototype</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="kt">string</span> <span class="kt">array</span>
+
+<span class="c">(* func - This type represents a function definition itself. *)</span>
+<span class="k">type</span> <span class="n">func</span> <span class="o">=</span> <span class="nc">Function</span> <span class="k">of</span> <span class="n">proto</span> <span class="o">*</span> <span class="n">expr</span>
+</pre></div>
+</div>
+</dd>
+<dt>parser.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===---------------------------------------------------------------------===</span>
+<span class="c"> * Parser</span>
+<span class="c"> *===---------------------------------------------------------------------===*)</span>
+
+<span class="c">(* binop_precedence - This holds the precedence for each binary operator that is</span>
+<span class="c"> * defined *)</span>
+<span class="k">let</span> <span class="n">binop_precedence</span><span class="o">:(</span><span class="kt">char</span><span class="o">,</span> <span class="kt">int</span><span class="o">)</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">t</span> <span class="o">=</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">create</span> <span class="mi">10</span>
+
+<span class="c">(* precedence - Get the precedence of the pending binary operator token. *)</span>
+<span class="k">let</span> <span class="n">precedence</span> <span class="n">c</span> <span class="o">=</span> <span class="k">try</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">binop_precedence</span> <span class="n">c</span> <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="o">-</span><span class="mi">1</span>
+
+<span class="c">(* primary</span>
+<span class="c"> * ::= identifier</span>
+<span class="c"> * ::= numberexpr</span>
+<span class="c"> * ::= parenexpr</span>
+<span class="c"> * ::= ifexpr</span>
+<span class="c"> * ::= forexpr *)</span>
+<span class="k">let</span> <span class="k">rec</span> <span class="n">parse_primary</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* numberexpr ::= number *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">>]</span> <span class="o">-></span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span>
+
+ <span class="c">(* parenexpr ::= '(' expression ')' *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')'"</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+
+ <span class="c">(* identifierexpr</span>
+<span class="c"> * ::= identifier</span>
+<span class="c"> * ::= identifier '(' argumentexpr ')' *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_args</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_args</span> <span class="o">(</span><span class="n">e</span> <span class="o">::</span> <span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span> <span class="o">::</span> <span class="n">accumulator</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_ident</span> <span class="n">id</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* Call. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')'"</span><span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Call</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">))</span>
+
+ <span class="c">(* Simple variable ref. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Variable</span> <span class="n">id</span>
+ <span class="k">in</span>
+ <span class="n">parse_ident</span> <span class="n">id</span> <span class="n">stream</span>
+
+ <span class="c">(* ifexpr ::= 'if' expr 'then' expr 'else' expr *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">If</span><span class="o">;</span> <span class="n">c</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Then</span> <span class="o">??</span> <span class="s2">"expected 'then'"</span><span class="o">;</span> <span class="n">t</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Else</span> <span class="o">??</span> <span class="s2">"expected 'else'"</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">If</span> <span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="n">t</span><span class="o">,</span> <span class="n">e</span><span class="o">)</span>
+
+ <span class="c">(* forexpr</span>
+<span class="c"> ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span> <span class="o">??</span> <span class="s2">"expected identifier after for"</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'='</span> <span class="o">??</span> <span class="s2">"expected '=' after for"</span><span class="o">;</span>
+ <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span>
+ <span class="n">start</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span> <span class="o">??</span> <span class="s2">"expected ',' after for"</span><span class="o">;</span>
+ <span class="n">end_</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">step</span> <span class="o">=</span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span><span class="o">;</span> <span class="n">step</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">Some</span> <span class="n">step</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">None</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="k">in</span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">body</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">For</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">end_</span><span class="o">,</span> <span class="n">step</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected 'in' after for"</span><span class="o">)</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected '=' after for"</span><span class="o">)</span>
+ <span class="k">end</span> <span class="n">stream</span>
+
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"unknown token when expecting an expression."</span><span class="o">)</span>
+
+<span class="c">(* binoprhs</span>
+<span class="c"> * ::= ('+' primary)* *)</span>
+<span class="ow">and</span> <span class="n">parse_bin_rhs</span> <span class="n">expr_prec</span> <span class="n">lhs</span> <span class="n">stream</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="nn">Stream</span><span class="p">.</span><span class="n">peek</span> <span class="n">stream</span> <span class="k">with</span>
+ <span class="c">(* If this is a binop, find its precedence. *)</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">c</span><span class="o">)</span> <span class="k">when</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">mem</span> <span class="n">binop_precedence</span> <span class="n">c</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">token_prec</span> <span class="o">=</span> <span class="n">precedence</span> <span class="n">c</span> <span class="k">in</span>
+
+ <span class="c">(* If this is a binop that binds at least as tightly as the current binop,</span>
+<span class="c"> * consume it, otherwise we are done. *)</span>
+ <span class="k">if</span> <span class="n">token_prec</span> <span class="o"><</span> <span class="n">expr_prec</span> <span class="k">then</span> <span class="n">lhs</span> <span class="k">else</span> <span class="k">begin</span>
+ <span class="c">(* Eat the binop. *)</span>
+ <span class="nn">Stream</span><span class="p">.</span><span class="n">junk</span> <span class="n">stream</span><span class="o">;</span>
+
+ <span class="c">(* Parse the primary expression after the binary operator. *)</span>
+ <span class="k">let</span> <span class="n">rhs</span> <span class="o">=</span> <span class="n">parse_primary</span> <span class="n">stream</span> <span class="k">in</span>
+
+ <span class="c">(* Okay, we know this is a binop. *)</span>
+ <span class="k">let</span> <span class="n">rhs</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="nn">Stream</span><span class="p">.</span><span class="n">peek</span> <span class="n">stream</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">c2</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* If BinOp binds less tightly with rhs than the operator after</span>
+<span class="c"> * rhs, let the pending operator take rhs as its lhs. *)</span>
+ <span class="k">let</span> <span class="n">next_prec</span> <span class="o">=</span> <span class="n">precedence</span> <span class="n">c2</span> <span class="k">in</span>
+ <span class="k">if</span> <span class="n">token_prec</span> <span class="o"><</span> <span class="n">next_prec</span>
+ <span class="k">then</span> <span class="n">parse_bin_rhs</span> <span class="o">(</span><span class="n">token_prec</span> <span class="o">+</span> <span class="mi">1</span><span class="o">)</span> <span class="n">rhs</span> <span class="n">stream</span>
+ <span class="k">else</span> <span class="n">rhs</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="n">rhs</span>
+ <span class="k">in</span>
+
+ <span class="c">(* Merge lhs/rhs. *)</span>
+ <span class="k">let</span> <span class="n">lhs</span> <span class="o">=</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="n">lhs</span><span class="o">,</span> <span class="n">rhs</span><span class="o">)</span> <span class="k">in</span>
+ <span class="n">parse_bin_rhs</span> <span class="n">expr_prec</span> <span class="n">lhs</span> <span class="n">stream</span>
+ <span class="k">end</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="n">lhs</span>
+
+<span class="c">(* expression</span>
+<span class="c"> * ::= primary binoprhs *)</span>
+<span class="ow">and</span> <span class="n">parse_expr</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">lhs</span><span class="o">=</span><span class="n">parse_primary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">parse_bin_rhs</span> <span class="mi">0</span> <span class="n">lhs</span> <span class="n">stream</span>
+
+<span class="c">(* prototype</span>
+<span class="c"> * ::= id '(' id* ')' *)</span>
+<span class="k">let</span> <span class="n">parse_prototype</span> <span class="o">=</span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_args</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_args</span> <span class="o">(</span><span class="n">id</span><span class="o">::</span><span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+ <span class="k">in</span>
+
+ <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span> <span class="o">??</span> <span class="s2">"expected '(' in prototype"</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')' in prototype"</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="c">(* success. *)</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">))</span>
+
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected function name in prototype"</span><span class="o">)</span>
+
+<span class="c">(* definition ::= 'def' prototype expression *)</span>
+<span class="k">let</span> <span class="n">parse_definition</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span><span class="o">;</span> <span class="n">p</span><span class="o">=</span><span class="n">parse_prototype</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="n">p</span><span class="o">,</span> <span class="n">e</span><span class="o">)</span>
+
+<span class="c">(* toplevelexpr ::= expression *)</span>
+<span class="k">let</span> <span class="n">parse_toplevel</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="c">(* Make an anonymous proto. *)</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="s2">""</span><span class="o">,</span> <span class="o">[||]),</span> <span class="n">e</span><span class="o">)</span>
+
+<span class="c">(* external ::= 'extern' prototype *)</span>
+<span class="k">let</span> <span class="n">parse_extern</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_prototype</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+</pre></div>
+</div>
+</dd>
+<dt>codegen.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Code Generation</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">open</span> <span class="nc">Llvm</span>
+
+<span class="k">exception</span> <span class="nc">Error</span> <span class="k">of</span> <span class="kt">string</span>
+
+<span class="k">let</span> <span class="n">context</span> <span class="o">=</span> <span class="n">global_context</span> <span class="bp">()</span>
+<span class="k">let</span> <span class="n">the_module</span> <span class="o">=</span> <span class="n">create_module</span> <span class="n">context</span> <span class="s2">"my cool jit"</span>
+<span class="k">let</span> <span class="n">builder</span> <span class="o">=</span> <span class="n">builder</span> <span class="n">context</span>
+<span class="k">let</span> <span class="n">named_values</span><span class="o">:(</span><span class="kt">string</span><span class="o">,</span> <span class="n">llvalue</span><span class="o">)</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">t</span> <span class="o">=</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">create</span> <span class="mi">10</span>
+<span class="k">let</span> <span class="n">double_type</span> <span class="o">=</span> <span class="n">double_type</span> <span class="n">context</span>
+
+<span class="k">let</span> <span class="k">rec</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">-></span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="n">n</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Variable</span> <span class="n">name</span> <span class="o">-></span>
+ <span class="o">(</span><span class="k">try</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">name</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown variable name"</span><span class="o">))</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">lhs</span><span class="o">,</span> <span class="n">rhs</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">lhs_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">lhs</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">rhs_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">rhs</span> <span class="k">in</span>
+ <span class="k">begin</span>
+ <span class="k">match</span> <span class="n">op</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="sc">'+'</span> <span class="o">-></span> <span class="n">build_add</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"addtmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'-'</span> <span class="o">-></span> <span class="n">build_sub</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"subtmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'*'</span> <span class="o">-></span> <span class="n">build_mul</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"multmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'<'</span> <span class="o">-></span>
+ <span class="c">(* Convert bool 0/1 to double 0.0 or 1.0 *)</span>
+ <span class="k">let</span> <span class="n">i</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">Ult</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"cmptmp"</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="n">build_uitofp</span> <span class="n">i</span> <span class="n">double_type</span> <span class="s2">"booltmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"invalid binary operator"</span><span class="o">)</span>
+ <span class="k">end</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Call</span> <span class="o">(</span><span class="n">callee</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* Look up the name in the module table. *)</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">callee</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">callee</span> <span class="o">-></span> <span class="n">callee</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown function referenced"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">params</span> <span class="o">=</span> <span class="n">params</span> <span class="n">callee</span> <span class="k">in</span>
+
+ <span class="c">(* If argument mismatch error. *)</span>
+ <span class="k">if</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">params</span> <span class="o">==</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span> <span class="k">then</span> <span class="bp">()</span> <span class="k">else</span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"incorrect # arguments passed"</span><span class="o">);</span>
+ <span class="k">let</span> <span class="n">args</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">map</span> <span class="n">codegen_expr</span> <span class="n">args</span> <span class="k">in</span>
+ <span class="n">build_call</span> <span class="n">callee</span> <span class="n">args</span> <span class="s2">"calltmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">If</span> <span class="o">(</span><span class="n">cond</span><span class="o">,</span> <span class="n">then_</span><span class="o">,</span> <span class="n">else_</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">cond</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">cond</span> <span class="k">in</span>
+
+ <span class="c">(* Convert condition to a bool by comparing equal to 0.0 *)</span>
+ <span class="k">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">cond_val</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">One</span> <span class="n">cond</span> <span class="n">zero</span> <span class="s2">"ifcond"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Grab the first block so that we might later add the conditional branch</span>
+<span class="c"> * to it at the end of the function. *)</span>
+ <span class="k">let</span> <span class="n">start_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="n">start_bb</span> <span class="k">in</span>
+
+ <span class="k">let</span> <span class="n">then_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"then"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+ <span class="c">(* Emit 'then' value. *)</span>
+ <span class="n">position_at_end</span> <span class="n">then_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">then_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">then_</span> <span class="k">in</span>
+
+ <span class="c">(* Codegen of 'then' can change the current block, update then_bb for the</span>
+<span class="c"> * phi. We create a new name because one is used for the phi node, and the</span>
+<span class="c"> * other is used for the conditional branch. *)</span>
+ <span class="k">let</span> <span class="n">new_then_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Emit 'else' value. *)</span>
+ <span class="k">let</span> <span class="n">else_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"else"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">else_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">else_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">else_</span> <span class="k">in</span>
+
+ <span class="c">(* Codegen of 'else' can change the current block, update else_bb for the</span>
+<span class="c"> * phi. *)</span>
+ <span class="k">let</span> <span class="n">new_else_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Emit merge block. *)</span>
+ <span class="k">let</span> <span class="n">merge_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"ifcont"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">incoming</span> <span class="o">=</span> <span class="o">[(</span><span class="n">then_val</span><span class="o">,</span> <span class="n">new_then_bb</span><span class="o">);</span> <span class="o">(</span><span class="n">else_val</span><span class="o">,</span> <span class="n">new_else_bb</span><span class="o">)]</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">phi</span> <span class="o">=</span> <span class="n">build_phi</span> <span class="n">incoming</span> <span class="s2">"iftmp"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Return to the start block to add the conditional branch. *)</span>
+ <span class="n">position_at_end</span> <span class="n">start_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">build_cond_br</span> <span class="n">cond_val</span> <span class="n">then_bb</span> <span class="n">else_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Set a unconditional branch at the end of the 'then' block and the</span>
+<span class="c"> * 'else' block to the 'merge' block. *)</span>
+ <span class="n">position_at_end</span> <span class="n">new_then_bb</span> <span class="n">builder</span><span class="o">;</span> <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">);</span>
+ <span class="n">position_at_end</span> <span class="n">new_else_bb</span> <span class="n">builder</span><span class="o">;</span> <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Finally, set the builder to the end of the merge block. *)</span>
+ <span class="n">position_at_end</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="n">phi</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">For</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">end_</span><span class="o">,</span> <span class="n">step</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* Emit the start code first, without 'variable' in scope. *)</span>
+ <span class="k">let</span> <span class="n">start_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">start</span> <span class="k">in</span>
+
+ <span class="c">(* Make the new basic block for the loop header, inserting after current</span>
+<span class="c"> * block. *)</span>
+ <span class="k">let</span> <span class="n">preheader_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="n">preheader_bb</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">loop_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"loop"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+ <span class="c">(* Insert an explicit fall through from the current block to the</span>
+<span class="c"> * loop_bb. *)</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">loop_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Start insertion in loop_bb. *)</span>
+ <span class="n">position_at_end</span> <span class="n">loop_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="c">(* Start the PHI node with an entry for start. *)</span>
+ <span class="k">let</span> <span class="n">variable</span> <span class="o">=</span> <span class="n">build_phi</span> <span class="o">[(</span><span class="n">start_val</span><span class="o">,</span> <span class="n">preheader_bb</span><span class="o">)]</span> <span class="n">var_name</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Within the loop, the variable is defined equal to the PHI node. If it</span>
+<span class="c"> * shadows an existing variable, we have to restore it, so save it</span>
+<span class="c"> * now. *)</span>
+ <span class="k">let</span> <span class="n">old_val</span> <span class="o">=</span>
+ <span class="k">try</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">var_name</span><span class="o">)</span> <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="nc">None</span>
+ <span class="k">in</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">variable</span><span class="o">;</span>
+
+ <span class="c">(* Emit the body of the loop. This, like any other expr, can change the</span>
+<span class="c"> * current BB. Note that we ignore the value computed by the body, but</span>
+<span class="c"> * don't allow an error *)</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">codegen_expr</span> <span class="n">body</span><span class="o">);</span>
+
+ <span class="c">(* Emit the step value. *)</span>
+ <span class="k">let</span> <span class="n">step_val</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">step</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">step</span> <span class="o">-></span> <span class="n">codegen_expr</span> <span class="n">step</span>
+ <span class="c">(* If not specified, use 1.0. *)</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">1</span><span class="o">.</span><span class="mi">0</span>
+ <span class="k">in</span>
+
+ <span class="k">let</span> <span class="n">next_var</span> <span class="o">=</span> <span class="n">build_add</span> <span class="n">variable</span> <span class="n">step_val</span> <span class="s2">"nextvar"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Compute the end condition. *)</span>
+ <span class="k">let</span> <span class="n">end_cond</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">end_</span> <span class="k">in</span>
+
+ <span class="c">(* Convert condition to a bool by comparing equal to 0.0. *)</span>
+ <span class="k">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">end_cond</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">One</span> <span class="n">end_cond</span> <span class="n">zero</span> <span class="s2">"loopcond"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Create the "after loop" block and insert it. *)</span>
+ <span class="k">let</span> <span class="n">loop_end_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">after_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"afterloop"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+ <span class="c">(* Insert the conditional branch into the end of loop_end_bb. *)</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">build_cond_br</span> <span class="n">end_cond</span> <span class="n">loop_bb</span> <span class="n">after_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Any new code will be inserted in after_bb. *)</span>
+ <span class="n">position_at_end</span> <span class="n">after_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="c">(* Add a new entry to the PHI node for the backedge. *)</span>
+ <span class="n">add_incoming</span> <span class="o">(</span><span class="n">next_var</span><span class="o">,</span> <span class="n">loop_end_bb</span><span class="o">)</span> <span class="n">variable</span><span class="o">;</span>
+
+ <span class="c">(* Restore the unshadowed variable. *)</span>
+ <span class="k">begin</span> <span class="k">match</span> <span class="n">old_val</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">old_val</span> <span class="o">-></span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">old_val</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="bp">()</span>
+ <span class="k">end</span><span class="o">;</span>
+
+ <span class="c">(* for expr always returns 0.0. *)</span>
+ <span class="n">const_null</span> <span class="n">double_type</span>
+
+<span class="k">let</span> <span class="n">codegen_proto</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* Make the function type: double(double,double) etc. *)</span>
+ <span class="k">let</span> <span class="n">doubles</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">make</span> <span class="o">(</span><span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span><span class="o">)</span> <span class="n">double_type</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">ft</span> <span class="o">=</span> <span class="n">function_type</span> <span class="n">double_type</span> <span class="n">doubles</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">f</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">name</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="n">declare_function</span> <span class="n">name</span> <span class="n">ft</span> <span class="n">the_module</span>
+
+ <span class="c">(* If 'f' conflicted, there was already something named 'name'. If it</span>
+<span class="c"> * has a body, don't allow redefinition or reextern. *)</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">f</span> <span class="o">-></span>
+ <span class="c">(* If 'f' already has a body, reject this. *)</span>
+ <span class="k">if</span> <span class="n">block_begin</span> <span class="n">f</span> <span class="o"><></span> <span class="nc">At_end</span> <span class="n">f</span> <span class="k">then</span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"redefinition of function"</span><span class="o">);</span>
+
+ <span class="c">(* If 'f' took a different number of arguments, reject. *)</span>
+ <span class="k">if</span> <span class="n">element_type</span> <span class="o">(</span><span class="n">type_of</span> <span class="n">f</span><span class="o">)</span> <span class="o"><></span> <span class="n">ft</span> <span class="k">then</span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"redefinition of function with different # args"</span><span class="o">);</span>
+ <span class="n">f</span>
+ <span class="k">in</span>
+
+ <span class="c">(* Set names for all arguments. *)</span>
+ <span class="nn">Array</span><span class="p">.</span><span class="n">iteri</span> <span class="o">(</span><span class="k">fun</span> <span class="n">i</span> <span class="n">a</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">n</span> <span class="o">=</span> <span class="n">args</span><span class="o">.(</span><span class="n">i</span><span class="o">)</span> <span class="k">in</span>
+ <span class="n">set_value_name</span> <span class="n">n</span> <span class="n">a</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">n</span> <span class="n">a</span><span class="o">;</span>
+ <span class="o">)</span> <span class="o">(</span><span class="n">params</span> <span class="n">f</span><span class="o">);</span>
+ <span class="n">f</span>
+
+<span class="k">let</span> <span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="n">proto</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">clear</span> <span class="n">named_values</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">codegen_proto</span> <span class="n">proto</span> <span class="k">in</span>
+
+ <span class="c">(* Create a new basic block to start insertion into. *)</span>
+ <span class="k">let</span> <span class="n">bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"entry"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="k">try</span>
+ <span class="k">let</span> <span class="n">ret_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">body</span> <span class="k">in</span>
+
+ <span class="c">(* Finish off the function. *)</span>
+ <span class="k">let</span> <span class="o">_</span> <span class="o">=</span> <span class="n">build_ret</span> <span class="n">ret_val</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Validate the generated code, checking for consistency. *)</span>
+ <span class="nn">Llvm_analysis</span><span class="p">.</span><span class="n">assert_valid_function</span> <span class="n">the_function</span><span class="o">;</span>
+
+ <span class="c">(* Optimize the function. *)</span>
+ <span class="k">let</span> <span class="o">_</span> <span class="o">=</span> <span class="nn">PassManager</span><span class="p">.</span><span class="n">run_function</span> <span class="n">the_function</span> <span class="n">the_fpm</span> <span class="k">in</span>
+
+ <span class="n">the_function</span>
+ <span class="k">with</span> <span class="n">e</span> <span class="o">-></span>
+ <span class="n">delete_function</span> <span class="n">the_function</span><span class="o">;</span>
+ <span class="k">raise</span> <span class="n">e</span>
+</pre></div>
+</div>
+</dd>
+<dt>toplevel.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Top-Level parsing and JIT Driver</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">open</span> <span class="nc">Llvm</span>
+<span class="k">open</span> <span class="nc">Llvm_executionengine</span>
+
+<span class="c">(* top ::= definition | external | expression | ';' *)</span>
+<span class="k">let</span> <span class="k">rec</span> <span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="nn">Stream</span><span class="p">.</span><span class="n">peek</span> <span class="n">stream</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="bp">()</span>
+
+ <span class="c">(* ignore top-level semicolons. *)</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">';'</span><span class="o">)</span> <span class="o">-></span>
+ <span class="nn">Stream</span><span class="p">.</span><span class="n">junk</span> <span class="n">stream</span><span class="o">;</span>
+ <span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span>
+
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">token</span> <span class="o">-></span>
+ <span class="k">begin</span>
+ <span class="k">try</span> <span class="k">match</span> <span class="n">token</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">e</span> <span class="o">=</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">parse_definition</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="n">print_endline</span> <span class="s2">"parsed a function definition."</span><span class="o">;</span>
+ <span class="n">dump_value</span> <span class="o">(</span><span class="nn">Codegen</span><span class="p">.</span><span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="n">e</span><span class="o">);</span>
+ <span class="o">|</span> <span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">e</span> <span class="o">=</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">parse_extern</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="n">print_endline</span> <span class="s2">"parsed an extern."</span><span class="o">;</span>
+ <span class="n">dump_value</span> <span class="o">(</span><span class="nn">Codegen</span><span class="p">.</span><span class="n">codegen_proto</span> <span class="n">e</span><span class="o">);</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span>
+ <span class="c">(* Evaluate a top-level expression into an anonymous function. *)</span>
+ <span class="k">let</span> <span class="n">e</span> <span class="o">=</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">parse_toplevel</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="n">print_endline</span> <span class="s2">"parsed a top-level expr"</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="n">e</span> <span class="k">in</span>
+ <span class="n">dump_value</span> <span class="n">the_function</span><span class="o">;</span>
+
+ <span class="c">(* JIT the function, returning a function pointer. *)</span>
+ <span class="k">let</span> <span class="n">result</span> <span class="o">=</span> <span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">run_function</span> <span class="n">the_function</span> <span class="o">[||]</span>
+ <span class="n">the_execution_engine</span> <span class="k">in</span>
+
+ <span class="n">print_string</span> <span class="s2">"Evaluated to "</span><span class="o">;</span>
+ <span class="n">print_float</span> <span class="o">(</span><span class="nn">GenericValue</span><span class="p">.</span><span class="n">as_float</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">double_type</span> <span class="n">result</span><span class="o">);</span>
+ <span class="n">print_newline</span> <span class="bp">()</span><span class="o">;</span>
+ <span class="k">with</span> <span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="n">s</span> <span class="o">|</span> <span class="nn">Codegen</span><span class="p">.</span><span class="nc">Error</span> <span class="n">s</span> <span class="o">-></span>
+ <span class="c">(* Skip token for error recovery. *)</span>
+ <span class="nn">Stream</span><span class="p">.</span><span class="n">junk</span> <span class="n">stream</span><span class="o">;</span>
+ <span class="n">print_endline</span> <span class="n">s</span><span class="o">;</span>
+ <span class="k">end</span><span class="o">;</span>
+ <span class="n">print_string</span> <span class="s2">"ready> "</span><span class="o">;</span> <span class="n">flush</span> <span class="n">stdout</span><span class="o">;</span>
+ <span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span>
+</pre></div>
+</div>
+</dd>
+<dt>toy.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Main driver code.</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">open</span> <span class="nc">Llvm</span>
+<span class="k">open</span> <span class="nc">Llvm_executionengine</span>
+<span class="k">open</span> <span class="nc">Llvm_target</span>
+<span class="k">open</span> <span class="nc">Llvm_scalar_opts</span>
+
+<span class="k">let</span> <span class="n">main</span> <span class="bp">()</span> <span class="o">=</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">initialize_native_target</span> <span class="bp">()</span><span class="o">);</span>
+
+ <span class="c">(* Install standard binary operators.</span>
+<span class="c"> * 1 is the lowest precedence. *)</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'<'</span> <span class="mi">10</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'+'</span> <span class="mi">20</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'-'</span> <span class="mi">20</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'*'</span> <span class="mi">40</span><span class="o">;</span> <span class="c">(* highest. *)</span>
+
+ <span class="c">(* Prime the first token. *)</span>
+ <span class="n">print_string</span> <span class="s2">"ready> "</span><span class="o">;</span> <span class="n">flush</span> <span class="n">stdout</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">stream</span> <span class="o">=</span> <span class="nn">Lexer</span><span class="p">.</span><span class="n">lex</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="n">of_channel</span> <span class="n">stdin</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Create the JIT. *)</span>
+ <span class="k">let</span> <span class="n">the_execution_engine</span> <span class="o">=</span> <span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">create</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">the_fpm</span> <span class="o">=</span> <span class="nn">PassManager</span><span class="p">.</span><span class="n">create_function</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span> <span class="k">in</span>
+
+ <span class="c">(* Set up the optimizer pipeline. Start with registering info about how the</span>
+<span class="c"> * target lays out data structures. *)</span>
+ <span class="nn">DataLayout</span><span class="p">.</span><span class="n">add</span> <span class="o">(</span><span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">target_data</span> <span class="n">the_execution_engine</span><span class="o">)</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Do simple "peephole" optimizations and bit-twiddling optzn. *)</span>
+ <span class="n">add_instruction_combination</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* reassociate expressions. *)</span>
+ <span class="n">add_reassociation</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Eliminate Common SubExpressions. *)</span>
+ <span class="n">add_gvn</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Simplify the control flow graph (deleting unreachable blocks, etc). *)</span>
+ <span class="n">add_cfg_simplification</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="n">ignore</span> <span class="o">(</span><span class="nn">PassManager</span><span class="p">.</span><span class="n">initialize</span> <span class="n">the_fpm</span><span class="o">);</span>
+
+ <span class="c">(* Run the main "interpreter loop" now. *)</span>
+ <span class="nn">Toplevel</span><span class="p">.</span><span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span><span class="o">;</span>
+
+ <span class="c">(* Print out all the generated code. *)</span>
+ <span class="n">dump_module</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span>
+<span class="o">;;</span>
+
+<span class="n">main</span> <span class="bp">()</span>
+</pre></div>
+</div>
+</dd>
+<dt>bindings.c</dt>
+<dd><div class="first last highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp"></span>
+
+<span class="cm">/* putchard - putchar that takes a double and returns 0. */</span>
+<span class="k">extern</span> <span class="kt">double</span> <span class="nf">putchard</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">putchar</span><span class="p">((</span><span class="kt">char</span><span class="p">)</span><span class="n">X</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</dd>
+</dl>
+<p><a class="reference external" href="OCamlLangImpl6.html">Next: Extending the language: user-defined
+operators</a></p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="OCamlLangImpl6.html" title="6. Kaleidoscope: Extending the Language: User-defined Operators"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="OCamlLangImpl4.html" title="4. Kaleidoscope: Adding JIT and Optimizer Support"
+ >previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" >LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-03-18.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl6.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl6.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl6.html (added)
+++ www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl6.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,1481 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>6. Kaleidoscope: Extending the Language: User-defined Operators — LLVM 8 documentation</title>
+ <link rel="stylesheet" href="../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="7. Kaleidoscope: Extending the Language: Mutable Variables" href="OCamlLangImpl7.html" />
+ <link rel="prev" title="5. Kaleidoscope: Extending the Language: Control Flow" href="OCamlLangImpl5.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../index.html">
+ <img src="../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="OCamlLangImpl7.html" title="7. Kaleidoscope: Extending the Language: Mutable Variables"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="OCamlLangImpl5.html" title="5. Kaleidoscope: Extending the Language: Control Flow"
+ accesskey="P">previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-extending-the-language-user-defined-operators">
+<h1>6. Kaleidoscope: Extending the Language: User-defined Operators<a class="headerlink" href="#kaleidoscope-extending-the-language-user-defined-operators" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#chapter-6-introduction" id="id1">Chapter 6 Introduction</a></li>
+<li><a class="reference internal" href="#user-defined-operators-the-idea" id="id2">User-defined Operators: the Idea</a></li>
+<li><a class="reference internal" href="#user-defined-binary-operators" id="id3">User-defined Binary Operators</a></li>
+<li><a class="reference internal" href="#user-defined-unary-operators" id="id4">User-defined Unary Operators</a></li>
+<li><a class="reference internal" href="#kicking-the-tires" id="id5">Kicking the Tires</a></li>
+<li><a class="reference internal" href="#full-code-listing" id="id6">Full Code Listing</a></li>
+</ul>
+</div>
+<div class="section" id="chapter-6-introduction">
+<h2><a class="toc-backref" href="#id1">6.1. Chapter 6 Introduction</a><a class="headerlink" href="#chapter-6-introduction" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to Chapter 6 of the â<a class="reference external" href="index.html">Implementing a language with
+LLVM</a>â tutorial. At this point in our tutorial, we now
+have a fully functional language that is fairly minimal, but also
+useful. There is still one big problem with it, however. Our language
+doesnât have many useful operators (like division, logical negation, or
+even any comparisons besides less-than).</p>
+<p>This chapter of the tutorial takes a wild digression into adding
+user-defined operators to the simple and beautiful Kaleidoscope
+language. This digression now gives us a simple and ugly language in
+some ways, but also a powerful one at the same time. One of the great
+things about creating your own language is that you get to decide what
+is good or bad. In this tutorial weâll assume that it is okay to use
+this as a way to show some interesting parsing techniques.</p>
+<p>At the end of this tutorial, weâll run through an example Kaleidoscope
+application that <a class="reference external" href="#kicking-the-tires">renders the Mandelbrot set</a>. This gives an
+example of what you can build with Kaleidoscope and its feature set.</p>
+</div>
+<div class="section" id="user-defined-operators-the-idea">
+<h2><a class="toc-backref" href="#id2">6.2. User-defined Operators: the Idea</a><a class="headerlink" href="#user-defined-operators-the-idea" title="Permalink to this headline">¶</a></h2>
+<p>The âoperator overloadingâ that we will add to Kaleidoscope is more
+general than languages like C++. In C++, you are only allowed to
+redefine existing operators: you canât programmatically change the
+grammar, introduce new operators, change precedence levels, etc. In this
+chapter, we will add this capability to Kaleidoscope, which will let the
+user round out the set of operators that are supported.</p>
+<p>The point of going into user-defined operators in a tutorial like this
+is to show the power and flexibility of using a hand-written parser.
+Thus far, the parser we have been implementing uses recursive descent
+for most parts of the grammar and operator precedence parsing for the
+expressions. See <a class="reference external" href="OCamlLangImpl2.html">Chapter 2</a> for details. Without
+using operator precedence parsing, it would be very difficult to allow
+the programmer to introduce new operators into the grammar: the grammar
+is dynamically extensible as the JIT runs.</p>
+<p>The two specific features weâll add are programmable unary operators
+(right now, Kaleidoscope has no unary operators at all) as well as
+binary operators. An example of this is:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span># Logical unary not.
+def unary!(v)
+ if v then
+ 0
+ else
+ 1;
+
+# Define > with the same precedence as <.
+def binary> 10 (LHS RHS)
+ RHS < LHS;
+
+# Binary "logical or", (note that it does not "short circuit")
+def binary| 5 (LHS RHS)
+ if LHS then
+ 1
+ else if RHS then
+ 1
+ else
+ 0;
+
+# Define = with slightly lower precedence than relationals.
+def binary= 9 (LHS RHS)
+ !(LHS < RHS | LHS > RHS);
+</pre></div>
+</div>
+<p>Many languages aspire to being able to implement their standard runtime
+library in the language itself. In Kaleidoscope, we can implement
+significant parts of the language in the library!</p>
+<p>We will break down implementation of these features into two parts:
+implementing support for user-defined binary operators and adding unary
+operators.</p>
+</div>
+<div class="section" id="user-defined-binary-operators">
+<h2><a class="toc-backref" href="#id3">6.3. User-defined Binary Operators</a><a class="headerlink" href="#user-defined-binary-operators" title="Permalink to this headline">¶</a></h2>
+<p>Adding support for user-defined binary operators is pretty simple with
+our current framework. Weâll first add support for the unary/binary
+keywords:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">type</span> <span class="n">token</span> <span class="o">=</span>
+ <span class="o">...</span>
+ <span class="c">(* operators *)</span>
+ <span class="o">|</span> <span class="nc">Binary</span> <span class="o">|</span> <span class="nn">Unary</span>
+
+<span class="p">...</span>
+
+<span class="n">and</span> <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">...</span>
+ <span class="o">|</span> <span class="s2">"for"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"in"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"binary"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Binary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"unary"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Unary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+</pre></div>
+</div>
+<p>This just adds lexer support for the unary and binary keywords, like we
+did in <a class="reference external" href="OCamlLangImpl5.html#lexer-extensions-for-if-then-else">previous chapters</a>. One nice
+thing about our current AST, is that we represent binary operators with
+full generalisation by using their ASCII code as the opcode. For our
+extended operators, weâll use this same representation, so we donât need
+any new AST or parser support.</p>
+<p>On the other hand, we have to be able to represent the definitions of
+these new operators, in the âdef binary| 5â part of the function
+definition. In our grammar so far, the ânameâ for the function
+definition is parsed as the âprototypeâ production and into the
+<code class="docutils literal notranslate"><span class="pre">Ast.Prototype</span></code> AST node. To represent our new user-defined operators
+as prototypes, we have to extend the <code class="docutils literal notranslate"><span class="pre">Ast.Prototype</span></code> AST node like
+this:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* proto - This type represents the "prototype" for a function, which captures</span>
+<span class="c"> * its name, and its argument names (thus implicitly the number of arguments the</span>
+<span class="c"> * function takes). *)</span>
+<span class="k">type</span> <span class="n">proto</span> <span class="o">=</span>
+ <span class="o">|</span> <span class="nc">Prototype</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="kt">string</span> <span class="kt">array</span>
+ <span class="o">|</span> <span class="nc">BinOpPrototype</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="kt">string</span> <span class="kt">array</span> <span class="o">*</span> <span class="kt">int</span>
+</pre></div>
+</div>
+<p>Basically, in addition to knowing a name for the prototype, we now keep
+track of whether it was an operator, and if it was, what precedence
+level the operator is at. The precedence is only used for binary
+operators (as youâll see below, it just doesnât apply for unary
+operators). Now that we have a way to represent the prototype for a
+user-defined operator, we need to parse it:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* prototype</span>
+<span class="c"> * ::= id '(' id* ')'</span>
+<span class="c"> * ::= binary LETTER number? (id, id)</span>
+<span class="c"> * ::= unary LETTER number? (id) *)</span>
+<span class="k">let</span> <span class="n">parse_prototype</span> <span class="o">=</span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_args</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_args</span> <span class="o">(</span><span class="n">id</span><span class="o">::</span><span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">parse_operator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">>]</span> <span class="o">-></span> <span class="s2">"unary"</span><span class="o">,</span> <span class="mi">1</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">>]</span> <span class="o">-></span> <span class="s2">"binary"</span><span class="o">,</span> <span class="mi">2</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">parse_binary_precedence</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">int_of_float</span> <span class="n">n</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="mi">30</span>
+ <span class="k">in</span>
+ <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span> <span class="o">??</span> <span class="s2">"expected '(' in prototype"</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')' in prototype"</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="c">(* success. *)</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">))</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">(</span><span class="n">prefix</span><span class="o">,</span> <span class="n">kind</span><span class="o">)=</span><span class="n">parse_operator</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">op</span> <span class="o">??</span> <span class="s2">"expected an operator"</span><span class="o">;</span>
+ <span class="c">(* Read the precedence if present. *)</span>
+ <span class="n">binary_precedence</span><span class="o">=</span><span class="n">parse_binary_precedence</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span> <span class="o">??</span> <span class="s2">"expected '(' in prototype"</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')' in prototype"</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">name</span> <span class="o">=</span> <span class="n">prefix</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">args</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Verify right number of arguments for operator. *)</span>
+ <span class="k">if</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span> <span class="o">!=</span> <span class="n">kind</span>
+ <span class="k">then</span> <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"invalid number of operands for operator"</span><span class="o">)</span>
+ <span class="k">else</span>
+ <span class="k">if</span> <span class="n">kind</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">then</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span>
+ <span class="k">else</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">,</span> <span class="n">binary_precedence</span><span class="o">)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected function name in prototype"</span><span class="o">)</span>
+</pre></div>
+</div>
+<p>This is all fairly straightforward parsing code, and we have already
+seen a lot of similar code in the past. One interesting part about the
+code above is the couple lines that set up <code class="docutils literal notranslate"><span class="pre">name</span></code> for binary
+operators. This builds names like âbinary@â for a newly defined â@â
+operator. This then takes advantage of the fact that symbol names in the
+LLVM symbol table are allowed to have any character in them, including
+embedded nul characters.</p>
+<p>The next interesting thing to add, is codegen support for these binary
+operators. Given our current structure, this is a simple addition of a
+default case for our existing binary operator node:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">...</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">lhs</span><span class="o">,</span> <span class="n">rhs</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">lhs_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">lhs</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">rhs_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">rhs</span> <span class="k">in</span>
+ <span class="k">begin</span>
+ <span class="k">match</span> <span class="n">op</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="sc">'+'</span> <span class="o">-></span> <span class="n">build_add</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"addtmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'-'</span> <span class="o">-></span> <span class="n">build_sub</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"subtmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'*'</span> <span class="o">-></span> <span class="n">build_mul</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"multmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'<'</span> <span class="o">-></span>
+ <span class="c">(* Convert bool 0/1 to double 0.0 or 1.0 *)</span>
+ <span class="k">let</span> <span class="n">i</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">Ult</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"cmptmp"</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="n">build_uitofp</span> <span class="n">i</span> <span class="n">double_type</span> <span class="s2">"booltmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span>
+ <span class="c">(* If it wasn't a builtin binary operator, it must be a user defined</span>
+<span class="c"> * one. Emit a call to it. *)</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span> <span class="s2">"binary"</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">callee</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">callee</span> <span class="o">-></span> <span class="n">callee</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"binary operator not found!"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="n">build_call</span> <span class="n">callee</span> <span class="o">[|</span><span class="n">lhs_val</span><span class="o">;</span> <span class="n">rhs_val</span><span class="o">|]</span> <span class="s2">"binop"</span> <span class="n">builder</span>
+ <span class="k">end</span>
+</pre></div>
+</div>
+<p>As you can see above, the new code is actually really simple. It just
+does a lookup for the appropriate operator in the symbol table and
+generates a function call to it. Since user-defined operators are just
+built as normal functions (because the âprototypeâ boils down to a
+function with the right name) everything falls into place.</p>
+<p>The final piece of code we are missing, is a bit of top level magic:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="n">proto</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">clear</span> <span class="n">named_values</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">codegen_proto</span> <span class="n">proto</span> <span class="k">in</span>
+
+ <span class="c">(* If this is an operator, install it. *)</span>
+ <span class="k">begin</span> <span class="k">match</span> <span class="n">proto</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">,</span> <span class="n">prec</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">op</span> <span class="o">=</span> <span class="n">name</span><span class="o">.[</span><span class="nn">String</span><span class="p">.</span><span class="n">length</span> <span class="n">name</span> <span class="o">-</span> <span class="mi">1</span><span class="o">]</span> <span class="k">in</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="n">op</span> <span class="n">prec</span><span class="o">;</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="bp">()</span>
+ <span class="k">end</span><span class="o">;</span>
+
+ <span class="c">(* Create a new basic block to start insertion into. *)</span>
+ <span class="k">let</span> <span class="n">bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"entry"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="o">...</span>
+</pre></div>
+</div>
+<p>Basically, before codegening a function, if it is a user-defined
+operator, we register it in the precedence table. This allows the binary
+operator parsing logic we already have in place to handle it. Since we
+are working on a fully-general operator precedence parser, this is all
+we need to do to âextend the grammarâ.</p>
+<p>Now we have useful user-defined binary operators. This builds a lot on
+the previous framework we built for other operators. Adding unary
+operators is a bit more challenging, because we donât have any framework
+for it yet - lets see what it takes.</p>
+</div>
+<div class="section" id="user-defined-unary-operators">
+<h2><a class="toc-backref" href="#id4">6.4. User-defined Unary Operators</a><a class="headerlink" href="#user-defined-unary-operators" title="Permalink to this headline">¶</a></h2>
+<p>Since we donât currently support unary operators in the Kaleidoscope
+language, weâll need to add everything to support them. Above, we added
+simple support for the âunaryâ keyword to the lexer. In addition to
+that, we need an AST node:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">type</span> <span class="n">expr</span> <span class="o">=</span>
+ <span class="o">...</span>
+ <span class="c">(* variant for a unary operator. *)</span>
+ <span class="o">|</span> <span class="nc">Unary</span> <span class="k">of</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">expr</span>
+ <span class="o">...</span>
+</pre></div>
+</div>
+<p>This AST node is very simple and obvious by now. It directly mirrors the
+binary operator AST node, except that it only has one child. With this,
+we need to add the parsing logic. Parsing a unary operator is pretty
+simple: weâll add a new function to do it:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* unary</span>
+<span class="c"> * ::= primary</span>
+<span class="c"> * ::= '!' unary *)</span>
+<span class="ow">and</span> <span class="n">parse_unary</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* If this is a unary operator, read it. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">op</span> <span class="k">when</span> <span class="n">op</span> <span class="o">!=</span> <span class="sc">'('</span> <span class="o">&&</span> <span class="n">op</span> <span class="o">!=</span> <span class="sc">')'</span><span class="o">;</span> <span class="n">operand</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">operand</span><span class="o">)</span>
+
+ <span class="c">(* If the current token is not an operator, it must be a primary expr. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">parse_primary</span> <span class="n">stream</span>
+</pre></div>
+</div>
+<p>The grammar we add is pretty straightforward here. If we see a unary
+operator when parsing a primary operator, we eat the operator as a
+prefix and parse the remaining piece as another unary operator. This
+allows us to handle multiple unary operators (e.g. â!!xâ). Note that
+unary operators canât have ambiguous parses like binary operators can,
+so there is no need for precedence information.</p>
+<p>The problem with this function, is that we need to call ParseUnary from
+somewhere. To do this, we change previous callers of ParsePrimary to
+call <code class="docutils literal notranslate"><span class="pre">parse_unary</span></code> instead:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* binoprhs</span>
+<span class="c"> * ::= ('+' primary)* *)</span>
+<span class="ow">and</span> <span class="n">parse_bin_rhs</span> <span class="n">expr_prec</span> <span class="n">lhs</span> <span class="n">stream</span> <span class="o">=</span>
+ <span class="o">...</span>
+ <span class="c">(* Parse the unary expression after the binary operator. *)</span>
+ <span class="k">let</span> <span class="n">rhs</span> <span class="o">=</span> <span class="n">parse_unary</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="o">...</span>
+
+<span class="o">...</span>
+
+<span class="c">(* expression</span>
+<span class="c"> * ::= primary binoprhs *)</span>
+<span class="ow">and</span> <span class="n">parse_expr</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">lhs</span><span class="o">=</span><span class="n">parse_unary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">parse_bin_rhs</span> <span class="mi">0</span> <span class="n">lhs</span> <span class="n">stream</span>
+</pre></div>
+</div>
+<p>With these two simple changes, we are now able to parse unary operators
+and build the AST for them. Next up, we need to add parser support for
+prototypes, to parse the unary operator prototype. We extend the binary
+operator code above with:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* prototype</span>
+<span class="c"> * ::= id '(' id* ')'</span>
+<span class="c"> * ::= binary LETTER number? (id, id)</span>
+<span class="c"> * ::= unary LETTER number? (id) *)</span>
+<span class="k">let</span> <span class="n">parse_prototype</span> <span class="o">=</span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_args</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_args</span> <span class="o">(</span><span class="n">id</span><span class="o">::</span><span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">parse_operator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">>]</span> <span class="o">-></span> <span class="s2">"unary"</span><span class="o">,</span> <span class="mi">1</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">>]</span> <span class="o">-></span> <span class="s2">"binary"</span><span class="o">,</span> <span class="mi">2</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">parse_binary_precedence</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">int_of_float</span> <span class="n">n</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="mi">30</span>
+ <span class="k">in</span>
+ <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span> <span class="o">??</span> <span class="s2">"expected '(' in prototype"</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')' in prototype"</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="c">(* success. *)</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">))</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">(</span><span class="n">prefix</span><span class="o">,</span> <span class="n">kind</span><span class="o">)=</span><span class="n">parse_operator</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">op</span> <span class="o">??</span> <span class="s2">"expected an operator"</span><span class="o">;</span>
+ <span class="c">(* Read the precedence if present. *)</span>
+ <span class="n">binary_precedence</span><span class="o">=</span><span class="n">parse_binary_precedence</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span> <span class="o">??</span> <span class="s2">"expected '(' in prototype"</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')' in prototype"</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">name</span> <span class="o">=</span> <span class="n">prefix</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">args</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Verify right number of arguments for operator. *)</span>
+ <span class="k">if</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span> <span class="o">!=</span> <span class="n">kind</span>
+ <span class="k">then</span> <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"invalid number of operands for operator"</span><span class="o">)</span>
+ <span class="k">else</span>
+ <span class="k">if</span> <span class="n">kind</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">then</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span>
+ <span class="k">else</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">,</span> <span class="n">binary_precedence</span><span class="o">)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected function name in prototype"</span><span class="o">)</span>
+</pre></div>
+</div>
+<p>As with binary operators, we name unary operators with a name that
+includes the operator character. This assists us at code generation
+time. Speaking of, the final piece we need to add is codegen support for
+unary operators. It looks like this:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="k">rec</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">...</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">operand</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">operand</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">operand</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span> <span class="s2">"unary"</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">callee</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">callee</span> <span class="o">-></span> <span class="n">callee</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown unary operator"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="n">build_call</span> <span class="n">callee</span> <span class="o">[|</span><span class="n">operand</span><span class="o">|]</span> <span class="s2">"unop"</span> <span class="n">builder</span>
+</pre></div>
+</div>
+<p>This code is similar to, but simpler than, the code for binary
+operators. It is simpler primarily because it doesnât need to handle any
+predefined operators.</p>
+</div>
+<div class="section" id="kicking-the-tires">
+<h2><a class="toc-backref" href="#id5">6.5. Kicking the Tires</a><a class="headerlink" href="#kicking-the-tires" title="Permalink to this headline">¶</a></h2>
+<p>It is somewhat hard to believe, but with a few simple extensions weâve
+covered in the last chapters, we have grown a real-ish language. With
+this, we can do a lot of interesting things, including I/O, math, and a
+bunch of other things. For example, we can now add a nice sequencing
+operator (printd is defined to print out the specified value and a
+newline):</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="n">extern</span> <span class="n">printd</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
+<span class="n">Read</span> <span class="n">extern</span><span class="p">:</span> <span class="n">declare</span> <span class="n">double</span> <span class="nd">@printd</span><span class="p">(</span><span class="n">double</span><span class="p">)</span>
+<span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">binary</span> <span class="p">:</span> <span class="mi">1</span> <span class="p">(</span><span class="n">x</span> <span class="n">y</span><span class="p">)</span> <span class="mi">0</span><span class="p">;</span> <span class="c1"># Low-precedence operator that ignores operands.</span>
+<span class="o">..</span>
+<span class="n">ready</span><span class="o">></span> <span class="n">printd</span><span class="p">(</span><span class="mi">123</span><span class="p">)</span> <span class="p">:</span> <span class="n">printd</span><span class="p">(</span><span class="mi">456</span><span class="p">)</span> <span class="p">:</span> <span class="n">printd</span><span class="p">(</span><span class="mi">789</span><span class="p">);</span>
+<span class="mf">123.000000</span>
+<span class="mf">456.000000</span>
+<span class="mf">789.000000</span>
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">0.000000</span>
+</pre></div>
+</div>
+<p>We can also define a bunch of other âprimitiveâ operations, such as:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span># Logical unary not.
+def unary!(v)
+ if v then
+ 0
+ else
+ 1;
+
+# Unary negate.
+def unary-(v)
+ 0-v;
+
+# Define > with the same precedence as <.
+def binary> 10 (LHS RHS)
+ RHS < LHS;
+
+# Binary logical or, which does not short circuit.
+def binary| 5 (LHS RHS)
+ if LHS then
+ 1
+ else if RHS then
+ 1
+ else
+ 0;
+
+# Binary logical and, which does not short circuit.
+def binary& 6 (LHS RHS)
+ if !LHS then
+ 0
+ else
+ !!RHS;
+
+# Define = with slightly lower precedence than relationals.
+def binary = 9 (LHS RHS)
+ !(LHS < RHS | LHS > RHS);
+</pre></div>
+</div>
+<p>Given the previous if/then/else support, we can also define interesting
+functions for I/O. For example, the following prints out a character
+whose âdensityâ reflects the value passed in: the lower the value, the
+denser the character:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span>
+
+<span class="n">extern</span> <span class="n">putchard</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
+<span class="k">def</span> <span class="nf">printdensity</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">d</span> <span class="o">></span> <span class="mi">8</span> <span class="n">then</span>
+ <span class="n">putchard</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span> <span class="c1"># ' '</span>
+ <span class="k">else</span> <span class="k">if</span> <span class="n">d</span> <span class="o">></span> <span class="mi">4</span> <span class="n">then</span>
+ <span class="n">putchard</span><span class="p">(</span><span class="mi">46</span><span class="p">)</span> <span class="c1"># '.'</span>
+ <span class="k">else</span> <span class="k">if</span> <span class="n">d</span> <span class="o">></span> <span class="mi">2</span> <span class="n">then</span>
+ <span class="n">putchard</span><span class="p">(</span><span class="mi">43</span><span class="p">)</span> <span class="c1"># '+'</span>
+ <span class="k">else</span>
+ <span class="n">putchard</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span> <span class="c1"># '*'</span>
+<span class="o">...</span>
+<span class="n">ready</span><span class="o">></span> <span class="n">printdensity</span><span class="p">(</span><span class="mi">1</span><span class="p">):</span> <span class="n">printdensity</span><span class="p">(</span><span class="mi">2</span><span class="p">):</span> <span class="n">printdensity</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="p">:</span>
+ <span class="n">printdensity</span><span class="p">(</span><span class="mi">4</span><span class="p">):</span> <span class="n">printdensity</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span> <span class="n">printdensity</span><span class="p">(</span><span class="mi">9</span><span class="p">):</span> <span class="n">putchard</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
+<span class="o">*++..</span>
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">0.000000</span>
+</pre></div>
+</div>
+<p>Based on these simple primitive operations, we can start to define more
+interesting things. For example, hereâs a little function that solves
+for the number of iterations it takes a function in the complex plane to
+converge:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># determine whether the specific location diverges.</span>
+<span class="c1"># Solve for z = z^2 + c in the complex plane.</span>
+<span class="k">def</span> <span class="nf">mandelconverger</span><span class="p">(</span><span class="n">real</span> <span class="n">imag</span> <span class="n">iters</span> <span class="n">creal</span> <span class="n">cimag</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">iters</span> <span class="o">></span> <span class="mi">255</span> <span class="o">|</span> <span class="p">(</span><span class="n">real</span><span class="o">*</span><span class="n">real</span> <span class="o">+</span> <span class="n">imag</span><span class="o">*</span><span class="n">imag</span> <span class="o">></span> <span class="mi">4</span><span class="p">)</span> <span class="n">then</span>
+ <span class="n">iters</span>
+ <span class="k">else</span>
+ <span class="n">mandelconverger</span><span class="p">(</span><span class="n">real</span><span class="o">*</span><span class="n">real</span> <span class="o">-</span> <span class="n">imag</span><span class="o">*</span><span class="n">imag</span> <span class="o">+</span> <span class="n">creal</span><span class="p">,</span>
+ <span class="mi">2</span><span class="o">*</span><span class="n">real</span><span class="o">*</span><span class="n">imag</span> <span class="o">+</span> <span class="n">cimag</span><span class="p">,</span>
+ <span class="n">iters</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">creal</span><span class="p">,</span> <span class="n">cimag</span><span class="p">);</span>
+
+<span class="c1"># return the number of iterations required for the iteration to escape</span>
+<span class="k">def</span> <span class="nf">mandelconverge</span><span class="p">(</span><span class="n">real</span> <span class="n">imag</span><span class="p">)</span>
+ <span class="n">mandelconverger</span><span class="p">(</span><span class="n">real</span><span class="p">,</span> <span class="n">imag</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">real</span><span class="p">,</span> <span class="n">imag</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>This âz = z<sup>2</sup> + câ function is a beautiful little creature
+that is the basis for computation of the <a class="reference external" href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot
+Set</a>. Our
+<code class="docutils literal notranslate"><span class="pre">mandelconverge</span></code> function returns the number of iterations that it
+takes for a complex orbit to escape, saturating to 255. This is not a
+very useful function by itself, but if you plot its value over a
+two-dimensional plane, you can see the Mandelbrot set. Given that we are
+limited to using putchard here, our amazing graphical output is limited,
+but we can whip together something using the density plotter above:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># compute and plot the mandelbrot set with the specified 2 dimensional range</span>
+<span class="c1"># info.</span>
+<span class="k">def</span> <span class="nf">mandelhelp</span><span class="p">(</span><span class="n">xmin</span> <span class="n">xmax</span> <span class="n">xstep</span> <span class="n">ymin</span> <span class="n">ymax</span> <span class="n">ystep</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">y</span> <span class="o">=</span> <span class="n">ymin</span><span class="p">,</span> <span class="n">y</span> <span class="o"><</span> <span class="n">ymax</span><span class="p">,</span> <span class="n">ystep</span> <span class="ow">in</span> <span class="p">(</span>
+ <span class="p">(</span><span class="k">for</span> <span class="n">x</span> <span class="o">=</span> <span class="n">xmin</span><span class="p">,</span> <span class="n">x</span> <span class="o"><</span> <span class="n">xmax</span><span class="p">,</span> <span class="n">xstep</span> <span class="ow">in</span>
+ <span class="n">printdensity</span><span class="p">(</span><span class="n">mandelconverge</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">)))</span>
+ <span class="p">:</span> <span class="n">putchard</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
+ <span class="p">)</span>
+
+<span class="c1"># mandel - This is a convenient helper function for plotting the mandelbrot set</span>
+<span class="c1"># from the specified position with the specified Magnification.</span>
+<span class="k">def</span> <span class="nf">mandel</span><span class="p">(</span><span class="n">realstart</span> <span class="n">imagstart</span> <span class="n">realmag</span> <span class="n">imagmag</span><span class="p">)</span>
+ <span class="n">mandelhelp</span><span class="p">(</span><span class="n">realstart</span><span class="p">,</span> <span class="n">realstart</span><span class="o">+</span><span class="n">realmag</span><span class="o">*</span><span class="mi">78</span><span class="p">,</span> <span class="n">realmag</span><span class="p">,</span>
+ <span class="n">imagstart</span><span class="p">,</span> <span class="n">imagstart</span><span class="o">+</span><span class="n">imagmag</span><span class="o">*</span><span class="mi">40</span><span class="p">,</span> <span class="n">imagmag</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>Given this, we can try plotting out the mandelbrot set! Lets try it out:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="n">mandel</span><span class="p">(</span><span class="o">-</span><span class="mf">2.3</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.3</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">,</span> <span class="mf">0.07</span><span class="p">);</span>
+<span class="o">*******************************+++++++++++*************************************</span>
+<span class="o">*************************+++++++++++++++++++++++*******************************</span>
+<span class="o">**********************+++++++++++++++++++++++++++++****************************</span>
+<span class="o">*******************+++++++++++++++++++++..</span> <span class="o">...++++++++*************************</span>
+<span class="o">*****************++++++++++++++++++++++....</span> <span class="o">...+++++++++***********************</span>
+<span class="o">***************+++++++++++++++++++++++.....</span> <span class="o">...+++++++++*********************</span>
+<span class="o">**************+++++++++++++++++++++++....</span> <span class="o">....+++++++++********************</span>
+<span class="o">*************++++++++++++++++++++++......</span> <span class="o">.....++++++++*******************</span>
+<span class="o">************+++++++++++++++++++++.......</span> <span class="o">.......+++++++******************</span>
+<span class="o">***********+++++++++++++++++++....</span> <span class="o">...</span> <span class="o">.+++++++*****************</span>
+<span class="o">**********+++++++++++++++++.......</span> <span class="o">.+++++++****************</span>
+<span class="o">*********++++++++++++++...........</span> <span class="o">...+++++++***************</span>
+<span class="o">********++++++++++++............</span> <span class="o">...++++++++**************</span>
+<span class="o">********++++++++++...</span> <span class="o">..........</span> <span class="o">.++++++++**************</span>
+<span class="o">*******+++++++++.....</span> <span class="o">.+++++++++*************</span>
+<span class="o">*******++++++++......</span> <span class="o">..+++++++++*************</span>
+<span class="o">*******++++++.......</span> <span class="o">..+++++++++*************</span>
+<span class="o">*******+++++......</span> <span class="o">..+++++++++*************</span>
+<span class="o">*******....</span> <span class="o">....</span> <span class="o">...+++++++++*************</span>
+<span class="o">*******....</span> <span class="o">.</span> <span class="o">...+++++++++*************</span>
+<span class="o">*******+++++......</span> <span class="o">...+++++++++*************</span>
+<span class="o">*******++++++.......</span> <span class="o">..+++++++++*************</span>
+<span class="o">*******++++++++......</span> <span class="o">.+++++++++*************</span>
+<span class="o">*******+++++++++.....</span> <span class="o">..+++++++++*************</span>
+<span class="o">********++++++++++...</span> <span class="o">..........</span> <span class="o">.++++++++**************</span>
+<span class="o">********++++++++++++............</span> <span class="o">...++++++++**************</span>
+<span class="o">*********++++++++++++++..........</span> <span class="o">...+++++++***************</span>
+<span class="o">**********++++++++++++++++........</span> <span class="o">.+++++++****************</span>
+<span class="o">**********++++++++++++++++++++....</span> <span class="o">...</span> <span class="o">..+++++++****************</span>
+<span class="o">***********++++++++++++++++++++++.......</span> <span class="o">.......++++++++*****************</span>
+<span class="o">************+++++++++++++++++++++++......</span> <span class="o">......++++++++******************</span>
+<span class="o">**************+++++++++++++++++++++++....</span> <span class="o">....++++++++********************</span>
+<span class="o">***************+++++++++++++++++++++++.....</span> <span class="o">...+++++++++*********************</span>
+<span class="o">*****************++++++++++++++++++++++....</span> <span class="o">...++++++++***********************</span>
+<span class="o">*******************+++++++++++++++++++++......++++++++*************************</span>
+<span class="o">*********************++++++++++++++++++++++.++++++++***************************</span>
+<span class="o">*************************+++++++++++++++++++++++*******************************</span>
+<span class="o">******************************+++++++++++++************************************</span>
+<span class="o">*******************************************************************************</span>
+<span class="o">*******************************************************************************</span>
+<span class="o">*******************************************************************************</span>
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">0.000000</span>
+<span class="n">ready</span><span class="o">></span> <span class="n">mandel</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mf">0.02</span><span class="p">,</span> <span class="mf">0.04</span><span class="p">);</span>
+<span class="o">**************************+++++++++++++++++++++++++++++++++++++++++++++++++++++</span>
+<span class="o">***********************++++++++++++++++++++++++++++++++++++++++++++++++++++++++</span>
+<span class="o">*********************+++++++++++++++++++++++++++++++++++++++++++++++++++++++++.</span>
+<span class="o">*******************+++++++++++++++++++++++++++++++++++++++++++++++++++++++++...</span>
+<span class="o">*****************+++++++++++++++++++++++++++++++++++++++++++++++++++++++++.....</span>
+<span class="o">***************++++++++++++++++++++++++++++++++++++++++++++++++++++++++........</span>
+<span class="o">**************++++++++++++++++++++++++++++++++++++++++++++++++++++++...........</span>
+<span class="o">************+++++++++++++++++++++++++++++++++++++++++++++++++++++..............</span>
+<span class="o">***********++++++++++++++++++++++++++++++++++++++++++++++++++........</span> <span class="o">.</span>
+<span class="o">**********++++++++++++++++++++++++++++++++++++++++++++++.............</span>
+<span class="o">********+++++++++++++++++++++++++++++++++++++++++++..................</span>
+<span class="o">*******+++++++++++++++++++++++++++++++++++++++.......................</span>
+<span class="o">******+++++++++++++++++++++++++++++++++++...........................</span>
+<span class="o">*****++++++++++++++++++++++++++++++++............................</span>
+<span class="o">*****++++++++++++++++++++++++++++...............................</span>
+<span class="o">****++++++++++++++++++++++++++......</span> <span class="o">.........................</span>
+<span class="o">***++++++++++++++++++++++++.........</span> <span class="o">......</span> <span class="o">...........</span>
+<span class="o">***++++++++++++++++++++++............</span>
+<span class="o">**+++++++++++++++++++++..............</span>
+<span class="o">**+++++++++++++++++++................</span>
+<span class="o">*++++++++++++++++++.................</span>
+<span class="o">*++++++++++++++++............</span> <span class="o">...</span>
+<span class="o">*++++++++++++++..............</span>
+<span class="o">*+++....++++................</span>
+<span class="o">*..........</span> <span class="o">...........</span>
+<span class="o">*</span>
+<span class="o">*..........</span> <span class="o">...........</span>
+<span class="o">*+++....++++................</span>
+<span class="o">*++++++++++++++..............</span>
+<span class="o">*++++++++++++++++............</span> <span class="o">...</span>
+<span class="o">*++++++++++++++++++.................</span>
+<span class="o">**+++++++++++++++++++................</span>
+<span class="o">**+++++++++++++++++++++..............</span>
+<span class="o">***++++++++++++++++++++++............</span>
+<span class="o">***++++++++++++++++++++++++.........</span> <span class="o">......</span> <span class="o">...........</span>
+<span class="o">****++++++++++++++++++++++++++......</span> <span class="o">.........................</span>
+<span class="o">*****++++++++++++++++++++++++++++...............................</span>
+<span class="o">*****++++++++++++++++++++++++++++++++............................</span>
+<span class="o">******+++++++++++++++++++++++++++++++++++...........................</span>
+<span class="o">*******+++++++++++++++++++++++++++++++++++++++.......................</span>
+<span class="o">********+++++++++++++++++++++++++++++++++++++++++++..................</span>
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">0.000000</span>
+<span class="n">ready</span><span class="o">></span> <span class="n">mandel</span><span class="p">(</span><span class="o">-</span><span class="mf">0.9</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.4</span><span class="p">,</span> <span class="mf">0.02</span><span class="p">,</span> <span class="mf">0.03</span><span class="p">);</span>
+<span class="o">*******************************************************************************</span>
+<span class="o">*******************************************************************************</span>
+<span class="o">*******************************************************************************</span>
+<span class="o">**********+++++++++++++++++++++************************************************</span>
+<span class="o">*+++++++++++++++++++++++++++++++++++++++***************************************</span>
+<span class="o">+++++++++++++++++++++++++++++++++++++++++++++**********************************</span>
+<span class="o">++++++++++++++++++++++++++++++++++++++++++++++++++*****************************</span>
+<span class="o">++++++++++++++++++++++++++++++++++++++++++++++++++++++*************************</span>
+<span class="o">+++++++++++++++++++++++++++++++++++++++++++++++++++++++++**********************</span>
+<span class="o">+++++++++++++++++++++++++++++++++.........++++++++++++++++++*******************</span>
+<span class="o">+++++++++++++++++++++++++++++++....</span> <span class="o">......+++++++++++++++++++****************</span>
+<span class="o">+++++++++++++++++++++++++++++.......</span> <span class="o">........+++++++++++++++++++**************</span>
+<span class="o">++++++++++++++++++++++++++++........</span> <span class="o">........++++++++++++++++++++************</span>
+<span class="o">+++++++++++++++++++++++++++.........</span> <span class="o">..</span> <span class="o">...+++++++++++++++++++++**********</span>
+<span class="o">++++++++++++++++++++++++++...........</span> <span class="o">....++++++++++++++++++++++********</span>
+<span class="o">++++++++++++++++++++++++.............</span> <span class="o">.......++++++++++++++++++++++******</span>
+<span class="o">+++++++++++++++++++++++.............</span> <span class="o">........+++++++++++++++++++++++****</span>
+<span class="o">++++++++++++++++++++++...........</span> <span class="o">..........++++++++++++++++++++++***</span>
+<span class="o">++++++++++++++++++++...........</span> <span class="o">.........++++++++++++++++++++++*</span>
+<span class="o">++++++++++++++++++............</span> <span class="o">...........++++++++++++++++++++</span>
+<span class="o">++++++++++++++++...............</span> <span class="o">.............++++++++++++++++++</span>
+<span class="o">++++++++++++++.................</span> <span class="o">...............++++++++++++++++</span>
+<span class="o">++++++++++++..................</span> <span class="o">.................++++++++++++++</span>
+<span class="o">+++++++++..................</span> <span class="o">.................+++++++++++++</span>
+<span class="o">++++++........</span> <span class="o">.</span> <span class="o">.........</span> <span class="o">..++++++++++++</span>
+<span class="o">++............</span> <span class="o">......</span> <span class="o">....++++++++++</span>
+<span class="o">..............</span> <span class="o">...++++++++++</span>
+<span class="o">..............</span> <span class="o">....+++++++++</span>
+<span class="o">..............</span> <span class="o">.....++++++++</span>
+<span class="o">.............</span> <span class="o">......++++++++</span>
+<span class="o">...........</span> <span class="o">.......++++++++</span>
+<span class="o">.........</span> <span class="o">........+++++++</span>
+<span class="o">.........</span> <span class="o">........+++++++</span>
+<span class="o">.........</span> <span class="o">....+++++++</span>
+<span class="o">........</span> <span class="o">...+++++++</span>
+<span class="o">.......</span> <span class="o">...+++++++</span>
+ <span class="o">....+++++++</span>
+ <span class="o">.....+++++++</span>
+ <span class="o">....+++++++</span>
+ <span class="o">....+++++++</span>
+ <span class="o">....+++++++</span>
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">0.000000</span>
+<span class="n">ready</span><span class="o">></span> <span class="o">^</span><span class="n">D</span>
+</pre></div>
+</div>
+<p>At this point, you may be starting to realize that Kaleidoscope is a
+real and powerful language. It may not be self-similar :), but it can be
+used to plot things that are!</p>
+<p>With this, we conclude the âadding user-defined operatorsâ chapter of
+the tutorial. We have successfully augmented our language, adding the
+ability to extend the language in the library, and we have shown how
+this can be used to build a simple but interesting end-user application
+in Kaleidoscope. At this point, Kaleidoscope can build a variety of
+applications that are functional and can call functions with
+side-effects, but it canât actually define and mutate a variable itself.</p>
+<p>Strikingly, variable mutation is an important feature of some languages,
+and it is not at all obvious how to <a class="reference external" href="OCamlLangImpl7.html">add support for mutable
+variables</a> without having to add an âSSA
+constructionâ phase to your front-end. In the next chapter, we will
+describe how you can add variable mutation without building SSA in your
+front-end.</p>
+</div>
+<div class="section" id="full-code-listing">
+<h2><a class="toc-backref" href="#id6">6.6. Full Code Listing</a><a class="headerlink" href="#full-code-listing" title="Permalink to this headline">¶</a></h2>
+<p>Here is the complete code listing for our running example, enhanced with
+the if/then/else and for expressions.. To build this example, use:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># Compile</span>
+ocamlbuild toy.byte
+<span class="c1"># Run</span>
+./toy.byte
+</pre></div>
+</div>
+<p>Here is the code:</p>
+<dl class="docutils">
+<dt>_tags:</dt>
+<dd><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o"><</span><span class="p">{</span><span class="n">lexer</span><span class="p">,</span><span class="n">parser</span><span class="p">}</span><span class="o">.</span><span class="n">ml</span><span class="o">></span><span class="p">:</span> <span class="n">use_camlp4</span><span class="p">,</span> <span class="n">pp</span><span class="p">(</span><span class="n">camlp4of</span><span class="p">)</span>
+<span class="o"><*.</span><span class="p">{</span><span class="n">byte</span><span class="p">,</span><span class="n">native</span><span class="p">}</span><span class="o">></span><span class="p">:</span> <span class="n">g</span><span class="o">++</span><span class="p">,</span> <span class="n">use_llvm</span><span class="p">,</span> <span class="n">use_llvm_analysis</span>
+<span class="o"><*.</span><span class="p">{</span><span class="n">byte</span><span class="p">,</span><span class="n">native</span><span class="p">}</span><span class="o">></span><span class="p">:</span> <span class="n">use_llvm_executionengine</span><span class="p">,</span> <span class="n">use_llvm_target</span>
+<span class="o"><*.</span><span class="p">{</span><span class="n">byte</span><span class="p">,</span><span class="n">native</span><span class="p">}</span><span class="o">></span><span class="p">:</span> <span class="n">use_llvm_scalar_opts</span><span class="p">,</span> <span class="n">use_bindings</span>
+</pre></div>
+</div>
+</dd>
+<dt>myocamlbuild.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">open</span> <span class="nc">Ocamlbuild_plugin</span><span class="o">;;</span>
+
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_analysis"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_executionengine"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_target"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_scalar_opts"</span><span class="o">;;</span>
+
+<span class="n">flag</span> <span class="o">[</span><span class="s2">"link"</span><span class="o">;</span> <span class="s2">"ocaml"</span><span class="o">;</span> <span class="s2">"g++"</span><span class="o">]</span> <span class="o">(</span><span class="nc">S</span><span class="o">[</span><span class="nc">A</span><span class="s2">"-cc"</span><span class="o">;</span> <span class="nc">A</span><span class="s2">"g++"</span><span class="o">;</span> <span class="nc">A</span><span class="s2">"-cclib"</span><span class="o">;</span> <span class="nc">A</span><span class="s2">"-rdynamic"</span><span class="o">]);;</span>
+<span class="n">dep</span> <span class="o">[</span><span class="s2">"link"</span><span class="o">;</span> <span class="s2">"ocaml"</span><span class="o">;</span> <span class="s2">"use_bindings"</span><span class="o">]</span> <span class="o">[</span><span class="s2">"bindings.o"</span><span class="o">];;</span>
+</pre></div>
+</div>
+</dd>
+<dt>token.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Lexer Tokens</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="c">(* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of</span>
+<span class="c"> * these others for known things. *)</span>
+<span class="k">type</span> <span class="n">token</span> <span class="o">=</span>
+ <span class="c">(* commands *)</span>
+ <span class="o">|</span> <span class="nc">Def</span> <span class="o">|</span> <span class="nc">Extern</span>
+
+ <span class="c">(* primary *)</span>
+ <span class="o">|</span> <span class="nc">Ident</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">|</span> <span class="nc">Number</span> <span class="k">of</span> <span class="kt">float</span>
+
+ <span class="c">(* unknown *)</span>
+ <span class="o">|</span> <span class="nc">Kwd</span> <span class="k">of</span> <span class="kt">char</span>
+
+ <span class="c">(* control *)</span>
+ <span class="o">|</span> <span class="nc">If</span> <span class="o">|</span> <span class="nc">Then</span> <span class="o">|</span> <span class="nc">Else</span>
+ <span class="o">|</span> <span class="nc">For</span> <span class="o">|</span> <span class="nc">In</span>
+
+ <span class="c">(* operators *)</span>
+ <span class="o">|</span> <span class="nc">Binary</span> <span class="o">|</span> <span class="nc">Unary</span>
+</pre></div>
+</div>
+</dd>
+<dt>lexer.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Lexer</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">let</span> <span class="k">rec</span> <span class="n">lex</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* Skip any whitespace. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">' '</span> <span class="o">|</span> <span class="sc">'\n'</span> <span class="o">|</span> <span class="sc">'\r'</span> <span class="o">|</span> <span class="sc">'\t'</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">lex</span> <span class="n">stream</span>
+
+ <span class="c">(* identifier: [a-zA-Z][a-zA-Z0-9] *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'A'</span> <span class="o">..</span> <span class="sc">'Z'</span> <span class="o">|</span> <span class="sc">'a'</span> <span class="o">..</span> <span class="sc">'z'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">buffer</span> <span class="o">=</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">create</span> <span class="mi">1</span> <span class="k">in</span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="n">stream</span>
+
+ <span class="c">(* number: [0-9.]+ *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'0'</span> <span class="o">..</span> <span class="sc">'9'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">buffer</span> <span class="o">=</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">create</span> <span class="mi">1</span> <span class="k">in</span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_number</span> <span class="n">buffer</span> <span class="n">stream</span>
+
+ <span class="c">(* Comment until end of line. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'#'</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="n">lex_comment</span> <span class="n">stream</span>
+
+ <span class="c">(* Otherwise, just return the character as its ascii value. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="n">c</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">c</span><span class="o">;</span> <span class="n">lex</span> <span class="n">stream</span> <span class="o">>]</span>
+
+ <span class="c">(* end of stream. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="o">[<</span> <span class="o">>]</span>
+
+<span class="ow">and</span> <span class="n">lex_number</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'0'</span> <span class="o">..</span> <span class="sc">'9'</span> <span class="o">|</span> <span class="sc">'.'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_number</span> <span class="n">buffer</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">stream</span><span class="o">=</span><span class="n">lex</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="o">(</span><span class="n">float_of_string</span> <span class="o">(</span><span class="nn">Buffer</span><span class="p">.</span><span class="n">contents</span> <span class="n">buffer</span><span class="o">));</span> <span class="n">stream</span> <span class="o">>]</span>
+
+<span class="ow">and</span> <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'A'</span> <span class="o">..</span> <span class="sc">'Z'</span> <span class="o">|</span> <span class="sc">'a'</span> <span class="o">..</span> <span class="sc">'z'</span> <span class="o">|</span> <span class="sc">'0'</span> <span class="o">..</span> <span class="sc">'9'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">stream</span><span class="o">=</span><span class="n">lex</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">match</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">contents</span> <span class="n">buffer</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="s2">"def"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"extern"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"if"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">If</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"then"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Then</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"else"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Else</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"for"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"in"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"binary"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Binary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"unary"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Unary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="n">id</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+
+<span class="ow">and</span> <span class="n">lex_comment</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'\n'</span><span class="o">);</span> <span class="n">stream</span><span class="o">=</span><span class="n">lex</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="n">c</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">lex_comment</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="o">[<</span> <span class="o">>]</span>
+</pre></div>
+</div>
+</dd>
+<dt>ast.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Abstract Syntax Tree (aka Parse Tree)</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="c">(* expr - Base type for all expression nodes. *)</span>
+<span class="k">type</span> <span class="n">expr</span> <span class="o">=</span>
+ <span class="c">(* variant for numeric literals like "1.0". *)</span>
+ <span class="o">|</span> <span class="nc">Number</span> <span class="k">of</span> <span class="kt">float</span>
+
+ <span class="c">(* variant for referencing a variable, like "a". *)</span>
+ <span class="o">|</span> <span class="nc">Variable</span> <span class="k">of</span> <span class="kt">string</span>
+
+ <span class="c">(* variant for a unary operator. *)</span>
+ <span class="o">|</span> <span class="nc">Unary</span> <span class="k">of</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">expr</span>
+
+ <span class="c">(* variant for a binary operator. *)</span>
+ <span class="o">|</span> <span class="nc">Binary</span> <span class="k">of</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span>
+
+ <span class="c">(* variant for function calls. *)</span>
+ <span class="o">|</span> <span class="nc">Call</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="n">expr</span> <span class="kt">array</span>
+
+ <span class="c">(* variant for if/then/else. *)</span>
+ <span class="o">|</span> <span class="nc">If</span> <span class="k">of</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span>
+
+ <span class="c">(* variant for for/in. *)</span>
+ <span class="o">|</span> <span class="nc">For</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="n">option</span> <span class="o">*</span> <span class="n">expr</span>
+
+<span class="c">(* proto - This type represents the "prototype" for a function, which captures</span>
+<span class="c"> * its name, and its argument names (thus implicitly the number of arguments the</span>
+<span class="c"> * function takes). *)</span>
+<span class="k">type</span> <span class="n">proto</span> <span class="o">=</span>
+ <span class="o">|</span> <span class="nc">Prototype</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="kt">string</span> <span class="kt">array</span>
+ <span class="o">|</span> <span class="nc">BinOpPrototype</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="kt">string</span> <span class="kt">array</span> <span class="o">*</span> <span class="kt">int</span>
+
+<span class="c">(* func - This type represents a function definition itself. *)</span>
+<span class="k">type</span> <span class="n">func</span> <span class="o">=</span> <span class="nc">Function</span> <span class="k">of</span> <span class="n">proto</span> <span class="o">*</span> <span class="n">expr</span>
+</pre></div>
+</div>
+</dd>
+<dt>parser.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===---------------------------------------------------------------------===</span>
+<span class="c"> * Parser</span>
+<span class="c"> *===---------------------------------------------------------------------===*)</span>
+
+<span class="c">(* binop_precedence - This holds the precedence for each binary operator that is</span>
+<span class="c"> * defined *)</span>
+<span class="k">let</span> <span class="n">binop_precedence</span><span class="o">:(</span><span class="kt">char</span><span class="o">,</span> <span class="kt">int</span><span class="o">)</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">t</span> <span class="o">=</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">create</span> <span class="mi">10</span>
+
+<span class="c">(* precedence - Get the precedence of the pending binary operator token. *)</span>
+<span class="k">let</span> <span class="n">precedence</span> <span class="n">c</span> <span class="o">=</span> <span class="k">try</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">binop_precedence</span> <span class="n">c</span> <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="o">-</span><span class="mi">1</span>
+
+<span class="c">(* primary</span>
+<span class="c"> * ::= identifier</span>
+<span class="c"> * ::= numberexpr</span>
+<span class="c"> * ::= parenexpr</span>
+<span class="c"> * ::= ifexpr</span>
+<span class="c"> * ::= forexpr *)</span>
+<span class="k">let</span> <span class="k">rec</span> <span class="n">parse_primary</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* numberexpr ::= number *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">>]</span> <span class="o">-></span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span>
+
+ <span class="c">(* parenexpr ::= '(' expression ')' *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')'"</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+
+ <span class="c">(* identifierexpr</span>
+<span class="c"> * ::= identifier</span>
+<span class="c"> * ::= identifier '(' argumentexpr ')' *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_args</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_args</span> <span class="o">(</span><span class="n">e</span> <span class="o">::</span> <span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span> <span class="o">::</span> <span class="n">accumulator</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_ident</span> <span class="n">id</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* Call. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')'"</span><span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Call</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">))</span>
+
+ <span class="c">(* Simple variable ref. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Variable</span> <span class="n">id</span>
+ <span class="k">in</span>
+ <span class="n">parse_ident</span> <span class="n">id</span> <span class="n">stream</span>
+
+ <span class="c">(* ifexpr ::= 'if' expr 'then' expr 'else' expr *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">If</span><span class="o">;</span> <span class="n">c</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Then</span> <span class="o">??</span> <span class="s2">"expected 'then'"</span><span class="o">;</span> <span class="n">t</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Else</span> <span class="o">??</span> <span class="s2">"expected 'else'"</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">If</span> <span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="n">t</span><span class="o">,</span> <span class="n">e</span><span class="o">)</span>
+
+ <span class="c">(* forexpr</span>
+<span class="c"> ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span> <span class="o">??</span> <span class="s2">"expected identifier after for"</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'='</span> <span class="o">??</span> <span class="s2">"expected '=' after for"</span><span class="o">;</span>
+ <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span>
+ <span class="n">start</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span> <span class="o">??</span> <span class="s2">"expected ',' after for"</span><span class="o">;</span>
+ <span class="n">end_</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">step</span> <span class="o">=</span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span><span class="o">;</span> <span class="n">step</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">Some</span> <span class="n">step</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">None</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="k">in</span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">body</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">For</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">end_</span><span class="o">,</span> <span class="n">step</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected 'in' after for"</span><span class="o">)</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected '=' after for"</span><span class="o">)</span>
+ <span class="k">end</span> <span class="n">stream</span>
+
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"unknown token when expecting an expression."</span><span class="o">)</span>
+
+<span class="c">(* unary</span>
+<span class="c"> * ::= primary</span>
+<span class="c"> * ::= '!' unary *)</span>
+<span class="ow">and</span> <span class="n">parse_unary</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* If this is a unary operator, read it. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">op</span> <span class="k">when</span> <span class="n">op</span> <span class="o">!=</span> <span class="sc">'('</span> <span class="o">&&</span> <span class="n">op</span> <span class="o">!=</span> <span class="sc">')'</span><span class="o">;</span> <span class="n">operand</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">operand</span><span class="o">)</span>
+
+ <span class="c">(* If the current token is not an operator, it must be a primary expr. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">parse_primary</span> <span class="n">stream</span>
+
+<span class="c">(* binoprhs</span>
+<span class="c"> * ::= ('+' primary)* *)</span>
+<span class="ow">and</span> <span class="n">parse_bin_rhs</span> <span class="n">expr_prec</span> <span class="n">lhs</span> <span class="n">stream</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="nn">Stream</span><span class="p">.</span><span class="n">peek</span> <span class="n">stream</span> <span class="k">with</span>
+ <span class="c">(* If this is a binop, find its precedence. *)</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">c</span><span class="o">)</span> <span class="k">when</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">mem</span> <span class="n">binop_precedence</span> <span class="n">c</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">token_prec</span> <span class="o">=</span> <span class="n">precedence</span> <span class="n">c</span> <span class="k">in</span>
+
+ <span class="c">(* If this is a binop that binds at least as tightly as the current binop,</span>
+<span class="c"> * consume it, otherwise we are done. *)</span>
+ <span class="k">if</span> <span class="n">token_prec</span> <span class="o"><</span> <span class="n">expr_prec</span> <span class="k">then</span> <span class="n">lhs</span> <span class="k">else</span> <span class="k">begin</span>
+ <span class="c">(* Eat the binop. *)</span>
+ <span class="nn">Stream</span><span class="p">.</span><span class="n">junk</span> <span class="n">stream</span><span class="o">;</span>
+
+ <span class="c">(* Parse the unary expression after the binary operator. *)</span>
+ <span class="k">let</span> <span class="n">rhs</span> <span class="o">=</span> <span class="n">parse_unary</span> <span class="n">stream</span> <span class="k">in</span>
+
+ <span class="c">(* Okay, we know this is a binop. *)</span>
+ <span class="k">let</span> <span class="n">rhs</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="nn">Stream</span><span class="p">.</span><span class="n">peek</span> <span class="n">stream</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">c2</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* If BinOp binds less tightly with rhs than the operator after</span>
+<span class="c"> * rhs, let the pending operator take rhs as its lhs. *)</span>
+ <span class="k">let</span> <span class="n">next_prec</span> <span class="o">=</span> <span class="n">precedence</span> <span class="n">c2</span> <span class="k">in</span>
+ <span class="k">if</span> <span class="n">token_prec</span> <span class="o"><</span> <span class="n">next_prec</span>
+ <span class="k">then</span> <span class="n">parse_bin_rhs</span> <span class="o">(</span><span class="n">token_prec</span> <span class="o">+</span> <span class="mi">1</span><span class="o">)</span> <span class="n">rhs</span> <span class="n">stream</span>
+ <span class="k">else</span> <span class="n">rhs</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="n">rhs</span>
+ <span class="k">in</span>
+
+ <span class="c">(* Merge lhs/rhs. *)</span>
+ <span class="k">let</span> <span class="n">lhs</span> <span class="o">=</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="n">lhs</span><span class="o">,</span> <span class="n">rhs</span><span class="o">)</span> <span class="k">in</span>
+ <span class="n">parse_bin_rhs</span> <span class="n">expr_prec</span> <span class="n">lhs</span> <span class="n">stream</span>
+ <span class="k">end</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="n">lhs</span>
+
+<span class="c">(* expression</span>
+<span class="c"> * ::= primary binoprhs *)</span>
+<span class="ow">and</span> <span class="n">parse_expr</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">lhs</span><span class="o">=</span><span class="n">parse_unary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">parse_bin_rhs</span> <span class="mi">0</span> <span class="n">lhs</span> <span class="n">stream</span>
+
+<span class="c">(* prototype</span>
+<span class="c"> * ::= id '(' id* ')'</span>
+<span class="c"> * ::= binary LETTER number? (id, id)</span>
+<span class="c"> * ::= unary LETTER number? (id) *)</span>
+<span class="k">let</span> <span class="n">parse_prototype</span> <span class="o">=</span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_args</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_args</span> <span class="o">(</span><span class="n">id</span><span class="o">::</span><span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">parse_operator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">>]</span> <span class="o">-></span> <span class="s2">"unary"</span><span class="o">,</span> <span class="mi">1</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">>]</span> <span class="o">-></span> <span class="s2">"binary"</span><span class="o">,</span> <span class="mi">2</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">parse_binary_precedence</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">int_of_float</span> <span class="n">n</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="mi">30</span>
+ <span class="k">in</span>
+ <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span> <span class="o">??</span> <span class="s2">"expected '(' in prototype"</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')' in prototype"</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="c">(* success. *)</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">))</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">(</span><span class="n">prefix</span><span class="o">,</span> <span class="n">kind</span><span class="o">)=</span><span class="n">parse_operator</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">op</span> <span class="o">??</span> <span class="s2">"expected an operator"</span><span class="o">;</span>
+ <span class="c">(* Read the precedence if present. *)</span>
+ <span class="n">binary_precedence</span><span class="o">=</span><span class="n">parse_binary_precedence</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span> <span class="o">??</span> <span class="s2">"expected '(' in prototype"</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')' in prototype"</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">name</span> <span class="o">=</span> <span class="n">prefix</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">args</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Verify right number of arguments for operator. *)</span>
+ <span class="k">if</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span> <span class="o">!=</span> <span class="n">kind</span>
+ <span class="k">then</span> <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"invalid number of operands for operator"</span><span class="o">)</span>
+ <span class="k">else</span>
+ <span class="k">if</span> <span class="n">kind</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">then</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span>
+ <span class="k">else</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">,</span> <span class="n">binary_precedence</span><span class="o">)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected function name in prototype"</span><span class="o">)</span>
+
+<span class="c">(* definition ::= 'def' prototype expression *)</span>
+<span class="k">let</span> <span class="n">parse_definition</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span><span class="o">;</span> <span class="n">p</span><span class="o">=</span><span class="n">parse_prototype</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="n">p</span><span class="o">,</span> <span class="n">e</span><span class="o">)</span>
+
+<span class="c">(* toplevelexpr ::= expression *)</span>
+<span class="k">let</span> <span class="n">parse_toplevel</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="c">(* Make an anonymous proto. *)</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="s2">""</span><span class="o">,</span> <span class="o">[||]),</span> <span class="n">e</span><span class="o">)</span>
+
+<span class="c">(* external ::= 'extern' prototype *)</span>
+<span class="k">let</span> <span class="n">parse_extern</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_prototype</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+</pre></div>
+</div>
+</dd>
+<dt>codegen.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Code Generation</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">open</span> <span class="nc">Llvm</span>
+
+<span class="k">exception</span> <span class="nc">Error</span> <span class="k">of</span> <span class="kt">string</span>
+
+<span class="k">let</span> <span class="n">context</span> <span class="o">=</span> <span class="n">global_context</span> <span class="bp">()</span>
+<span class="k">let</span> <span class="n">the_module</span> <span class="o">=</span> <span class="n">create_module</span> <span class="n">context</span> <span class="s2">"my cool jit"</span>
+<span class="k">let</span> <span class="n">builder</span> <span class="o">=</span> <span class="n">builder</span> <span class="n">context</span>
+<span class="k">let</span> <span class="n">named_values</span><span class="o">:(</span><span class="kt">string</span><span class="o">,</span> <span class="n">llvalue</span><span class="o">)</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">t</span> <span class="o">=</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">create</span> <span class="mi">10</span>
+<span class="k">let</span> <span class="n">double_type</span> <span class="o">=</span> <span class="n">double_type</span> <span class="n">context</span>
+
+<span class="k">let</span> <span class="k">rec</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">-></span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="n">n</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Variable</span> <span class="n">name</span> <span class="o">-></span>
+ <span class="o">(</span><span class="k">try</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">name</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown variable name"</span><span class="o">))</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">operand</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">operand</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">operand</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span> <span class="s2">"unary"</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">callee</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">callee</span> <span class="o">-></span> <span class="n">callee</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown unary operator"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="n">build_call</span> <span class="n">callee</span> <span class="o">[|</span><span class="n">operand</span><span class="o">|]</span> <span class="s2">"unop"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">lhs</span><span class="o">,</span> <span class="n">rhs</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">lhs_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">lhs</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">rhs_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">rhs</span> <span class="k">in</span>
+ <span class="k">begin</span>
+ <span class="k">match</span> <span class="n">op</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="sc">'+'</span> <span class="o">-></span> <span class="n">build_add</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"addtmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'-'</span> <span class="o">-></span> <span class="n">build_sub</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"subtmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'*'</span> <span class="o">-></span> <span class="n">build_mul</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"multmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'<'</span> <span class="o">-></span>
+ <span class="c">(* Convert bool 0/1 to double 0.0 or 1.0 *)</span>
+ <span class="k">let</span> <span class="n">i</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">Ult</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"cmptmp"</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="n">build_uitofp</span> <span class="n">i</span> <span class="n">double_type</span> <span class="s2">"booltmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span>
+ <span class="c">(* If it wasn't a builtin binary operator, it must be a user defined</span>
+<span class="c"> * one. Emit a call to it. *)</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span> <span class="s2">"binary"</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">callee</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">callee</span> <span class="o">-></span> <span class="n">callee</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"binary operator not found!"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="n">build_call</span> <span class="n">callee</span> <span class="o">[|</span><span class="n">lhs_val</span><span class="o">;</span> <span class="n">rhs_val</span><span class="o">|]</span> <span class="s2">"binop"</span> <span class="n">builder</span>
+ <span class="k">end</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Call</span> <span class="o">(</span><span class="n">callee</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* Look up the name in the module table. *)</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">callee</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">callee</span> <span class="o">-></span> <span class="n">callee</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown function referenced"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">params</span> <span class="o">=</span> <span class="n">params</span> <span class="n">callee</span> <span class="k">in</span>
+
+ <span class="c">(* If argument mismatch error. *)</span>
+ <span class="k">if</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">params</span> <span class="o">==</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span> <span class="k">then</span> <span class="bp">()</span> <span class="k">else</span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"incorrect # arguments passed"</span><span class="o">);</span>
+ <span class="k">let</span> <span class="n">args</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">map</span> <span class="n">codegen_expr</span> <span class="n">args</span> <span class="k">in</span>
+ <span class="n">build_call</span> <span class="n">callee</span> <span class="n">args</span> <span class="s2">"calltmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">If</span> <span class="o">(</span><span class="n">cond</span><span class="o">,</span> <span class="n">then_</span><span class="o">,</span> <span class="n">else_</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">cond</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">cond</span> <span class="k">in</span>
+
+ <span class="c">(* Convert condition to a bool by comparing equal to 0.0 *)</span>
+ <span class="k">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">cond_val</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">One</span> <span class="n">cond</span> <span class="n">zero</span> <span class="s2">"ifcond"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Grab the first block so that we might later add the conditional branch</span>
+<span class="c"> * to it at the end of the function. *)</span>
+ <span class="k">let</span> <span class="n">start_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="n">start_bb</span> <span class="k">in</span>
+
+ <span class="k">let</span> <span class="n">then_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"then"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+ <span class="c">(* Emit 'then' value. *)</span>
+ <span class="n">position_at_end</span> <span class="n">then_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">then_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">then_</span> <span class="k">in</span>
+
+ <span class="c">(* Codegen of 'then' can change the current block, update then_bb for the</span>
+<span class="c"> * phi. We create a new name because one is used for the phi node, and the</span>
+<span class="c"> * other is used for the conditional branch. *)</span>
+ <span class="k">let</span> <span class="n">new_then_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Emit 'else' value. *)</span>
+ <span class="k">let</span> <span class="n">else_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"else"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">else_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">else_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">else_</span> <span class="k">in</span>
+
+ <span class="c">(* Codegen of 'else' can change the current block, update else_bb for the</span>
+<span class="c"> * phi. *)</span>
+ <span class="k">let</span> <span class="n">new_else_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Emit merge block. *)</span>
+ <span class="k">let</span> <span class="n">merge_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"ifcont"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">incoming</span> <span class="o">=</span> <span class="o">[(</span><span class="n">then_val</span><span class="o">,</span> <span class="n">new_then_bb</span><span class="o">);</span> <span class="o">(</span><span class="n">else_val</span><span class="o">,</span> <span class="n">new_else_bb</span><span class="o">)]</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">phi</span> <span class="o">=</span> <span class="n">build_phi</span> <span class="n">incoming</span> <span class="s2">"iftmp"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Return to the start block to add the conditional branch. *)</span>
+ <span class="n">position_at_end</span> <span class="n">start_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">build_cond_br</span> <span class="n">cond_val</span> <span class="n">then_bb</span> <span class="n">else_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Set a unconditional branch at the end of the 'then' block and the</span>
+<span class="c"> * 'else' block to the 'merge' block. *)</span>
+ <span class="n">position_at_end</span> <span class="n">new_then_bb</span> <span class="n">builder</span><span class="o">;</span> <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">);</span>
+ <span class="n">position_at_end</span> <span class="n">new_else_bb</span> <span class="n">builder</span><span class="o">;</span> <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Finally, set the builder to the end of the merge block. *)</span>
+ <span class="n">position_at_end</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="n">phi</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">For</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">end_</span><span class="o">,</span> <span class="n">step</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* Emit the start code first, without 'variable' in scope. *)</span>
+ <span class="k">let</span> <span class="n">start_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">start</span> <span class="k">in</span>
+
+ <span class="c">(* Make the new basic block for the loop header, inserting after current</span>
+<span class="c"> * block. *)</span>
+ <span class="k">let</span> <span class="n">preheader_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="n">preheader_bb</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">loop_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"loop"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+ <span class="c">(* Insert an explicit fall through from the current block to the</span>
+<span class="c"> * loop_bb. *)</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">loop_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Start insertion in loop_bb. *)</span>
+ <span class="n">position_at_end</span> <span class="n">loop_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="c">(* Start the PHI node with an entry for start. *)</span>
+ <span class="k">let</span> <span class="n">variable</span> <span class="o">=</span> <span class="n">build_phi</span> <span class="o">[(</span><span class="n">start_val</span><span class="o">,</span> <span class="n">preheader_bb</span><span class="o">)]</span> <span class="n">var_name</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Within the loop, the variable is defined equal to the PHI node. If it</span>
+<span class="c"> * shadows an existing variable, we have to restore it, so save it</span>
+<span class="c"> * now. *)</span>
+ <span class="k">let</span> <span class="n">old_val</span> <span class="o">=</span>
+ <span class="k">try</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">var_name</span><span class="o">)</span> <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="nc">None</span>
+ <span class="k">in</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">variable</span><span class="o">;</span>
+
+ <span class="c">(* Emit the body of the loop. This, like any other expr, can change the</span>
+<span class="c"> * current BB. Note that we ignore the value computed by the body, but</span>
+<span class="c"> * don't allow an error *)</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">codegen_expr</span> <span class="n">body</span><span class="o">);</span>
+
+ <span class="c">(* Emit the step value. *)</span>
+ <span class="k">let</span> <span class="n">step_val</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">step</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">step</span> <span class="o">-></span> <span class="n">codegen_expr</span> <span class="n">step</span>
+ <span class="c">(* If not specified, use 1.0. *)</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">1</span><span class="o">.</span><span class="mi">0</span>
+ <span class="k">in</span>
+
+ <span class="k">let</span> <span class="n">next_var</span> <span class="o">=</span> <span class="n">build_add</span> <span class="n">variable</span> <span class="n">step_val</span> <span class="s2">"nextvar"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Compute the end condition. *)</span>
+ <span class="k">let</span> <span class="n">end_cond</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">end_</span> <span class="k">in</span>
+
+ <span class="c">(* Convert condition to a bool by comparing equal to 0.0. *)</span>
+ <span class="k">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">end_cond</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">One</span> <span class="n">end_cond</span> <span class="n">zero</span> <span class="s2">"loopcond"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Create the "after loop" block and insert it. *)</span>
+ <span class="k">let</span> <span class="n">loop_end_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">after_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"afterloop"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+ <span class="c">(* Insert the conditional branch into the end of loop_end_bb. *)</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">build_cond_br</span> <span class="n">end_cond</span> <span class="n">loop_bb</span> <span class="n">after_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Any new code will be inserted in after_bb. *)</span>
+ <span class="n">position_at_end</span> <span class="n">after_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="c">(* Add a new entry to the PHI node for the backedge. *)</span>
+ <span class="n">add_incoming</span> <span class="o">(</span><span class="n">next_var</span><span class="o">,</span> <span class="n">loop_end_bb</span><span class="o">)</span> <span class="n">variable</span><span class="o">;</span>
+
+ <span class="c">(* Restore the unshadowed variable. *)</span>
+ <span class="k">begin</span> <span class="k">match</span> <span class="n">old_val</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">old_val</span> <span class="o">-></span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">old_val</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="bp">()</span>
+ <span class="k">end</span><span class="o">;</span>
+
+ <span class="c">(* for expr always returns 0.0. *)</span>
+ <span class="n">const_null</span> <span class="n">double_type</span>
+
+<span class="k">let</span> <span class="n">codegen_proto</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span> <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">,</span> <span class="o">_)</span> <span class="o">-></span>
+ <span class="c">(* Make the function type: double(double,double) etc. *)</span>
+ <span class="k">let</span> <span class="n">doubles</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">make</span> <span class="o">(</span><span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span><span class="o">)</span> <span class="n">double_type</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">ft</span> <span class="o">=</span> <span class="n">function_type</span> <span class="n">double_type</span> <span class="n">doubles</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">f</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">name</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="n">declare_function</span> <span class="n">name</span> <span class="n">ft</span> <span class="n">the_module</span>
+
+ <span class="c">(* If 'f' conflicted, there was already something named 'name'. If it</span>
+<span class="c"> * has a body, don't allow redefinition or reextern. *)</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">f</span> <span class="o">-></span>
+ <span class="c">(* If 'f' already has a body, reject this. *)</span>
+ <span class="k">if</span> <span class="n">block_begin</span> <span class="n">f</span> <span class="o"><></span> <span class="nc">At_end</span> <span class="n">f</span> <span class="k">then</span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"redefinition of function"</span><span class="o">);</span>
+
+ <span class="c">(* If 'f' took a different number of arguments, reject. *)</span>
+ <span class="k">if</span> <span class="n">element_type</span> <span class="o">(</span><span class="n">type_of</span> <span class="n">f</span><span class="o">)</span> <span class="o"><></span> <span class="n">ft</span> <span class="k">then</span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"redefinition of function with different # args"</span><span class="o">);</span>
+ <span class="n">f</span>
+ <span class="k">in</span>
+
+ <span class="c">(* Set names for all arguments. *)</span>
+ <span class="nn">Array</span><span class="p">.</span><span class="n">iteri</span> <span class="o">(</span><span class="k">fun</span> <span class="n">i</span> <span class="n">a</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">n</span> <span class="o">=</span> <span class="n">args</span><span class="o">.(</span><span class="n">i</span><span class="o">)</span> <span class="k">in</span>
+ <span class="n">set_value_name</span> <span class="n">n</span> <span class="n">a</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">n</span> <span class="n">a</span><span class="o">;</span>
+ <span class="o">)</span> <span class="o">(</span><span class="n">params</span> <span class="n">f</span><span class="o">);</span>
+ <span class="n">f</span>
+
+<span class="k">let</span> <span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="n">proto</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">clear</span> <span class="n">named_values</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">codegen_proto</span> <span class="n">proto</span> <span class="k">in</span>
+
+ <span class="c">(* If this is an operator, install it. *)</span>
+ <span class="k">begin</span> <span class="k">match</span> <span class="n">proto</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">,</span> <span class="n">prec</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">op</span> <span class="o">=</span> <span class="n">name</span><span class="o">.[</span><span class="nn">String</span><span class="p">.</span><span class="n">length</span> <span class="n">name</span> <span class="o">-</span> <span class="mi">1</span><span class="o">]</span> <span class="k">in</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="n">op</span> <span class="n">prec</span><span class="o">;</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="bp">()</span>
+ <span class="k">end</span><span class="o">;</span>
+
+ <span class="c">(* Create a new basic block to start insertion into. *)</span>
+ <span class="k">let</span> <span class="n">bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"entry"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="k">try</span>
+ <span class="k">let</span> <span class="n">ret_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">body</span> <span class="k">in</span>
+
+ <span class="c">(* Finish off the function. *)</span>
+ <span class="k">let</span> <span class="o">_</span> <span class="o">=</span> <span class="n">build_ret</span> <span class="n">ret_val</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Validate the generated code, checking for consistency. *)</span>
+ <span class="nn">Llvm_analysis</span><span class="p">.</span><span class="n">assert_valid_function</span> <span class="n">the_function</span><span class="o">;</span>
+
+ <span class="c">(* Optimize the function. *)</span>
+ <span class="k">let</span> <span class="o">_</span> <span class="o">=</span> <span class="nn">PassManager</span><span class="p">.</span><span class="n">run_function</span> <span class="n">the_function</span> <span class="n">the_fpm</span> <span class="k">in</span>
+
+ <span class="n">the_function</span>
+ <span class="k">with</span> <span class="n">e</span> <span class="o">-></span>
+ <span class="n">delete_function</span> <span class="n">the_function</span><span class="o">;</span>
+ <span class="k">raise</span> <span class="n">e</span>
+</pre></div>
+</div>
+</dd>
+<dt>toplevel.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Top-Level parsing and JIT Driver</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">open</span> <span class="nc">Llvm</span>
+<span class="k">open</span> <span class="nc">Llvm_executionengine</span>
+
+<span class="c">(* top ::= definition | external | expression | ';' *)</span>
+<span class="k">let</span> <span class="k">rec</span> <span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="nn">Stream</span><span class="p">.</span><span class="n">peek</span> <span class="n">stream</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="bp">()</span>
+
+ <span class="c">(* ignore top-level semicolons. *)</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">';'</span><span class="o">)</span> <span class="o">-></span>
+ <span class="nn">Stream</span><span class="p">.</span><span class="n">junk</span> <span class="n">stream</span><span class="o">;</span>
+ <span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span>
+
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">token</span> <span class="o">-></span>
+ <span class="k">begin</span>
+ <span class="k">try</span> <span class="k">match</span> <span class="n">token</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">e</span> <span class="o">=</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">parse_definition</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="n">print_endline</span> <span class="s2">"parsed a function definition."</span><span class="o">;</span>
+ <span class="n">dump_value</span> <span class="o">(</span><span class="nn">Codegen</span><span class="p">.</span><span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="n">e</span><span class="o">);</span>
+ <span class="o">|</span> <span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">e</span> <span class="o">=</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">parse_extern</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="n">print_endline</span> <span class="s2">"parsed an extern."</span><span class="o">;</span>
+ <span class="n">dump_value</span> <span class="o">(</span><span class="nn">Codegen</span><span class="p">.</span><span class="n">codegen_proto</span> <span class="n">e</span><span class="o">);</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span>
+ <span class="c">(* Evaluate a top-level expression into an anonymous function. *)</span>
+ <span class="k">let</span> <span class="n">e</span> <span class="o">=</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">parse_toplevel</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="n">print_endline</span> <span class="s2">"parsed a top-level expr"</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="n">e</span> <span class="k">in</span>
+ <span class="n">dump_value</span> <span class="n">the_function</span><span class="o">;</span>
+
+ <span class="c">(* JIT the function, returning a function pointer. *)</span>
+ <span class="k">let</span> <span class="n">result</span> <span class="o">=</span> <span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">run_function</span> <span class="n">the_function</span> <span class="o">[||]</span>
+ <span class="n">the_execution_engine</span> <span class="k">in</span>
+
+ <span class="n">print_string</span> <span class="s2">"Evaluated to "</span><span class="o">;</span>
+ <span class="n">print_float</span> <span class="o">(</span><span class="nn">GenericValue</span><span class="p">.</span><span class="n">as_float</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">double_type</span> <span class="n">result</span><span class="o">);</span>
+ <span class="n">print_newline</span> <span class="bp">()</span><span class="o">;</span>
+ <span class="k">with</span> <span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="n">s</span> <span class="o">|</span> <span class="nn">Codegen</span><span class="p">.</span><span class="nc">Error</span> <span class="n">s</span> <span class="o">-></span>
+ <span class="c">(* Skip token for error recovery. *)</span>
+ <span class="nn">Stream</span><span class="p">.</span><span class="n">junk</span> <span class="n">stream</span><span class="o">;</span>
+ <span class="n">print_endline</span> <span class="n">s</span><span class="o">;</span>
+ <span class="k">end</span><span class="o">;</span>
+ <span class="n">print_string</span> <span class="s2">"ready> "</span><span class="o">;</span> <span class="n">flush</span> <span class="n">stdout</span><span class="o">;</span>
+ <span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span>
+</pre></div>
+</div>
+</dd>
+<dt>toy.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Main driver code.</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">open</span> <span class="nc">Llvm</span>
+<span class="k">open</span> <span class="nc">Llvm_executionengine</span>
+<span class="k">open</span> <span class="nc">Llvm_target</span>
+<span class="k">open</span> <span class="nc">Llvm_scalar_opts</span>
+
+<span class="k">let</span> <span class="n">main</span> <span class="bp">()</span> <span class="o">=</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">initialize_native_target</span> <span class="bp">()</span><span class="o">);</span>
+
+ <span class="c">(* Install standard binary operators.</span>
+<span class="c"> * 1 is the lowest precedence. *)</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'<'</span> <span class="mi">10</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'+'</span> <span class="mi">20</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'-'</span> <span class="mi">20</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'*'</span> <span class="mi">40</span><span class="o">;</span> <span class="c">(* highest. *)</span>
+
+ <span class="c">(* Prime the first token. *)</span>
+ <span class="n">print_string</span> <span class="s2">"ready> "</span><span class="o">;</span> <span class="n">flush</span> <span class="n">stdout</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">stream</span> <span class="o">=</span> <span class="nn">Lexer</span><span class="p">.</span><span class="n">lex</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="n">of_channel</span> <span class="n">stdin</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Create the JIT. *)</span>
+ <span class="k">let</span> <span class="n">the_execution_engine</span> <span class="o">=</span> <span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">create</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">the_fpm</span> <span class="o">=</span> <span class="nn">PassManager</span><span class="p">.</span><span class="n">create_function</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span> <span class="k">in</span>
+
+ <span class="c">(* Set up the optimizer pipeline. Start with registering info about how the</span>
+<span class="c"> * target lays out data structures. *)</span>
+ <span class="nn">DataLayout</span><span class="p">.</span><span class="n">add</span> <span class="o">(</span><span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">target_data</span> <span class="n">the_execution_engine</span><span class="o">)</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Do simple "peephole" optimizations and bit-twiddling optzn. *)</span>
+ <span class="n">add_instruction_combination</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* reassociate expressions. *)</span>
+ <span class="n">add_reassociation</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Eliminate Common SubExpressions. *)</span>
+ <span class="n">add_gvn</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Simplify the control flow graph (deleting unreachable blocks, etc). *)</span>
+ <span class="n">add_cfg_simplification</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="n">ignore</span> <span class="o">(</span><span class="nn">PassManager</span><span class="p">.</span><span class="n">initialize</span> <span class="n">the_fpm</span><span class="o">);</span>
+
+ <span class="c">(* Run the main "interpreter loop" now. *)</span>
+ <span class="nn">Toplevel</span><span class="p">.</span><span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span><span class="o">;</span>
+
+ <span class="c">(* Print out all the generated code. *)</span>
+ <span class="n">dump_module</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span>
+<span class="o">;;</span>
+
+<span class="n">main</span> <span class="bp">()</span>
+</pre></div>
+</div>
+</dd>
+<dt>bindings.c</dt>
+<dd><div class="first last highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp"></span>
+
+<span class="cm">/* putchard - putchar that takes a double and returns 0. */</span>
+<span class="k">extern</span> <span class="kt">double</span> <span class="nf">putchard</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">putchar</span><span class="p">((</span><span class="kt">char</span><span class="p">)</span><span class="n">X</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="cm">/* printd - printf that takes a double prints it as "%f\n", returning 0. */</span>
+<span class="k">extern</span> <span class="kt">double</span> <span class="nf">printd</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">printf</span><span class="p">(</span><span class="s">"%f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">X</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</dd>
+</dl>
+<p><a class="reference external" href="OCamlLangImpl7.html">Next: Extending the language: mutable variables / SSA
+construction</a></p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="OCamlLangImpl7.html" title="7. Kaleidoscope: Extending the Language: Mutable Variables"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="OCamlLangImpl5.html" title="5. Kaleidoscope: Extending the Language: Control Flow"
+ >previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" >LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-03-18.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl7.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl7.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl7.html (added)
+++ www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl7.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,1740 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>7. Kaleidoscope: Extending the Language: Mutable Variables — LLVM 8 documentation</title>
+ <link rel="stylesheet" href="../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="8. Kaleidoscope: Conclusion and other useful LLVM tidbits" href="OCamlLangImpl8.html" />
+ <link rel="prev" title="6. Kaleidoscope: Extending the Language: User-defined Operators" href="OCamlLangImpl6.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../index.html">
+ <img src="../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="OCamlLangImpl8.html" title="8. Kaleidoscope: Conclusion and other useful LLVM tidbits"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="OCamlLangImpl6.html" title="6. Kaleidoscope: Extending the Language: User-defined Operators"
+ accesskey="P">previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-extending-the-language-mutable-variables">
+<h1>7. Kaleidoscope: Extending the Language: Mutable Variables<a class="headerlink" href="#kaleidoscope-extending-the-language-mutable-variables" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#chapter-7-introduction" id="id2">Chapter 7 Introduction</a></li>
+<li><a class="reference internal" href="#why-is-this-a-hard-problem" id="id3">Why is this a hard problem?</a></li>
+<li><a class="reference internal" href="#memory-in-llvm" id="id4">Memory in LLVM</a></li>
+<li><a class="reference internal" href="#mutable-variables-in-kaleidoscope" id="id5">Mutable Variables in Kaleidoscope</a></li>
+<li><a class="reference internal" href="#adjusting-existing-variables-for-mutation" id="id6">Adjusting Existing Variables for Mutation</a></li>
+<li><a class="reference internal" href="#new-assignment-operator" id="id7">New Assignment Operator</a></li>
+<li><a class="reference internal" href="#user-defined-local-variables" id="id8">User-defined Local Variables</a></li>
+<li><a class="reference internal" href="#id1" id="id9">Full Code Listing</a></li>
+</ul>
+</div>
+<div class="section" id="chapter-7-introduction">
+<h2><a class="toc-backref" href="#id2">7.1. Chapter 7 Introduction</a><a class="headerlink" href="#chapter-7-introduction" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to Chapter 7 of the â<a class="reference external" href="index.html">Implementing a language with
+LLVM</a>â tutorial. In chapters 1 through 6, weâve built a
+very respectable, albeit simple, <a class="reference external" href="http://en.wikipedia.org/wiki/Functional_programming">functional programming
+language</a>. In our
+journey, we learned some parsing techniques, how to build and represent
+an AST, how to build LLVM IR, and how to optimize the resultant code as
+well as JIT compile it.</p>
+<p>While Kaleidoscope is interesting as a functional language, the fact
+that it is functional makes it âtoo easyâ to generate LLVM IR for it. In
+particular, a functional language makes it very easy to build LLVM IR
+directly in <a class="reference external" href="http://en.wikipedia.org/wiki/Static_single_assignment_form">SSA
+form</a>.
+Since LLVM requires that the input code be in SSA form, this is a very
+nice property and it is often unclear to newcomers how to generate code
+for an imperative language with mutable variables.</p>
+<p>The short (and happy) summary of this chapter is that there is no need
+for your front-end to build SSA form: LLVM provides highly tuned and
+well tested support for this, though the way it works is a bit
+unexpected for some.</p>
+</div>
+<div class="section" id="why-is-this-a-hard-problem">
+<h2><a class="toc-backref" href="#id3">7.2. Why is this a hard problem?</a><a class="headerlink" href="#why-is-this-a-hard-problem" title="Permalink to this headline">¶</a></h2>
+<p>To understand why mutable variables cause complexities in SSA
+construction, consider this extremely simple C example:</p>
+<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span> <span class="n">G</span><span class="p">,</span> <span class="n">H</span><span class="p">;</span>
+<span class="kt">int</span> <span class="nf">test</span><span class="p">(</span><span class="kt">_Bool</span> <span class="n">Condition</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">X</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Condition</span><span class="p">)</span>
+ <span class="n">X</span> <span class="o">=</span> <span class="n">G</span><span class="p">;</span>
+ <span class="k">else</span>
+ <span class="n">X</span> <span class="o">=</span> <span class="n">H</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">X</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>In this case, we have the variable âXâ, whose value depends on the path
+executed in the program. Because there are two different possible values
+for X before the return instruction, a PHI node is inserted to merge the
+two values. The LLVM IR that we want for this example looks like this:</p>
+<div class="highlight-llvm notranslate"><div class="highlight"><pre><span></span><span class="vg">@G</span> <span class="p">=</span> <span class="k">weak</span> <span class="k">global</span> <span class="k">i32</span> <span class="m">0</span> <span class="c">; type of @G is i32*</span>
+<span class="vg">@H</span> <span class="p">=</span> <span class="k">weak</span> <span class="k">global</span> <span class="k">i32</span> <span class="m">0</span> <span class="c">; type of @H is i32*</span>
+
+<span class="k">define</span> <span class="k">i32</span> <span class="vg">@test</span><span class="p">(</span><span class="k">i1</span> <span class="nv">%Condition</span><span class="p">)</span> <span class="p">{</span>
+<span class="nl">entry:</span>
+ <span class="k">br</span> <span class="k">i1</span> <span class="nv">%Condition</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%cond_true</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%cond_false</span>
+
+<span class="nl">cond_true:</span>
+ <span class="nv">%X.0</span> <span class="p">=</span> <span class="k">load</span> <span class="k">i32</span><span class="p">*</span> <span class="vg">@G</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%cond_next</span>
+
+<span class="nl">cond_false:</span>
+ <span class="nv">%X.1</span> <span class="p">=</span> <span class="k">load</span> <span class="k">i32</span><span class="p">*</span> <span class="vg">@H</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%cond_next</span>
+
+<span class="nl">cond_next:</span>
+ <span class="nv">%X.2</span> <span class="p">=</span> <span class="k">phi</span> <span class="k">i32</span> <span class="p">[</span> <span class="nv">%X.1</span><span class="p">,</span> <span class="nv">%cond_false</span> <span class="p">],</span> <span class="p">[</span> <span class="nv">%X.0</span><span class="p">,</span> <span class="nv">%cond_true</span> <span class="p">]</span>
+ <span class="k">ret</span> <span class="k">i32</span> <span class="nv">%X.2</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>In this example, the loads from the G and H global variables are
+explicit in the LLVM IR, and they live in the then/else branches of the
+if statement (cond_true/cond_false). In order to merge the incoming
+values, the X.2 phi node in the cond_next block selects the right value
+to use based on where control flow is coming from: if control flow comes
+from the cond_false block, X.2 gets the value of X.1. Alternatively, if
+control flow comes from cond_true, it gets the value of X.0. The intent
+of this chapter is not to explain the details of SSA form. For more
+information, see one of the many <a class="reference external" href="http://en.wikipedia.org/wiki/Static_single_assignment_form">online
+references</a>.</p>
+<p>The question for this article is âwho places the phi nodes when lowering
+assignments to mutable variables?â. The issue here is that LLVM
+<em>requires</em> that its IR be in SSA form: there is no ânon-ssaâ mode for
+it. However, SSA construction requires non-trivial algorithms and data
+structures, so it is inconvenient and wasteful for every front-end to
+have to reproduce this logic.</p>
+</div>
+<div class="section" id="memory-in-llvm">
+<h2><a class="toc-backref" href="#id4">7.3. Memory in LLVM</a><a class="headerlink" href="#memory-in-llvm" title="Permalink to this headline">¶</a></h2>
+<p>The âtrickâ here is that while LLVM does require all register values to
+be in SSA form, it does not require (or permit) memory objects to be in
+SSA form. In the example above, note that the loads from G and H are
+direct accesses to G and H: they are not renamed or versioned. This
+differs from some other compiler systems, which do try to version memory
+objects. In LLVM, instead of encoding dataflow analysis of memory into
+the LLVM IR, it is handled with <a class="reference external" href="../WritingAnLLVMPass.html">Analysis
+Passes</a> which are computed on demand.</p>
+<p>With this in mind, the high-level idea is that we want to make a stack
+variable (which lives in memory, because it is on the stack) for each
+mutable object in a function. To take advantage of this trick, we need
+to talk about how LLVM represents stack variables.</p>
+<p>In LLVM, all memory accesses are explicit with load/store instructions,
+and it is carefully designed not to have (or need) an âaddress-ofâ
+operator. Notice how the type of the @G/@H global variables is actually
+âi32*â even though the variable is defined as âi32â. What this means is
+that @G defines <em>space</em> for an i32 in the global data area, but its
+<em>name</em> actually refers to the address for that space. Stack variables
+work the same way, except that instead of being declared with global
+variable definitions, they are declared with the <a class="reference external" href="../LangRef.html#alloca-instruction">LLVM alloca
+instruction</a>:</p>
+<div class="highlight-llvm notranslate"><div class="highlight"><pre><span></span><span class="k">define</span> <span class="k">i32</span> <span class="vg">@example</span><span class="p">()</span> <span class="p">{</span>
+<span class="nl">entry:</span>
+ <span class="nv">%X</span> <span class="p">=</span> <span class="k">alloca</span> <span class="k">i32</span> <span class="c">; type of %X is i32*.</span>
+ <span class="p">...</span>
+ <span class="nv">%tmp</span> <span class="p">=</span> <span class="k">load</span> <span class="k">i32</span><span class="p">*</span> <span class="nv">%X</span> <span class="c">; load the stack value %X from the stack.</span>
+ <span class="nv">%tmp2</span> <span class="p">=</span> <span class="k">add</span> <span class="k">i32</span> <span class="nv">%tmp</span><span class="p">,</span> <span class="m">1</span> <span class="c">; increment it</span>
+ <span class="k">store</span> <span class="k">i32</span> <span class="nv">%tmp2</span><span class="p">,</span> <span class="k">i32</span><span class="p">*</span> <span class="nv">%X</span> <span class="c">; store it back</span>
+ <span class="p">...</span>
+</pre></div>
+</div>
+<p>This code shows an example of how you can declare and manipulate a stack
+variable in the LLVM IR. Stack memory allocated with the alloca
+instruction is fully general: you can pass the address of the stack slot
+to functions, you can store it in other variables, etc. In our example
+above, we could rewrite the example to use the alloca technique to avoid
+using a PHI node:</p>
+<div class="highlight-llvm notranslate"><div class="highlight"><pre><span></span><span class="vg">@G</span> <span class="p">=</span> <span class="k">weak</span> <span class="k">global</span> <span class="k">i32</span> <span class="m">0</span> <span class="c">; type of @G is i32*</span>
+<span class="vg">@H</span> <span class="p">=</span> <span class="k">weak</span> <span class="k">global</span> <span class="k">i32</span> <span class="m">0</span> <span class="c">; type of @H is i32*</span>
+
+<span class="k">define</span> <span class="k">i32</span> <span class="vg">@test</span><span class="p">(</span><span class="k">i1</span> <span class="nv">%Condition</span><span class="p">)</span> <span class="p">{</span>
+<span class="nl">entry:</span>
+ <span class="nv">%X</span> <span class="p">=</span> <span class="k">alloca</span> <span class="k">i32</span> <span class="c">; type of %X is i32*.</span>
+ <span class="k">br</span> <span class="k">i1</span> <span class="nv">%Condition</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%cond_true</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%cond_false</span>
+
+<span class="nl">cond_true:</span>
+ <span class="nv">%X.0</span> <span class="p">=</span> <span class="k">load</span> <span class="k">i32</span><span class="p">*</span> <span class="vg">@G</span>
+ <span class="k">store</span> <span class="k">i32</span> <span class="nv">%X.0</span><span class="p">,</span> <span class="k">i32</span><span class="p">*</span> <span class="nv">%X</span> <span class="c">; Update X</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%cond_next</span>
+
+<span class="nl">cond_false:</span>
+ <span class="nv">%X.1</span> <span class="p">=</span> <span class="k">load</span> <span class="k">i32</span><span class="p">*</span> <span class="vg">@H</span>
+ <span class="k">store</span> <span class="k">i32</span> <span class="nv">%X.1</span><span class="p">,</span> <span class="k">i32</span><span class="p">*</span> <span class="nv">%X</span> <span class="c">; Update X</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%cond_next</span>
+
+<span class="nl">cond_next:</span>
+ <span class="nv">%X.2</span> <span class="p">=</span> <span class="k">load</span> <span class="k">i32</span><span class="p">*</span> <span class="nv">%X</span> <span class="c">; Read X</span>
+ <span class="k">ret</span> <span class="k">i32</span> <span class="nv">%X.2</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>With this, we have discovered a way to handle arbitrary mutable
+variables without the need to create Phi nodes at all:</p>
+<ol class="arabic simple">
+<li>Each mutable variable becomes a stack allocation.</li>
+<li>Each read of the variable becomes a load from the stack.</li>
+<li>Each update of the variable becomes a store to the stack.</li>
+<li>Taking the address of a variable just uses the stack address
+directly.</li>
+</ol>
+<p>While this solution has solved our immediate problem, it introduced
+another one: we have now apparently introduced a lot of stack traffic
+for very simple and common operations, a major performance problem.
+Fortunately for us, the LLVM optimizer has a highly-tuned optimization
+pass named âmem2regâ that handles this case, promoting allocas like this
+into SSA registers, inserting Phi nodes as appropriate. If you run this
+example through the pass, for example, youâll get:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ llvm-as < example.ll <span class="p">|</span> opt -mem2reg <span class="p">|</span> llvm-dis
+ at G <span class="o">=</span> weak global i32 <span class="m">0</span>
+ at H <span class="o">=</span> weak global i32 <span class="m">0</span>
+
+define i32 @test<span class="o">(</span>i1 %Condition<span class="o">)</span> <span class="o">{</span>
+entry:
+ br i1 %Condition, label %cond_true, label %cond_false
+
+cond_true:
+ %X.0 <span class="o">=</span> load i32* @G
+ br label %cond_next
+
+cond_false:
+ %X.1 <span class="o">=</span> load i32* @H
+ br label %cond_next
+
+cond_next:
+ %X.01 <span class="o">=</span> phi i32 <span class="o">[</span> %X.1, %cond_false <span class="o">]</span>, <span class="o">[</span> %X.0, %cond_true <span class="o">]</span>
+ ret i32 %X.01
+<span class="o">}</span>
+</pre></div>
+</div>
+<p>The mem2reg pass implements the standard âiterated dominance frontierâ
+algorithm for constructing SSA form and has a number of optimizations
+that speed up (very common) degenerate cases. The mem2reg optimization
+pass is the answer to dealing with mutable variables, and we highly
+recommend that you depend on it. Note that mem2reg only works on
+variables in certain circumstances:</p>
+<ol class="arabic simple">
+<li>mem2reg is alloca-driven: it looks for allocas and if it can handle
+them, it promotes them. It does not apply to global variables or heap
+allocations.</li>
+<li>mem2reg only looks for alloca instructions in the entry block of the
+function. Being in the entry block guarantees that the alloca is only
+executed once, which makes analysis simpler.</li>
+<li>mem2reg only promotes allocas whose uses are direct loads and stores.
+If the address of the stack object is passed to a function, or if any
+funny pointer arithmetic is involved, the alloca will not be
+promoted.</li>
+<li>mem2reg only works on allocas of <a class="reference external" href="../LangRef.html#first-class-types">first
+class</a> values (such as pointers,
+scalars and vectors), and only if the array size of the allocation is
+1 (or missing in the .ll file). mem2reg is not capable of promoting
+structs or arrays to registers. Note that the âsroaâ pass is
+more powerful and can promote structs, âunionsâ, and arrays in many
+cases.</li>
+</ol>
+<p>All of these properties are easy to satisfy for most imperative
+languages, and weâll illustrate it below with Kaleidoscope. The final
+question you may be asking is: should I bother with this nonsense for my
+front-end? Wouldnât it be better if I just did SSA construction
+directly, avoiding use of the mem2reg optimization pass? In short, we
+strongly recommend that you use this technique for building SSA form,
+unless there is an extremely good reason not to. Using this technique
+is:</p>
+<ul class="simple">
+<li>Proven and well tested: clang uses this technique
+for local mutable variables. As such, the most common clients of LLVM
+are using this to handle a bulk of their variables. You can be sure
+that bugs are found fast and fixed early.</li>
+<li>Extremely Fast: mem2reg has a number of special cases that make it
+fast in common cases as well as fully general. For example, it has
+fast-paths for variables that are only used in a single block,
+variables that only have one assignment point, good heuristics to
+avoid insertion of unneeded phi nodes, etc.</li>
+<li>Needed for debug info generation: <a class="reference external" href="../SourceLevelDebugging.html">Debug information in
+LLVM</a> relies on having the address of
+the variable exposed so that debug info can be attached to it. This
+technique dovetails very naturally with this style of debug info.</li>
+</ul>
+<p>If nothing else, this makes it much easier to get your front-end up and
+running, and is very simple to implement. Lets extend Kaleidoscope with
+mutable variables now!</p>
+</div>
+<div class="section" id="mutable-variables-in-kaleidoscope">
+<h2><a class="toc-backref" href="#id5">7.4. Mutable Variables in Kaleidoscope</a><a class="headerlink" href="#mutable-variables-in-kaleidoscope" title="Permalink to this headline">¶</a></h2>
+<p>Now that we know the sort of problem we want to tackle, lets see what
+this looks like in the context of our little Kaleidoscope language.
+Weâre going to add two features:</p>
+<ol class="arabic simple">
+<li>The ability to mutate variables with the â=â operator.</li>
+<li>The ability to define new variables.</li>
+</ol>
+<p>While the first item is really what this is about, we only have
+variables for incoming arguments as well as for induction variables, and
+redefining those only goes so far :). Also, the ability to define new
+variables is a useful thing regardless of whether you will be mutating
+them. Hereâs a motivating example that shows how we could use these:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Define ':' for sequencing: as a low-precedence operator that ignores operands</span>
+<span class="c1"># and just returns the RHS.</span>
+<span class="k">def</span> <span class="nf">binary</span> <span class="p">:</span> <span class="mi">1</span> <span class="p">(</span><span class="n">x</span> <span class="n">y</span><span class="p">)</span> <span class="n">y</span><span class="p">;</span>
+
+<span class="c1"># Recursive fib, we could do this before.</span>
+<span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o"><</span> <span class="mi">3</span><span class="p">)</span> <span class="n">then</span>
+ <span class="mi">1</span>
+ <span class="k">else</span>
+ <span class="n">fib</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="n">fib</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">2</span><span class="p">);</span>
+
+<span class="c1"># Iterative fib.</span>
+<span class="k">def</span> <span class="nf">fibi</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
+ <span class="n">var</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span> <span class="ow">in</span>
+ <span class="p">(</span><span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span> <span class="n">i</span> <span class="o"><</span> <span class="n">x</span> <span class="ow">in</span>
+ <span class="n">c</span> <span class="o">=</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span> <span class="p">:</span>
+ <span class="n">a</span> <span class="o">=</span> <span class="n">b</span> <span class="p">:</span>
+ <span class="n">b</span> <span class="o">=</span> <span class="n">c</span><span class="p">)</span> <span class="p">:</span>
+ <span class="n">b</span><span class="p">;</span>
+
+<span class="c1"># Call it.</span>
+<span class="n">fibi</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>In order to mutate variables, we have to change our existing variables
+to use the âalloca trickâ. Once we have that, weâll add our new
+operator, then extend Kaleidoscope to support new variable definitions.</p>
+</div>
+<div class="section" id="adjusting-existing-variables-for-mutation">
+<h2><a class="toc-backref" href="#id6">7.5. Adjusting Existing Variables for Mutation</a><a class="headerlink" href="#adjusting-existing-variables-for-mutation" title="Permalink to this headline">¶</a></h2>
+<p>The symbol table in Kaleidoscope is managed at code generation time by
+the â<code class="docutils literal notranslate"><span class="pre">named_values</span></code>â map. This map currently keeps track of the LLVM
+âValue*â that holds the double value for the named variable. In order
+to support mutation, we need to change this slightly, so that it
+<code class="docutils literal notranslate"><span class="pre">named_values</span></code> holds the <em>memory location</em> of the variable in
+question. Note that this change is a refactoring: it changes the
+structure of the code, but does not (by itself) change the behavior of
+the compiler. All of these changes are isolated in the Kaleidoscope code
+generator.</p>
+<p>At this point in Kaleidoscopeâs development, it only supports variables
+for two things: incoming arguments to functions and the induction
+variable of âforâ loops. For consistency, weâll allow mutation of these
+variables in addition to other user-defined variables. This means that
+these will both need memory locations.</p>
+<p>To start our transformation of Kaleidoscope, weâll change the
+<code class="docutils literal notranslate"><span class="pre">named_values</span></code> map so that it maps to AllocaInst* instead of Value*.
+Once we do this, the C++ compiler will tell us what parts of the code we
+need to update:</p>
+<p><strong>Note:</strong> the ocaml bindings currently model both <code class="docutils literal notranslate"><span class="pre">Value*</span></code>âs and
+<code class="docutils literal notranslate"><span class="pre">AllocInst*</span></code>âs as <code class="docutils literal notranslate"><span class="pre">Llvm.llvalue</span></code>âs, but this may change in the future
+to be more type safe.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="n">named_values</span><span class="o">:(</span><span class="kt">string</span><span class="o">,</span> <span class="n">llvalue</span><span class="o">)</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">t</span> <span class="o">=</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">create</span> <span class="mi">10</span>
+</pre></div>
+</div>
+<p>Also, since we will need to create these allocaâs, weâll use a helper
+function that ensures that the allocas are created in the entry block of
+the function:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Create an alloca instruction in the entry block of the function. This</span>
+<span class="c"> * is used for mutable variables etc. *)</span>
+<span class="k">let</span> <span class="n">create_entry_block_alloca</span> <span class="n">the_function</span> <span class="n">var_name</span> <span class="o">=</span>
+ <span class="k">let</span> <span class="n">builder</span> <span class="o">=</span> <span class="n">builder_at</span> <span class="o">(</span><span class="n">instr_begin</span> <span class="o">(</span><span class="n">entry_block</span> <span class="n">the_function</span><span class="o">))</span> <span class="k">in</span>
+ <span class="n">build_alloca</span> <span class="n">double_type</span> <span class="n">var_name</span> <span class="n">builder</span>
+</pre></div>
+</div>
+<p>This funny looking code creates an <code class="docutils literal notranslate"><span class="pre">Llvm.llbuilder</span></code> object that is
+pointing at the first instruction of the entry block. It then creates an
+alloca with the expected name and returns it. Because all values in
+Kaleidoscope are doubles, there is no need to pass in a type to use.</p>
+<p>With this in place, the first functionality change we want to make is to
+variable references. In our new scheme, variables live on the stack, so
+code generating a reference to them actually needs to produce a load
+from the stack slot:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="k">rec</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">...</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Variable</span> <span class="n">name</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">v</span> <span class="o">=</span> <span class="k">try</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">name</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown variable name"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="c">(* Load the value. *)</span>
+ <span class="n">build_load</span> <span class="n">v</span> <span class="n">name</span> <span class="n">builder</span>
+</pre></div>
+</div>
+<p>As you can see, this is pretty straightforward. Now we need to update
+the things that define the variables to set up the alloca. Weâll start
+with <code class="docutils literal notranslate"><span class="pre">codegen_expr</span> <span class="pre">Ast.For</span> <span class="pre">...</span></code> (see the <a class="reference external" href="#id1">full code listing</a>
+for the unabridged code):</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">For</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">end_</span><span class="o">,</span> <span class="n">step</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="o">(</span><span class="n">insertion_block</span> <span class="n">builder</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Create an alloca for the variable in the entry block. *)</span>
+ <span class="k">let</span> <span class="n">alloca</span> <span class="o">=</span> <span class="n">create_entry_block_alloca</span> <span class="n">the_function</span> <span class="n">var_name</span> <span class="k">in</span>
+
+ <span class="c">(* Emit the start code first, without 'variable' in scope. *)</span>
+ <span class="k">let</span> <span class="n">start_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">start</span> <span class="k">in</span>
+
+ <span class="c">(* Store the value into the alloca. *)</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">start_val</span> <span class="n">alloca</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="o">...</span>
+
+ <span class="c">(* Within the loop, the variable is defined equal to the PHI node. If it</span>
+<span class="c"> * shadows an existing variable, we have to restore it, so save it</span>
+<span class="c"> * now. *)</span>
+ <span class="k">let</span> <span class="n">old_val</span> <span class="o">=</span>
+ <span class="k">try</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">var_name</span><span class="o">)</span> <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="nc">None</span>
+ <span class="k">in</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">alloca</span><span class="o">;</span>
+
+ <span class="o">...</span>
+
+ <span class="c">(* Compute the end condition. *)</span>
+ <span class="k">let</span> <span class="n">end_cond</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">end_</span> <span class="k">in</span>
+
+ <span class="c">(* Reload, increment, and restore the alloca. This handles the case where</span>
+<span class="c"> * the body of the loop mutates the variable. *)</span>
+ <span class="k">let</span> <span class="n">cur_var</span> <span class="o">=</span> <span class="n">build_load</span> <span class="n">alloca</span> <span class="n">var_name</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">next_var</span> <span class="o">=</span> <span class="n">build_add</span> <span class="n">cur_var</span> <span class="n">step_val</span> <span class="s2">"nextvar"</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">next_var</span> <span class="n">alloca</span> <span class="n">builder</span><span class="o">);</span>
+ <span class="o">...</span>
+</pre></div>
+</div>
+<p>This code is virtually identical to the code <a class="reference external" href="OCamlLangImpl5.html#code-generation-for-the-for-loop">before we allowed mutable
+variables</a>. The big difference is that
+we no longer have to construct a PHI node, and we use load/store to
+access the variable as needed.</p>
+<p>To support mutable argument variables, we need to also make allocas for
+them. The code for this is also pretty simple:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Create an alloca for each argument and register the argument in the symbol</span>
+<span class="c"> * table so that references to it will succeed. *)</span>
+<span class="k">let</span> <span class="n">create_argument_allocas</span> <span class="n">the_function</span> <span class="n">proto</span> <span class="o">=</span>
+ <span class="k">let</span> <span class="n">args</span> <span class="o">=</span> <span class="k">match</span> <span class="n">proto</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(_,</span> <span class="n">args</span><span class="o">)</span> <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(_,</span> <span class="n">args</span><span class="o">,</span> <span class="o">_)</span> <span class="o">-></span> <span class="n">args</span>
+ <span class="k">in</span>
+ <span class="nn">Array</span><span class="p">.</span><span class="n">iteri</span> <span class="o">(</span><span class="k">fun</span> <span class="n">i</span> <span class="n">ai</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">var_name</span> <span class="o">=</span> <span class="n">args</span><span class="o">.(</span><span class="n">i</span><span class="o">)</span> <span class="k">in</span>
+ <span class="c">(* Create an alloca for this variable. *)</span>
+ <span class="k">let</span> <span class="n">alloca</span> <span class="o">=</span> <span class="n">create_entry_block_alloca</span> <span class="n">the_function</span> <span class="n">var_name</span> <span class="k">in</span>
+
+ <span class="c">(* Store the initial value into the alloca. *)</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">ai</span> <span class="n">alloca</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Add arguments to variable symbol table. *)</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">alloca</span><span class="o">;</span>
+ <span class="o">)</span> <span class="o">(</span><span class="n">params</span> <span class="n">the_function</span><span class="o">)</span>
+</pre></div>
+</div>
+<p>For each argument, we make an alloca, store the input value to the
+function into the alloca, and register the alloca as the memory location
+for the argument. This method gets invoked by <code class="docutils literal notranslate"><span class="pre">Codegen.codegen_func</span></code>
+right after it sets up the entry block for the function.</p>
+<p>The final missing piece is adding the mem2reg pass, which allows us to
+get good codegen once again:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="n">main</span> <span class="bp">()</span> <span class="o">=</span>
+ <span class="o">...</span>
+ <span class="k">let</span> <span class="n">the_fpm</span> <span class="o">=</span> <span class="nn">PassManager</span><span class="p">.</span><span class="n">create_function</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span> <span class="k">in</span>
+
+ <span class="c">(* Set up the optimizer pipeline. Start with registering info about how the</span>
+<span class="c"> * target lays out data structures. *)</span>
+ <span class="nn">DataLayout</span><span class="p">.</span><span class="n">add</span> <span class="o">(</span><span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">target_data</span> <span class="n">the_execution_engine</span><span class="o">)</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Promote allocas to registers. *)</span>
+ <span class="n">add_memory_to_register_promotion</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Do simple "peephole" optimizations and bit-twiddling optzn. *)</span>
+ <span class="n">add_instruction_combining</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* reassociate expressions. *)</span>
+ <span class="n">add_reassociation</span> <span class="n">the_fpm</span><span class="o">;</span>
+</pre></div>
+</div>
+<p>It is interesting to see what the code looks like before and after the
+mem2reg optimization runs. For example, this is the before/after code
+for our recursive fib function. Before the optimization:</p>
+<div class="highlight-llvm notranslate"><div class="highlight"><pre><span></span><span class="k">define</span> <span class="kt">double</span> <span class="vg">@fib</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%x</span><span class="p">)</span> <span class="p">{</span>
+<span class="nl">entry:</span>
+ <span class="nv">%x1</span> <span class="p">=</span> <span class="k">alloca</span> <span class="kt">double</span>
+ <span class="k">store</span> <span class="kt">double</span> <span class="nv">%x</span><span class="p">,</span> <span class="kt">double</span><span class="p">*</span> <span class="nv">%x1</span>
+ <span class="nv">%x2</span> <span class="p">=</span> <span class="k">load</span> <span class="kt">double</span><span class="p">*</span> <span class="nv">%x1</span>
+ <span class="nv">%cmptmp</span> <span class="p">=</span> <span class="k">fcmp</span> <span class="k">ult</span> <span class="kt">double</span> <span class="nv">%x2</span><span class="p">,</span> <span class="m">3.000000e+00</span>
+ <span class="nv">%booltmp</span> <span class="p">=</span> <span class="k">uitofp</span> <span class="k">i1</span> <span class="nv">%cmptmp</span> <span class="k">to</span> <span class="kt">double</span>
+ <span class="nv">%ifcond</span> <span class="p">=</span> <span class="k">fcmp</span> <span class="k">one</span> <span class="kt">double</span> <span class="nv">%booltmp</span><span class="p">,</span> <span class="m">0.000000e+00</span>
+ <span class="k">br</span> <span class="k">i1</span> <span class="nv">%ifcond</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%then</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%else</span>
+
+<span class="nl">then:</span> <span class="c">; preds = %entry</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%ifcont</span>
+
+<span class="nl">else:</span> <span class="c">; preds = %entry</span>
+ <span class="nv">%x3</span> <span class="p">=</span> <span class="k">load</span> <span class="kt">double</span><span class="p">*</span> <span class="nv">%x1</span>
+ <span class="nv">%subtmp</span> <span class="p">=</span> <span class="k">fsub</span> <span class="kt">double</span> <span class="nv">%x3</span><span class="p">,</span> <span class="m">1.000000e+00</span>
+ <span class="nv">%calltmp</span> <span class="p">=</span> <span class="k">call</span> <span class="kt">double</span> <span class="vg">@fib</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%subtmp</span><span class="p">)</span>
+ <span class="nv">%x4</span> <span class="p">=</span> <span class="k">load</span> <span class="kt">double</span><span class="p">*</span> <span class="nv">%x1</span>
+ <span class="nv">%subtmp5</span> <span class="p">=</span> <span class="k">fsub</span> <span class="kt">double</span> <span class="nv">%x4</span><span class="p">,</span> <span class="m">2.000000e+00</span>
+ <span class="nv">%calltmp6</span> <span class="p">=</span> <span class="k">call</span> <span class="kt">double</span> <span class="vg">@fib</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%subtmp5</span><span class="p">)</span>
+ <span class="nv">%addtmp</span> <span class="p">=</span> <span class="k">fadd</span> <span class="kt">double</span> <span class="nv">%calltmp</span><span class="p">,</span> <span class="nv">%calltmp6</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%ifcont</span>
+
+<span class="nl">ifcont:</span> <span class="c">; preds = %else, %then</span>
+ <span class="nv">%iftmp</span> <span class="p">=</span> <span class="k">phi</span> <span class="kt">double</span> <span class="p">[</span> <span class="m">1.000000e+00</span><span class="p">,</span> <span class="nv">%then</span> <span class="p">],</span> <span class="p">[</span> <span class="nv">%addtmp</span><span class="p">,</span> <span class="nv">%else</span> <span class="p">]</span>
+ <span class="k">ret</span> <span class="kt">double</span> <span class="nv">%iftmp</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Here there is only one variable (x, the input argument) but you can
+still see the extremely simple-minded code generation strategy we are
+using. In the entry block, an alloca is created, and the initial input
+value is stored into it. Each reference to the variable does a reload
+from the stack. Also, note that we didnât modify the if/then/else
+expression, so it still inserts a PHI node. While we could make an
+alloca for it, it is actually easier to create a PHI node for it, so we
+still just make the PHI.</p>
+<p>Here is the code after the mem2reg pass runs:</p>
+<div class="highlight-llvm notranslate"><div class="highlight"><pre><span></span><span class="k">define</span> <span class="kt">double</span> <span class="vg">@fib</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%x</span><span class="p">)</span> <span class="p">{</span>
+<span class="nl">entry:</span>
+ <span class="nv">%cmptmp</span> <span class="p">=</span> <span class="k">fcmp</span> <span class="k">ult</span> <span class="kt">double</span> <span class="nv">%x</span><span class="p">,</span> <span class="m">3.000000e+00</span>
+ <span class="nv">%booltmp</span> <span class="p">=</span> <span class="k">uitofp</span> <span class="k">i1</span> <span class="nv">%cmptmp</span> <span class="k">to</span> <span class="kt">double</span>
+ <span class="nv">%ifcond</span> <span class="p">=</span> <span class="k">fcmp</span> <span class="k">one</span> <span class="kt">double</span> <span class="nv">%booltmp</span><span class="p">,</span> <span class="m">0.000000e+00</span>
+ <span class="k">br</span> <span class="k">i1</span> <span class="nv">%ifcond</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%then</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%else</span>
+
+<span class="nl">then:</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%ifcont</span>
+
+<span class="nl">else:</span>
+ <span class="nv">%subtmp</span> <span class="p">=</span> <span class="k">fsub</span> <span class="kt">double</span> <span class="nv">%x</span><span class="p">,</span> <span class="m">1.000000e+00</span>
+ <span class="nv">%calltmp</span> <span class="p">=</span> <span class="k">call</span> <span class="kt">double</span> <span class="vg">@fib</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%subtmp</span><span class="p">)</span>
+ <span class="nv">%subtmp5</span> <span class="p">=</span> <span class="k">fsub</span> <span class="kt">double</span> <span class="nv">%x</span><span class="p">,</span> <span class="m">2.000000e+00</span>
+ <span class="nv">%calltmp6</span> <span class="p">=</span> <span class="k">call</span> <span class="kt">double</span> <span class="vg">@fib</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%subtmp5</span><span class="p">)</span>
+ <span class="nv">%addtmp</span> <span class="p">=</span> <span class="k">fadd</span> <span class="kt">double</span> <span class="nv">%calltmp</span><span class="p">,</span> <span class="nv">%calltmp6</span>
+ <span class="k">br</span> <span class="kt">label</span> <span class="nv">%ifcont</span>
+
+<span class="nl">ifcont:</span> <span class="c">; preds = %else, %then</span>
+ <span class="nv">%iftmp</span> <span class="p">=</span> <span class="k">phi</span> <span class="kt">double</span> <span class="p">[</span> <span class="m">1.000000e+00</span><span class="p">,</span> <span class="nv">%then</span> <span class="p">],</span> <span class="p">[</span> <span class="nv">%addtmp</span><span class="p">,</span> <span class="nv">%else</span> <span class="p">]</span>
+ <span class="k">ret</span> <span class="kt">double</span> <span class="nv">%iftmp</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This is a trivial case for mem2reg, since there are no redefinitions of
+the variable. The point of showing this is to calm your tension about
+inserting such blatent inefficiencies :).</p>
+<p>After the rest of the optimizers run, we get:</p>
+<div class="highlight-llvm notranslate"><div class="highlight"><pre><span></span><span class="k">define</span> <span class="kt">double</span> <span class="vg">@fib</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%x</span><span class="p">)</span> <span class="p">{</span>
+<span class="nl">entry:</span>
+ <span class="nv">%cmptmp</span> <span class="p">=</span> <span class="k">fcmp</span> <span class="k">ult</span> <span class="kt">double</span> <span class="nv">%x</span><span class="p">,</span> <span class="m">3.000000e+00</span>
+ <span class="nv">%booltmp</span> <span class="p">=</span> <span class="k">uitofp</span> <span class="k">i1</span> <span class="nv">%cmptmp</span> <span class="k">to</span> <span class="kt">double</span>
+ <span class="nv">%ifcond</span> <span class="p">=</span> <span class="k">fcmp</span> <span class="k">ueq</span> <span class="kt">double</span> <span class="nv">%booltmp</span><span class="p">,</span> <span class="m">0.000000e+00</span>
+ <span class="k">br</span> <span class="k">i1</span> <span class="nv">%ifcond</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%else</span><span class="p">,</span> <span class="kt">label</span> <span class="nv">%ifcont</span>
+
+<span class="nl">else:</span>
+ <span class="nv">%subtmp</span> <span class="p">=</span> <span class="k">fsub</span> <span class="kt">double</span> <span class="nv">%x</span><span class="p">,</span> <span class="m">1.000000e+00</span>
+ <span class="nv">%calltmp</span> <span class="p">=</span> <span class="k">call</span> <span class="kt">double</span> <span class="vg">@fib</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%subtmp</span><span class="p">)</span>
+ <span class="nv">%subtmp5</span> <span class="p">=</span> <span class="k">fsub</span> <span class="kt">double</span> <span class="nv">%x</span><span class="p">,</span> <span class="m">2.000000e+00</span>
+ <span class="nv">%calltmp6</span> <span class="p">=</span> <span class="k">call</span> <span class="kt">double</span> <span class="vg">@fib</span><span class="p">(</span><span class="kt">double</span> <span class="nv">%subtmp5</span><span class="p">)</span>
+ <span class="nv">%addtmp</span> <span class="p">=</span> <span class="k">fadd</span> <span class="kt">double</span> <span class="nv">%calltmp</span><span class="p">,</span> <span class="nv">%calltmp6</span>
+ <span class="k">ret</span> <span class="kt">double</span> <span class="nv">%addtmp</span>
+
+<span class="nl">ifcont:</span>
+ <span class="k">ret</span> <span class="kt">double</span> <span class="m">1.000000e+00</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Here we see that the simplifycfg pass decided to clone the return
+instruction into the end of the âelseâ block. This allowed it to
+eliminate some branches and the PHI node.</p>
+<p>Now that all symbol table references are updated to use stack variables,
+weâll add the assignment operator.</p>
+</div>
+<div class="section" id="new-assignment-operator">
+<h2><a class="toc-backref" href="#id7">7.6. New Assignment Operator</a><a class="headerlink" href="#new-assignment-operator" title="Permalink to this headline">¶</a></h2>
+<p>With our current framework, adding a new assignment operator is really
+simple. We will parse it just like any other binary operator, but handle
+it internally (instead of allowing the user to define it). The first
+step is to set a precedence:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="n">main</span> <span class="bp">()</span> <span class="o">=</span>
+ <span class="c">(* Install standard binary operators.</span>
+<span class="c"> * 1 is the lowest precedence. *)</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'='</span> <span class="mi">2</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'<'</span> <span class="mi">10</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'+'</span> <span class="mi">20</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'-'</span> <span class="mi">20</span><span class="o">;</span>
+ <span class="o">...</span>
+</pre></div>
+</div>
+<p>Now that the parser knows the precedence of the binary operator, it
+takes care of all the parsing and AST generation. We just need to
+implement codegen for the assignment operator. This looks like:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="k">rec</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="k">begin</span> <span class="k">match</span> <span class="n">op</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="sc">'='</span> <span class="o">-></span>
+ <span class="c">(* Special case '=' because we don't want to emit the LHS as an</span>
+<span class="c"> * expression. *)</span>
+ <span class="k">let</span> <span class="n">name</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lhs</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Variable</span> <span class="n">name</span> <span class="o">-></span> <span class="n">name</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"destination of '=' must be a variable"</span><span class="o">)</span>
+ <span class="k">in</span>
+</pre></div>
+</div>
+<p>Unlike the rest of the binary operators, our assignment operator doesnât
+follow the âemit LHS, emit RHS, do computationâ model. As such, it is
+handled as a special case before the other binary operators are handled.
+The other strange thing is that it requires the LHS to be a variable. It
+is invalid to have â(x+1) = exprâ - only things like âx = exprâ are
+allowed.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span> <span class="c">(* Codegen the rhs. *)</span>
+ <span class="k">let</span> <span class="n">val_</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">rhs</span> <span class="k">in</span>
+
+ <span class="c">(* Lookup the name. *)</span>
+ <span class="k">let</span> <span class="n">variable</span> <span class="o">=</span> <span class="k">try</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">name</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown variable name"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">val_</span> <span class="n">variable</span> <span class="n">builder</span><span class="o">);</span>
+ <span class="n">val_</span>
+<span class="o">|</span> <span class="o">_</span> <span class="o">-></span>
+ <span class="o">...</span>
+</pre></div>
+</div>
+<p>Once we have the variable, codegenâing the assignment is
+straightforward: we emit the RHS of the assignment, create a store, and
+return the computed value. Returning a value allows for chained
+assignments like âX = (Y = Z)â.</p>
+<p>Now that we have an assignment operator, we can mutate loop variables
+and arguments. For example, we can now run code like this:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Function to print a double.</span>
+<span class="n">extern</span> <span class="n">printd</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
+
+<span class="c1"># Define ':' for sequencing: as a low-precedence operator that ignores operands</span>
+<span class="c1"># and just returns the RHS.</span>
+<span class="k">def</span> <span class="nf">binary</span> <span class="p">:</span> <span class="mi">1</span> <span class="p">(</span><span class="n">x</span> <span class="n">y</span><span class="p">)</span> <span class="n">y</span><span class="p">;</span>
+
+<span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
+ <span class="n">printd</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="p">:</span>
+ <span class="n">x</span> <span class="o">=</span> <span class="mi">4</span> <span class="p">:</span>
+ <span class="n">printd</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
+
+<span class="n">test</span><span class="p">(</span><span class="mi">123</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>When run, this example prints â123â and then â4â, showing that we did
+actually mutate the value! Okay, we have now officially implemented our
+goal: getting this to work requires SSA construction in the general
+case. However, to be really useful, we want the ability to define our
+own local variables, lets add this next!</p>
+</div>
+<div class="section" id="user-defined-local-variables">
+<h2><a class="toc-backref" href="#id8">7.7. User-defined Local Variables</a><a class="headerlink" href="#user-defined-local-variables" title="Permalink to this headline">¶</a></h2>
+<p>Adding var/in is just like any other other extensions we made to
+Kaleidoscope: we extend the lexer, the parser, the AST and the code
+generator. The first step for adding our new âvar/inâ construct is to
+extend the lexer. As before, this is pretty trivial, the code looks like
+this:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">type</span> <span class="n">token</span> <span class="o">=</span>
+ <span class="o">...</span>
+ <span class="c">(* var definition *)</span>
+ <span class="o">|</span> <span class="nn">Var</span>
+
+<span class="p">...</span>
+
+<span class="n">and</span> <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">...</span>
+ <span class="o">|</span> <span class="s2">"in"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"binary"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Binary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"unary"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Unary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"var"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Var</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">...</span>
+</pre></div>
+</div>
+<p>The next step is to define the AST node that we will construct. For
+var/in, it looks like this:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">type</span> <span class="n">expr</span> <span class="o">=</span>
+ <span class="o">...</span>
+ <span class="c">(* variant for var/in. *)</span>
+ <span class="o">|</span> <span class="nc">Var</span> <span class="k">of</span> <span class="o">(</span><span class="kt">string</span> <span class="o">*</span> <span class="n">expr</span> <span class="n">option</span><span class="o">)</span> <span class="kt">array</span> <span class="o">*</span> <span class="n">expr</span>
+ <span class="o">...</span>
+</pre></div>
+</div>
+<p>var/in allows a list of names to be defined all at once, and each name
+can optionally have an initializer value. As such, we capture this
+information in the VarNames vector. Also, var/in has a body, this body
+is allowed to access the variables defined by the var/in.</p>
+<p>With this in place, we can define the parser pieces. The first thing we
+do is add it as a primary expression:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* primary</span>
+<span class="c"> * ::= identifier</span>
+<span class="c"> * ::= numberexpr</span>
+<span class="c"> * ::= parenexpr</span>
+<span class="c"> * ::= ifexpr</span>
+<span class="c"> * ::= forexpr</span>
+<span class="c"> * ::= varexpr *)</span>
+<span class="k">let</span> <span class="k">rec</span> <span class="n">parse_primary</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">...</span>
+ <span class="c">(* varexpr</span>
+<span class="c"> * ::= 'var' identifier ('=' expression?</span>
+<span class="c"> * (',' identifier ('=' expression)?)* 'in' expression *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Var</span><span class="o">;</span>
+ <span class="c">(* At least one variable name is required. *)</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span> <span class="o">??</span> <span class="s2">"expected identifier after var"</span><span class="o">;</span>
+ <span class="n">init</span><span class="o">=</span><span class="n">parse_var_init</span><span class="o">;</span>
+ <span class="n">var_names</span><span class="o">=</span><span class="n">parse_var_names</span> <span class="o">[(</span><span class="n">id</span><span class="o">,</span> <span class="n">init</span><span class="o">)];</span>
+ <span class="c">(* At this point, we have to have 'in'. *)</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span> <span class="o">??</span> <span class="s2">"expected 'in' keyword after 'var'"</span><span class="o">;</span>
+ <span class="n">body</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Var</span> <span class="o">(</span><span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">var_names</span><span class="o">),</span> <span class="n">body</span><span class="o">)</span>
+
+<span class="o">...</span>
+
+<span class="ow">and</span> <span class="n">parse_var_init</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* read in the optional initializer. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'='</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">Some</span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">None</span>
+
+<span class="ow">and</span> <span class="n">parse_var_names</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span> <span class="o">??</span> <span class="s2">"expected identifier list after var"</span><span class="o">;</span>
+ <span class="n">init</span><span class="o">=</span><span class="n">parse_var_init</span><span class="o">;</span>
+ <span class="n">e</span><span class="o">=</span><span class="n">parse_var_names</span> <span class="o">((</span><span class="n">id</span><span class="o">,</span> <span class="n">init</span><span class="o">)</span> <span class="o">::</span> <span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+</pre></div>
+</div>
+<p>Now that we can parse and represent the code, we need to support
+emission of LLVM IR for it. This code starts out with:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">let</span> <span class="k">rec</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">...</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Var</span> <span class="o">(</span><span class="n">var_names</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span>
+ <span class="k">let</span> <span class="n">old_bindings</span> <span class="o">=</span> <span class="n">ref</span> <span class="bp">[]</span> <span class="k">in</span>
+
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="o">(</span><span class="n">insertion_block</span> <span class="n">builder</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Register all variables and emit their initializer. *)</span>
+ <span class="nn">Array</span><span class="p">.</span><span class="n">iter</span> <span class="o">(</span><span class="k">fun</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">init</span><span class="o">)</span> <span class="o">-></span>
+</pre></div>
+</div>
+<p>Basically it loops over all the variables, installing them one at a
+time. For each variable we put into the symbol table, we remember the
+previous value that we replace in OldBindings.</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span> <span class="c">(* Emit the initializer before adding the variable to scope, this</span>
+<span class="c"> * prevents the initializer from referencing the variable itself, and</span>
+<span class="c"> * permits stuff like this:</span>
+<span class="c"> * var a = 1 in</span>
+<span class="c"> * var a = a in ... # refers to outer 'a'. *)</span>
+ <span class="k">let</span> <span class="n">init_val</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">init</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">init</span> <span class="o">-></span> <span class="n">codegen_expr</span> <span class="n">init</span>
+ <span class="c">(* If not specified, use 0.0. *)</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span>
+ <span class="k">in</span>
+
+ <span class="k">let</span> <span class="n">alloca</span> <span class="o">=</span> <span class="n">create_entry_block_alloca</span> <span class="n">the_function</span> <span class="n">var_name</span> <span class="k">in</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">init_val</span> <span class="n">alloca</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Remember the old variable binding so that we can restore the binding</span>
+<span class="c"> * when we unrecurse. *)</span>
+
+ <span class="k">begin</span>
+ <span class="k">try</span>
+ <span class="k">let</span> <span class="n">old_value</span> <span class="o">=</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="k">in</span>
+ <span class="n">old_bindings</span> <span class="o">:=</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">old_value</span><span class="o">)</span> <span class="o">::</span> <span class="o">!</span><span class="n">old_bindings</span><span class="o">;</span>
+ <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">></span> <span class="bp">()</span>
+ <span class="k">end</span><span class="o">;</span>
+
+ <span class="c">(* Remember this binding. *)</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">alloca</span><span class="o">;</span>
+<span class="o">)</span> <span class="n">var_names</span><span class="o">;</span>
+</pre></div>
+</div>
+<p>There are more comments here than code. The basic idea is that we emit
+the initializer, create the alloca, then update the symbol table to
+point to it. Once all the variables are installed in the symbol table,
+we evaluate the body of the var/in expression:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Codegen the body, now that all vars are in scope. *)</span>
+<span class="k">let</span> <span class="n">body_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">body</span> <span class="k">in</span>
+</pre></div>
+</div>
+<p>Finally, before returning, we restore the previous variable bindings:</p>
+<div class="highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(* Pop all our variables from scope. *)</span>
+<span class="nn">List</span><span class="p">.</span><span class="n">iter</span> <span class="o">(</span><span class="k">fun</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">old_value</span><span class="o">)</span> <span class="o">-></span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">old_value</span>
+<span class="o">)</span> <span class="o">!</span><span class="n">old_bindings</span><span class="o">;</span>
+
+<span class="c">(* Return the body computation. *)</span>
+<span class="n">body_val</span>
+</pre></div>
+</div>
+<p>The end result of all of this is that we get properly scoped variable
+definitions, and we even (trivially) allow mutation of them :).</p>
+<p>With this, we completed what we set out to do. Our nice iterative fib
+example from the intro compiles and runs just fine. The mem2reg pass
+optimizes all of our stack variables into SSA registers, inserting PHI
+nodes where needed, and our front-end remains simple: no âiterated
+dominance frontierâ computation anywhere in sight.</p>
+</div>
+<div class="section" id="id1">
+<h2><a class="toc-backref" href="#id9">7.8. Full Code Listing</a><a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h2>
+<p>Here is the complete code listing for our running example, enhanced with
+mutable variables and var/in support. To build this example, use:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># Compile</span>
+ocamlbuild toy.byte
+<span class="c1"># Run</span>
+./toy.byte
+</pre></div>
+</div>
+<p>Here is the code:</p>
+<dl class="docutils">
+<dt>_tags:</dt>
+<dd><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o"><</span><span class="p">{</span><span class="n">lexer</span><span class="p">,</span><span class="n">parser</span><span class="p">}</span><span class="o">.</span><span class="n">ml</span><span class="o">></span><span class="p">:</span> <span class="n">use_camlp4</span><span class="p">,</span> <span class="n">pp</span><span class="p">(</span><span class="n">camlp4of</span><span class="p">)</span>
+<span class="o"><*.</span><span class="p">{</span><span class="n">byte</span><span class="p">,</span><span class="n">native</span><span class="p">}</span><span class="o">></span><span class="p">:</span> <span class="n">g</span><span class="o">++</span><span class="p">,</span> <span class="n">use_llvm</span><span class="p">,</span> <span class="n">use_llvm_analysis</span>
+<span class="o"><*.</span><span class="p">{</span><span class="n">byte</span><span class="p">,</span><span class="n">native</span><span class="p">}</span><span class="o">></span><span class="p">:</span> <span class="n">use_llvm_executionengine</span><span class="p">,</span> <span class="n">use_llvm_target</span>
+<span class="o"><*.</span><span class="p">{</span><span class="n">byte</span><span class="p">,</span><span class="n">native</span><span class="p">}</span><span class="o">></span><span class="p">:</span> <span class="n">use_llvm_scalar_opts</span><span class="p">,</span> <span class="n">use_bindings</span>
+</pre></div>
+</div>
+</dd>
+<dt>myocamlbuild.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="k">open</span> <span class="nc">Ocamlbuild_plugin</span><span class="o">;;</span>
+
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_analysis"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_executionengine"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_target"</span><span class="o">;;</span>
+<span class="n">ocaml_lib</span> <span class="o">~</span><span class="n">extern</span><span class="o">:</span><span class="bp">true</span> <span class="s2">"llvm_scalar_opts"</span><span class="o">;;</span>
+
+<span class="n">flag</span> <span class="o">[</span><span class="s2">"link"</span><span class="o">;</span> <span class="s2">"ocaml"</span><span class="o">;</span> <span class="s2">"g++"</span><span class="o">]</span> <span class="o">(</span><span class="nc">S</span><span class="o">[</span><span class="nc">A</span><span class="s2">"-cc"</span><span class="o">;</span> <span class="nc">A</span><span class="s2">"g++"</span><span class="o">;</span> <span class="nc">A</span><span class="s2">"-cclib"</span><span class="o">;</span> <span class="nc">A</span><span class="s2">"-rdynamic"</span><span class="o">]);;</span>
+<span class="n">dep</span> <span class="o">[</span><span class="s2">"link"</span><span class="o">;</span> <span class="s2">"ocaml"</span><span class="o">;</span> <span class="s2">"use_bindings"</span><span class="o">]</span> <span class="o">[</span><span class="s2">"bindings.o"</span><span class="o">];;</span>
+</pre></div>
+</div>
+</dd>
+<dt>token.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Lexer Tokens</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="c">(* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of</span>
+<span class="c"> * these others for known things. *)</span>
+<span class="k">type</span> <span class="n">token</span> <span class="o">=</span>
+ <span class="c">(* commands *)</span>
+ <span class="o">|</span> <span class="nc">Def</span> <span class="o">|</span> <span class="nc">Extern</span>
+
+ <span class="c">(* primary *)</span>
+ <span class="o">|</span> <span class="nc">Ident</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">|</span> <span class="nc">Number</span> <span class="k">of</span> <span class="kt">float</span>
+
+ <span class="c">(* unknown *)</span>
+ <span class="o">|</span> <span class="nc">Kwd</span> <span class="k">of</span> <span class="kt">char</span>
+
+ <span class="c">(* control *)</span>
+ <span class="o">|</span> <span class="nc">If</span> <span class="o">|</span> <span class="nc">Then</span> <span class="o">|</span> <span class="nc">Else</span>
+ <span class="o">|</span> <span class="nc">For</span> <span class="o">|</span> <span class="nc">In</span>
+
+ <span class="c">(* operators *)</span>
+ <span class="o">|</span> <span class="nc">Binary</span> <span class="o">|</span> <span class="nc">Unary</span>
+
+ <span class="c">(* var definition *)</span>
+ <span class="o">|</span> <span class="nc">Var</span>
+</pre></div>
+</div>
+</dd>
+<dt>lexer.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Lexer</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">let</span> <span class="k">rec</span> <span class="n">lex</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* Skip any whitespace. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">' '</span> <span class="o">|</span> <span class="sc">'\n'</span> <span class="o">|</span> <span class="sc">'\r'</span> <span class="o">|</span> <span class="sc">'\t'</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">lex</span> <span class="n">stream</span>
+
+ <span class="c">(* identifier: [a-zA-Z][a-zA-Z0-9] *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'A'</span> <span class="o">..</span> <span class="sc">'Z'</span> <span class="o">|</span> <span class="sc">'a'</span> <span class="o">..</span> <span class="sc">'z'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">buffer</span> <span class="o">=</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">create</span> <span class="mi">1</span> <span class="k">in</span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="n">stream</span>
+
+ <span class="c">(* number: [0-9.]+ *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'0'</span> <span class="o">..</span> <span class="sc">'9'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">buffer</span> <span class="o">=</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">create</span> <span class="mi">1</span> <span class="k">in</span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_number</span> <span class="n">buffer</span> <span class="n">stream</span>
+
+ <span class="c">(* Comment until end of line. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'#'</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="n">lex_comment</span> <span class="n">stream</span>
+
+ <span class="c">(* Otherwise, just return the character as its ascii value. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="n">c</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">c</span><span class="o">;</span> <span class="n">lex</span> <span class="n">stream</span> <span class="o">>]</span>
+
+ <span class="c">(* end of stream. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="o">[<</span> <span class="o">>]</span>
+
+<span class="ow">and</span> <span class="n">lex_number</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'0'</span> <span class="o">..</span> <span class="sc">'9'</span> <span class="o">|</span> <span class="sc">'.'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_number</span> <span class="n">buffer</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">stream</span><span class="o">=</span><span class="n">lex</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="o">(</span><span class="n">float_of_string</span> <span class="o">(</span><span class="nn">Buffer</span><span class="p">.</span><span class="n">contents</span> <span class="n">buffer</span><span class="o">));</span> <span class="n">stream</span> <span class="o">>]</span>
+
+<span class="ow">and</span> <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'A'</span> <span class="o">..</span> <span class="sc">'Z'</span> <span class="o">|</span> <span class="sc">'a'</span> <span class="o">..</span> <span class="sc">'z'</span> <span class="o">|</span> <span class="sc">'0'</span> <span class="o">..</span> <span class="sc">'9'</span> <span class="k">as</span> <span class="n">c</span><span class="o">);</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Buffer</span><span class="p">.</span><span class="n">add_char</span> <span class="n">buffer</span> <span class="n">c</span><span class="o">;</span>
+ <span class="n">lex_ident</span> <span class="n">buffer</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">stream</span><span class="o">=</span><span class="n">lex</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">match</span> <span class="nn">Buffer</span><span class="p">.</span><span class="n">contents</span> <span class="n">buffer</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="s2">"def"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"extern"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"if"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">If</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"then"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Then</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"else"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Else</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"for"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"in"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"binary"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Binary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"unary"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Unary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="s2">"var"</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Var</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+ <span class="o">|</span> <span class="n">id</span> <span class="o">-></span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span>
+
+<span class="ow">and</span> <span class="n">lex_comment</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span> <span class="o">(</span><span class="sc">'\n'</span><span class="o">);</span> <span class="n">stream</span><span class="o">=</span><span class="n">lex</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="n">c</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">lex_comment</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="o">[<</span> <span class="o">>]</span>
+</pre></div>
+</div>
+</dd>
+<dt>ast.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Abstract Syntax Tree (aka Parse Tree)</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="c">(* expr - Base type for all expression nodes. *)</span>
+<span class="k">type</span> <span class="n">expr</span> <span class="o">=</span>
+ <span class="c">(* variant for numeric literals like "1.0". *)</span>
+ <span class="o">|</span> <span class="nc">Number</span> <span class="k">of</span> <span class="kt">float</span>
+
+ <span class="c">(* variant for referencing a variable, like "a". *)</span>
+ <span class="o">|</span> <span class="nc">Variable</span> <span class="k">of</span> <span class="kt">string</span>
+
+ <span class="c">(* variant for a unary operator. *)</span>
+ <span class="o">|</span> <span class="nc">Unary</span> <span class="k">of</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">expr</span>
+
+ <span class="c">(* variant for a binary operator. *)</span>
+ <span class="o">|</span> <span class="nc">Binary</span> <span class="k">of</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span>
+
+ <span class="c">(* variant for function calls. *)</span>
+ <span class="o">|</span> <span class="nc">Call</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="n">expr</span> <span class="kt">array</span>
+
+ <span class="c">(* variant for if/then/else. *)</span>
+ <span class="o">|</span> <span class="nc">If</span> <span class="k">of</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span>
+
+ <span class="c">(* variant for for/in. *)</span>
+ <span class="o">|</span> <span class="nc">For</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="o">*</span> <span class="n">expr</span> <span class="n">option</span> <span class="o">*</span> <span class="n">expr</span>
+
+ <span class="c">(* variant for var/in. *)</span>
+ <span class="o">|</span> <span class="nc">Var</span> <span class="k">of</span> <span class="o">(</span><span class="kt">string</span> <span class="o">*</span> <span class="n">expr</span> <span class="n">option</span><span class="o">)</span> <span class="kt">array</span> <span class="o">*</span> <span class="n">expr</span>
+
+<span class="c">(* proto - This type represents the "prototype" for a function, which captures</span>
+<span class="c"> * its name, and its argument names (thus implicitly the number of arguments the</span>
+<span class="c"> * function takes). *)</span>
+<span class="k">type</span> <span class="n">proto</span> <span class="o">=</span>
+ <span class="o">|</span> <span class="nc">Prototype</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="kt">string</span> <span class="kt">array</span>
+ <span class="o">|</span> <span class="nc">BinOpPrototype</span> <span class="k">of</span> <span class="kt">string</span> <span class="o">*</span> <span class="kt">string</span> <span class="kt">array</span> <span class="o">*</span> <span class="kt">int</span>
+
+<span class="c">(* func - This type represents a function definition itself. *)</span>
+<span class="k">type</span> <span class="n">func</span> <span class="o">=</span> <span class="nc">Function</span> <span class="k">of</span> <span class="n">proto</span> <span class="o">*</span> <span class="n">expr</span>
+</pre></div>
+</div>
+</dd>
+<dt>parser.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===---------------------------------------------------------------------===</span>
+<span class="c"> * Parser</span>
+<span class="c"> *===---------------------------------------------------------------------===*)</span>
+
+<span class="c">(* binop_precedence - This holds the precedence for each binary operator that is</span>
+<span class="c"> * defined *)</span>
+<span class="k">let</span> <span class="n">binop_precedence</span><span class="o">:(</span><span class="kt">char</span><span class="o">,</span> <span class="kt">int</span><span class="o">)</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">t</span> <span class="o">=</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">create</span> <span class="mi">10</span>
+
+<span class="c">(* precedence - Get the precedence of the pending binary operator token. *)</span>
+<span class="k">let</span> <span class="n">precedence</span> <span class="n">c</span> <span class="o">=</span> <span class="k">try</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">binop_precedence</span> <span class="n">c</span> <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="o">-</span><span class="mi">1</span>
+
+<span class="c">(* primary</span>
+<span class="c"> * ::= identifier</span>
+<span class="c"> * ::= numberexpr</span>
+<span class="c"> * ::= parenexpr</span>
+<span class="c"> * ::= ifexpr</span>
+<span class="c"> * ::= forexpr</span>
+<span class="c"> * ::= varexpr *)</span>
+<span class="k">let</span> <span class="k">rec</span> <span class="n">parse_primary</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* numberexpr ::= number *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">>]</span> <span class="o">-></span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span>
+
+ <span class="c">(* parenexpr ::= '(' expression ')' *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')'"</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+
+ <span class="c">(* identifierexpr</span>
+<span class="c"> * ::= identifier</span>
+<span class="c"> * ::= identifier '(' argumentexpr ')' *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_args</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_args</span> <span class="o">(</span><span class="n">e</span> <span class="o">::</span> <span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span> <span class="o">::</span> <span class="n">accumulator</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_ident</span> <span class="n">id</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* Call. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')'"</span><span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Call</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">))</span>
+
+ <span class="c">(* Simple variable ref. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Variable</span> <span class="n">id</span>
+ <span class="k">in</span>
+ <span class="n">parse_ident</span> <span class="n">id</span> <span class="n">stream</span>
+
+ <span class="c">(* ifexpr ::= 'if' expr 'then' expr 'else' expr *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">If</span><span class="o">;</span> <span class="n">c</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Then</span> <span class="o">??</span> <span class="s2">"expected 'then'"</span><span class="o">;</span> <span class="n">t</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Else</span> <span class="o">??</span> <span class="s2">"expected 'else'"</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">If</span> <span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="n">t</span><span class="o">,</span> <span class="n">e</span><span class="o">)</span>
+
+ <span class="c">(* forexpr</span>
+<span class="c"> ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">For</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span> <span class="o">??</span> <span class="s2">"expected identifier after for"</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'='</span> <span class="o">??</span> <span class="s2">"expected '=' after for"</span><span class="o">;</span>
+ <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span>
+ <span class="n">start</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span> <span class="o">??</span> <span class="s2">"expected ',' after for"</span><span class="o">;</span>
+ <span class="n">end_</span><span class="o">=</span><span class="n">parse_expr</span><span class="o">;</span>
+ <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">step</span> <span class="o">=</span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span><span class="o">;</span> <span class="n">step</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">Some</span> <span class="n">step</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">None</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="k">in</span>
+ <span class="k">begin</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span><span class="o">;</span> <span class="n">body</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">For</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">end_</span><span class="o">,</span> <span class="n">step</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected 'in' after for"</span><span class="o">)</span>
+ <span class="k">end</span> <span class="n">stream</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected '=' after for"</span><span class="o">)</span>
+ <span class="k">end</span> <span class="n">stream</span>
+
+ <span class="c">(* varexpr</span>
+<span class="c"> * ::= 'var' identifier ('=' expression?</span>
+<span class="c"> * (',' identifier ('=' expression)?)* 'in' expression *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Var</span><span class="o">;</span>
+ <span class="c">(* At least one variable name is required. *)</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span> <span class="o">??</span> <span class="s2">"expected identifier after var"</span><span class="o">;</span>
+ <span class="n">init</span><span class="o">=</span><span class="n">parse_var_init</span><span class="o">;</span>
+ <span class="n">var_names</span><span class="o">=</span><span class="n">parse_var_names</span> <span class="o">[(</span><span class="n">id</span><span class="o">,</span> <span class="n">init</span><span class="o">)];</span>
+ <span class="c">(* At this point, we have to have 'in'. *)</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">In</span> <span class="o">??</span> <span class="s2">"expected 'in' keyword after 'var'"</span><span class="o">;</span>
+ <span class="n">body</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Var</span> <span class="o">(</span><span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">var_names</span><span class="o">),</span> <span class="n">body</span><span class="o">)</span>
+
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"unknown token when expecting an expression."</span><span class="o">)</span>
+
+<span class="c">(* unary</span>
+<span class="c"> * ::= primary</span>
+<span class="c"> * ::= '!' unary *)</span>
+<span class="ow">and</span> <span class="n">parse_unary</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* If this is a unary operator, read it. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">op</span> <span class="k">when</span> <span class="n">op</span> <span class="o">!=</span> <span class="sc">'('</span> <span class="o">&&</span> <span class="n">op</span> <span class="o">!=</span> <span class="sc">')'</span><span class="o">;</span> <span class="n">operand</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">operand</span><span class="o">)</span>
+
+ <span class="c">(* If the current token is not an operator, it must be a primary expr. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">parse_primary</span> <span class="n">stream</span>
+
+<span class="c">(* binoprhs</span>
+<span class="c"> * ::= ('+' primary)* *)</span>
+<span class="ow">and</span> <span class="n">parse_bin_rhs</span> <span class="n">expr_prec</span> <span class="n">lhs</span> <span class="n">stream</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="nn">Stream</span><span class="p">.</span><span class="n">peek</span> <span class="n">stream</span> <span class="k">with</span>
+ <span class="c">(* If this is a binop, find its precedence. *)</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">c</span><span class="o">)</span> <span class="k">when</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">mem</span> <span class="n">binop_precedence</span> <span class="n">c</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">token_prec</span> <span class="o">=</span> <span class="n">precedence</span> <span class="n">c</span> <span class="k">in</span>
+
+ <span class="c">(* If this is a binop that binds at least as tightly as the current binop,</span>
+<span class="c"> * consume it, otherwise we are done. *)</span>
+ <span class="k">if</span> <span class="n">token_prec</span> <span class="o"><</span> <span class="n">expr_prec</span> <span class="k">then</span> <span class="n">lhs</span> <span class="k">else</span> <span class="k">begin</span>
+ <span class="c">(* Eat the binop. *)</span>
+ <span class="nn">Stream</span><span class="p">.</span><span class="n">junk</span> <span class="n">stream</span><span class="o">;</span>
+
+ <span class="c">(* Parse the primary expression after the binary operator. *)</span>
+ <span class="k">let</span> <span class="n">rhs</span> <span class="o">=</span> <span class="n">parse_unary</span> <span class="n">stream</span> <span class="k">in</span>
+
+ <span class="c">(* Okay, we know this is a binop. *)</span>
+ <span class="k">let</span> <span class="n">rhs</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="nn">Stream</span><span class="p">.</span><span class="n">peek</span> <span class="n">stream</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">c2</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* If BinOp binds less tightly with rhs than the operator after</span>
+<span class="c"> * rhs, let the pending operator take rhs as its lhs. *)</span>
+ <span class="k">let</span> <span class="n">next_prec</span> <span class="o">=</span> <span class="n">precedence</span> <span class="n">c2</span> <span class="k">in</span>
+ <span class="k">if</span> <span class="n">token_prec</span> <span class="o"><</span> <span class="n">next_prec</span>
+ <span class="k">then</span> <span class="n">parse_bin_rhs</span> <span class="o">(</span><span class="n">token_prec</span> <span class="o">+</span> <span class="mi">1</span><span class="o">)</span> <span class="n">rhs</span> <span class="n">stream</span>
+ <span class="k">else</span> <span class="n">rhs</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="n">rhs</span>
+ <span class="k">in</span>
+
+ <span class="c">(* Merge lhs/rhs. *)</span>
+ <span class="k">let</span> <span class="n">lhs</span> <span class="o">=</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="n">lhs</span><span class="o">,</span> <span class="n">rhs</span><span class="o">)</span> <span class="k">in</span>
+ <span class="n">parse_bin_rhs</span> <span class="n">expr_prec</span> <span class="n">lhs</span> <span class="n">stream</span>
+ <span class="k">end</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="n">lhs</span>
+
+<span class="ow">and</span> <span class="n">parse_var_init</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="c">(* read in the optional initializer. *)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'='</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">Some</span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="nc">None</span>
+
+<span class="ow">and</span> <span class="n">parse_var_names</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">','</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span> <span class="o">??</span> <span class="s2">"expected identifier list after var"</span><span class="o">;</span>
+ <span class="n">init</span><span class="o">=</span><span class="n">parse_var_init</span><span class="o">;</span>
+ <span class="n">e</span><span class="o">=</span><span class="n">parse_var_names</span> <span class="o">((</span><span class="n">id</span><span class="o">,</span> <span class="n">init</span><span class="o">)</span> <span class="o">::</span> <span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+
+<span class="c">(* expression</span>
+<span class="c"> * ::= primary binoprhs *)</span>
+<span class="ow">and</span> <span class="n">parse_expr</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">lhs</span><span class="o">=</span><span class="n">parse_unary</span><span class="o">;</span> <span class="n">stream</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">parse_bin_rhs</span> <span class="mi">0</span> <span class="n">lhs</span> <span class="n">stream</span>
+
+<span class="c">(* prototype</span>
+<span class="c"> * ::= id '(' id* ')'</span>
+<span class="c"> * ::= binary LETTER number? (id, id)</span>
+<span class="c"> * ::= unary LETTER number? (id) *)</span>
+<span class="k">let</span> <span class="n">parse_prototype</span> <span class="o">=</span>
+ <span class="k">let</span> <span class="k">rec</span> <span class="n">parse_args</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_args</span> <span class="o">(</span><span class="n">id</span><span class="o">::</span><span class="n">accumulator</span><span class="o">)</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">accumulator</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">parse_operator</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">>]</span> <span class="o">-></span> <span class="s2">"unary"</span><span class="o">,</span> <span class="mi">1</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">>]</span> <span class="o">-></span> <span class="s2">"binary"</span><span class="o">,</span> <span class="mi">2</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">parse_binary_precedence</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">int_of_float</span> <span class="n">n</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span> <span class="mi">30</span>
+ <span class="k">in</span>
+ <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Ident</span> <span class="n">id</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span> <span class="o">??</span> <span class="s2">"expected '(' in prototype"</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')' in prototype"</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="c">(* success. *)</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">))</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">(</span><span class="n">prefix</span><span class="o">,</span> <span class="n">kind</span><span class="o">)=</span><span class="n">parse_operator</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="n">op</span> <span class="o">??</span> <span class="s2">"expected an operator"</span><span class="o">;</span>
+ <span class="c">(* Read the precedence if present. *)</span>
+ <span class="n">binary_precedence</span><span class="o">=</span><span class="n">parse_binary_precedence</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">'('</span> <span class="o">??</span> <span class="s2">"expected '(' in prototype"</span><span class="o">;</span>
+ <span class="n">args</span><span class="o">=</span><span class="n">parse_args</span> <span class="bp">[]</span><span class="o">;</span>
+ <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">')'</span> <span class="o">??</span> <span class="s2">"expected ')' in prototype"</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">name</span> <span class="o">=</span> <span class="n">prefix</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">args</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">of_list</span> <span class="o">(</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">args</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Verify right number of arguments for operator. *)</span>
+ <span class="k">if</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span> <span class="o">!=</span> <span class="n">kind</span>
+ <span class="k">then</span> <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"invalid number of operands for operator"</span><span class="o">)</span>
+ <span class="k">else</span>
+ <span class="k">if</span> <span class="n">kind</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">then</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span>
+ <span class="k">else</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">,</span> <span class="n">binary_precedence</span><span class="o">)</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="s2">"expected function name in prototype"</span><span class="o">)</span>
+
+<span class="c">(* definition ::= 'def' prototype expression *)</span>
+<span class="k">let</span> <span class="n">parse_definition</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span><span class="o">;</span> <span class="n">p</span><span class="o">=</span><span class="n">parse_prototype</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="n">p</span><span class="o">,</span> <span class="n">e</span><span class="o">)</span>
+
+<span class="c">(* toplevelexpr ::= expression *)</span>
+<span class="k">let</span> <span class="n">parse_toplevel</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_expr</span> <span class="o">>]</span> <span class="o">-></span>
+ <span class="c">(* Make an anonymous proto. *)</span>
+ <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="s2">""</span><span class="o">,</span> <span class="o">[||]),</span> <span class="n">e</span><span class="o">)</span>
+
+<span class="c">(* external ::= 'extern' prototype *)</span>
+<span class="k">let</span> <span class="n">parse_extern</span> <span class="o">=</span> <span class="n">parser</span>
+ <span class="o">|</span> <span class="o">[<</span> <span class="k">'</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span><span class="o">;</span> <span class="n">e</span><span class="o">=</span><span class="n">parse_prototype</span> <span class="o">>]</span> <span class="o">-></span> <span class="n">e</span>
+</pre></div>
+</div>
+</dd>
+<dt>codegen.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Code Generation</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">open</span> <span class="nc">Llvm</span>
+
+<span class="k">exception</span> <span class="nc">Error</span> <span class="k">of</span> <span class="kt">string</span>
+
+<span class="k">let</span> <span class="n">context</span> <span class="o">=</span> <span class="n">global_context</span> <span class="bp">()</span>
+<span class="k">let</span> <span class="n">the_module</span> <span class="o">=</span> <span class="n">create_module</span> <span class="n">context</span> <span class="s2">"my cool jit"</span>
+<span class="k">let</span> <span class="n">builder</span> <span class="o">=</span> <span class="n">builder</span> <span class="n">context</span>
+<span class="k">let</span> <span class="n">named_values</span><span class="o">:(</span><span class="kt">string</span><span class="o">,</span> <span class="n">llvalue</span><span class="o">)</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">t</span> <span class="o">=</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">create</span> <span class="mi">10</span>
+<span class="k">let</span> <span class="n">double_type</span> <span class="o">=</span> <span class="n">double_type</span> <span class="n">context</span>
+
+<span class="c">(* Create an alloca instruction in the entry block of the function. This</span>
+<span class="c"> * is used for mutable variables etc. *)</span>
+<span class="k">let</span> <span class="n">create_entry_block_alloca</span> <span class="n">the_function</span> <span class="n">var_name</span> <span class="o">=</span>
+ <span class="k">let</span> <span class="n">builder</span> <span class="o">=</span> <span class="n">builder_at</span> <span class="n">context</span> <span class="o">(</span><span class="n">instr_begin</span> <span class="o">(</span><span class="n">entry_block</span> <span class="n">the_function</span><span class="o">))</span> <span class="k">in</span>
+ <span class="n">build_alloca</span> <span class="n">double_type</span> <span class="n">var_name</span> <span class="n">builder</span>
+
+<span class="k">let</span> <span class="k">rec</span> <span class="n">codegen_expr</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Number</span> <span class="n">n</span> <span class="o">-></span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="n">n</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Variable</span> <span class="n">name</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">v</span> <span class="o">=</span> <span class="k">try</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">name</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown variable name"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="c">(* Load the value. *)</span>
+ <span class="n">build_load</span> <span class="n">v</span> <span class="n">name</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Unary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">operand</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">operand</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">operand</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span> <span class="s2">"unary"</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">callee</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">callee</span> <span class="o">-></span> <span class="n">callee</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown unary operator"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="n">build_call</span> <span class="n">callee</span> <span class="o">[|</span><span class="n">operand</span><span class="o">|]</span> <span class="s2">"unop"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Binary</span> <span class="o">(</span><span class="n">op</span><span class="o">,</span> <span class="n">lhs</span><span class="o">,</span> <span class="n">rhs</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">begin</span> <span class="k">match</span> <span class="n">op</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="sc">'='</span> <span class="o">-></span>
+ <span class="c">(* Special case '=' because we don't want to emit the LHS as an</span>
+<span class="c"> * expression. *)</span>
+ <span class="k">let</span> <span class="n">name</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lhs</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Variable</span> <span class="n">name</span> <span class="o">-></span> <span class="n">name</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"destination of '=' must be a variable"</span><span class="o">)</span>
+ <span class="k">in</span>
+
+ <span class="c">(* Codegen the rhs. *)</span>
+ <span class="k">let</span> <span class="n">val_</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">rhs</span> <span class="k">in</span>
+
+ <span class="c">(* Lookup the name. *)</span>
+ <span class="k">let</span> <span class="n">variable</span> <span class="o">=</span> <span class="k">try</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">name</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown variable name"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">val_</span> <span class="n">variable</span> <span class="n">builder</span><span class="o">);</span>
+ <span class="n">val_</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">lhs_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">lhs</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">rhs_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">rhs</span> <span class="k">in</span>
+ <span class="k">begin</span>
+ <span class="k">match</span> <span class="n">op</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="sc">'+'</span> <span class="o">-></span> <span class="n">build_add</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"addtmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'-'</span> <span class="o">-></span> <span class="n">build_sub</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"subtmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'*'</span> <span class="o">-></span> <span class="n">build_mul</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"multmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="sc">'<'</span> <span class="o">-></span>
+ <span class="c">(* Convert bool 0/1 to double 0.0 or 1.0 *)</span>
+ <span class="k">let</span> <span class="n">i</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">Ult</span> <span class="n">lhs_val</span> <span class="n">rhs_val</span> <span class="s2">"cmptmp"</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="n">build_uitofp</span> <span class="n">i</span> <span class="n">double_type</span> <span class="s2">"booltmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span>
+ <span class="c">(* If it wasn't a builtin binary operator, it must be a user defined</span>
+<span class="c"> * one. Emit a call to it. *)</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span> <span class="s2">"binary"</span> <span class="o">^</span> <span class="o">(</span><span class="nn">String</span><span class="p">.</span><span class="n">make</span> <span class="mi">1</span> <span class="n">op</span><span class="o">)</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">callee</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">callee</span> <span class="o">-></span> <span class="n">callee</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"binary operator not found!"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="n">build_call</span> <span class="n">callee</span> <span class="o">[|</span><span class="n">lhs_val</span><span class="o">;</span> <span class="n">rhs_val</span><span class="o">|]</span> <span class="s2">"binop"</span> <span class="n">builder</span>
+ <span class="k">end</span>
+ <span class="k">end</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Call</span> <span class="o">(</span><span class="n">callee</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* Look up the name in the module table. *)</span>
+ <span class="k">let</span> <span class="n">callee</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">callee</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">callee</span> <span class="o">-></span> <span class="n">callee</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"unknown function referenced"</span><span class="o">)</span>
+ <span class="k">in</span>
+ <span class="k">let</span> <span class="n">params</span> <span class="o">=</span> <span class="n">params</span> <span class="n">callee</span> <span class="k">in</span>
+
+ <span class="c">(* If argument mismatch error. *)</span>
+ <span class="k">if</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">params</span> <span class="o">==</span> <span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span> <span class="k">then</span> <span class="bp">()</span> <span class="k">else</span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"incorrect # arguments passed"</span><span class="o">);</span>
+ <span class="k">let</span> <span class="n">args</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">map</span> <span class="n">codegen_expr</span> <span class="n">args</span> <span class="k">in</span>
+ <span class="n">build_call</span> <span class="n">callee</span> <span class="n">args</span> <span class="s2">"calltmp"</span> <span class="n">builder</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">If</span> <span class="o">(</span><span class="n">cond</span><span class="o">,</span> <span class="n">then_</span><span class="o">,</span> <span class="n">else_</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">cond</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">cond</span> <span class="k">in</span>
+
+ <span class="c">(* Convert condition to a bool by comparing equal to 0.0 *)</span>
+ <span class="k">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">cond_val</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">One</span> <span class="n">cond</span> <span class="n">zero</span> <span class="s2">"ifcond"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Grab the first block so that we might later add the conditional branch</span>
+<span class="c"> * to it at the end of the function. *)</span>
+ <span class="k">let</span> <span class="n">start_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="n">start_bb</span> <span class="k">in</span>
+
+ <span class="k">let</span> <span class="n">then_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"then"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+ <span class="c">(* Emit 'then' value. *)</span>
+ <span class="n">position_at_end</span> <span class="n">then_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">then_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">then_</span> <span class="k">in</span>
+
+ <span class="c">(* Codegen of 'then' can change the current block, update then_bb for the</span>
+<span class="c"> * phi. We create a new name because one is used for the phi node, and the</span>
+<span class="c"> * other is used for the conditional branch. *)</span>
+ <span class="k">let</span> <span class="n">new_then_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Emit 'else' value. *)</span>
+ <span class="k">let</span> <span class="n">else_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"else"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">else_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">else_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">else_</span> <span class="k">in</span>
+
+ <span class="c">(* Codegen of 'else' can change the current block, update else_bb for the</span>
+<span class="c"> * phi. *)</span>
+ <span class="k">let</span> <span class="n">new_else_bb</span> <span class="o">=</span> <span class="n">insertion_block</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Emit merge block. *)</span>
+ <span class="k">let</span> <span class="n">merge_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"ifcont"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">incoming</span> <span class="o">=</span> <span class="o">[(</span><span class="n">then_val</span><span class="o">,</span> <span class="n">new_then_bb</span><span class="o">);</span> <span class="o">(</span><span class="n">else_val</span><span class="o">,</span> <span class="n">new_else_bb</span><span class="o">)]</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">phi</span> <span class="o">=</span> <span class="n">build_phi</span> <span class="n">incoming</span> <span class="s2">"iftmp"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Return to the start block to add the conditional branch. *)</span>
+ <span class="n">position_at_end</span> <span class="n">start_bb</span> <span class="n">builder</span><span class="o">;</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">build_cond_br</span> <span class="n">cond_val</span> <span class="n">then_bb</span> <span class="n">else_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Set a unconditional branch at the end of the 'then' block and the</span>
+<span class="c"> * 'else' block to the 'merge' block. *)</span>
+ <span class="n">position_at_end</span> <span class="n">new_then_bb</span> <span class="n">builder</span><span class="o">;</span> <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">);</span>
+ <span class="n">position_at_end</span> <span class="n">new_else_bb</span> <span class="n">builder</span><span class="o">;</span> <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Finally, set the builder to the end of the merge block. *)</span>
+ <span class="n">position_at_end</span> <span class="n">merge_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="n">phi</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">For</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">end_</span><span class="o">,</span> <span class="n">step</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* Output this as:</span>
+<span class="c"> * var = alloca double</span>
+<span class="c"> * ...</span>
+<span class="c"> * start = startexpr</span>
+<span class="c"> * store start -> var</span>
+<span class="c"> * goto loop</span>
+<span class="c"> * loop:</span>
+<span class="c"> * ...</span>
+<span class="c"> * bodyexpr</span>
+<span class="c"> * ...</span>
+<span class="c"> * loopend:</span>
+<span class="c"> * step = stepexpr</span>
+<span class="c"> * endcond = endexpr</span>
+<span class="c"> *</span>
+<span class="c"> * curvar = load var</span>
+<span class="c"> * nextvar = curvar + step</span>
+<span class="c"> * store nextvar -> var</span>
+<span class="c"> * br endcond, loop, endloop</span>
+<span class="c"> * outloop: *)</span>
+
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="o">(</span><span class="n">insertion_block</span> <span class="n">builder</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Create an alloca for the variable in the entry block. *)</span>
+ <span class="k">let</span> <span class="n">alloca</span> <span class="o">=</span> <span class="n">create_entry_block_alloca</span> <span class="n">the_function</span> <span class="n">var_name</span> <span class="k">in</span>
+
+ <span class="c">(* Emit the start code first, without 'variable' in scope. *)</span>
+ <span class="k">let</span> <span class="n">start_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">start</span> <span class="k">in</span>
+
+ <span class="c">(* Store the value into the alloca. *)</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">start_val</span> <span class="n">alloca</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Make the new basic block for the loop header, inserting after current</span>
+<span class="c"> * block. *)</span>
+ <span class="k">let</span> <span class="n">loop_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"loop"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+ <span class="c">(* Insert an explicit fall through from the current block to the</span>
+<span class="c"> * loop_bb. *)</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">build_br</span> <span class="n">loop_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Start insertion in loop_bb. *)</span>
+ <span class="n">position_at_end</span> <span class="n">loop_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="c">(* Within the loop, the variable is defined equal to the PHI node. If it</span>
+<span class="c"> * shadows an existing variable, we have to restore it, so save it</span>
+<span class="c"> * now. *)</span>
+ <span class="k">let</span> <span class="n">old_val</span> <span class="o">=</span>
+ <span class="k">try</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">var_name</span><span class="o">)</span> <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="nc">None</span>
+ <span class="k">in</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">alloca</span><span class="o">;</span>
+
+ <span class="c">(* Emit the body of the loop. This, like any other expr, can change the</span>
+<span class="c"> * current BB. Note that we ignore the value computed by the body, but</span>
+<span class="c"> * don't allow an error *)</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">codegen_expr</span> <span class="n">body</span><span class="o">);</span>
+
+ <span class="c">(* Emit the step value. *)</span>
+ <span class="k">let</span> <span class="n">step_val</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">step</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">step</span> <span class="o">-></span> <span class="n">codegen_expr</span> <span class="n">step</span>
+ <span class="c">(* If not specified, use 1.0. *)</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">1</span><span class="o">.</span><span class="mi">0</span>
+ <span class="k">in</span>
+
+ <span class="c">(* Compute the end condition. *)</span>
+ <span class="k">let</span> <span class="n">end_cond</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">end_</span> <span class="k">in</span>
+
+ <span class="c">(* Reload, increment, and restore the alloca. This handles the case where</span>
+<span class="c"> * the body of the loop mutates the variable. *)</span>
+ <span class="k">let</span> <span class="n">cur_var</span> <span class="o">=</span> <span class="n">build_load</span> <span class="n">alloca</span> <span class="n">var_name</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">next_var</span> <span class="o">=</span> <span class="n">build_add</span> <span class="n">cur_var</span> <span class="n">step_val</span> <span class="s2">"nextvar"</span> <span class="n">builder</span> <span class="k">in</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">next_var</span> <span class="n">alloca</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Convert condition to a bool by comparing equal to 0.0. *)</span>
+ <span class="k">let</span> <span class="n">zero</span> <span class="o">=</span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">end_cond</span> <span class="o">=</span> <span class="n">build_fcmp</span> <span class="nn">Fcmp</span><span class="p">.</span><span class="nc">One</span> <span class="n">end_cond</span> <span class="n">zero</span> <span class="s2">"loopcond"</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Create the "after loop" block and insert it. *)</span>
+ <span class="k">let</span> <span class="n">after_bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"afterloop"</span> <span class="n">the_function</span> <span class="k">in</span>
+
+ <span class="c">(* Insert the conditional branch into the end of loop_end_bb. *)</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">build_cond_br</span> <span class="n">end_cond</span> <span class="n">loop_bb</span> <span class="n">after_bb</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Any new code will be inserted in after_bb. *)</span>
+ <span class="n">position_at_end</span> <span class="n">after_bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="c">(* Restore the unshadowed variable. *)</span>
+ <span class="k">begin</span> <span class="k">match</span> <span class="n">old_val</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">old_val</span> <span class="o">-></span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">old_val</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="bp">()</span>
+ <span class="k">end</span><span class="o">;</span>
+
+ <span class="c">(* for expr always returns 0.0. *)</span>
+ <span class="n">const_null</span> <span class="n">double_type</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Var</span> <span class="o">(</span><span class="n">var_names</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">old_bindings</span> <span class="o">=</span> <span class="n">ref</span> <span class="bp">[]</span> <span class="k">in</span>
+
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">block_parent</span> <span class="o">(</span><span class="n">insertion_block</span> <span class="n">builder</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Register all variables and emit their initializer. *)</span>
+ <span class="nn">Array</span><span class="p">.</span><span class="n">iter</span> <span class="o">(</span><span class="k">fun</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">init</span><span class="o">)</span> <span class="o">-></span>
+ <span class="c">(* Emit the initializer before adding the variable to scope, this</span>
+<span class="c"> * prevents the initializer from referencing the variable itself, and</span>
+<span class="c"> * permits stuff like this:</span>
+<span class="c"> * var a = 1 in</span>
+<span class="c"> * var a = a in ... # refers to outer 'a'. *)</span>
+ <span class="k">let</span> <span class="n">init_val</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">init</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">init</span> <span class="o">-></span> <span class="n">codegen_expr</span> <span class="n">init</span>
+ <span class="c">(* If not specified, use 0.0. *)</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="n">const_float</span> <span class="n">double_type</span> <span class="mi">0</span><span class="o">.</span><span class="mi">0</span>
+ <span class="k">in</span>
+
+ <span class="k">let</span> <span class="n">alloca</span> <span class="o">=</span> <span class="n">create_entry_block_alloca</span> <span class="n">the_function</span> <span class="n">var_name</span> <span class="k">in</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">init_val</span> <span class="n">alloca</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Remember the old variable binding so that we can restore the binding</span>
+<span class="c"> * when we unrecurse. *)</span>
+ <span class="k">begin</span>
+ <span class="k">try</span>
+ <span class="k">let</span> <span class="n">old_value</span> <span class="o">=</span> <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">find</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="k">in</span>
+ <span class="n">old_bindings</span> <span class="o">:=</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">old_value</span><span class="o">)</span> <span class="o">::</span> <span class="o">!</span><span class="n">old_bindings</span><span class="o">;</span>
+ <span class="k">with</span> <span class="nc">Not_found</span> <span class="o">-></span> <span class="bp">()</span>
+ <span class="k">end</span><span class="o">;</span>
+
+ <span class="c">(* Remember this binding. *)</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">alloca</span><span class="o">;</span>
+ <span class="o">)</span> <span class="n">var_names</span><span class="o">;</span>
+
+ <span class="c">(* Codegen the body, now that all vars are in scope. *)</span>
+ <span class="k">let</span> <span class="n">body_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">body</span> <span class="k">in</span>
+
+ <span class="c">(* Pop all our variables from scope. *)</span>
+ <span class="nn">List</span><span class="p">.</span><span class="n">iter</span> <span class="o">(</span><span class="k">fun</span> <span class="o">(</span><span class="n">var_name</span><span class="o">,</span> <span class="n">old_value</span><span class="o">)</span> <span class="o">-></span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">old_value</span>
+ <span class="o">)</span> <span class="o">!</span><span class="n">old_bindings</span><span class="o">;</span>
+
+ <span class="c">(* Return the body computation. *)</span>
+ <span class="n">body_val</span>
+
+<span class="k">let</span> <span class="n">codegen_proto</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span> <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">,</span> <span class="o">_)</span> <span class="o">-></span>
+ <span class="c">(* Make the function type: double(double,double) etc. *)</span>
+ <span class="k">let</span> <span class="n">doubles</span> <span class="o">=</span> <span class="nn">Array</span><span class="p">.</span><span class="n">make</span> <span class="o">(</span><span class="nn">Array</span><span class="p">.</span><span class="n">length</span> <span class="n">args</span><span class="o">)</span> <span class="n">double_type</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">ft</span> <span class="o">=</span> <span class="n">function_type</span> <span class="n">double_type</span> <span class="n">doubles</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">f</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="n">lookup_function</span> <span class="n">name</span> <span class="n">the_module</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="n">declare_function</span> <span class="n">name</span> <span class="n">ft</span> <span class="n">the_module</span>
+
+ <span class="c">(* If 'f' conflicted, there was already something named 'name'. If it</span>
+<span class="c"> * has a body, don't allow redefinition or reextern. *)</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">f</span> <span class="o">-></span>
+ <span class="c">(* If 'f' already has a body, reject this. *)</span>
+ <span class="k">if</span> <span class="n">block_begin</span> <span class="n">f</span> <span class="o"><></span> <span class="nc">At_end</span> <span class="n">f</span> <span class="k">then</span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"redefinition of function"</span><span class="o">);</span>
+
+ <span class="c">(* If 'f' took a different number of arguments, reject. *)</span>
+ <span class="k">if</span> <span class="n">element_type</span> <span class="o">(</span><span class="n">type_of</span> <span class="n">f</span><span class="o">)</span> <span class="o"><></span> <span class="n">ft</span> <span class="k">then</span>
+ <span class="k">raise</span> <span class="o">(</span><span class="nc">Error</span> <span class="s2">"redefinition of function with different # args"</span><span class="o">);</span>
+ <span class="n">f</span>
+ <span class="k">in</span>
+
+ <span class="c">(* Set names for all arguments. *)</span>
+ <span class="nn">Array</span><span class="p">.</span><span class="n">iteri</span> <span class="o">(</span><span class="k">fun</span> <span class="n">i</span> <span class="n">a</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">n</span> <span class="o">=</span> <span class="n">args</span><span class="o">.(</span><span class="n">i</span><span class="o">)</span> <span class="k">in</span>
+ <span class="n">set_value_name</span> <span class="n">n</span> <span class="n">a</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">n</span> <span class="n">a</span><span class="o">;</span>
+ <span class="o">)</span> <span class="o">(</span><span class="n">params</span> <span class="n">f</span><span class="o">);</span>
+ <span class="n">f</span>
+
+<span class="c">(* Create an alloca for each argument and register the argument in the symbol</span>
+<span class="c"> * table so that references to it will succeed. *)</span>
+<span class="k">let</span> <span class="n">create_argument_allocas</span> <span class="n">the_function</span> <span class="n">proto</span> <span class="o">=</span>
+ <span class="k">let</span> <span class="n">args</span> <span class="o">=</span> <span class="k">match</span> <span class="n">proto</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Prototype</span> <span class="o">(_,</span> <span class="n">args</span><span class="o">)</span> <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(_,</span> <span class="n">args</span><span class="o">,</span> <span class="o">_)</span> <span class="o">-></span> <span class="n">args</span>
+ <span class="k">in</span>
+ <span class="nn">Array</span><span class="p">.</span><span class="n">iteri</span> <span class="o">(</span><span class="k">fun</span> <span class="n">i</span> <span class="n">ai</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">var_name</span> <span class="o">=</span> <span class="n">args</span><span class="o">.(</span><span class="n">i</span><span class="o">)</span> <span class="k">in</span>
+ <span class="c">(* Create an alloca for this variable. *)</span>
+ <span class="k">let</span> <span class="n">alloca</span> <span class="o">=</span> <span class="n">create_entry_block_alloca</span> <span class="n">the_function</span> <span class="n">var_name</span> <span class="k">in</span>
+
+ <span class="c">(* Store the initial value into the alloca. *)</span>
+ <span class="n">ignore</span><span class="o">(</span><span class="n">build_store</span> <span class="n">ai</span> <span class="n">alloca</span> <span class="n">builder</span><span class="o">);</span>
+
+ <span class="c">(* Add arguments to variable symbol table. *)</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="n">named_values</span> <span class="n">var_name</span> <span class="n">alloca</span><span class="o">;</span>
+ <span class="o">)</span> <span class="o">(</span><span class="n">params</span> <span class="n">the_function</span><span class="o">)</span>
+
+<span class="k">let</span> <span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="o">=</span> <span class="k">function</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">Function</span> <span class="o">(</span><span class="n">proto</span><span class="o">,</span> <span class="n">body</span><span class="o">)</span> <span class="o">-></span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">clear</span> <span class="n">named_values</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="n">codegen_proto</span> <span class="n">proto</span> <span class="k">in</span>
+
+ <span class="c">(* If this is an operator, install it. *)</span>
+ <span class="k">begin</span> <span class="k">match</span> <span class="n">proto</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Ast</span><span class="p">.</span><span class="nc">BinOpPrototype</span> <span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">args</span><span class="o">,</span> <span class="n">prec</span><span class="o">)</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">op</span> <span class="o">=</span> <span class="n">name</span><span class="o">.[</span><span class="nn">String</span><span class="p">.</span><span class="n">length</span> <span class="n">name</span> <span class="o">-</span> <span class="mi">1</span><span class="o">]</span> <span class="k">in</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="n">op</span> <span class="n">prec</span><span class="o">;</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span> <span class="bp">()</span>
+ <span class="k">end</span><span class="o">;</span>
+
+ <span class="c">(* Create a new basic block to start insertion into. *)</span>
+ <span class="k">let</span> <span class="n">bb</span> <span class="o">=</span> <span class="n">append_block</span> <span class="n">context</span> <span class="s2">"entry"</span> <span class="n">the_function</span> <span class="k">in</span>
+ <span class="n">position_at_end</span> <span class="n">bb</span> <span class="n">builder</span><span class="o">;</span>
+
+ <span class="k">try</span>
+ <span class="c">(* Add all arguments to the symbol table and create their allocas. *)</span>
+ <span class="n">create_argument_allocas</span> <span class="n">the_function</span> <span class="n">proto</span><span class="o">;</span>
+
+ <span class="k">let</span> <span class="n">ret_val</span> <span class="o">=</span> <span class="n">codegen_expr</span> <span class="n">body</span> <span class="k">in</span>
+
+ <span class="c">(* Finish off the function. *)</span>
+ <span class="k">let</span> <span class="o">_</span> <span class="o">=</span> <span class="n">build_ret</span> <span class="n">ret_val</span> <span class="n">builder</span> <span class="k">in</span>
+
+ <span class="c">(* Validate the generated code, checking for consistency. *)</span>
+ <span class="nn">Llvm_analysis</span><span class="p">.</span><span class="n">assert_valid_function</span> <span class="n">the_function</span><span class="o">;</span>
+
+ <span class="c">(* Optimize the function. *)</span>
+ <span class="k">let</span> <span class="o">_</span> <span class="o">=</span> <span class="nn">PassManager</span><span class="p">.</span><span class="n">run_function</span> <span class="n">the_function</span> <span class="n">the_fpm</span> <span class="k">in</span>
+
+ <span class="n">the_function</span>
+ <span class="k">with</span> <span class="n">e</span> <span class="o">-></span>
+ <span class="n">delete_function</span> <span class="n">the_function</span><span class="o">;</span>
+ <span class="k">raise</span> <span class="n">e</span>
+</pre></div>
+</div>
+</dd>
+<dt>toplevel.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Top-Level parsing and JIT Driver</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">open</span> <span class="nc">Llvm</span>
+<span class="k">open</span> <span class="nc">Llvm_executionengine</span>
+
+<span class="c">(* top ::= definition | external | expression | ';' *)</span>
+<span class="k">let</span> <span class="k">rec</span> <span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span> <span class="o">=</span>
+ <span class="k">match</span> <span class="nn">Stream</span><span class="p">.</span><span class="n">peek</span> <span class="n">stream</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="bp">()</span>
+
+ <span class="c">(* ignore top-level semicolons. *)</span>
+ <span class="o">|</span> <span class="nc">Some</span> <span class="o">(</span><span class="nn">Token</span><span class="p">.</span><span class="nc">Kwd</span> <span class="sc">';'</span><span class="o">)</span> <span class="o">-></span>
+ <span class="nn">Stream</span><span class="p">.</span><span class="n">junk</span> <span class="n">stream</span><span class="o">;</span>
+ <span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span>
+
+ <span class="o">|</span> <span class="nc">Some</span> <span class="n">token</span> <span class="o">-></span>
+ <span class="k">begin</span>
+ <span class="k">try</span> <span class="k">match</span> <span class="n">token</span> <span class="k">with</span>
+ <span class="o">|</span> <span class="nn">Token</span><span class="p">.</span><span class="nc">Def</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">e</span> <span class="o">=</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">parse_definition</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="n">print_endline</span> <span class="s2">"parsed a function definition."</span><span class="o">;</span>
+ <span class="n">dump_value</span> <span class="o">(</span><span class="nn">Codegen</span><span class="p">.</span><span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="n">e</span><span class="o">);</span>
+ <span class="o">|</span> <span class="nn">Token</span><span class="p">.</span><span class="nc">Extern</span> <span class="o">-></span>
+ <span class="k">let</span> <span class="n">e</span> <span class="o">=</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">parse_extern</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="n">print_endline</span> <span class="s2">"parsed an extern."</span><span class="o">;</span>
+ <span class="n">dump_value</span> <span class="o">(</span><span class="nn">Codegen</span><span class="p">.</span><span class="n">codegen_proto</span> <span class="n">e</span><span class="o">);</span>
+ <span class="o">|</span> <span class="o">_</span> <span class="o">-></span>
+ <span class="c">(* Evaluate a top-level expression into an anonymous function. *)</span>
+ <span class="k">let</span> <span class="n">e</span> <span class="o">=</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">parse_toplevel</span> <span class="n">stream</span> <span class="k">in</span>
+ <span class="n">print_endline</span> <span class="s2">"parsed a top-level expr"</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">the_function</span> <span class="o">=</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">codegen_func</span> <span class="n">the_fpm</span> <span class="n">e</span> <span class="k">in</span>
+ <span class="n">dump_value</span> <span class="n">the_function</span><span class="o">;</span>
+
+ <span class="c">(* JIT the function, returning a function pointer. *)</span>
+ <span class="k">let</span> <span class="n">result</span> <span class="o">=</span> <span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">run_function</span> <span class="n">the_function</span> <span class="o">[||]</span>
+ <span class="n">the_execution_engine</span> <span class="k">in</span>
+
+ <span class="n">print_string</span> <span class="s2">"Evaluated to "</span><span class="o">;</span>
+ <span class="n">print_float</span> <span class="o">(</span><span class="nn">GenericValue</span><span class="p">.</span><span class="n">as_float</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">double_type</span> <span class="n">result</span><span class="o">);</span>
+ <span class="n">print_newline</span> <span class="bp">()</span><span class="o">;</span>
+ <span class="k">with</span> <span class="nn">Stream</span><span class="p">.</span><span class="nc">Error</span> <span class="n">s</span> <span class="o">|</span> <span class="nn">Codegen</span><span class="p">.</span><span class="nc">Error</span> <span class="n">s</span> <span class="o">-></span>
+ <span class="c">(* Skip token for error recovery. *)</span>
+ <span class="nn">Stream</span><span class="p">.</span><span class="n">junk</span> <span class="n">stream</span><span class="o">;</span>
+ <span class="n">print_endline</span> <span class="n">s</span><span class="o">;</span>
+ <span class="k">end</span><span class="o">;</span>
+ <span class="n">print_string</span> <span class="s2">"ready> "</span><span class="o">;</span> <span class="n">flush</span> <span class="n">stdout</span><span class="o">;</span>
+ <span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span>
+</pre></div>
+</div>
+</dd>
+<dt>toy.ml:</dt>
+<dd><div class="first last highlight-ocaml notranslate"><div class="highlight"><pre><span></span><span class="c">(*===----------------------------------------------------------------------===</span>
+<span class="c"> * Main driver code.</span>
+<span class="c"> *===----------------------------------------------------------------------===*)</span>
+
+<span class="k">open</span> <span class="nc">Llvm</span>
+<span class="k">open</span> <span class="nc">Llvm_executionengine</span>
+<span class="k">open</span> <span class="nc">Llvm_target</span>
+<span class="k">open</span> <span class="nc">Llvm_scalar_opts</span>
+
+<span class="k">let</span> <span class="n">main</span> <span class="bp">()</span> <span class="o">=</span>
+ <span class="n">ignore</span> <span class="o">(</span><span class="n">initialize_native_target</span> <span class="bp">()</span><span class="o">);</span>
+
+ <span class="c">(* Install standard binary operators.</span>
+<span class="c"> * 1 is the lowest precedence. *)</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'='</span> <span class="mi">2</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'<'</span> <span class="mi">10</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'+'</span> <span class="mi">20</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'-'</span> <span class="mi">20</span><span class="o">;</span>
+ <span class="nn">Hashtbl</span><span class="p">.</span><span class="n">add</span> <span class="nn">Parser</span><span class="p">.</span><span class="n">binop_precedence</span> <span class="sc">'*'</span> <span class="mi">40</span><span class="o">;</span> <span class="c">(* highest. *)</span>
+
+ <span class="c">(* Prime the first token. *)</span>
+ <span class="n">print_string</span> <span class="s2">"ready> "</span><span class="o">;</span> <span class="n">flush</span> <span class="n">stdout</span><span class="o">;</span>
+ <span class="k">let</span> <span class="n">stream</span> <span class="o">=</span> <span class="nn">Lexer</span><span class="p">.</span><span class="n">lex</span> <span class="o">(</span><span class="nn">Stream</span><span class="p">.</span><span class="n">of_channel</span> <span class="n">stdin</span><span class="o">)</span> <span class="k">in</span>
+
+ <span class="c">(* Create the JIT. *)</span>
+ <span class="k">let</span> <span class="n">the_execution_engine</span> <span class="o">=</span> <span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">create</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span> <span class="k">in</span>
+ <span class="k">let</span> <span class="n">the_fpm</span> <span class="o">=</span> <span class="nn">PassManager</span><span class="p">.</span><span class="n">create_function</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span> <span class="k">in</span>
+
+ <span class="c">(* Set up the optimizer pipeline. Start with registering info about how the</span>
+<span class="c"> * target lays out data structures. *)</span>
+ <span class="nn">DataLayout</span><span class="p">.</span><span class="n">add</span> <span class="o">(</span><span class="nn">ExecutionEngine</span><span class="p">.</span><span class="n">target_data</span> <span class="n">the_execution_engine</span><span class="o">)</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Promote allocas to registers. *)</span>
+ <span class="n">add_memory_to_register_promotion</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Do simple "peephole" optimizations and bit-twiddling optzn. *)</span>
+ <span class="n">add_instruction_combination</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* reassociate expressions. *)</span>
+ <span class="n">add_reassociation</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Eliminate Common SubExpressions. *)</span>
+ <span class="n">add_gvn</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="c">(* Simplify the control flow graph (deleting unreachable blocks, etc). *)</span>
+ <span class="n">add_cfg_simplification</span> <span class="n">the_fpm</span><span class="o">;</span>
+
+ <span class="n">ignore</span> <span class="o">(</span><span class="nn">PassManager</span><span class="p">.</span><span class="n">initialize</span> <span class="n">the_fpm</span><span class="o">);</span>
+
+ <span class="c">(* Run the main "interpreter loop" now. *)</span>
+ <span class="nn">Toplevel</span><span class="p">.</span><span class="n">main_loop</span> <span class="n">the_fpm</span> <span class="n">the_execution_engine</span> <span class="n">stream</span><span class="o">;</span>
+
+ <span class="c">(* Print out all the generated code. *)</span>
+ <span class="n">dump_module</span> <span class="nn">Codegen</span><span class="p">.</span><span class="n">the_module</span>
+<span class="o">;;</span>
+
+<span class="n">main</span> <span class="bp">()</span>
+</pre></div>
+</div>
+</dd>
+<dt>bindings.c</dt>
+<dd><div class="first last highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp"></span>
+
+<span class="cm">/* putchard - putchar that takes a double and returns 0. */</span>
+<span class="k">extern</span> <span class="kt">double</span> <span class="nf">putchard</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">putchar</span><span class="p">((</span><span class="kt">char</span><span class="p">)</span><span class="n">X</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="cm">/* printd - printf that takes a double prints it as "%f\n", returning 0. */</span>
+<span class="k">extern</span> <span class="kt">double</span> <span class="nf">printd</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">printf</span><span class="p">(</span><span class="s">"%f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">X</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</dd>
+</dl>
+<p><a class="reference external" href="OCamlLangImpl8.html">Next: Conclusion and other useful LLVM tidbits</a></p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="OCamlLangImpl8.html" title="8. Kaleidoscope: Conclusion and other useful LLVM tidbits"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="OCamlLangImpl6.html" title="6. Kaleidoscope: Extending the Language: User-defined Operators"
+ >previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" >LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-03-18.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl8.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl8.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl8.html (added)
+++ www-releases/trunk/8.0.0/docs/tutorial/OCamlLangImpl8.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,341 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>8. Kaleidoscope: Conclusion and other useful LLVM tidbits — LLVM 8 documentation</title>
+ <link rel="stylesheet" href="../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="1. Building a JIT: Starting out with KaleidoscopeJIT" href="BuildingAJIT1.html" />
+ <link rel="prev" title="7. Kaleidoscope: Extending the Language: Mutable Variables" href="OCamlLangImpl7.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../index.html">
+ <img src="../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="BuildingAJIT1.html" title="1. Building a JIT: Starting out with KaleidoscopeJIT"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="OCamlLangImpl7.html" title="7. Kaleidoscope: Extending the Language: Mutable Variables"
+ accesskey="P">previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-conclusion-and-other-useful-llvm-tidbits">
+<h1>8. Kaleidoscope: Conclusion and other useful LLVM tidbits<a class="headerlink" href="#kaleidoscope-conclusion-and-other-useful-llvm-tidbits" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#tutorial-conclusion" id="id2">Tutorial Conclusion</a></li>
+<li><a class="reference internal" href="#properties-of-the-llvm-ir" id="id3">Properties of the LLVM IR</a><ul>
+<li><a class="reference internal" href="#target-independence" id="id4">Target Independence</a></li>
+<li><a class="reference internal" href="#safety-guarantees" id="id5">Safety Guarantees</a></li>
+<li><a class="reference internal" href="#language-specific-optimizations" id="id6">Language-Specific Optimizations</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#tips-and-tricks" id="id7">Tips and Tricks</a><ul>
+<li><a class="reference internal" href="#implementing-portable-offsetof-sizeof" id="id8">Implementing portable offsetof/sizeof</a></li>
+<li><a class="reference internal" href="#garbage-collected-stack-frames" id="id9">Garbage Collected Stack Frames</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="tutorial-conclusion">
+<h2><a class="toc-backref" href="#id2">8.1. Tutorial Conclusion</a><a class="headerlink" href="#tutorial-conclusion" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to the final chapter of the â<a class="reference external" href="index.html">Implementing a language with
+LLVM</a>â tutorial. In the course of this tutorial, we have
+grown our little Kaleidoscope language from being a useless toy, to
+being a semi-interesting (but probably still useless) toy. :)</p>
+<p>It is interesting to see how far weâve come, and how little code it has
+taken. We built the entire lexer, parser, AST, code generator, and an
+interactive run-loop (with a JIT!) by-hand in under 700 lines of
+(non-comment/non-blank) code.</p>
+<p>Our little language supports a couple of interesting features: it
+supports user defined binary and unary operators, it uses JIT
+compilation for immediate evaluation, and it supports a few control flow
+constructs with SSA construction.</p>
+<p>Part of the idea of this tutorial was to show you how easy and fun it
+can be to define, build, and play with languages. Building a compiler
+need not be a scary or mystical process! Now that youâve seen some of
+the basics, I strongly encourage you to take the code and hack on it.
+For example, try adding:</p>
+<ul class="simple">
+<li><strong>global variables</strong> - While global variables have questional value
+in modern software engineering, they are often useful when putting
+together quick little hacks like the Kaleidoscope compiler itself.
+Fortunately, our current setup makes it very easy to add global
+variables: just have value lookup check to see if an unresolved
+variable is in the global variable symbol table before rejecting it.
+To create a new global variable, make an instance of the LLVM
+<code class="docutils literal notranslate"><span class="pre">GlobalVariable</span></code> class.</li>
+<li><strong>typed variables</strong> - Kaleidoscope currently only supports variables
+of type double. This gives the language a very nice elegance, because
+only supporting one type means that you never have to specify types.
+Different languages have different ways of handling this. The easiest
+way is to require the user to specify types for every variable
+definition, and record the type of the variable in the symbol table
+along with its Value*.</li>
+<li><strong>arrays, structs, vectors, etc</strong> - Once you add types, you can start
+extending the type system in all sorts of interesting ways. Simple
+arrays are very easy and are quite useful for many different
+applications. Adding them is mostly an exercise in learning how the
+LLVM <a class="reference external" href="../LangRef.html#getelementptr-instruction">getelementptr</a> instruction
+works: it is so nifty/unconventional, it <a class="reference external" href="../GetElementPtr.html">has its own
+FAQ</a>! If you add support for recursive types
+(e.g. linked lists), make sure to read the <a class="reference external" href="../ProgrammersManual.html#TypeResolve">section in the LLVM
+Programmerâs Manual</a> that
+describes how to construct them.</li>
+<li><strong>standard runtime</strong> - Our current language allows the user to access
+arbitrary external functions, and we use it for things like âprintdâ
+and âputchardâ. As you extend the language to add higher-level
+constructs, often these constructs make the most sense if they are
+lowered to calls into a language-supplied runtime. For example, if
+you add hash tables to the language, it would probably make sense to
+add the routines to a runtime, instead of inlining them all the way.</li>
+<li><strong>memory management</strong> - Currently we can only access the stack in
+Kaleidoscope. It would also be useful to be able to allocate heap
+memory, either with calls to the standard libc malloc/free interface
+or with a garbage collector. If you would like to use garbage
+collection, note that LLVM fully supports <a class="reference external" href="../GarbageCollection.html">Accurate Garbage
+Collection</a> including algorithms that
+move objects and need to scan/update the stack.</li>
+<li><strong>debugger support</strong> - LLVM supports generation of <a class="reference external" href="../SourceLevelDebugging.html">DWARF Debug
+info</a> which is understood by common
+debuggers like GDB. Adding support for debug info is fairly
+straightforward. The best way to understand it is to compile some
+C/C++ code with â<code class="docutils literal notranslate"><span class="pre">clang</span> <span class="pre">-g</span> <span class="pre">-O0</span></code>â and taking a look at what it
+produces.</li>
+<li><strong>exception handling support</strong> - LLVM supports generation of <a class="reference external" href="../ExceptionHandling.html">zero
+cost exceptions</a> which interoperate with
+code compiled in other languages. You could also generate code by
+implicitly making every function return an error value and checking
+it. You could also make explicit use of setjmp/longjmp. There are
+many different ways to go here.</li>
+<li><strong>object orientation, generics, database access, complex numbers,
+geometric programming, â¦</strong> - Really, there is no end of crazy
+features that you can add to the language.</li>
+<li><strong>unusual domains</strong> - Weâve been talking about applying LLVM to a
+domain that many people are interested in: building a compiler for a
+specific language. However, there are many other domains that can use
+compiler technology that are not typically considered. For example,
+LLVM has been used to implement OpenGL graphics acceleration,
+translate C++ code to ActionScript, and many other cute and clever
+things. Maybe you will be the first to JIT compile a regular
+expression interpreter into native code with LLVM?</li>
+</ul>
+<p>Have fun - try doing something crazy and unusual. Building a language
+like everyone else always has, is much less fun than trying something a
+little crazy or off the wall and seeing how it turns out. If you get
+stuck or want to talk about it, feel free to email the <a class="reference external" href="http://lists.llvm.org/mailman/listinfo/llvm-dev">llvm-dev mailing
+list</a>: it has lots
+of people who are interested in languages and are often willing to help
+out.</p>
+<p>Before we end this tutorial, I want to talk about some âtips and tricksâ
+for generating LLVM IR. These are some of the more subtle things that
+may not be obvious, but are very useful if you want to take advantage of
+LLVMâs capabilities.</p>
+</div>
+<div class="section" id="properties-of-the-llvm-ir">
+<h2><a class="toc-backref" href="#id3">8.2. Properties of the LLVM IR</a><a class="headerlink" href="#properties-of-the-llvm-ir" title="Permalink to this headline">¶</a></h2>
+<p>We have a couple common questions about code in the LLVM IR form - lets
+just get these out of the way right now, shall we?</p>
+<div class="section" id="target-independence">
+<h3><a class="toc-backref" href="#id4">8.2.1. Target Independence</a><a class="headerlink" href="#target-independence" title="Permalink to this headline">¶</a></h3>
+<p>Kaleidoscope is an example of a âportable languageâ: any program written
+in Kaleidoscope will work the same way on any target that it runs on.
+Many other languages have this property, e.g. lisp, java, haskell,
+javascript, python, etc (note that while these languages are portable,
+not all their libraries are).</p>
+<p>One nice aspect of LLVM is that it is often capable of preserving target
+independence in the IR: you can take the LLVM IR for a
+Kaleidoscope-compiled program and run it on any target that LLVM
+supports, even emitting C code and compiling that on targets that LLVM
+doesnât support natively. You can trivially tell that the Kaleidoscope
+compiler generates target-independent code because it never queries for
+any target-specific information when generating code.</p>
+<p>The fact that LLVM provides a compact, target-independent,
+representation for code gets a lot of people excited. Unfortunately,
+these people are usually thinking about C or a language from the C
+family when they are asking questions about language portability. I say
+âunfortunatelyâ, because there is really no way to make (fully general)
+C code portable, other than shipping the source code around (and of
+course, C source code is not actually portable in general either - ever
+port a really old application from 32- to 64-bits?).</p>
+<p>The problem with C (again, in its full generality) is that it is heavily
+laden with target specific assumptions. As one simple example, the
+preprocessor often destructively removes target-independence from the
+code when it processes the input text:</p>
+<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef __i386__</span>
+ <span class="kt">int</span> <span class="n">X</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
+<span class="cp">#else</span>
+ <span class="kt">int</span> <span class="n">X</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span>
+<span class="cp">#endif</span>
+</pre></div>
+</div>
+<p>While it is possible to engineer more and more complex solutions to
+problems like this, it cannot be solved in full generality in a way that
+is better than shipping the actual source code.</p>
+<p>That said, there are interesting subsets of C that can be made portable.
+If you are willing to fix primitive types to a fixed size (say int =
+32-bits, and long = 64-bits), donât care about ABI compatibility with
+existing binaries, and are willing to give up some other minor features,
+you can have portable code. This can make sense for specialized domains
+such as an in-kernel language.</p>
+</div>
+<div class="section" id="safety-guarantees">
+<h3><a class="toc-backref" href="#id5">8.2.2. Safety Guarantees</a><a class="headerlink" href="#safety-guarantees" title="Permalink to this headline">¶</a></h3>
+<p>Many of the languages above are also âsafeâ languages: it is impossible
+for a program written in Java to corrupt its address space and crash the
+process (assuming the JVM has no bugs). Safety is an interesting
+property that requires a combination of language design, runtime
+support, and often operating system support.</p>
+<p>It is certainly possible to implement a safe language in LLVM, but LLVM
+IR does not itself guarantee safety. The LLVM IR allows unsafe pointer
+casts, use after free bugs, buffer over-runs, and a variety of other
+problems. Safety needs to be implemented as a layer on top of LLVM and,
+conveniently, several groups have investigated this. Ask on the <a class="reference external" href="http://lists.llvm.org/mailman/listinfo/llvm-dev">llvm-dev
+mailing list</a> if
+you are interested in more details.</p>
+</div>
+<div class="section" id="language-specific-optimizations">
+<h3><a class="toc-backref" href="#id6">8.2.3. Language-Specific Optimizations</a><a class="headerlink" href="#language-specific-optimizations" title="Permalink to this headline">¶</a></h3>
+<p>One thing about LLVM that turns off many people is that it does not
+solve all the worldâs problems in one system (sorry âworld hungerâ,
+someone else will have to solve you some other day). One specific
+complaint is that people perceive LLVM as being incapable of performing
+high-level language-specific optimization: LLVM âloses too much
+informationâ.</p>
+<p>Unfortunately, this is really not the place to give you a full and
+unified version of âChris Lattnerâs theory of compiler designâ. Instead,
+Iâll make a few observations:</p>
+<p>First, youâre right that LLVM does lose information. For example, as of
+this writing, there is no way to distinguish in the LLVM IR whether an
+SSA-value came from a C âintâ or a C âlongâ on an ILP32 machine (other
+than debug info). Both get compiled down to an âi32â value and the
+information about what it came from is lost. The more general issue
+here, is that the LLVM type system uses âstructural equivalenceâ instead
+of âname equivalenceâ. Another place this surprises people is if you
+have two types in a high-level language that have the same structure
+(e.g. two different structs that have a single int field): these types
+will compile down into a single LLVM type and it will be impossible to
+tell what it came from.</p>
+<p>Second, while LLVM does lose information, LLVM is not a fixed target: we
+continue to enhance and improve it in many different ways. In addition
+to adding new features (LLVM did not always support exceptions or debug
+info), we also extend the IR to capture important information for
+optimization (e.g. whether an argument is sign or zero extended,
+information about pointers aliasing, etc). Many of the enhancements are
+user-driven: people want LLVM to include some specific feature, so they
+go ahead and extend it.</p>
+<p>Third, it is <em>possible and easy</em> to add language-specific optimizations,
+and you have a number of choices in how to do it. As one trivial
+example, it is easy to add language-specific optimization passes that
+âknowâ things about code compiled for a language. In the case of the C
+family, there is an optimization pass that âknowsâ about the standard C
+library functions. If you call âexit(0)â in main(), it knows that it is
+safe to optimize that into âreturn 0;â because C specifies what the
+âexitâ function does.</p>
+<p>In addition to simple library knowledge, it is possible to embed a
+variety of other language-specific information into the LLVM IR. If you
+have a specific need and run into a wall, please bring the topic up on
+the llvm-dev list. At the very worst, you can always treat LLVM as if it
+were a âdumb code generatorâ and implement the high-level optimizations
+you desire in your front-end, on the language-specific AST.</p>
+</div>
+</div>
+<div class="section" id="tips-and-tricks">
+<h2><a class="toc-backref" href="#id7">8.3. Tips and Tricks</a><a class="headerlink" href="#tips-and-tricks" title="Permalink to this headline">¶</a></h2>
+<p>There is a variety of useful tips and tricks that you come to know after
+working on/with LLVM that arenât obvious at first glance. Instead of
+letting everyone rediscover them, this section talks about some of these
+issues.</p>
+<div class="section" id="implementing-portable-offsetof-sizeof">
+<h3><a class="toc-backref" href="#id8">8.3.1. Implementing portable offsetof/sizeof</a><a class="headerlink" href="#implementing-portable-offsetof-sizeof" title="Permalink to this headline">¶</a></h3>
+<p>One interesting thing that comes up, if you are trying to keep the code
+generated by your compiler âtarget independentâ, is that you often need
+to know the size of some LLVM type or the offset of some field in an
+llvm structure. For example, you might need to pass the size of a type
+into a function that allocates memory.</p>
+<p>Unfortunately, this can vary widely across targets: for example the
+width of a pointer is trivially target-specific. However, there is a
+<a class="reference external" href="http://nondot.org/sabre/LLVMNotes/SizeOf-OffsetOf-VariableSizedStructs.txt">clever way to use the getelementptr
+instruction</a>
+that allows you to compute this in a portable way.</p>
+</div>
+<div class="section" id="garbage-collected-stack-frames">
+<h3><a class="toc-backref" href="#id9">8.3.2. Garbage Collected Stack Frames</a><a class="headerlink" href="#garbage-collected-stack-frames" title="Permalink to this headline">¶</a></h3>
+<p>Some languages want to explicitly manage their stack frames, often so
+that they are garbage collected or to allow easy implementation of
+closures. There are often better ways to implement these features than
+explicit stack frames, but <a class="reference external" href="http://nondot.org/sabre/LLVMNotes/ExplicitlyManagedStackFrames.txt">LLVM does support
+them,</a>
+if you want. It requires your front-end to convert the code into
+<a class="reference external" href="http://en.wikipedia.org/wiki/Continuation-passing_style">Continuation Passing
+Style</a> and
+the use of tail calls (which LLVM also supports).</p>
+</div>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="BuildingAJIT1.html" title="1. Building a JIT: Starting out with KaleidoscopeJIT"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="OCamlLangImpl7.html" title="7. Kaleidoscope: Extending the Language: Mutable Variables"
+ >previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" >LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-03-18.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/docs/tutorial/index.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/docs/tutorial/index.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/docs/tutorial/index.html (added)
+++ www-releases/trunk/8.0.0/docs/tutorial/index.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,150 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>LLVM Tutorial: Table of Contents — LLVM 8 documentation</title>
+ <link rel="stylesheet" href="../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="1. Kaleidoscope: Tutorial Introduction and the Lexer" href="LangImpl01.html" />
+ <link rel="prev" title="test-suite Makefile Guide (deprecated)" href="../TestSuiteMakefileGuide.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../index.html">
+ <img src="../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="LangImpl01.html" title="1. Kaleidoscope: Tutorial Introduction and the Lexer"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="../TestSuiteMakefileGuide.html" title="test-suite Makefile Guide (deprecated)"
+ accesskey="P">previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="llvm-tutorial-table-of-contents">
+<h1>LLVM Tutorial: Table of Contents<a class="headerlink" href="#llvm-tutorial-table-of-contents" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="kaleidoscope-implementing-a-language-with-llvm">
+<h2>Kaleidoscope: Implementing a Language with LLVM<a class="headerlink" href="#kaleidoscope-implementing-a-language-with-llvm" title="Permalink to this headline">¶</a></h2>
+<div class="toctree-wrapper compound">
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl01.html">1. Kaleidoscope: Tutorial Introduction and the Lexer</a></li>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl02.html">2. Kaleidoscope: Implementing a Parser and AST</a></li>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl03.html">3. Kaleidoscope: Code generation to LLVM IR</a></li>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl04.html">4. Kaleidoscope: Adding JIT and Optimizer Support</a></li>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl05.html">5. Kaleidoscope: Extending the Language: Control Flow</a></li>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl06.html">6. Kaleidoscope: Extending the Language: User-defined Operators</a></li>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl07.html">7. Kaleidoscope: Extending the Language: Mutable Variables</a></li>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl08.html">8. Kaleidoscope: Compiling to Object Code</a></li>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl09.html">9. Kaleidoscope: Adding Debug Information</a></li>
+<li class="toctree-l1"><a class="reference internal" href="LangImpl10.html">10. Kaleidoscope: Conclusion and other useful LLVM tidbits</a></li>
+</ul>
+</div>
+</div>
+<div class="section" id="kaleidoscope-implementing-a-language-with-llvm-in-objective-caml">
+<h2>Kaleidoscope: Implementing a Language with LLVM in Objective Caml<a class="headerlink" href="#kaleidoscope-implementing-a-language-with-llvm-in-objective-caml" title="Permalink to this headline">¶</a></h2>
+<div class="toctree-wrapper compound">
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="OCamlLangImpl1.html">1. Kaleidoscope: Tutorial Introduction and the Lexer</a></li>
+<li class="toctree-l1"><a class="reference internal" href="OCamlLangImpl2.html">2. Kaleidoscope: Implementing a Parser and AST</a></li>
+<li class="toctree-l1"><a class="reference internal" href="OCamlLangImpl3.html">3. Kaleidoscope: Code generation to LLVM IR</a></li>
+<li class="toctree-l1"><a class="reference internal" href="OCamlLangImpl4.html">4. Kaleidoscope: Adding JIT and Optimizer Support</a></li>
+<li class="toctree-l1"><a class="reference internal" href="OCamlLangImpl5.html">5. Kaleidoscope: Extending the Language: Control Flow</a></li>
+<li class="toctree-l1"><a class="reference internal" href="OCamlLangImpl6.html">6. Kaleidoscope: Extending the Language: User-defined Operators</a></li>
+<li class="toctree-l1"><a class="reference internal" href="OCamlLangImpl7.html">7. Kaleidoscope: Extending the Language: Mutable Variables</a></li>
+<li class="toctree-l1"><a class="reference internal" href="OCamlLangImpl8.html">8. Kaleidoscope: Conclusion and other useful LLVM tidbits</a></li>
+</ul>
+</div>
+</div>
+<div class="section" id="building-a-jit-in-llvm">
+<h2>Building a JIT in LLVM<a class="headerlink" href="#building-a-jit-in-llvm" title="Permalink to this headline">¶</a></h2>
+<div class="toctree-wrapper compound">
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="BuildingAJIT1.html">1. Building a JIT: Starting out with KaleidoscopeJIT</a></li>
+<li class="toctree-l1"><a class="reference internal" href="BuildingAJIT2.html">2. Building a JIT: Adding Optimizations â An introduction to ORC Layers</a></li>
+<li class="toctree-l1"><a class="reference internal" href="BuildingAJIT3.html">3. Building a JIT: Per-function Lazy Compilation</a></li>
+<li class="toctree-l1"><a class="reference internal" href="BuildingAJIT4.html">4. Building a JIT: Extreme Laziness - Using Compile Callbacks to JIT from ASTs</a></li>
+<li class="toctree-l1"><a class="reference internal" href="BuildingAJIT5.html">5. Building a JIT: Remote-JITing â Process Isolation and Laziness at a Distance</a></li>
+</ul>
+</div>
+</div>
+<div class="section" id="external-tutorials">
+<h2>External Tutorials<a class="headerlink" href="#external-tutorials" title="Permalink to this headline">¶</a></h2>
+<dl class="docutils">
+<dt><a class="reference external" href="http://jonathan2251.github.com/lbd/">Tutorial: Creating an LLVM Backend for the Cpu0 Architecture</a></dt>
+<dd>A step-by-step tutorial for developing an LLVM backend. Under
+active development at <a class="reference external" href="https://github.com/Jonathan2251/lbd">https://github.com/Jonathan2251/lbd</a> (please
+contribute!).</dd>
+<dt><a class="reference external" href="http://www.embecosm.com/appnotes/ean10/ean10-howto-llvmas-1.0.html">Howto: Implementing LLVM Integrated Assembler</a></dt>
+<dd>A simple guide for how to implement an LLVM integrated assembler for an
+architecture.</dd>
+</dl>
+</div>
+<div class="section" id="advanced-topics">
+<h2>Advanced Topics<a class="headerlink" href="#advanced-topics" title="Permalink to this headline">¶</a></h2>
+<ol class="arabic simple">
+<li><a class="reference external" href="http://llvm.org/pubs/2004-09-22-LCPCLLVMTutorial.html">Writing an Optimization for LLVM</a></li>
+</ol>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="LangImpl01.html" title="1. Kaleidoscope: Tutorial Introduction and the Lexer"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="../TestSuiteMakefileGuide.html" title="test-suite Makefile Guide (deprecated)"
+ >previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-03-18.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/docs/yaml2obj.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/docs/yaml2obj.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/docs/yaml2obj.html (added)
+++ www-releases/trunk/8.0.0/docs/yaml2obj.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,297 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>yaml2obj — LLVM 8 documentation</title>
+ <link rel="stylesheet" href="_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+ <link rel="next" title="How to submit an LLVM bug report" href="HowToSubmitABug.html" />
+ <link rel="prev" title="How To Add Your Build Configuration To LLVM Buildbot Infrastructure" href="HowToAddABuilder.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="index.html">
+ <img src="_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="HowToSubmitABug.html" title="How to submit an LLVM bug report"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="HowToAddABuilder.html" title="How To Add Your Build Configuration To LLVM Buildbot Infrastructure"
+ accesskey="P">previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="yaml2obj">
+<h1>yaml2obj<a class="headerlink" href="#yaml2obj" title="Permalink to this headline">¶</a></h1>
+<p>yaml2obj takes a YAML description of an object file and converts it to a binary
+file.</p>
+<blockquote>
+<div>$ yaml2obj input-file</div></blockquote>
+<p>Outputs the binary to stdout.</p>
+<div class="section" id="coff-syntax">
+<h2>COFF Syntax<a class="headerlink" href="#coff-syntax" title="Permalink to this headline">¶</a></h2>
+<p>Hereâs a sample COFF file.</p>
+<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="l l-Scalar l-Scalar-Plain">header</span><span class="p p-Indicator">:</span>
+ <span class="l l-Scalar l-Scalar-Plain">Machine</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">IMAGE_FILE_MACHINE_I386</span> <span class="c1"># (0x14C)</span>
+
+<span class="l l-Scalar l-Scalar-Plain">sections</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">Name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">.text</span>
+ <span class="l l-Scalar l-Scalar-Plain">Characteristics</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span> <span class="nv">IMAGE_SCN_CNT_CODE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_16BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_EXECUTE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_READ</span>
+ <span class="p p-Indicator">]</span> <span class="c1"># 0x60500020</span>
+ <span class="l l-Scalar l-Scalar-Plain">SectionData</span><span class="p p-Indicator">:</span>
+ <span class="s">"</span><span class="se">\x83\xEC\x0C\xC7\x44\x24\x08\x00\x00\x00\x00\xC7\x04\x24\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x8B\x44\x24\x08\x83\xC4\x0C\xC3</span><span class="s">"</span> <span class="c1"># |....D$.......$...............D$.....|</span>
+
+<span class="l l-Scalar l-Scalar-Plain">symbols</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">Name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">.text</span>
+ <span class="l l-Scalar l-Scalar-Plain">Value</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">0</span>
+ <span class="l l-Scalar l-Scalar-Plain">SectionNumber</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">1</span>
+ <span class="l l-Scalar l-Scalar-Plain">SimpleType</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">IMAGE_SYM_TYPE_NULL</span> <span class="c1"># (0)</span>
+ <span class="l l-Scalar l-Scalar-Plain">ComplexType</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">IMAGE_SYM_DTYPE_NULL</span> <span class="c1"># (0)</span>
+ <span class="l l-Scalar l-Scalar-Plain">StorageClass</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">IMAGE_SYM_CLASS_STATIC</span> <span class="c1"># (3)</span>
+ <span class="l l-Scalar l-Scalar-Plain">NumberOfAuxSymbols</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">1</span>
+ <span class="l l-Scalar l-Scalar-Plain">AuxiliaryData</span><span class="p p-Indicator">:</span>
+ <span class="s">"</span><span class="se">\x24\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00</span><span class="s">"</span> <span class="c1"># |$.................|</span>
+
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">Name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">_main</span>
+ <span class="l l-Scalar l-Scalar-Plain">Value</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">0</span>
+ <span class="l l-Scalar l-Scalar-Plain">SectionNumber</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">1</span>
+ <span class="l l-Scalar l-Scalar-Plain">SimpleType</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">IMAGE_SYM_TYPE_NULL</span> <span class="c1"># (0)</span>
+ <span class="l l-Scalar l-Scalar-Plain">ComplexType</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">IMAGE_SYM_DTYPE_NULL</span> <span class="c1"># (0)</span>
+ <span class="l l-Scalar l-Scalar-Plain">StorageClass</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">IMAGE_SYM_CLASS_EXTERNAL</span> <span class="c1"># (2)</span>
+</pre></div>
+</div>
+<p>Hereâs a simplified <a class="reference external" href="http://www.kuwata-lab.com/kwalify/ruby/users-guide.html">Kwalify</a> schema with an extension to allow alternate types.</p>
+<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">map</span>
+ <span class="l l-Scalar l-Scalar-Plain">mapping</span><span class="p p-Indicator">:</span>
+ <span class="l l-Scalar l-Scalar-Plain">header</span><span class="p p-Indicator">:</span>
+ <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">map</span>
+ <span class="l l-Scalar l-Scalar-Plain">mapping</span><span class="p p-Indicator">:</span>
+ <span class="l l-Scalar l-Scalar-Plain">Machine</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">str</span><span class="p p-Indicator">,</span> <span class="nv">enum</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">[</span> <span class="nv">IMAGE_FILE_MACHINE_UNKNOWN</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_AM33</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_AMD64</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_ARM</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_ARMNT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_ARM64</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_EBC</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_I386</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_IA64</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_M32R</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_MIPS16</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_MIPSFPU</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_MIPSFPU16</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_POWERPC</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_POWERPCFP</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_R4000</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_SH3</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_SH3DSP</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_SH4</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_SH5</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_THUMB</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_MACHINE_WCEMIPSV2</span>
+ <span class="p p-Indicator">]}</span>
+ <span class="p p-Indicator">,</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">int</span><span class="p p-Indicator">}</span>
+ <span class="p p-Indicator">]</span>
+ <span class="l l-Scalar l-Scalar-Plain">Characteristics</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">seq</span>
+ <span class="l l-Scalar l-Scalar-Plain">sequence</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">str</span>
+ <span class="l l-Scalar l-Scalar-Plain">enum</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span> <span class="nv">IMAGE_FILE_RELOCS_STRIPPED</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_EXECUTABLE_IMAGE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_LINE_NUMS_STRIPPED</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_LOCAL_SYMS_STRIPPED</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_AGGRESSIVE_WS_TRIM</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_LARGE_ADDRESS_AWARE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_BYTES_REVERSED_LO</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_32BIT_MACHINE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_DEBUG_STRIPPED</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_NET_RUN_FROM_SWAP</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_SYSTEM</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_DLL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_UP_SYSTEM_ONLY</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_FILE_BYTES_REVERSED_HI</span>
+ <span class="p p-Indicator">]</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">int</span>
+ <span class="l l-Scalar l-Scalar-Plain">sections</span><span class="p p-Indicator">:</span>
+ <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">seq</span>
+ <span class="l l-Scalar l-Scalar-Plain">sequence</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">map</span>
+ <span class="l l-Scalar l-Scalar-Plain">mapping</span><span class="p p-Indicator">:</span>
+ <span class="l l-Scalar l-Scalar-Plain">Name</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">str</span><span class="p p-Indicator">}</span>
+ <span class="l l-Scalar l-Scalar-Plain">Characteristics</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">seq</span>
+ <span class="l l-Scalar l-Scalar-Plain">sequence</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">str</span>
+ <span class="l l-Scalar l-Scalar-Plain">enum</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span> <span class="nv">IMAGE_SCN_TYPE_NO_PAD</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_CNT_CODE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_CNT_INITIALIZED_DATA</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_CNT_UNINITIALIZED_DATA</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_LNK_OTHER</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_LNK_INFO</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_LNK_REMOVE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_LNK_COMDAT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_GPREL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_PURGEABLE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_16BIT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_LOCKED</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_PRELOAD</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_1BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_2BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_4BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_8BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_16BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_32BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_64BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_128BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_256BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_512BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_1024BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_2048BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_4096BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_ALIGN_8192BYTES</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_LNK_NRELOC_OVFL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_DISCARDABLE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_NOT_CACHED</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_NOT_PAGED</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_SHARED</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_EXECUTE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_READ</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SCN_MEM_WRITE</span>
+ <span class="p p-Indicator">]</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">int</span>
+ <span class="l l-Scalar l-Scalar-Plain">SectionData</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">str</span><span class="p p-Indicator">}</span>
+ <span class="l l-Scalar l-Scalar-Plain">symbols</span><span class="p p-Indicator">:</span>
+ <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">seq</span>
+ <span class="l l-Scalar l-Scalar-Plain">sequence</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">map</span>
+ <span class="l l-Scalar l-Scalar-Plain">mapping</span><span class="p p-Indicator">:</span>
+ <span class="l l-Scalar l-Scalar-Plain">Name</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">str</span><span class="p p-Indicator">}</span>
+ <span class="l l-Scalar l-Scalar-Plain">Value</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">int</span><span class="p p-Indicator">}</span>
+ <span class="l l-Scalar l-Scalar-Plain">SectionNumber</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">int</span><span class="p p-Indicator">}</span>
+ <span class="l l-Scalar l-Scalar-Plain">SimpleType</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">str</span><span class="p p-Indicator">,</span> <span class="nv">enum</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span> <span class="nv">IMAGE_SYM_TYPE_NULL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_VOID</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_CHAR</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_SHORT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_INT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_LONG</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_FLOAT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_DOUBLE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_STRUCT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_UNION</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_ENUM</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_MOE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_BYTE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_WORD</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_UINT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_TYPE_DWORD</span>
+ <span class="p p-Indicator">]}</span>
+ <span class="p p-Indicator">,</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">int</span><span class="p p-Indicator">}</span>
+ <span class="p p-Indicator">]</span>
+ <span class="l l-Scalar l-Scalar-Plain">ComplexType</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">str</span><span class="p p-Indicator">,</span> <span class="nv">enum</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span> <span class="nv">IMAGE_SYM_DTYPE_NULL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_DTYPE_POINTER</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_DTYPE_FUNCTION</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_DTYPE_ARRAY</span>
+ <span class="p p-Indicator">]}</span>
+ <span class="p p-Indicator">,</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">int</span><span class="p p-Indicator">}</span>
+ <span class="p p-Indicator">]</span>
+ <span class="l l-Scalar l-Scalar-Plain">StorageClass</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">str</span><span class="p p-Indicator">,</span> <span class="nv">enum</span><span class="p p-Indicator">:</span>
+ <span class="p p-Indicator">[</span> <span class="nv">IMAGE_SYM_CLASS_END_OF_FUNCTION</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_NULL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_AUTOMATIC</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_EXTERNAL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_STATIC</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_REGISTER</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_EXTERNAL_DEF</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_LABEL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_UNDEFINED_LABEL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_MEMBER_OF_STRUCT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_ARGUMENT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_STRUCT_TAG</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_MEMBER_OF_UNION</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_UNION_TAG</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_TYPE_DEFINITION</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_UNDEFINED_STATIC</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_ENUM_TAG</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_MEMBER_OF_ENUM</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_REGISTER_PARAM</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_BIT_FIELD</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_BLOCK</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_FUNCTION</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_END_OF_STRUCT</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_FILE</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_SECTION</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_WEAK_EXTERNAL</span>
+ <span class="p p-Indicator">,</span> <span class="nv">IMAGE_SYM_CLASS_CLR_TOKEN</span>
+ <span class="p p-Indicator">]}</span>
+ <span class="p p-Indicator">,</span> <span class="p p-Indicator">{</span><span class="nv">type</span><span class="p p-Indicator">:</span> <span class="nv">int</span><span class="p p-Indicator">}</span>
+ <span class="p p-Indicator">]</span>
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="HowToSubmitABug.html" title="How to submit an LLVM bug report"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="HowToAddABuilder.html" title="How To Add Your Build Configuration To LLVM Buildbot Infrastructure"
+ >previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-03-18.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/hans-gpg-key.asc
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/hans-gpg-key.asc?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/hans-gpg-key.asc (added)
+++ www-releases/trunk/8.0.0/hans-gpg-key.asc Wed Mar 20 02:13:27 2019
@@ -0,0 +1,52 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBFS+1SABEACnmkESkY7eZq0GhDjbkWpKmURGk9+ycsfAhA44NqUvf4tk1GPM
+5SkJ/fYedYZJaDVhIp98fHgucD0O+vjOzghtgwtITusYjiPHPFBd/MN+MQqSEAP+
+LUa/kjHLjgyXxKhFUIDGVaDWL5tKOA7/AQKl1TyJ8lz89NHQoUHFsF/hu10+qhJe
+V65d32MXFehIUSvegh8DrPuExrliSiORO4HOhuc6151dWA4YBWVg4rX5kfKrGMMT
+pTWnSSZtgoRhkKW2Ey8cmZUqPuUJIfWyeNVu1e4SFtAivLvu/Ymz2WBJcNA1ZlTr
+RCOR5SIRgZ453pQnI/Bzna2nnJ/TV1gGJIGRahj/ini0cs2x1CILfS/YJQ3rWGGo
+OxwG0BVmPk0cmLVtyTq8gUPwxcPUd6WcBKhot3TDMlrffZACnQwQjlVjk5S1dEEz
+atUfpEuNitU9WOM4jr/gjv36ZNCOWm95YwLhsuci/NddBN8HXhyvs+zYTVZEXa2W
+l/FqOdQsQqZBcJjjWckGKhESdd7934+cesGD3O8KaeSGxww7slJrS0+6QJ8oBoAB
+P/WCn/y2AiY2syEKp3wYIGJyAbsm542zMZ4nc7pYfSu49mcyhQQICmqN5QvOyYUx
+OSqwbAOUNtlOyeRLZNIKoXtTqWDEu5aEiDROTw6Rkq+dIcxPNgOLdeQ3HwARAQAB
+tCFIYW5zIFdlbm5ib3JnIDxoYW5zQGNocm9taXVtLm9yZz6JAlUEEwECAD8CGwMG
+CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAFiEEtsj5goK5ROOw1cJTD8MELjRa0F0F
+Alpd+i0FCQ8FJo0ACgkQD8MELjRa0F3X3A//dBQLm6GmXlQFjxZbukTw0lZsevFR
+M/6ljZTxp7bsC+HFzYoaCKv6rikaWzytxk//SOaLKrB4Z9HjAlpBMtyLl2Hk7tcZ
+bPpFafNmQ+4KgWNjLXCvt9se8BGrQvGQUrbE6YowbXa2YIgxIVEncFzIECAsp/+N
+xbMcZN5/X1PJxKi/N22gP4nn47muN6L3pKez3CXgWnhGYSc7BuD5ALWYH7yMYUem
+d4jlXfu5xkBIqirj1arIYC9wmF4ldbLNDPuracc8LmXcSqa5Rpao0s4iVzAD+tkX
+vE/73m3rhepwBXxrfk0McXuI9aucf5h4/KkIBzZsaJ6JM1tzlrJzzjaBKJF9OI5T
+jA0qTxdGzdPztS8gPaPcMkRFfh9ti0ZDx4VeF3s8sOtmMRHeGEWfxqUAbBUbwFsa
+JDu/+8/VO4KijfcuUi8tqJ/JHeosCuGE7TM93LwJu6ZcqMYOPDROE/hsnGm0ZU92
+xedu+07/X1ESHkSFPoaSHD5/DCNa/tXIyJZ8X7gF3eoDP5mSmrJqIqsOBR9WOVYv
+dI8i0GHTXbrZj8WXdoS+N8wlyMLLbAS2jvTe7M5RoqbLz4ABOUUnLVoEE0CiccVZ
+bW75BPxOfaD0szbinAeX6HDPI7St0MbKrRPjuDXjD0JVkLqFINtZfYLGMLss4tgn
+suefr0Bo9ISwG3u5Ag0EVL7VIAEQAOxBxrQesChjrCqKjY5PnSsSYpeb4froucrC
+898AFw2DgN/Zz+W7wtSTbtz/GRcCurjzZvN7o2rCuNk0j0+s1sgZZm2BdldlabLy
++UF/kSW1rb5qhfXcGGubu48OMdtSfok9lOc0Q1L4HNlGE4lUBkZzmI7Ykqfl+Bwr
+m9rpi54g4ua9PIiiHIAmMoZIcbtOG1KaDr6CoXRk/3g2ZiGUwhq3jFGroiBsKEap
+2FJ1bh5NJk2Eg8pV7fMOF7hUQKBZrNOtIPu8hA5WEgku3U3VYjRSI3SDi6QXnDL+
+xHxajiWpKtF3JjZh8y/CCTD8PyP34YjfZuFmkdske5cdx6H0V2UCiH453ncgFVdQ
+DXkY4n+0MTzhy2xu0IVVnBxYDYNhi+3MjTHJd9C4xMi9t+5IuEvDAPhgfZjDpQak
+EPz6hVmgj0mlKIgRilBRK9/kOxky9utBpGk3jEJGru/hKNloFNspoYtY6zATAr8E
+cOgoCFQE0nIktcg3wF9+OCEnV28/a7XZwUZ7Gl/qfOHtdr374wo8kd8R3V8d2G9q
+5w0/uCV9NNQ0fGWZDPDoYt6wnPL6gZv/nJM8oZY+u0rC24WwScZIniaryC4JHDas
+Ahr2S2CtgCvBgslK6f3gD16KHxPZMBpX73TzOYIhMEP/vXgVJbUD6dYht+U9c4Oh
+EDJown0dABEBAAGJAjwEGAECACYCGwwWIQS2yPmCgrlE47DVwlMPwwQuNFrQXQUC
+Wl36SwUJDwUmqwAKCRAPwwQuNFrQXT1/D/9YpRDNgaJl3YVDtVZoeQwh7BQ6ULZT
+eXFPogYkF2j3VWg8s9UmAs4sg/4a+9KLSantXjX+JFsRv0lQe5Gr/Vl8VQ4LKEXB
+fiGmSivjIZ7eopdd3YP2w6G5T3SA4d2CQfsg4rnJPnXIjzKNiSOi368ybnt9fL0Y
+2r2aqLTmP6Y7issDUO+J1TW1XHm349JPR0Hl4cTuNnWm4JuX2m2CJEc5XBlDAha9
+pUVs+J5C2D0UFFkyeOzeJPwy6x5ApWHm84n8AjhQSpu1qRKxKXdwei6tkQWWMHui
++TgSY/zCkmD9/oY15Ei5avJ4WgIbTLJUoZMi70riPmU8ThjpzA7S+Nk0g7rMPq+X
+l1whjKU/u0udlsrIJjzkh6ftqKUmIkbxYTpjhnEujNrEr5m2S6Z6x3y9E5QagBMR
+dxRhfk+HbyACcP/p9rXOzl4M291DoKeAAH70GHniGxyNs9rAoMr/hD5XW/Wrz3dc
+KMc2s555E6MZILE2ZiolcRn+bYOMPZtWlbx98t8uqMf49gY4FGQBZAwPglMrx7mr
+m7HTIiXahThQGOJg6izJDAD5RwSEGlAcL28T8KAuM6CLLkhlBfQwiKsUBNnh9r8w
+V3lB+pV0GhL+3i077gTYfZBRwLzjFdhm9xUKEaZ6rN1BX9lzix4eSNK5nln0jUq1
+67H2IH//2sf8dw==
+=ADVe
+-----END PGP PUBLIC KEY BLOCK-----
Added: www-releases/trunk/8.0.0/libcxx-8.0.0.src.tar.xz
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/libcxx-8.0.0.src.tar.xz?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/libcxx-8.0.0.src.tar.xz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/libcxx-8.0.0.src.tar.xz.sig
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/libcxx-8.0.0.src.tar.xz.sig?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/libcxx-8.0.0.src.tar.xz.sig
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/libcxxabi-8.0.0.src.tar.xz
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/libcxxabi-8.0.0.src.tar.xz?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/libcxxabi-8.0.0.src.tar.xz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/libcxxabi-8.0.0.src.tar.xz.sig
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/libcxxabi-8.0.0.src.tar.xz.sig?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/libcxxabi-8.0.0.src.tar.xz.sig
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/libunwind-8.0.0.src.tar.xz
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/libunwind-8.0.0.src.tar.xz?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/libunwind-8.0.0.src.tar.xz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/libunwind-8.0.0.src.tar.xz.sig
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/libunwind-8.0.0.src.tar.xz.sig?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/libunwind-8.0.0.src.tar.xz.sig
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/lld-8.0.0.src.tar.xz
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/lld-8.0.0.src.tar.xz?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/lld-8.0.0.src.tar.xz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/lld-8.0.0.src.tar.xz.sig
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/lld-8.0.0.src.tar.xz.sig?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/lld-8.0.0.src.tar.xz.sig
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/lldb-8.0.0.src.tar.xz
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/lldb-8.0.0.src.tar.xz?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/lldb-8.0.0.src.tar.xz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/lldb-8.0.0.src.tar.xz.sig
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/lldb-8.0.0.src.tar.xz.sig?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/lldb-8.0.0.src.tar.xz.sig
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/llvm-8.0.0.src.tar.xz
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/llvm-8.0.0.src.tar.xz?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/llvm-8.0.0.src.tar.xz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/llvm-8.0.0.src.tar.xz.sig
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/llvm-8.0.0.src.tar.xz.sig?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/llvm-8.0.0.src.tar.xz.sig
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/llvm_doxygen-8.0.0.tar.xz
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/llvm_doxygen-8.0.0.tar.xz?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/llvm_doxygen-8.0.0.tar.xz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/openmp-8.0.0.src.tar.xz
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/openmp-8.0.0.src.tar.xz?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/openmp-8.0.0.src.tar.xz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/openmp-8.0.0.src.tar.xz.sig
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/openmp-8.0.0.src.tar.xz.sig?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/openmp-8.0.0.src.tar.xz.sig
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/polly-8.0.0.src.tar.xz
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/polly-8.0.0.src.tar.xz?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/polly-8.0.0.src.tar.xz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/polly-8.0.0.src.tar.xz.sig
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/polly-8.0.0.src.tar.xz.sig?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/polly-8.0.0.src.tar.xz.sig
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/.buildinfo
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/.buildinfo?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/.buildinfo (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/.buildinfo Wed Mar 20 02:13:27 2019
@@ -0,0 +1,4 @@
+# Sphinx build info version 1
+# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
+config: 4947eaba5ba3d0e0b017fa65c6024cb3
+tags: 645f666f9bcd5a90fca523b33c5a78b7
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/BuildingLibcxx.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/BuildingLibcxx.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/BuildingLibcxx.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/BuildingLibcxx.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,614 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Building libc++ — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+ <link rel="next" title="Testing libc++" href="TestingLibcxx.html" />
+ <link rel="prev" title="Using libc++" href="UsingLibcxx.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Building libc++</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="UsingLibcxx.html">Using libc++</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="TestingLibcxx.html">Testing libc++</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="building-libc">
+<span id="buildinglibcxx"></span><h1>Building libc++<a class="headerlink" href="#building-libc" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#getting-started" id="id3">Getting Started</a><ul>
+<li><a class="reference internal" href="#experimental-support-for-windows" id="id4">Experimental Support for Windows</a><ul>
+<li><a class="reference internal" href="#cmake-visual-studio" id="id5">CMake + Visual Studio</a></li>
+<li><a class="reference internal" href="#cmake-ninja" id="id6">CMake + ninja</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#cmake-options" id="id7">CMake Options</a><ul>
+<li><a class="reference internal" href="#libc-specific-options" id="id8">libc++ specific options</a></li>
+<li><a class="reference internal" href="#libc-experimental-specific-options" id="id9">libc++experimental Specific Options</a></li>
+<li><a class="reference internal" href="#abi-library-specific-options" id="id10">ABI Library Specific Options</a></li>
+<li><a class="reference internal" href="#libc-feature-options" id="id11">libc++ Feature Options</a></li>
+<li><a class="reference internal" href="#libc-abi-feature-options" id="id12">libc++ ABI Feature Options</a></li>
+<li><a class="reference internal" href="#llvm-specific-options" id="id13">LLVM-specific options</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#using-alternate-abi-libraries" id="id14">Using Alternate ABI libraries</a><ul>
+<li><a class="reference internal" href="#using-libsupc-on-linux" id="id15">Using libsupc++ on Linux</a></li>
+<li><a class="reference internal" href="#using-libcxxrt-on-linux" id="id16">Using libcxxrt on Linux</a></li>
+<li><a class="reference internal" href="#using-a-local-abi-library-installation" id="id17">Using a local ABI library installation</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="getting-started">
+<span id="build-instructions"></span><h2><a class="toc-backref" href="#id3">Getting Started</a><a class="headerlink" href="#getting-started" title="Permalink to this headline">¶</a></h2>
+<p>On Mac OS 10.7 (Lion) and later, the easiest way to get this library is to install
+Xcode 4.2 or later. However if you want to install tip-of-trunk from here
+(getting the bleeding edge), read on.</p>
+<p>The basic steps needed to build libc++ are:</p>
+<ol class="arabic">
+<li><p class="first">Checkout LLVM:</p>
+<ul class="simple">
+<li><code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">where-you-want-llvm-to-live</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">svn</span> <span class="pre">co</span> <span class="pre">http://llvm.org/svn/llvm-project/llvm/trunk</span> <span class="pre">llvm</span></code></li>
+</ul>
+</li>
+<li><p class="first">Checkout libc++:</p>
+<ul class="simple">
+<li><code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">where-you-want-llvm-to-live</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">llvm/projects</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">svn</span> <span class="pre">co</span> <span class="pre">http://llvm.org/svn/llvm-project/libcxx/trunk</span> <span class="pre">libcxx</span></code></li>
+</ul>
+</li>
+<li><p class="first">Checkout libc++abi:</p>
+<ul class="simple">
+<li><code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">where-you-want-llvm-to-live</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">llvm/projects</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">svn</span> <span class="pre">co</span> <span class="pre">http://llvm.org/svn/llvm-project/libcxxabi/trunk</span> <span class="pre">libcxxabi</span></code></li>
+</ul>
+</li>
+<li><p class="first">Configure and build libc++ with libc++abi:</p>
+<p>CMake is the only supported configuration system.</p>
+<p>Clang is the preferred compiler when building and using libc++.</p>
+<ul class="simple">
+<li><code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">where</span> <span class="pre">you</span> <span class="pre">want</span> <span class="pre">to</span> <span class="pre">build</span> <span class="pre">llvm</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">mkdir</span> <span class="pre">build</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">build</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">cmake</span> <span class="pre">-G</span> <span class="pre"><generator></span> <span class="pre">[options]</span> <span class="pre"><path</span> <span class="pre">to</span> <span class="pre">llvm</span> <span class="pre">sources></span></code></li>
+</ul>
+<p>For more information about configuring libc++ see <a class="reference internal" href="#cmake-options"><span class="std std-ref">CMake Options</span></a>.</p>
+<ul class="simple">
+<li><code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">cxx</span></code> â will build libc++ and libc++abi.</li>
+<li><code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">check-cxx</span> <span class="pre">check-cxxabi</span></code> â will run the test suites.</li>
+</ul>
+<p>Shared libraries for libc++ and libc++ abi should now be present in llvm/build/lib.
+See <a class="reference internal" href="UsingLibcxx.html#alternate-libcxx"><span class="std std-ref">using an alternate libc++ installation</span></a></p>
+</li>
+<li><p class="first"><strong>Optional</strong>: Install libc++ and libc++abi</p>
+<p>If your system already provides a libc++ installation it is important to be
+careful not to replace it. Remember Use the CMake option <code class="docutils literal notranslate"><span class="pre">CMAKE_INSTALL_PREFIX</span></code> to
+select a safe place to install libc++.</p>
+<ul class="simple">
+<li><code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">install-cxx</span> <span class="pre">install-cxxabi</span></code> â Will install the libraries and the headers</li>
+</ul>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<ul class="last simple">
+<li>Replacing your systems libc++ installation could render the system non-functional.</li>
+<li>Mac OS X will not boot without a valid copy of <code class="docutils literal notranslate"><span class="pre">libc++.1.dylib</span></code> in <code class="docutils literal notranslate"><span class="pre">/usr/lib</span></code>.</li>
+</ul>
+</div>
+</li>
+</ol>
+<p>The instructions are for building libc++ on
+FreeBSD, Linux, or Mac using <a class="reference external" href="http://libcxxabi.llvm.org/">libc++abi</a> as the C++ ABI library.
+On Linux, it is also possible to use <a class="reference internal" href="#libsupcxx"><span class="std std-ref">libsupc++</span></a> or libcxxrt.</p>
+<p>It is sometimes beneficial to build outside of the LLVM tree. An out-of-tree
+build would look like this:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nb">cd</span> where-you-want-libcxx-to-live
+$ <span class="c1"># Check out llvm, libc++ and libc++abi.</span>
+$ <span class="sb">``</span>svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm<span class="sb">``</span>
+$ <span class="sb">``</span>svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx<span class="sb">``</span>
+$ <span class="sb">``</span>svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi<span class="sb">``</span>
+$ <span class="nb">cd</span> where-you-want-to-build
+$ mkdir build <span class="o">&&</span> <span class="nb">cd</span> build
+$ <span class="nb">export</span> <span class="nv">CC</span><span class="o">=</span>clang <span class="nv">CXX</span><span class="o">=</span>clang++
+$ cmake -DLLVM_PATH<span class="o">=</span>path/to/llvm <span class="se">\</span>
+ -DLIBCXX_CXX_ABI<span class="o">=</span>libcxxabi <span class="se">\</span>
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS<span class="o">=</span>path/to/libcxxabi/include <span class="se">\</span>
+ path/to/libcxx
+$ make
+$ make check-libcxx <span class="c1"># optional</span>
+</pre></div>
+</div>
+<div class="section" id="experimental-support-for-windows">
+<h3><a class="toc-backref" href="#id4">Experimental Support for Windows</a><a class="headerlink" href="#experimental-support-for-windows" title="Permalink to this headline">¶</a></h3>
+<p>The Windows support requires building with clang-cl as cl does not support one
+required extension: <cite>#include_next</cite>. Furthermore, VS 2015 or newer (19.00) is
+required. In the case of clang-cl, we need to specify the âMS Compatibility
+Versionâ as it defaults to 2014 (18.00).</p>
+<div class="section" id="cmake-visual-studio">
+<h4><a class="toc-backref" href="#id5">CMake + Visual Studio</a><a class="headerlink" href="#cmake-visual-studio" title="Permalink to this headline">¶</a></h4>
+<p>Building with Visual Studio currently does not permit running tests. However,
+it is the simplest way to build.</p>
+<div class="highlight-batch notranslate"><div class="highlight"><pre><span></span><span class="p">></span> cmake -G <span class="s2">"Visual Studio 14 2015"</span> <span class="se">^</span>
+<span class="se"> </span> -T <span class="s2">"LLVM-vs2014"</span> <span class="se">^</span>
+<span class="se"> </span> -DLIBCXX_ENABLE_SHARED=YES <span class="se">^</span>
+<span class="se"> </span> -DLIBCXX_ENABLE_STATIC=NO <span class="se">^</span>
+<span class="se"> </span> -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO <span class="se">^</span>
+<span class="se"> </span> \path\to\libcxx
+<span class="p">></span> cmake --build .
+</pre></div>
+</div>
+</div>
+<div class="section" id="cmake-ninja">
+<h4><a class="toc-backref" href="#id6">CMake + ninja</a><a class="headerlink" href="#cmake-ninja" title="Permalink to this headline">¶</a></h4>
+<p>Building with ninja is required for development to enable tests.
+Unfortunately, doing so requires additional configuration as we cannot
+just specify a toolset.</p>
+<div class="highlight-batch notranslate"><div class="highlight"><pre><span></span><span class="p">></span> cmake -G Ninja <span class="se">^</span>
+<span class="se"> </span> -DCMAKE_MAKE_PROGRAM=/path/to/ninja <span class="se">^</span>
+<span class="se"> </span> -DCMAKE_SYSTEM_NAME=Windows <span class="se">^</span>
+<span class="se"> </span> -DCMAKE_C_COMPILER=clang-cl <span class="se">^</span>
+<span class="se"> </span> -DCMAKE_C_FLAGS=<span class="s2">"-fms-compatibility-version=19.00 --target=i686--windows"</span> <span class="se">^</span>
+<span class="se"> </span> -DCMAKE_CXX_COMPILER=clang-cl <span class="se">^</span>
+<span class="se"> </span> -DCMAKE_CXX_FLAGS=<span class="s2">"-fms-compatibility-version=19.00 --target=i686--windows"</span> <span class="se">^</span>
+<span class="se"> </span> -DLLVM_PATH=/path/to/llvm/tree <span class="se">^</span>
+<span class="se"> </span> -DLIBCXX_ENABLE_SHARED=YES <span class="se">^</span>
+<span class="se"> </span> -DLIBCXX_ENABLE_STATIC=NO <span class="se">^</span>
+<span class="se"> </span> -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO <span class="se">^</span>
+<span class="se"> </span> \path\to\libcxx
+<span class="p">></span> /path/to/ninja cxx
+<span class="p">></span> /path/to/ninja check-cxx
+</pre></div>
+</div>
+<p>Note that the paths specified with backward slashes must use the <cite>\</cite> as the
+directory separator as clang-cl may otherwise parse the path as an argument.</p>
+</div>
+</div>
+</div>
+<div class="section" id="cmake-options">
+<span id="id1"></span><h2><a class="toc-backref" href="#id7">CMake Options</a><a class="headerlink" href="#cmake-options" title="Permalink to this headline">¶</a></h2>
+<p>Here are some of the CMake variables that are used often, along with a
+brief explanation and LLVM-specific notes. For full documentation, check the
+CMake docs or execute <code class="docutils literal notranslate"><span class="pre">cmake</span> <span class="pre">--help-variable</span> <span class="pre">VARIABLE_NAME</span></code>.</p>
+<dl class="docutils">
+<dt><strong>CMAKE_BUILD_TYPE</strong>:STRING</dt>
+<dd>Sets the build type for <code class="docutils literal notranslate"><span class="pre">make</span></code> based generators. Possible values are
+Release, Debug, RelWithDebInfo and MinSizeRel. On systems like Visual Studio
+the user sets the build type with the IDE settings.</dd>
+<dt><strong>CMAKE_INSTALL_PREFIX</strong>:PATH</dt>
+<dd>Path where LLVM will be installed if âmake installâ is invoked or the
+âINSTALLâ target is built.</dd>
+<dt><strong>CMAKE_CXX_COMPILER</strong>:STRING</dt>
+<dd>The C++ compiler to use when building and testing libc++.</dd>
+</dl>
+<div class="section" id="libc-specific-options">
+<span id="libcxx-specific-options"></span><h3><a class="toc-backref" href="#id8">libc++ specific options</a><a class="headerlink" href="#libc-specific-options" title="Permalink to this headline">¶</a></h3>
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-install-library-bool">
+<code class="descname">LIBCXX_INSTALL_LIBRARY:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-install-library-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Toggle the installation of the library portion of libc++.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-install-headers-bool">
+<code class="descname">LIBCXX_INSTALL_HEADERS:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-install-headers-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Toggle the installation of the libc++ headers.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-enable-assertions-bool">
+<code class="descname">LIBCXX_ENABLE_ASSERTIONS:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-enable-assertions-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Build libc++ with assertions enabled.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-build-32-bits-bool">
+<code class="descname">LIBCXX_BUILD_32_BITS:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-build-32-bits-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">OFF</span></code></p>
+<p>Build libc++ as a 32 bit library. Also see <cite>LLVM_BUILD_32_BITS</cite>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-enable-shared-bool">
+<code class="descname">LIBCXX_ENABLE_SHARED:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-enable-shared-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Build libc++ as a shared library. Either <cite>LIBCXX_ENABLE_SHARED</cite> or
+<cite>LIBCXX_ENABLE_STATIC</cite> has to be enabled.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-enable-static-bool">
+<code class="descname">LIBCXX_ENABLE_STATIC:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-enable-static-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Build libc++ as a static library. Either <cite>LIBCXX_ENABLE_SHARED</cite> or
+<cite>LIBCXX_ENABLE_STATIC</cite> has to be enabled.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-libdir-suffix-string">
+<code class="descname">LIBCXX_LIBDIR_SUFFIX:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-libdir-suffix-string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Extra suffix to append to the directory where libraries are to be installed.
+This option overrides <cite>LLVM_LIBDIR_SUFFIX</cite>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-install-prefix-string">
+<code class="descname">LIBCXX_INSTALL_PREFIX:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-install-prefix-string" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">""</span></code></p>
+<p>Define libc++ destination prefix.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-hermetic-static-library-bool">
+<code class="descname">LIBCXX_HERMETIC_STATIC_LIBRARY:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-hermetic-static-library-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">OFF</span></code></p>
+<p>Do not export any symbols from the static libc++ library. This is useful when
+This is useful when the static libc++ library is being linked into shared
+libraries that may be used in with other shared libraries that use different
+C++ library. We want to avoid avoid exporting any libc++ symbols in that case.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="libc-experimental-specific-options">
+<span id="libc-experimental-options"></span><h3><a class="toc-backref" href="#id9">libc++experimental Specific Options</a><a class="headerlink" href="#libc-experimental-specific-options" title="Permalink to this headline">¶</a></h3>
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-enable-experimental-library-bool">
+<code class="descname">LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-enable-experimental-library-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Build and test libc++experimental.a.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-install-experimental-library-bool">
+<code class="descname">LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-install-experimental-library-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY</span> <span class="pre">AND</span> <span class="pre">LIBCXX_INSTALL_LIBRARY</span></code></p>
+<p>Install libc++experimental.a alongside libc++.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-enable-filesystem-bool">
+<code class="descname">LIBCXX_ENABLE_FILESYSTEM:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-enable-filesystem-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Build filesystem as a standalone library libc++fs.a.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-install-filesystem-library-bool">
+<code class="descname">LIBCXX_INSTALL_FILESYSTEM_LIBRARY:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-install-filesystem-library-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">LIBCXX_ENABLE_FILESYSTEM</span> <span class="pre">AND</span> <span class="pre">LIBCXX_INSTALL_LIBRARY</span></code></p>
+<p>Install libc++fs.a alongside libc++.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="abi-library-specific-options">
+<span id="id2"></span><h3><a class="toc-backref" href="#id10">ABI Library Specific Options</a><a class="headerlink" href="#abi-library-specific-options" title="Permalink to this headline">¶</a></h3>
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-cxx-abi-string">
+<code class="descname">LIBCXX_CXX_ABI:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-cxx-abi-string" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Values</strong>: <code class="docutils literal notranslate"><span class="pre">none</span></code>, <code class="docutils literal notranslate"><span class="pre">libcxxabi</span></code>, <code class="docutils literal notranslate"><span class="pre">libcxxrt</span></code>, <code class="docutils literal notranslate"><span class="pre">libstdc++</span></code>, <code class="docutils literal notranslate"><span class="pre">libsupc++</span></code>.</p>
+<p>Select the ABI library to build libc++ against.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-cxx-abi-include-paths-paths">
+<code class="descname">LIBCXX_CXX_ABI_INCLUDE_PATHS:PATHS</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-cxx-abi-include-paths-paths" title="Permalink to this definition">¶</a></dt>
+<dd><p>Provide additional search paths for the ABI library headers.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-cxx-abi-library-path-path">
+<code class="descname">LIBCXX_CXX_ABI_LIBRARY_PATH:PATH</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-cxx-abi-library-path-path" title="Permalink to this definition">¶</a></dt>
+<dd><p>Provide the path to the ABI library that libc++ should link against.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-enable-static-abi-library-bool">
+<code class="descname">LIBCXX_ENABLE_STATIC_ABI_LIBRARY:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-enable-static-abi-library-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">OFF</span></code></p>
+<p>If this option is enabled, libc++ will try and link the selected ABI library
+statically.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-enable-abi-linker-script-bool">
+<code class="descname">LIBCXX_ENABLE_ABI_LINKER_SCRIPT:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-enable-abi-linker-script-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code> by default on UNIX platforms other than Apple unless
+âLIBCXX_ENABLE_STATIC_ABI_LIBRARYâ is ON. Otherwise the default value is <code class="docutils literal notranslate"><span class="pre">OFF</span></code>.</p>
+<p>This option generate and installs a linker script as <code class="docutils literal notranslate"><span class="pre">libc++.so</span></code> which
+links the correct ABI library.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxxabi-use-llvm-unwinder-bool">
+<code class="descname">LIBCXXABI_USE_LLVM_UNWINDER:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxxabi-use-llvm-unwinder-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">OFF</span></code></p>
+<p>Build and use the LLVM unwinder. Note: This option can only be used when
+libc++abi is the C++ ABI library used.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="libc-feature-options">
+<h3><a class="toc-backref" href="#id11">libc++ Feature Options</a><a class="headerlink" href="#libc-feature-options" title="Permalink to this headline">¶</a></h3>
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-enable-exceptions-bool">
+<code class="descname">LIBCXX_ENABLE_EXCEPTIONS:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-enable-exceptions-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Build libc++ with exception support.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-enable-rtti-bool">
+<code class="descname">LIBCXX_ENABLE_RTTI:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-enable-rtti-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Build libc++ with run time type information.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-include-benchmarks-bool">
+<code class="descname">LIBCXX_INCLUDE_BENCHMARKS:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-include-benchmarks-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">ON</span></code></p>
+<p>Build the libc++ benchmark tests and the Google Benchmark library needed
+to support them.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-benchmark-test-args-string">
+<code class="descname">LIBCXX_BENCHMARK_TEST_ARGS:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-benchmark-test-args-string" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">--benchmark_min_time=0.01</span></code></p>
+<p>A semicolon list of arguments to pass when running the libc++ benchmarks using the
+<code class="docutils literal notranslate"><span class="pre">check-cxx-benchmarks</span></code> rule. By default we run the benchmarks for a very short amount of time,
+since the primary use of <code class="docutils literal notranslate"><span class="pre">check-cxx-benchmarks</span></code> is to get test and sanitizer coverage, not to
+get accurate measurements.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-benchmark-native-stdlib-string">
+<code class="descname">LIBCXX_BENCHMARK_NATIVE_STDLIB:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-benchmark-native-stdlib-string" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>:: <code class="docutils literal notranslate"><span class="pre">""</span></code></p>
+<p><strong>Values</strong>:: <code class="docutils literal notranslate"><span class="pre">libc++</span></code>, <code class="docutils literal notranslate"><span class="pre">libstdc++</span></code></p>
+<p>Build the libc++ benchmark tests and Google Benchmark library against the
+specified standard library on the platform. On linux this can be used to
+compare libc++ to libstdc++ by building the benchmark tests against both
+standard libraries.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-benchmark-native-gcc-toolchain-string">
+<code class="descname">LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-benchmark-native-gcc-toolchain-string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Use the specified GCC toolchain and standard library when building the native
+stdlib benchmark tests.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-hide-from-abi-per-tu-by-default-bool">
+<code class="descname">LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-hide-from-abi-per-tu-by-default-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">OFF</span></code></p>
+<p>Pick the default for whether to constrain ABI-unstable symbols to
+each individual translation unit. This setting controls whether
+<cite>_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT</cite> is defined by default â
+see the documentation of that macro for details.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="libc-abi-feature-options">
+<h3><a class="toc-backref" href="#id12">libc++ ABI Feature Options</a><a class="headerlink" href="#libc-abi-feature-options" title="Permalink to this headline">¶</a></h3>
+<p>The following options allow building libc++ for a different ABI version.</p>
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-abi-version-string">
+<code class="descname">LIBCXX_ABI_VERSION:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-abi-version-string" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">1</span></code></p>
+<p>Defines the target ABI version of libc++.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-abi-unstable-bool">
+<code class="descname">LIBCXX_ABI_UNSTABLE:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-abi-unstable-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">OFF</span></code></p>
+<p>Build the âunstableâ ABI version of libc++. Includes all ABI changing features
+on top of the current stable version.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-abi-namespace-string">
+<code class="descname">LIBCXX_ABI_NAMESPACE:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-abi-namespace-string" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">__n</span></code> where <code class="docutils literal notranslate"><span class="pre">n</span></code> is the current ABI version.</p>
+<p>This option defines the name of the inline ABI versioning namespace. It can be used for building
+custom versions of libc++ with unique symbol names in order to prevent conflicts or ODR issues
+with other libc++ versions.</p>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">When providing a custom namespace, itâs the users responsibility to ensure the name wonât cause
+conflicts with other names defined by libc++, both now and in the future. In particular, inline
+namespaces of the form <code class="docutils literal notranslate"><span class="pre">__[0-9]+</span></code> are strictly reserved by libc++ and may not be used by users.
+Doing otherwise could cause conflicts and hinder libc++ ABI evolution.</p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-libcxx-abi-defines-string">
+<code class="descname">LIBCXX_ABI_DEFINES:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-libcxx-abi-defines-string" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: <code class="docutils literal notranslate"><span class="pre">""</span></code></p>
+<p>A semicolon-separated list of ABI macros to persist in the site config header.
+See <code class="docutils literal notranslate"><span class="pre">include/__config</span></code> for the list of ABI macros.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="llvm-specific-options">
+<span id="llvm-specific-variables"></span><h3><a class="toc-backref" href="#id13">LLVM-specific options</a><a class="headerlink" href="#llvm-specific-options" title="Permalink to this headline">¶</a></h3>
+<dl class="option">
+<dt id="cmdoption-arg-llvm-libdir-suffix-string">
+<code class="descname">LLVM_LIBDIR_SUFFIX:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-llvm-libdir-suffix-string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Extra suffix to append to the directory where libraries are to be
+installed. On a 64-bit architecture, one could use <code class="docutils literal notranslate"><span class="pre">-DLLVM_LIBDIR_SUFFIX=64</span></code>
+to install libraries to <code class="docutils literal notranslate"><span class="pre">/usr/lib64</span></code>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-llvm-build-32-bits-bool">
+<code class="descname">LLVM_BUILD_32_BITS:BOOL</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-llvm-build-32-bits-bool" title="Permalink to this definition">¶</a></dt>
+<dd><p>Build 32-bits executables and libraries on 64-bits systems. This option is
+available only on some 64-bits unix systems. Defaults to OFF.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-arg-llvm-lit-args-string">
+<code class="descname">LLVM_LIT_ARGS:STRING</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-arg-llvm-lit-args-string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Arguments given to lit. <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">check</span></code> and <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">clang-test</span></code> are affected.
+By default, <code class="docutils literal notranslate"><span class="pre">'-sv</span> <span class="pre">--no-progress-bar'</span></code> on Visual C++ and Xcode, <code class="docutils literal notranslate"><span class="pre">'-sv'</span></code> on
+others.</p>
+</dd></dl>
+
+</div>
+</div>
+<div class="section" id="using-alternate-abi-libraries">
+<h2><a class="toc-backref" href="#id14">Using Alternate ABI libraries</a><a class="headerlink" href="#using-alternate-abi-libraries" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="using-libsupc-on-linux">
+<span id="libsupcxx"></span><h3><a class="toc-backref" href="#id15">Using libsupc++ on Linux</a><a class="headerlink" href="#using-libsupc-on-linux" title="Permalink to this headline">¶</a></h3>
+<p>You will need libstdc++ in order to provide libsupc++.</p>
+<p>Figure out where the libsupc++ headers are on your system. On Ubuntu this
+is <code class="docutils literal notranslate"><span class="pre">/usr/include/c++/<version></span></code> and <code class="docutils literal notranslate"><span class="pre">/usr/include/c++/<version>/<target-triple></span></code></p>
+<p>You can also figure this out by running</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nb">echo</span> <span class="p">|</span> g++ -Wp,-v -x c++ - -fsyntax-only
+ignoring nonexistent directory <span class="s2">"/usr/local/include/x86_64-linux-gnu"</span>
+ignoring nonexistent directory <span class="s2">"/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/include"</span>
+<span class="c1">#include "..." search starts here:</span>
+<span class="c1">#include <...> search starts here:</span>
+/usr/include/c++/4.7
+/usr/include/c++/4.7/x86_64-linux-gnu
+/usr/include/c++/4.7/backward
+/usr/lib/gcc/x86_64-linux-gnu/4.7/include
+/usr/local/include
+/usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed
+/usr/include/x86_64-linux-gnu
+/usr/include
+End of search list.
+</pre></div>
+</div>
+<p>Note that the first two entries happen to be what we are looking for. This
+may not be correct on other platforms.</p>
+<p>We can now run CMake:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nv">CC</span><span class="o">=</span>clang <span class="nv">CXX</span><span class="o">=</span>clang++ cmake -G <span class="s2">"Unix Makefiles"</span> <span class="se">\</span>
+ -DLIBCXX_CXX_ABI<span class="o">=</span>libstdc++ <span class="se">\</span>
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS<span class="o">=</span><span class="s2">"/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/"</span> <span class="se">\</span>
+ -DCMAKE_BUILD_TYPE<span class="o">=</span>Release -DCMAKE_INSTALL_PREFIX<span class="o">=</span>/usr <span class="se">\</span>
+ <libc++-source-dir>
+</pre></div>
+</div>
+<p>You can also substitute <code class="docutils literal notranslate"><span class="pre">-DLIBCXX_CXX_ABI=libsupc++</span></code>
+above, which will cause the library to be linked to libsupc++ instead
+of libstdc++, but this is only recommended if you know that you will
+never need to link against libstdc++ in the same executable as libc++.
+GCC ships libsupc++ separately but only as a static library. If a
+program also needs to link against libstdc++, it will provide its
+own copy of libsupc++ and this can lead to subtle problems.</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ make cxx
+$ make install
+</pre></div>
+</div>
+<p>You can now run clang with -stdlib=libc++.</p>
+</div>
+<div class="section" id="using-libcxxrt-on-linux">
+<span id="libcxxrt-ref"></span><h3><a class="toc-backref" href="#id16">Using libcxxrt on Linux</a><a class="headerlink" href="#using-libcxxrt-on-linux" title="Permalink to this headline">¶</a></h3>
+<p>You will need to keep the source tree of <a class="reference external" href="https://github.com/pathscale/libcxxrt/">libcxxrt</a> available
+on your build machine and your copy of the libcxxrt shared library must
+be placed where your linker will find it.</p>
+<p>We can now run CMake like:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nv">CC</span><span class="o">=</span>clang <span class="nv">CXX</span><span class="o">=</span>clang++ cmake -G <span class="s2">"Unix Makefiles"</span> <span class="se">\</span>
+ -DLIBCXX_CXX_ABI<span class="o">=</span>libcxxrt <span class="se">\</span>
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS<span class="o">=</span>path/to/libcxxrt-sources/src <span class="se">\</span>
+ -DCMAKE_BUILD_TYPE<span class="o">=</span>Release <span class="se">\</span>
+ -DCMAKE_INSTALL_PREFIX<span class="o">=</span>/usr <span class="se">\</span>
+ <libc++-source-directory>
+$ make cxx
+$ make install
+</pre></div>
+</div>
+<p>Unfortunately you canât simply run clang with â-stdlib=libc++â at this point, as
+clang is set up to link for libc++ linked to libsupc++. To get around this
+youâll have to set up your linker yourself (or patch clang). For example,</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ clang++ -stdlib<span class="o">=</span>libc++ helloworld.cpp <span class="se">\</span>
+ -nodefaultlibs -lc++ -lcxxrt -lm -lc -lgcc_s -lgcc
+</pre></div>
+</div>
+<p>Alternately, you could just add libcxxrt to your libraries list, which in most
+situations will give the same result:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ clang++ -stdlib<span class="o">=</span>libc++ helloworld.cpp -lcxxrt
+</pre></div>
+</div>
+</div>
+<div class="section" id="using-a-local-abi-library-installation">
+<h3><a class="toc-backref" href="#id17">Using a local ABI library installation</a><a class="headerlink" href="#using-a-local-abi-library-installation" title="Permalink to this headline">¶</a></h3>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">This is not recommended in almost all cases.</p>
+</div>
+<p>These instructions should only be used when you canât install your ABI library.</p>
+<p>Normally you must link libc++ against a ABI shared library that the
+linker can find. If you want to build and test libc++ against an ABI
+library not in the linkerâs path you needq to set
+<code class="docutils literal notranslate"><span class="pre">-DLIBCXX_CXX_ABI_LIBRARY_PATH=/path/to/abi/lib</span></code> when configuring CMake.</p>
+<p>An example build using libc++abi would look like:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nv">CC</span><span class="o">=</span>clang <span class="nv">CXX</span><span class="o">=</span>clang++ cmake <span class="se">\</span>
+ -DLIBCXX_CXX_ABI<span class="o">=</span>libc++abi <span class="se">\</span>
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS<span class="o">=</span><span class="s2">"/path/to/libcxxabi/include"</span> <span class="se">\</span>
+ -DLIBCXX_CXX_ABI_LIBRARY_PATH<span class="o">=</span><span class="s2">"/path/to/libcxxabi-build/lib"</span> <span class="se">\</span>
+ path/to/libcxx
+$ make
+</pre></div>
+</div>
+<p>When testing libc++ LIT will automatically link against the proper ABI
+library.</p>
+</div>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="UsingLibcxx.html">Using libc++</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="TestingLibcxx.html">Testing libc++</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/ABIVersioning.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/ABIVersioning.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/ABIVersioning.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/ABIVersioning.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,72 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Libc++ ABI stability — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="../_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="Symbol Visibility Macros" href="VisibilityMacros.html" />
+ <link rel="prev" title="Capturing configuration information during installation" href="CapturingConfigInfo.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="../index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Libc++ ABI stability</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="CapturingConfigInfo.html">Capturing configuration information during installation</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="VisibilityMacros.html">Symbol Visibility Macros</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="libc-abi-stability">
+<h1>Libc++ ABI stability<a class="headerlink" href="#libc-abi-stability" title="Permalink to this headline">¶</a></h1>
+<p>Libc++ aims to preserve stable ABI to avoid subtle bugs when code built to the old ABI
+is linked with the code build to the new ABI. At the same time, libc++ allows ABI-breaking
+improvements and bugfixes for the scenarios when ABI change is not a issue.</p>
+<p>To support both cases, libc++ allows specifying the ABI version at the
+build time. The version is defined with a cmake option
+LIBCXX_ABI_VERSION. Another option LIBCXX_ABI_UNSTABLE can be used to
+include all present ABI breaking features. These options translate
+into C++ macro definitions _LIBCPP_ABI_VERSION, _LIBCPP_ABI_UNSTABLE.</p>
+<p>Any ABI-changing feature is placed under itâs own macro, _LIBCPP_ABI_XXX, which is enabled
+based on the value of _LIBCPP_ABI_VERSION. _LIBCPP_ABI_UNSTABLE, if set, enables all features at once.</p>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="CapturingConfigInfo.html">Capturing configuration information during installation</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="VisibilityMacros.html">Symbol Visibility Macros</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/AvailabilityMarkup.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/AvailabilityMarkup.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/AvailabilityMarkup.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/AvailabilityMarkup.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,159 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Availability Markup — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="../_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="Debug Mode" href="DebugMode.html" />
+ <link rel="prev" title="Feature Test Macro Support" href="../FeatureTestMacroTable.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="../index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Availability Markup</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="../FeatureTestMacroTable.html">Feature Test Macro Support</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="DebugMode.html">Debug Mode</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="availability-markup">
+<h1>Availability Markup<a class="headerlink" href="#availability-markup" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
+<li><a class="reference internal" href="#design" id="id2">Design</a></li>
+<li><a class="reference internal" href="#testing" id="id3">Testing</a></li>
+</ul>
+</div>
+<div class="section" id="overview">
+<h2><a class="toc-backref" href="#id1">Overview</a><a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
+<p>Libc++ is used as a system library on macOS and iOS (amongst others). In order
+for users to be able to compile a binary that is intended to be deployed to an
+older version of the platform, clang provides the
+<a class="reference external" href="https://clang.llvm.org/docs/AttributeReference.html#availability">availability attribute</a>
+that can be placed on declarations to describe the lifecycle of a symbol in the
+library.</p>
+</div>
+<div class="section" id="design">
+<h2><a class="toc-backref" href="#id2">Design</a><a class="headerlink" href="#design" title="Permalink to this headline">¶</a></h2>
+<p>When a new feature is introduced that requires dylib support, a macro should be
+created in include/__config to mark this feature as unavailable for all the
+systems. For example:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">//</span> <span class="n">Define</span> <span class="n">availability</span> <span class="n">macros</span><span class="o">.</span>
+<span class="c1">#if defined(_LIBCPP_USE_AVAILABILITY_APPLE)</span>
+<span class="c1"># define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))</span>
+<span class="c1">#else if defined(_LIBCPP_USE_AVAILABILITY_SOME_OTHER_VENDOR)</span>
+<span class="c1"># define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))</span>
+<span class="c1">#else</span>
+<span class="c1"># define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS</span>
+<span class="c1">#endif</span>
+</pre></div>
+</div>
+<p>When the library is updated by the platform vendor, the markup can be updated.
+For example:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#define _LIBCPP_AVAILABILITY_SHARED_MUTEX \</span>
+ <span class="n">__attribute__</span><span class="p">((</span><span class="n">availability</span><span class="p">(</span><span class="n">macosx</span><span class="p">,</span><span class="n">strict</span><span class="p">,</span><span class="n">introduced</span><span class="o">=</span><span class="mf">10.12</span><span class="p">)))</span> \
+ <span class="n">__attribute__</span><span class="p">((</span><span class="n">availability</span><span class="p">(</span><span class="n">ios</span><span class="p">,</span><span class="n">strict</span><span class="p">,</span><span class="n">introduced</span><span class="o">=</span><span class="mf">10.0</span><span class="p">)))</span> \
+ <span class="n">__attribute__</span><span class="p">((</span><span class="n">availability</span><span class="p">(</span><span class="n">tvos</span><span class="p">,</span><span class="n">strict</span><span class="p">,</span><span class="n">introduced</span><span class="o">=</span><span class="mf">10.0</span><span class="p">)))</span> \
+ <span class="n">__attribute__</span><span class="p">((</span><span class="n">availability</span><span class="p">(</span><span class="n">watchos</span><span class="p">,</span><span class="n">strict</span><span class="p">,</span><span class="n">introduced</span><span class="o">=</span><span class="mf">3.0</span><span class="p">)))</span>
+</pre></div>
+</div>
+<p>In the source code, the macro can be added on a class if the full class requires
+type info from the library for example:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL</span>
+<span class="k">class</span> <span class="nc">_LIBCPP_EXCEPTION_ABI</span> <span class="n">_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS</span> <span class="n">bad_optional_access</span>
+ <span class="p">:</span> <span class="n">public</span> <span class="n">std</span><span class="p">::</span><span class="n">logic_error</span> <span class="p">{</span>
+</pre></div>
+</div>
+<p>or on a particular symbol:</p>
+<blockquote>
+<div>_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;</div></blockquote>
+</div>
+<div class="section" id="testing">
+<h2><a class="toc-backref" href="#id3">Testing</a><a class="headerlink" href="#testing" title="Permalink to this headline">¶</a></h2>
+<p>Some parameters can be passed to lit to run the test-suite and exercise the
+availability.</p>
+<ul class="simple">
+<li>The <cite>platform</cite> parameter controls the deployment target. For example lit can
+be invoked with <cite>âparam=platform=macosx10.8</cite>. Default is the current host.</li>
+<li>The <cite>use_system_cxx_lib</cite> parameter indicates to use another library than the
+just built one. Invoking lit with <cite>âparam=use_system_cxx_lib=true</cite> will run
+the test-suite against the host system library. Alternatively a path to the
+directory containing a specific prebuilt libc++ can be used, for example:
+<cite>âparam=use_system_cxx_lib=/path/to/macOS/10.8/</cite>.</li>
+</ul>
+<p>Tests can be marked as XFAIL based on multiple features made available by lit:</p>
+<ul>
+<li><p class="first">if <cite>âparam=platform=macosx10.8</cite> is passed, the following features will be available:</p>
+<ul class="simple">
+<li>availability</li>
+<li>availability=x86_64</li>
+<li>availability=macosx</li>
+<li>availability=x86_64-macosx</li>
+<li>availability=x86_64-apple-macosx10.8</li>
+<li>availability=macosx10.8</li>
+</ul>
+<p>This feature is used to XFAIL a test that <em>is</em> using a class or a method marked
+as unavailable <em>and</em> that is expected to <em>fail</em> if deployed on an older system.</p>
+</li>
+<li><p class="first">if <cite>use_system_cxx_lib</cite> and <cite>âparam=platform=macosx10.8</cite> are passed to lit,
+the following features will also be available:</p>
+<ul class="simple">
+<li>with_system_cxx_lib</li>
+<li>with_system_cxx_lib=x86_64</li>
+<li>with_system_cxx_lib=macosx</li>
+<li>with_system_cxx_lib=x86_64-macosx</li>
+<li>with_system_cxx_lib=x86_64-apple-macosx10.8</li>
+<li>with_system_cxx_lib=macosx10.8</li>
+</ul>
+<p>This feature is used to XFAIL a test that is <em>not</em> using a class or a method
+marked as unavailable <em>but</em> that is expected to fail if deployed on an older
+system. For example, if the test exhibits a bug in the libc on a particular
+system version, or if the test uses a symbol that is not available on an
+older version of the dylib (but for which there is no availability markup,
+otherwise the XFAIL should use <cite>availability</cite> above).</p>
+</li>
+</ul>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="../FeatureTestMacroTable.html">Feature Test Macro Support</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="DebugMode.html">Debug Mode</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/CapturingConfigInfo.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/CapturingConfigInfo.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/CapturingConfigInfo.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/CapturingConfigInfo.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,142 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Capturing configuration information during installation — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="../_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="Libc++ ABI stability" href="ABIVersioning.html" />
+ <link rel="prev" title="Debug Mode" href="DebugMode.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="../index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Capturing configuration information during installation</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="DebugMode.html">Debug Mode</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="ABIVersioning.html">Libc++ ABI stability</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="capturing-configuration-information-during-installation">
+<h1>Capturing configuration information during installation<a class="headerlink" href="#capturing-configuration-information-during-installation" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#the-problem" id="id1">The Problem</a></li>
+<li><a class="reference internal" href="#design-goals" id="id2">Design Goals</a></li>
+<li><a class="reference internal" href="#the-solution" id="id3">The Solution</a></li>
+</ul>
+</div>
+<div class="section" id="the-problem">
+<h2><a class="toc-backref" href="#id1">The Problem</a><a class="headerlink" href="#the-problem" title="Permalink to this headline">¶</a></h2>
+<p>Currently the libc++ supports building the library with a number of different
+configuration options. Unfortunately all of that configuration information is
+lost when libc++ is installed. In order to support âpersistentâ
+configurations libc++ needs a mechanism to capture the configuration options
+in the INSTALLED headers.</p>
+</div>
+<div class="section" id="design-goals">
+<h2><a class="toc-backref" href="#id2">Design Goals</a><a class="headerlink" href="#design-goals" title="Permalink to this headline">¶</a></h2>
+<ul class="simple">
+<li>The solution should not INSTALL any additional headers. We donât want an extra
+#include slowing everybody down.</li>
+<li>The solution should not unduly affect libc++ developers. The problem is limited
+to installed versions of libc++ and the solution should be as well.</li>
+<li>The solution should not modify any existing headers EXCEPT during installation.
+It makes developers lives harder if they have to regenerate the libc++ headers
+every time they are modified.</li>
+<li>The solution should not make any of the libc++ headers dependent on
+files generated by the build system. The headers should be able to compile
+out of the box without any modification.</li>
+<li>The solution should not have ANY effect on users who donât need special
+configuration options. The vast majority of users will never need this so it
+shouldnât cost them.</li>
+</ul>
+</div>
+<div class="section" id="the-solution">
+<h2><a class="toc-backref" href="#id3">The Solution</a><a class="headerlink" href="#the-solution" title="Permalink to this headline">¶</a></h2>
+<p>When you first configure libc++ using CMake we check to see if we need to
+capture any options. If we havenât been given any âpersistentâ options then
+we do NOTHING.</p>
+<p>Otherwise we create a custom installation rule that modifies the installed __config
+header. The rule first generates a dummy â__config_siteâ header containing the required
+#defines. The contents of the dummy header are then prepended to the installed
+__config header. By manually prepending the files we avoid the cost of an
+extra #include and we allow the __config header to be ignorant of the extra
+configuration all together. An example â__configâ header generated when
+-DLIBCXX_ENABLE_THREADS=OFF is given to CMake would look something like:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">//</span>
+<span class="c1">// The LLVM Compiler Infrastructure</span>
+<span class="c1">//</span>
+<span class="c1">// This file is dual licensed under the MIT and the University of Illinois Open</span>
+<span class="c1">// Source Licenses. See LICENSE.TXT for details.</span>
+<span class="c1">//</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="cp">#ifndef _LIBCPP_CONFIG_SITE</span>
+<span class="cp">#define _LIBCPP_CONFIG_SITE</span>
+
+<span class="cm">/* #undef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE */</span>
+<span class="cm">/* #undef _LIBCPP_HAS_NO_STDIN */</span>
+<span class="cm">/* #undef _LIBCPP_HAS_NO_STDOUT */</span>
+<span class="cp">#define _LIBCPP_HAS_NO_THREADS</span>
+<span class="cm">/* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */</span>
+<span class="cm">/* #undef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS */</span>
+
+<span class="cp">#endif</span>
+<span class="c1">// -*- C++ -*-</span>
+<span class="c1">//===--------------------------- __config ---------------------------------===//</span>
+<span class="c1">//</span>
+<span class="c1">// The LLVM Compiler Infrastructure</span>
+<span class="c1">//</span>
+<span class="c1">// This file is dual licensed under the MIT and the University of Illinois Open</span>
+<span class="c1">// Source Licenses. See LICENSE.TXT for details.</span>
+<span class="c1">//</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="cp">#ifndef _LIBCPP_CONFIG</span>
+<span class="cp">#define _LIBCPP_CONFIG</span>
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="DebugMode.html">Debug Mode</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="ABIVersioning.html">Libc++ ABI stability</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/DebugMode.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/DebugMode.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/DebugMode.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/DebugMode.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,161 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Debug Mode — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="../_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="Capturing configuration information during installation" href="CapturingConfigInfo.html" />
+ <link rel="prev" title="Availability Markup" href="AvailabilityMarkup.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="../index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Debug Mode</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="AvailabilityMarkup.html">Availability Markup</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="CapturingConfigInfo.html">Capturing configuration information during installation</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="debug-mode">
+<h1>Debug Mode<a class="headerlink" href="#debug-mode" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#using-debug-mode" id="id2">Using Debug Mode</a><ul>
+<li><a class="reference internal" href="#libcpp-debug-macro" id="id3"><strong>_LIBCPP_DEBUG</strong> Macro</a></li>
+<li><a class="reference internal" href="#handling-assertion-failures" id="id4">Handling Assertion Failures</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#debug-mode-checks" id="id5">Debug Mode Checks</a></li>
+<li><a class="reference internal" href="#basic-checks" id="id6">Basic Checks</a></li>
+<li><a class="reference internal" href="#iterator-debugging-checks" id="id7">Iterator Debugging Checks</a></li>
+</ul>
+</div>
+<div class="section" id="using-debug-mode">
+<span id="id1"></span><h2><a class="toc-backref" href="#id2">Using Debug Mode</a><a class="headerlink" href="#using-debug-mode" title="Permalink to this headline">¶</a></h2>
+<p>Libc++ provides a debug mode that enables assertions meant to detect incorrect
+usage of the standard library. By default these assertions are disabled but
+they can be enabled using the <code class="docutils literal notranslate"><span class="pre">_LIBCPP_DEBUG</span></code> macro.</p>
+<div class="section" id="libcpp-debug-macro">
+<h3><a class="toc-backref" href="#id3"><strong>_LIBCPP_DEBUG</strong> Macro</a><a class="headerlink" href="#libcpp-debug-macro" title="Permalink to this headline">¶</a></h3>
+<dl class="docutils">
+<dt><strong>_LIBCPP_DEBUG</strong>:</dt>
+<dd><p class="first">This macro is used to enable assertions and iterator debugging checks within
+libc++. By default it is undefined.</p>
+<p><strong>Values</strong>: <code class="docutils literal notranslate"><span class="pre">0</span></code>, <code class="docutils literal notranslate"><span class="pre">1</span></code></p>
+<p>Defining <code class="docutils literal notranslate"><span class="pre">_LIBCPP_DEBUG</span></code> to <code class="docutils literal notranslate"><span class="pre">0</span></code> or greater enables most of libc++âs
+assertions. Defining <code class="docutils literal notranslate"><span class="pre">_LIBCPP_DEBUG</span></code> to <code class="docutils literal notranslate"><span class="pre">1</span></code> enables âiterator debuggingâ
+which provides additional assertions about the validity of iterators used by
+the program.</p>
+<p class="last">Note that this option has no effect on libc++âs ABI</p>
+</dd>
+<dt><strong>_LIBCPP_DEBUG_USE_EXCEPTIONS</strong>:</dt>
+<dd>When this macro is defined <code class="docutils literal notranslate"><span class="pre">_LIBCPP_ASSERT</span></code> failures throw
+<code class="docutils literal notranslate"><span class="pre">__libcpp_debug_exception</span></code> instead of aborting. Additionally this macro
+disables exception specifications on functions containing <code class="docutils literal notranslate"><span class="pre">_LIBCPP_ASSERT</span></code>
+checks. This allows assertion failures to correctly throw through these
+functions.</dd>
+</dl>
+</div>
+<div class="section" id="handling-assertion-failures">
+<h3><a class="toc-backref" href="#id4">Handling Assertion Failures</a><a class="headerlink" href="#handling-assertion-failures" title="Permalink to this headline">¶</a></h3>
+<p>When a debug assertion fails the assertion handler is called via the
+<code class="docutils literal notranslate"><span class="pre">std::__libcpp_debug_function</span></code> function pointer. It is possible to override
+this function pointer using a different handler function. Libc++ provides two
+different assertion handlers, the default handler
+<code class="docutils literal notranslate"><span class="pre">std::__libcpp_abort_debug_handler</span></code> which aborts the program, and
+<code class="docutils literal notranslate"><span class="pre">std::__libcpp_throw_debug_handler</span></code> which throws an instance of
+<code class="docutils literal notranslate"><span class="pre">std::__libcpp_debug_exception</span></code>. Libc++ can be changed to use the throwing
+assertion handler as follows:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="cp">#define _LIBCPP_DEBUG 1</span>
+<span class="cp">#include</span> <span class="cpf"><string></span><span class="cp"></span>
+<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">__libcpp_debug_function</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">__libcpp_throw_debug_function</span><span class="p">;</span>
+ <span class="k">try</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">::</span><span class="n">iterator</span> <span class="n">bad_it</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">str</span><span class="p">(</span><span class="s">"hello world"</span><span class="p">);</span>
+ <span class="n">str</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">bad_it</span><span class="p">,</span> <span class="sc">'!'</span><span class="p">);</span> <span class="c1">// causes debug assertion</span>
+ <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">__libcpp_debug_exception</span> <span class="k">const</span><span class="o">&</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">EXIT_SUCCESS</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="k">return</span> <span class="n">EXIT_FAILURE</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="debug-mode-checks">
+<h2><a class="toc-backref" href="#id5">Debug Mode Checks</a><a class="headerlink" href="#debug-mode-checks" title="Permalink to this headline">¶</a></h2>
+<p>Libc++âs debug mode offers two levels of checking. The first enables various
+precondition checks throughout libc++. The second additionally enables
+âiterator debuggingâ which checks the validity of iterators used by the program.</p>
+</div>
+<div class="section" id="basic-checks">
+<h2><a class="toc-backref" href="#id6">Basic Checks</a><a class="headerlink" href="#basic-checks" title="Permalink to this headline">¶</a></h2>
+<p>These checks are enabled when <code class="docutils literal notranslate"><span class="pre">_LIBCPP_DEBUG</span></code> is defined to either 0 or 1.</p>
+<p>The following checks are enabled by <code class="docutils literal notranslate"><span class="pre">_LIBCPP_DEBUG</span></code>:</p>
+<blockquote>
+<div><ul class="simple">
+<li>FIXME: Update this list</li>
+</ul>
+</div></blockquote>
+</div>
+<div class="section" id="iterator-debugging-checks">
+<h2><a class="toc-backref" href="#id7">Iterator Debugging Checks</a><a class="headerlink" href="#iterator-debugging-checks" title="Permalink to this headline">¶</a></h2>
+<p>These checks are enabled when <code class="docutils literal notranslate"><span class="pre">_LIBCPP_DEBUG</span></code> is defined to 1.</p>
+<p>The following containers and STL classes support iterator debugging:</p>
+<blockquote>
+<div><ul class="simple">
+<li><code class="docutils literal notranslate"><span class="pre">std::string</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">std::vector<T></span></code> (<code class="docutils literal notranslate"><span class="pre">T</span> <span class="pre">!=</span> <span class="pre">bool</span></code>)</li>
+<li><code class="docutils literal notranslate"><span class="pre">std::list</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">std::unordered_map</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">std::unordered_multimap</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">std::unordered_set</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">std::unordered_multiset</span></code></li>
+</ul>
+</div></blockquote>
+<p>The remaining containers do not currently support iterator debugging.
+Patches welcome.</p>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="AvailabilityMarkup.html">Availability Markup</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="CapturingConfigInfo.html">Capturing configuration information during installation</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/FeatureTestMacros.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/FeatureTestMacros.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/FeatureTestMacros.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/FeatureTestMacros.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,98 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Feature Test Macros — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="../_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="prev" title="File Time Type" href="FileTimeType.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="../index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Feature Test Macros</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="FileTimeType.html">File Time Type</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="feature-test-macros">
+<h1>Feature Test Macros<a class="headerlink" href="#feature-test-macros" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
+<li><a class="reference internal" href="#design" id="id2">Design</a></li>
+<li><a class="reference internal" href="#usage" id="id3">Usage</a></li>
+</ul>
+</div>
+<div class="section" id="overview">
+<h2><a class="toc-backref" href="#id1">Overview</a><a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
+<p>Libc++ implements the C++ feature test macros as specified in the C++2a standard,
+and before that in non-normative guiding documents (<cite>See cppreference <https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros></cite>)</p>
+</div>
+<div class="section" id="design">
+<h2><a class="toc-backref" href="#id2">Design</a><a class="headerlink" href="#design" title="Permalink to this headline">¶</a></h2>
+<p>Feature test macros are tricky to track, implement, test, and document correctly.
+They must be available from a list of headers, they may have different values in
+different dialects, and they may or may not be implemented by libc++. In order to
+track all of these conditions correctly and easily, we want a Single Source of
+Truth (SSoT) that defines each feature test macro, its values, the headers it
+lives in, and whether or not is is implemented by libc++. From this SSoA we
+have enough information to automatically generate the <cite><version></cite> header,
+the tests, and the documentation.</p>
+<p>Therefore we maintain a SSoA in
+<cite>libcxx/test/std/language.support/support.limits/support.limits.general/generate_feature_test_macro_components.py</cite>
+which doubles as a script to generate the following components:</p>
+<ul class="simple">
+<li>The <cite><version></cite> header.</li>
+<li>The version tests under <cite>support.limits.general</cite>.</li>
+<li>Documentation of libc++âs implementation of each macro.</li>
+</ul>
+</div>
+<div class="section" id="usage">
+<h2><a class="toc-backref" href="#id3">Usage</a><a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h2>
+<p>The <cite>generate_feature_test_macro_components.py</cite> script is used to track and
+update feature test macros in libc++.</p>
+<p>Whenever a feature test macro is added or changed, the table should be updated
+and the script should be re-ran. The script will clobber the existing test files
+and the documentation and it will generate a new <cite><version></cite> header as a
+temporary file. The generated <cite><version></cite> header should be merged with the
+existing one.</p>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="FileTimeType.html">File Time Type</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/FileTimeType.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/FileTimeType.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/FileTimeType.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/FileTimeType.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,519 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>File Time Type — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="../_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="Feature Test Macros" href="FeatureTestMacros.html" />
+ <link rel="prev" title="Threading Support API" href="ThreadingSupportAPI.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="../index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>File Time Type</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="ThreadingSupportAPI.html">Threading Support API</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="FeatureTestMacros.html">Feature Test Macros</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="file-time-type">
+<h1>File Time Type<a class="headerlink" href="#file-time-type" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#motivation" id="id1">Motivation</a></li>
+<li><a class="reference internal" href="#problems-to-consider" id="id2">Problems To Consider</a><ul>
+<li><a class="reference internal" href="#having-a-smaller-range-than-timespec" id="id3">Having a Smaller Range than <code class="docutils literal notranslate"><span class="pre">timespec</span></code></a></li>
+<li><a class="reference internal" href="#having-a-smaller-resolution-than-timespec" id="id4">Having a Smaller Resolution than <code class="docutils literal notranslate"><span class="pre">timespec</span></code></a></li>
+<li><a class="reference internal" href="#having-a-larger-range-than-timespec" id="id5">Having a Larger Range than <code class="docutils literal notranslate"><span class="pre">timespec</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#potential-solutions-and-their-complications" id="id6">Potential Solutions And Their Complications</a><ul>
+<li><a class="reference internal" href="#source-code-portability-across-implementations" id="id7">Source Code Portability Across Implementations</a></li>
+<li><a class="reference internal" href="#chrono-and-timespec-emulation" id="id8">Chrono and <code class="docutils literal notranslate"><span class="pre">timespec</span></code> Emulation.</a></li>
+<li><a class="reference internal" href="#interactions-with-32-bit-time-t" id="id9">Interactions with 32 bit <code class="docutils literal notranslate"><span class="pre">time_t</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#summary" id="id10">Summary</a><ul>
+<li><a class="reference internal" href="#the-potential-solutions" id="id11">The Potential Solutions</a><ul>
+<li><a class="reference internal" href="#long-long-the-status-quo" id="id12"><code class="docutils literal notranslate"><span class="pre">long</span> <span class="pre">long</span></code> - The Status Quo</a></li>
+<li><a class="reference internal" href="#int128-t" id="id13">__int128_t</a></li>
+<li><a class="reference internal" href="#arithmetic-timespec-emulation" id="id14">Arithmetic <code class="docutils literal notranslate"><span class="pre">timespec</span></code> Emulation</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#selected-solution-using-int128-t" id="id15">Selected Solution - Using <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code></a></li>
+</ul>
+</div>
+<div class="section" id="motivation">
+<span id="file-time-type-motivation"></span><h2><a class="toc-backref" href="#id1">Motivation</a><a class="headerlink" href="#motivation" title="Permalink to this headline">¶</a></h2>
+<p>The filesystem library provides interfaces for getting and setting the last
+write time of a file or directory. The interfaces use the <code class="docutils literal notranslate"><span class="pre">file_time_type</span></code>
+type, which is a specialization of <code class="docutils literal notranslate"><span class="pre">chrono::time_point</span></code> for the
+âfilesystem clockâ. According to [fs.filesystem.syn]</p>
+<blockquote>
+<div>trivial-clock is an implementation-defined type that satisfies the
+Cpp17TrivialClock requirements ([time.clock.req]) and that is capable of
+representing and measuring file time values. Implementations should ensure
+that the resolution and range of file_Âtime_Âtype reflect the operating
+system dependent resolution and range of file time values.</div></blockquote>
+<p>On POSIX systems, file times are represented using the <code class="docutils literal notranslate"><span class="pre">timespec</span></code> struct,
+which is defined as follows:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span> <span class="n">timespec</span> <span class="p">{</span>
+ <span class="kt">time_t</span> <span class="n">tv_sec</span><span class="p">;</span>
+ <span class="kt">long</span> <span class="n">tv_nsec</span><span class="p">;</span>
+<span class="p">};</span>
+</pre></div>
+</div>
+<p>To represent the range and resolution of <code class="docutils literal notranslate"><span class="pre">timespec</span></code>, we need to (A) have
+nanosecond resolution, and (B) use more than 64 bits (assuming a 64 bit <code class="docutils literal notranslate"><span class="pre">time_t</span></code>).</p>
+<p>As the standard requires us to use the <code class="docutils literal notranslate"><span class="pre">chrono</span></code> interface, we have to define
+our own filesystem clock which specifies the period and representation of
+the time points and duration it provides. It will look like this:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span> <span class="n">_FilesystemClock</span> <span class="p">{</span>
+ <span class="k">using</span> <span class="n">period</span> <span class="o">=</span> <span class="n">nano</span><span class="p">;</span>
+ <span class="k">using</span> <span class="n">rep</span> <span class="o">=</span> <span class="n">TBD</span><span class="p">;</span> <span class="c1">// What is this?</span>
+
+ <span class="k">using</span> <span class="n">duration</span> <span class="o">=</span> <span class="n">chrono</span><span class="o">::</span><span class="n">duration</span><span class="o"><</span><span class="n">rep</span><span class="p">,</span> <span class="n">period</span><span class="o">></span><span class="p">;</span>
+ <span class="k">using</span> <span class="n">time_point</span> <span class="o">=</span> <span class="n">chrono</span><span class="o">::</span><span class="n">time_point</span><span class="o"><</span><span class="n">_FilesystemClock</span><span class="o">></span><span class="p">;</span>
+
+ <span class="c1">// ... //</span>
+<span class="p">};</span>
+
+<span class="k">using</span> <span class="n">file_time_type</span> <span class="o">=</span> <span class="n">_FilesystemClock</span><span class="o">::</span><span class="n">time_point</span><span class="p">;</span>
+</pre></div>
+</div>
+<p>To get nanosecond resolution, we simply define <code class="docutils literal notranslate"><span class="pre">period</span></code> to be <code class="docutils literal notranslate"><span class="pre">std::nano</span></code>.
+But what type can we use as the arithmetic representation that is capable
+of representing the range of the <code class="docutils literal notranslate"><span class="pre">timespec</span></code> struct?</p>
+</div>
+<div class="section" id="problems-to-consider">
+<h2><a class="toc-backref" href="#id2">Problems To Consider</a><a class="headerlink" href="#problems-to-consider" title="Permalink to this headline">¶</a></h2>
+<p>Before considering solutions, letâs consider the problems they should solve,
+and how important solving those problems are:</p>
+<div class="section" id="having-a-smaller-range-than-timespec">
+<h3><a class="toc-backref" href="#id3">Having a Smaller Range than <code class="docutils literal notranslate"><span class="pre">timespec</span></code></a><a class="headerlink" href="#having-a-smaller-range-than-timespec" title="Permalink to this headline">¶</a></h3>
+<p>One solution to the range problem is to simply reduce the resolution of
+<code class="docutils literal notranslate"><span class="pre">file_time_type</span></code> to be less than that of nanoseconds. This is what libc++âs
+initial implementation of <code class="docutils literal notranslate"><span class="pre">file_time_type</span></code> did; itâs also what
+<code class="docutils literal notranslate"><span class="pre">std::system_clock</span></code> does. As a result, it can represent time points about
+292 thousand years on either side of the epoch, as opposed to only 292 years
+at nanosecond resolution.</p>
+<p><code class="docutils literal notranslate"><span class="pre">timespec</span></code> can represent time points +/- 292 billion years from the epoch
+(just in case you needed a time point 200 billion years before the big bang,
+and with nanosecond resolution).</p>
+<p>To get the same range, we would need to drop our resolution to that of seconds
+to come close to having the same range.</p>
+<p>This begs the question, is the range problem âreally a problemâ? Sane usages
+of file time stamps shouldnât exceed +/- 300 years, so should we care to support it?</p>
+<p>I believe the answer is yes. Weâre not designing the filesystem time API, weâre
+providing glorified C++ wrappers for it. If the underlying API supports
+a value, then we should too. Our wrappers should not place artificial restrictions
+on users that are not present in the underlying filesystem.</p>
+<p>Having a smaller range that the underlying filesystem forces the
+implementation to report <code class="docutils literal notranslate"><span class="pre">value_too_large</span></code> errors when it encounters a time
+point that it canât represent. This can cause the call to <code class="docutils literal notranslate"><span class="pre">last_write_time</span></code>
+to throw in cases where the user was confident the call should succeed. (See below)</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf"><filesystem></span><span class="cp"></span>
+<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="o">::</span><span class="n">filesystem</span><span class="p">;</span>
+
+<span class="c1">// Set the times using the system interface.</span>
+<span class="kt">void</span> <span class="nf">set_file_times</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">path</span><span class="p">,</span> <span class="k">struct</span> <span class="n">timespec</span> <span class="n">ts</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">timespec</span> <span class="n">both_times</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
+ <span class="n">both_times</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">ts</span><span class="p">;</span>
+ <span class="n">both_times</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">ts</span><span class="p">;</span>
+ <span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="o">::</span><span class="n">utimensat</span><span class="p">(</span><span class="n">AT_FDCWD</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">both_times</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
+ <span class="n">assert</span><span class="p">(</span><span class="n">result</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">// Called elsewhere to set the file time to something insane, and way</span>
+<span class="c1">// out of the 300 year range we might expect.</span>
+<span class="kt">void</span> <span class="nf">some_bad_persons_code</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">struct</span> <span class="n">timespec</span> <span class="n">new_times</span><span class="p">;</span>
+ <span class="n">new_times</span><span class="p">.</span><span class="n">tv_sec</span> <span class="o">=</span> <span class="n">numeric_limits</span><span class="o"><</span><span class="kt">time_t</span><span class="o">>::</span><span class="n">max</span><span class="p">();</span>
+ <span class="n">new_times</span><span class="p">.</span><span class="n">tv_nsec</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="n">set_file_times</span><span class="p">(</span><span class="s">"/tmp/foo"</span><span class="p">,</span> <span class="n">new_times</span><span class="p">);</span> <span class="c1">// OK, supported by most FSes</span>
+<span class="p">}</span>
+
+<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">path</span> <span class="n">p</span> <span class="o">=</span> <span class="s">"/tmp/foo"</span><span class="p">;</span>
+ <span class="n">file_status</span> <span class="n">st</span> <span class="o">=</span> <span class="n">status</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">exists</span><span class="p">(</span><span class="n">st</span><span class="p">)</span> <span class="o">||</span> <span class="o">!</span><span class="n">is_regular_file</span><span class="p">(</span><span class="n">st</span><span class="p">))</span>
+ <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">((</span><span class="n">st</span><span class="p">.</span><span class="n">permissions</span><span class="p">()</span> <span class="o">&</span> <span class="n">perms</span><span class="o">::</span><span class="n">others_read</span><span class="p">)</span> <span class="o">==</span> <span class="n">perms</span><span class="o">::</span><span class="n">none</span><span class="p">)</span>
+ <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
+ <span class="c1">// It seems reasonable to assume this call should succeed.</span>
+ <span class="n">file_time_type</span> <span class="n">tp</span> <span class="o">=</span> <span class="n">last_write_time</span><span class="p">(</span><span class="n">p</span><span class="p">);</span> <span class="c1">// BAD! Throws value_too_large.</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="having-a-smaller-resolution-than-timespec">
+<h3><a class="toc-backref" href="#id4">Having a Smaller Resolution than <code class="docutils literal notranslate"><span class="pre">timespec</span></code></a><a class="headerlink" href="#having-a-smaller-resolution-than-timespec" title="Permalink to this headline">¶</a></h3>
+<p>As mentioned in the previous section, one way to solve the range problem
+is by reducing the resolution. But matching the range of <code class="docutils literal notranslate"><span class="pre">timespec</span></code> using a
+64 bit representation requires limiting the resolution to seconds.</p>
+<p>So we might ask: Do users âneedâ nanosecond precision? Is seconds not good enough?
+I limit my consideration of the point to this: Why was it not good enough for
+the underlying system interfaces? If it wasnât good enough for them, then it
+isnât good enough for us. Our job is to match the filesystems range and
+representation, not design it.</p>
+</div>
+<div class="section" id="having-a-larger-range-than-timespec">
+<h3><a class="toc-backref" href="#id5">Having a Larger Range than <code class="docutils literal notranslate"><span class="pre">timespec</span></code></a><a class="headerlink" href="#having-a-larger-range-than-timespec" title="Permalink to this headline">¶</a></h3>
+<p>We should also consider the opposite problem of having a <code class="docutils literal notranslate"><span class="pre">file_time_type</span></code>
+that is able to represent a larger range than <code class="docutils literal notranslate"><span class="pre">timespec</span></code>. At least in
+this case <code class="docutils literal notranslate"><span class="pre">last_write_time</span></code> can be used to get and set all possible values
+supported by the underlying filesystem; meaning <code class="docutils literal notranslate"><span class="pre">last_write_time(p)</span></code> will
+never throw a overflow error when retrieving a value.</p>
+<p>However, this introduces a new problem, where users are allowed to attempt to
+create a time point beyond what the filesystem can represent. Two particular
+values which cause this are <code class="docutils literal notranslate"><span class="pre">file_time_type::min()</span></code> and
+<code class="docutils literal notranslate"><span class="pre">file_time_type::max()</span></code>. As a result, the following code would throw:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span> <span class="nf">test</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">last_write_time</span><span class="p">(</span><span class="s">"/tmp/foo"</span><span class="p">,</span> <span class="n">file_time_type</span><span class="o">::</span><span class="n">max</span><span class="p">());</span> <span class="c1">// Throws</span>
+ <span class="n">last_write_time</span><span class="p">(</span><span class="s">"/tmp/foo"</span><span class="p">,</span> <span class="n">file_time_type</span><span class="o">::</span><span class="n">min</span><span class="p">());</span> <span class="c1">// Throws.</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Apart from cases explicitly using <code class="docutils literal notranslate"><span class="pre">min</span></code> and <code class="docutils literal notranslate"><span class="pre">max</span></code>, I donât see users taking
+a valid time point, adding a couple hundred billions of years in error,
+and then trying to update a fileâs write time to that value very often.</p>
+<p>Compared to having a smaller range, this problem seems preferable. At least
+now we can represent any time point the filesystem can, so users wonât be forced
+to revert back to system interfaces to avoid limitations in the C++ STL.</p>
+<p>I posit that we should only consider this concern <em>after</em> we have something
+with at least the same range and resolution of the underlying filesystem. The
+latter two problems are much more important to solve.</p>
+</div>
+</div>
+<div class="section" id="potential-solutions-and-their-complications">
+<h2><a class="toc-backref" href="#id6">Potential Solutions And Their Complications</a><a class="headerlink" href="#potential-solutions-and-their-complications" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="source-code-portability-across-implementations">
+<h3><a class="toc-backref" href="#id7">Source Code Portability Across Implementations</a><a class="headerlink" href="#source-code-portability-across-implementations" title="Permalink to this headline">¶</a></h3>
+<p>As weâve discussed, <code class="docutils literal notranslate"><span class="pre">file_time_type</span></code> needs a representation that uses more
+than 64 bits. The possible solutions include using <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code>, emulating a
+128 bit integer using a class, or potentially defining a <code class="docutils literal notranslate"><span class="pre">timespec</span></code> like
+arithmetic type. All three will allow us to, at minimum, match the range
+and resolution, and the last one might even allow us to match them exactly.</p>
+<p>But when considering these potential solutions we need to consider more than
+just the values they can represent. We need to consider the effects they will
+have on users and their code. For example, each of them breaks the following
+code in some way:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="c1">// Bug caused by an unexpected 'rep' type returned by count.</span>
+<span class="kt">void</span> <span class="nf">print_time</span><span class="p">(</span><span class="n">path</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// __int128_t doesn't have streaming operators, and neither would our</span>
+ <span class="c1">// custom arithmetic types.</span>
+ <span class="n">cout</span> <span class="o"><<</span> <span class="n">last_write_time</span><span class="p">(</span><span class="n">p</span><span class="p">).</span><span class="n">time_since_epoch</span><span class="p">().</span><span class="n">count</span><span class="p">()</span> <span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">// Overflow during creation bug.</span>
+<span class="n">file_time_type</span> <span class="nf">timespec_to_file_time_type</span><span class="p">(</span><span class="k">struct</span> <span class="n">timespec</span> <span class="n">ts</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// woops! chrono::seconds and chrono::nanoseconds use a 64 bit representation</span>
+ <span class="c1">// this may overflow before it's converted to a file_time_type.</span>
+ <span class="k">auto</span> <span class="n">dur</span> <span class="o">=</span> <span class="n">seconds</span><span class="p">(</span><span class="n">ts</span><span class="p">.</span><span class="n">tv_sec</span><span class="p">)</span> <span class="o">+</span> <span class="n">nanoseconds</span><span class="p">(</span><span class="n">ts</span><span class="p">.</span><span class="n">tv_nsec</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">file_time_type</span><span class="p">(</span><span class="n">dur</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">file_time_type</span> <span class="nf">correct_timespec_to_file_time_type</span><span class="p">(</span><span class="k">struct</span> <span class="n">timespec</span> <span class="n">ts</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// This is the correct version of the above example, where we</span>
+ <span class="c1">// avoid using the chrono typedefs as they're not sufficient.</span>
+ <span class="c1">// Can we expect users to avoid this bug?</span>
+ <span class="k">using</span> <span class="n">fs_seconds</span> <span class="o">=</span> <span class="n">chrono</span><span class="o">::</span><span class="n">duration</span><span class="o"><</span><span class="n">file_time_type</span><span class="o">::</span><span class="n">rep</span><span class="o">></span><span class="p">;</span>
+ <span class="k">using</span> <span class="n">fs_nanoseconds</span> <span class="o">=</span> <span class="n">chrono</span><span class="o">::</span><span class="n">duration</span><span class="o"><</span><span class="n">file_time_type</span><span class="o">::</span><span class="n">rep</span><span class="p">,</span> <span class="n">nano</span><span class="o">></span><span class="p">;</span>
+ <span class="k">auto</span> <span class="n">dur</span> <span class="o">=</span> <span class="n">fs_seconds</span><span class="p">(</span><span class="n">ts</span><span class="p">.</span><span class="n">tv_sec</span><span class="p">)</span> <span class="o">+</span> <span class="n">fs_nanoseconds</span><span class="p">(</span><span class="n">tv</span><span class="p">.</span><span class="n">tv_nsec</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">file_time_type</span><span class="p">(</span><span class="n">dur</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">// Implicit truncation during conversion bug.</span>
+<span class="kt">intmax_t</span> <span class="nf">get_time_in_seconds</span><span class="p">(</span><span class="n">path</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">using</span> <span class="n">fs_seconds</span> <span class="o">=</span> <span class="n">duration</span><span class="o"><</span><span class="n">file_time_type</span><span class="o">::</span><span class="n">rep</span><span class="p">,</span> <span class="n">ratio</span><span class="o"><</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="o">></span> <span class="o">></span><span class="p">;</span>
+ <span class="k">auto</span> <span class="n">tp</span> <span class="o">=</span> <span class="n">last_write_time</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
+
+ <span class="c1">// This works with truncation for __int128_t, but what does it do for</span>
+ <span class="c1">// our custom arithmetic types.</span>
+ <span class="k">return</span> <span class="n">duration_cast</span><span class="o"><</span><span class="n">fs_seconds</span><span class="o">></span><span class="p">().</span><span class="n">count</span><span class="p">();</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Each of the above examples would require a user to adjust their filesystem code
+to the particular eccentricities of the representation, hopefully only in such
+a way that the code is still portable across implementations.</p>
+<p>At least some of the above issues are unavoidable, no matter what
+representation we choose. But some representations may be quirkier than others,
+and, as Iâll argue later, using an actual arithmetic type (<code class="docutils literal notranslate"><span class="pre">__int128_t</span></code>)
+provides the least aberrant behavior.</p>
+</div>
+<div class="section" id="chrono-and-timespec-emulation">
+<h3><a class="toc-backref" href="#id8">Chrono and <code class="docutils literal notranslate"><span class="pre">timespec</span></code> Emulation.</a><a class="headerlink" href="#chrono-and-timespec-emulation" title="Permalink to this headline">¶</a></h3>
+<p>One of the options weâve considered is using something akin to <code class="docutils literal notranslate"><span class="pre">timespec</span></code>
+to represent the <code class="docutils literal notranslate"><span class="pre">file_time_type</span></code>. It only seems natural seeing as thatâs
+what the underlying system uses, and because it might allow us to match
+the range and resolution exactly. But would it work with chrono? And could
+it still act at all like a <code class="docutils literal notranslate"><span class="pre">timespec</span></code> struct?</p>
+<p>For ease of consideration, letâs consider what the implementation might
+look like.</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span> <span class="n">fs_timespec_rep</span> <span class="p">{</span>
+ <span class="n">fs_timespec_rep</span><span class="p">(</span><span class="kt">long</span> <span class="kt">long</span> <span class="n">v</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">tv_sec</span><span class="p">(</span><span class="n">v</span> <span class="o">/</span> <span class="n">nano</span><span class="o">::</span><span class="n">den</span><span class="p">),</span> <span class="n">tv_nsec</span><span class="p">(</span><span class="n">v</span> <span class="o">%</span> <span class="n">nano</span><span class="o">::</span><span class="n">den</span><span class="p">)</span>
+ <span class="p">{</span> <span class="p">}</span>
+<span class="k">private</span><span class="o">:</span>
+ <span class="kt">time_t</span> <span class="n">tv_sec</span><span class="p">;</span>
+ <span class="kt">long</span> <span class="n">tv_nsec</span><span class="p">;</span>
+<span class="p">};</span>
+<span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="n">fs_timespec_rep</span><span class="p">,</span> <span class="n">fs_timespec_rep</span><span class="p">);</span>
+<span class="n">fs_int128_rep</span> <span class="k">operator</span><span class="o">+</span><span class="p">(</span><span class="n">fs_timespec_rep</span><span class="p">,</span> <span class="n">fs_timespec_rep</span><span class="p">);</span>
+<span class="c1">// ... arithmetic operators ... //</span>
+</pre></div>
+</div>
+<p>The first thing to notice is that we canât construct <code class="docutils literal notranslate"><span class="pre">fs_timespec_rep</span></code> like
+a <code class="docutils literal notranslate"><span class="pre">timespec</span></code> by passing <code class="docutils literal notranslate"><span class="pre">{secs,</span> <span class="pre">nsecs}</span></code>. Instead weâre limited to
+constructing it from a single 64 bit integer.</p>
+<p>We also canât allow the user to inspect the <code class="docutils literal notranslate"><span class="pre">tv_sec</span></code> or <code class="docutils literal notranslate"><span class="pre">tv_nsec</span></code> values
+directly. A <code class="docutils literal notranslate"><span class="pre">chrono::duration</span></code> represents its value as a tick period and a
+number of ticks stored using <code class="docutils literal notranslate"><span class="pre">rep</span></code>. The representation is unaware of the
+tick period it is being used to represent, but <code class="docutils literal notranslate"><span class="pre">timespec</span></code> is setup to assume
+a nanosecond tick period; which is the only case where the names <code class="docutils literal notranslate"><span class="pre">tv_sec</span></code>
+and <code class="docutils literal notranslate"><span class="pre">tv_nsec</span></code> match the values they store.</p>
+<p>When we convert a nanosecond duration to seconds, <code class="docutils literal notranslate"><span class="pre">fs_timespec_rep</span></code> will
+use <code class="docutils literal notranslate"><span class="pre">tv_sec</span></code> to represent the number of giga seconds, and <code class="docutils literal notranslate"><span class="pre">tv_nsec</span></code> the
+remaining seconds. Letâs consider how this might cause a bug were users allowed
+to manipulate the fields directly.</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Period</span><span class="o">></span>
+<span class="n">timespec</span> <span class="n">convert_to_timespec</span><span class="p">(</span><span class="n">duration</span><span class="o"><</span><span class="n">fs_time_rep</span><span class="p">,</span> <span class="n">Period</span><span class="o">></span> <span class="n">dur</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fs_timespec_rep</span> <span class="n">rep</span> <span class="o">=</span> <span class="n">dur</span><span class="p">.</span><span class="n">count</span><span class="p">();</span>
+ <span class="k">return</span> <span class="p">{</span><span class="n">rep</span><span class="p">.</span><span class="n">tv_sec</span><span class="p">,</span> <span class="n">rep</span><span class="p">.</span><span class="n">tv_nsec</span><span class="p">};</span> <span class="c1">// Oops! Period may not be nanoseconds.</span>
+<span class="p">}</span>
+
+<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Duration</span><span class="o">></span>
+<span class="n">Duration</span> <span class="n">convert_to_duration</span><span class="p">(</span><span class="n">timespec</span> <span class="n">ts</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">Duration</span> <span class="n">dur</span><span class="p">({</span><span class="n">ts</span><span class="p">.</span><span class="n">tv_sec</span><span class="p">,</span> <span class="n">ts</span><span class="p">.</span><span class="n">tv_nsec</span><span class="p">});</span> <span class="c1">// Oops! Period may not be nanoseconds.</span>
+ <span class="k">return</span> <span class="nf">file_time_type</span><span class="p">(</span><span class="n">dur</span><span class="p">);</span>
+ <span class="n">file_time_type</span> <span class="n">tp</span> <span class="o">=</span> <span class="n">last_write_time</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
+ <span class="k">auto</span> <span class="n">dur</span> <span class="o">=</span>
+<span class="p">}</span>
+
+<span class="kt">time_t</span> <span class="n">extract_seconds</span><span class="p">(</span><span class="n">file_time_type</span> <span class="n">tp</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Converting to seconds is a silly bug, but I could see it happening.</span>
+ <span class="k">using</span> <span class="n">SecsT</span> <span class="o">=</span> <span class="n">chrono</span><span class="o">::</span><span class="n">duration</span><span class="o"><</span><span class="n">file_time_type</span><span class="o">::</span><span class="n">rep</span><span class="p">,</span> <span class="n">ratio</span><span class="o"><</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="o">>></span><span class="p">;</span>
+ <span class="k">auto</span> <span class="n">secs</span> <span class="o">=</span> <span class="n">duration_cast</span><span class="o"><</span><span class="n">Secs</span><span class="o">></span><span class="p">(</span><span class="n">tp</span><span class="p">.</span><span class="n">time_since_epoch</span><span class="p">());</span>
+ <span class="c1">// tv_sec is now representing gigaseconds.</span>
+ <span class="k">return</span> <span class="n">secs</span><span class="p">.</span><span class="n">count</span><span class="p">().</span><span class="n">tv_sec</span><span class="p">;</span> <span class="c1">// Oops!</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Despite <code class="docutils literal notranslate"><span class="pre">fs_timespec_rep</span></code> not being usable in any manner resembling
+<code class="docutils literal notranslate"><span class="pre">timespec</span></code>, it still might buy us our goal of matching its range exactly,
+right?</p>
+<p>Sort of. Chrono provides a specialization point which specifies the minimum
+and maximum values for a custom representation. It looks like this:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span> <span class="o"><></span>
+<span class="k">struct</span> <span class="n">duration_values</span><span class="o"><</span><span class="n">fs_timespec_rep</span><span class="o">></span> <span class="p">{</span>
+ <span class="k">static</span> <span class="n">fs_timespec_rep</span> <span class="n">zero</span><span class="p">();</span>
+ <span class="k">static</span> <span class="n">fs_timespec_rep</span> <span class="nf">min</span><span class="p">();</span>
+ <span class="k">static</span> <span class="n">fs_timespec_rep</span> <span class="nf">max</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// assume friendship.</span>
+ <span class="n">fs_timespec_rep</span> <span class="n">val</span><span class="p">;</span>
+ <span class="n">val</span><span class="p">.</span><span class="n">tv_sec</span> <span class="o">=</span> <span class="n">numeric_limits</span><span class="o"><</span><span class="kt">time_t</span><span class="o">>::</span><span class="n">max</span><span class="p">();</span>
+ <span class="n">val</span><span class="p">.</span><span class="n">tv_nsec</span> <span class="o">=</span> <span class="n">nano</span><span class="o">::</span><span class="n">den</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">val</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+</pre></div>
+</div>
+<p>Notice that <code class="docutils literal notranslate"><span class="pre">duration_values</span></code> doesnât tell the representation what tick
+period itâs actually representing. This would indeed correctly limit the range
+of <code class="docutils literal notranslate"><span class="pre">duration<fs_timespec_rep,</span> <span class="pre">nano></span></code> to exactly that of <code class="docutils literal notranslate"><span class="pre">timespec</span></code>. But
+nanoseconds isnât the only tick period it will be used to represent. For
+example:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span> <span class="nf">test</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">using</span> <span class="n">rep</span> <span class="o">=</span> <span class="n">file_time_type</span><span class="o">::</span><span class="n">rep</span><span class="p">;</span>
+ <span class="k">using</span> <span class="n">fs_nsec</span> <span class="o">=</span> <span class="n">duration</span><span class="o"><</span><span class="n">rep</span><span class="p">,</span> <span class="n">nano</span><span class="o">></span><span class="p">;</span>
+ <span class="k">using</span> <span class="n">fs_sec</span> <span class="o">=</span> <span class="n">duration</span><span class="o"><</span><span class="n">rep</span><span class="o">></span><span class="p">;</span>
+ <span class="n">fs_nsec</span> <span class="n">nsecs</span><span class="p">(</span><span class="n">fs_seconds</span><span class="o">::</span><span class="n">max</span><span class="p">());</span> <span class="c1">// Truncates</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Though the above example may appear silly, I think it follows from the incorrect
+notion that using a <code class="docutils literal notranslate"><span class="pre">timespec</span></code> rep in chrono actually makes it act as if it
+were an actual <code class="docutils literal notranslate"><span class="pre">timespec</span></code>.</p>
+</div>
+<div class="section" id="interactions-with-32-bit-time-t">
+<h3><a class="toc-backref" href="#id9">Interactions with 32 bit <code class="docutils literal notranslate"><span class="pre">time_t</span></code></a><a class="headerlink" href="#interactions-with-32-bit-time-t" title="Permalink to this headline">¶</a></h3>
+<p>Up until now weâve only be considering cases where <code class="docutils literal notranslate"><span class="pre">time_t</span></code> is 64 bits, but what
+about 32 bit systems/builds where <code class="docutils literal notranslate"><span class="pre">time_t</span></code> is 32 bits? (this is the common case
+for 32 bit builds).</p>
+<p>When <code class="docutils literal notranslate"><span class="pre">time_t</span></code> is 32 bits, we can implement <code class="docutils literal notranslate"><span class="pre">file_time_type</span></code> simply using 64-bit
+<code class="docutils literal notranslate"><span class="pre">long</span> <span class="pre">long</span></code>. There is no need to get either <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code> or <code class="docutils literal notranslate"><span class="pre">timespec</span></code> emulation
+involved. And nor should we, as it would suffer from the numerous complications
+described by this paper.</p>
+<p>Obviously our implementation for 32-bit builds should act as similarly to the
+64-bit build as possible. Code which compiles in one, should compile in the other.
+This consideration is important when choosing between <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code> and
+emulating <code class="docutils literal notranslate"><span class="pre">timespec</span></code>. The solution which provides the most uniformity with
+the least eccentricity is the preferable one.</p>
+</div>
+</div>
+<div class="section" id="summary">
+<h2><a class="toc-backref" href="#id10">Summary</a><a class="headerlink" href="#summary" title="Permalink to this headline">¶</a></h2>
+<p>The <code class="docutils literal notranslate"><span class="pre">file_time_type</span></code> time point is used to represent the write times for files.
+Its job is to act as part of a C++ wrapper for less ideal system interfaces. The
+underlying filesystem uses the <code class="docutils literal notranslate"><span class="pre">timespec</span></code> struct for the same purpose.</p>
+<p>However, the initial implementation of <code class="docutils literal notranslate"><span class="pre">file_time_type</span></code> could not represent
+either the range or resolution of <code class="docutils literal notranslate"><span class="pre">timespec</span></code>, making it unsuitable. Fixing
+this requires an implementation which uses more than 64 bits to store the
+time point.</p>
+<p>We primarily considered two solutions: Using <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code> and using a
+arithmetic emulation of <code class="docutils literal notranslate"><span class="pre">timespec</span></code>. Each has its pros and cons, and both
+come with more than one complication.</p>
+<div class="section" id="the-potential-solutions">
+<h3><a class="toc-backref" href="#id11">The Potential Solutions</a><a class="headerlink" href="#the-potential-solutions" title="Permalink to this headline">¶</a></h3>
+<div class="section" id="long-long-the-status-quo">
+<h4><a class="toc-backref" href="#id12"><code class="docutils literal notranslate"><span class="pre">long</span> <span class="pre">long</span></code> - The Status Quo</a><a class="headerlink" href="#long-long-the-status-quo" title="Permalink to this headline">¶</a></h4>
+<p>Pros:</p>
+<ul class="simple">
+<li>As a type <code class="docutils literal notranslate"><span class="pre">long</span> <span class="pre">long</span></code> plays the nicest with others:<ul>
+<li>It works with streaming operators and other library entities which support
+builtin integer types, but donât support <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code>.</li>
+<li>Its the representation used by chronoâs <code class="docutils literal notranslate"><span class="pre">nanosecond</span></code> and <code class="docutils literal notranslate"><span class="pre">second</span></code> typedefs.</li>
+</ul>
+</li>
+</ul>
+<p>Cons:</p>
+<ul class="simple">
+<li>It cannot provide the same resolution as <code class="docutils literal notranslate"><span class="pre">timespec</span></code> unless we limit it
+to a range of +/- 300 years from the epoch.</li>
+<li>It cannot provide the same range as <code class="docutils literal notranslate"><span class="pre">timespec</span></code> unless we limit its resolution
+to seconds.</li>
+<li><code class="docutils literal notranslate"><span class="pre">last_write_time</span></code> has to report an error when the time reported by the filesystem
+is unrepresentable.</li>
+</ul>
+</div>
+<div class="section" id="int128-t">
+<h4><a class="toc-backref" href="#id13">__int128_t</a><a class="headerlink" href="#int128-t" title="Permalink to this headline">¶</a></h4>
+<p>Pros:</p>
+<ul>
+<li><p class="first">It is an integer type.</p>
+</li>
+<li><p class="first">It makes the implementation simple and efficient.</p>
+</li>
+<li><p class="first">Acts exactly like other arithmetic types.</p>
+</li>
+<li><p class="first">Can be implicitly converted to a builtin integer type by the user.</p>
+<ul>
+<li><p class="first">This is important for doing things like:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span> <span class="nf">c_interface_using_time_t</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="kt">time_t</span><span class="p">);</span>
+
+<span class="kt">void</span> <span class="nf">foo</span><span class="p">(</span><span class="n">path</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">file_time_type</span> <span class="n">tp</span> <span class="o">=</span> <span class="n">last_write_time</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
+ <span class="kt">time_t</span> <span class="n">secs</span> <span class="o">=</span> <span class="n">duration_cast</span><span class="o"><</span><span class="n">seconds</span><span class="o">></span><span class="p">(</span><span class="n">tp</span><span class="p">.</span><span class="n">time_since_epoch</span><span class="p">()).</span><span class="n">count</span><span class="p">();</span>
+ <span class="n">c_interface_using_time_t</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="n">secs</span><span class="p">);</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</li>
+</ul>
+</li>
+</ul>
+<p>Cons:</p>
+<ul class="simple">
+<li>It isnât always available (but on 64 bit machines, it normally is).</li>
+<li>It causes <code class="docutils literal notranslate"><span class="pre">file_time_type</span></code> to have a larger range than <code class="docutils literal notranslate"><span class="pre">timespec</span></code>.</li>
+<li>It doesnât always act the same as other builtin integer types. For example
+with <code class="docutils literal notranslate"><span class="pre">cout</span></code> or <code class="docutils literal notranslate"><span class="pre">to_string</span></code>.</li>
+<li>Allows implicit truncation to 64 bit integers.</li>
+<li>It can be implicitly converted to a builtin integer type by the user,
+truncating its value.</li>
+</ul>
+</div>
+<div class="section" id="arithmetic-timespec-emulation">
+<h4><a class="toc-backref" href="#id14">Arithmetic <code class="docutils literal notranslate"><span class="pre">timespec</span></code> Emulation</a><a class="headerlink" href="#arithmetic-timespec-emulation" title="Permalink to this headline">¶</a></h4>
+<p>Pros:</p>
+<ul class="simple">
+<li>It has the exact same range and resolution of <code class="docutils literal notranslate"><span class="pre">timespec</span></code> when representing
+a nanosecond tick period.</li>
+<li>Itâs always available, unlike <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code>.</li>
+</ul>
+<p>Cons:</p>
+<ul class="simple">
+<li>It has a larger range when representing any period longer than a nanosecond.</li>
+<li>Doesnât actually allow users to use it like a <code class="docutils literal notranslate"><span class="pre">timespec</span></code>.</li>
+<li>The required representation of using <code class="docutils literal notranslate"><span class="pre">tv_sec</span></code> to store the giga tick count
+and <code class="docutils literal notranslate"><span class="pre">tv_nsec</span></code> to store the remainder adds nothing over a 128 bit integer,
+but complicates a lot.</li>
+<li>It isnât a builtin integer type, and canât be used anything like one.</li>
+<li>Chrono can be made to work with it, but not nicely.</li>
+<li>Emulating arithmetic classes come with their own host of problems regarding
+overload resolution (Each operator needs three SFINAE constrained versions of
+it in order to act like builtin integer types).</li>
+<li>It offers little over simply using <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code>.</li>
+<li>It acts the most differently than implementations using an actual integer type,
+which has a high chance of breaking source compatibility.</li>
+</ul>
+</div>
+</div>
+</div>
+<div class="section" id="selected-solution-using-int128-t">
+<h2><a class="toc-backref" href="#id15">Selected Solution - Using <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code></a><a class="headerlink" href="#selected-solution-using-int128-t" title="Permalink to this headline">¶</a></h2>
+<p>The solution I selected for libc++ is using <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code> when available,
+and otherwise falling back to using <code class="docutils literal notranslate"><span class="pre">long</span> <span class="pre">long</span></code> with nanosecond precision.</p>
+<p>When <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code> is available, or when <code class="docutils literal notranslate"><span class="pre">time_t</span></code> is 32-bits, the implementation
+provides same resolution and a greater range than <code class="docutils literal notranslate"><span class="pre">timespec</span></code>. Otherwise
+it still provides the same resolution, but is limited to a range of +/- 300
+years. This final case should be rather rare, as <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code>
+is normally available in 64-bit builds, and <code class="docutils literal notranslate"><span class="pre">time_t</span></code> is normally 32-bits
+during 32-bit builds.</p>
+<p>Although falling back to <code class="docutils literal notranslate"><span class="pre">long</span> <span class="pre">long</span></code> and nanosecond precision is less than
+ideal, it also happens to be the implementation provided by both libstdc++
+and MSVC. (So that makes it better, right?)</p>
+<p>Although the <code class="docutils literal notranslate"><span class="pre">timespec</span></code> emulation solution is feasible and would largely
+do what we want, it comes with too many complications, potential problems
+and discrepancies when compared to ânormalâ chrono time points and durations.</p>
+<p>An emulation of a builtin arithmetic type using a class is never going to act
+exactly the same, and the difference will be felt by users. Itâs not reasonable
+to expect them to tolerate and work around these differences. And once
+we commit to an ABI it will be too late to change. Committing to this seems
+risky.</p>
+<p>Therefore, <code class="docutils literal notranslate"><span class="pre">__int128_t</span></code> seems like the better solution.</p>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="ThreadingSupportAPI.html">Threading Support API</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="FeatureTestMacros.html">Feature Test Macros</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/ThreadingSupportAPI.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/ThreadingSupportAPI.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/ThreadingSupportAPI.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/ThreadingSupportAPI.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,136 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Threading Support API — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="../_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="File Time Type" href="FileTimeType.html" />
+ <link rel="prev" title="Symbol Visibility Macros" href="VisibilityMacros.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="../index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Threading Support API</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="VisibilityMacros.html">Symbol Visibility Macros</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="FileTimeType.html">File Time Type</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="threading-support-api">
+<h1>Threading Support API<a class="headerlink" href="#threading-support-api" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
+<li><a class="reference internal" href="#external-threading-api-and-the-external-threading-header" id="id2">External Threading API and the <code class="docutils literal notranslate"><span class="pre"><__external_threading></span></code> header</a></li>
+<li><a class="reference internal" href="#external-threading-library" id="id3">External Threading Library</a></li>
+<li><a class="reference internal" href="#threading-configuration-macros" id="id4">Threading Configuration Macros</a></li>
+</ul>
+</div>
+<div class="section" id="overview">
+<h2><a class="toc-backref" href="#id1">Overview</a><a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
+<p>Libc++ supports using multiple different threading models and configurations
+to implement the threading parts of libc++, including <code class="docutils literal notranslate"><span class="pre"><thread></span></code> and <code class="docutils literal notranslate"><span class="pre"><mutex></span></code>.
+These different models provide entirely different interfaces from each
+other. To address this libc++ wraps the underlying threading API in a new and
+consistent API, which it uses internally to implement threading primitives.</p>
+<p>The <code class="docutils literal notranslate"><span class="pre"><__threading_support></span></code> header is where libc++ defines its internal
+threading interface. It contains forward declarations of the internal threading
+interface as well as definitions for the interface.</p>
+</div>
+<div class="section" id="external-threading-api-and-the-external-threading-header">
+<h2><a class="toc-backref" href="#id2">External Threading API and the <code class="docutils literal notranslate"><span class="pre"><__external_threading></span></code> header</a><a class="headerlink" href="#external-threading-api-and-the-external-threading-header" title="Permalink to this headline">¶</a></h2>
+<p>In order to support vendors with custom threading APIâs libc++ allows the
+entire internal threading interface to be provided by an external,
+vendor provided, header.</p>
+<p>When <code class="docutils literal notranslate"><span class="pre">_LIBCPP_HAS_THREAD_API_EXTERNAL</span></code> is defined the <code class="docutils literal notranslate"><span class="pre"><__threading_support></span></code>
+header simply forwards to the <code class="docutils literal notranslate"><span class="pre"><__external_threading></span></code> header (which must exist).
+It is expected that the <code class="docutils literal notranslate"><span class="pre"><__external_threading></span></code> header provide the exact
+interface normally provided by <code class="docutils literal notranslate"><span class="pre"><__threading_support></span></code>.</p>
+</div>
+<div class="section" id="external-threading-library">
+<h2><a class="toc-backref" href="#id3">External Threading Library</a><a class="headerlink" href="#external-threading-library" title="Permalink to this headline">¶</a></h2>
+<p>libc++ can be compiled with its internal threading API delegating to an external
+library. Such a configuration is useful for library vendors who wish to
+distribute a thread-agnostic libc++ library, where the users of the library are
+expected to provide the implementation of the libc++ internal threading API.</p>
+<p>On a production setting, this would be achieved through a custom
+<code class="docutils literal notranslate"><span class="pre"><__external_threading></span></code> header, which declares the libc++ internal threading
+API but leaves out the implementation.</p>
+<p>The <code class="docutils literal notranslate"><span class="pre">-DLIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY</span></code> option allows building libc++ in
+such a configuration while allowing it to be tested on a platform that supports
+any of the threading systems (e.g. pthread) supported in <code class="docutils literal notranslate"><span class="pre">__threading_support</span></code>
+header. Therefore, the main purpose of this option is to allow testing of this
+particular configuration of the library without being tied to a vendor-specific
+threading system. This option is only meant to be used by libc++ library
+developers.</p>
+</div>
+<div class="section" id="threading-configuration-macros">
+<h2><a class="toc-backref" href="#id4">Threading Configuration Macros</a><a class="headerlink" href="#threading-configuration-macros" title="Permalink to this headline">¶</a></h2>
+<dl class="docutils">
+<dt><strong>_LIBCPP_HAS_NO_THREADS</strong></dt>
+<dd>This macro is defined when libc++ is built without threading support. It
+should not be manually defined by the user.</dd>
+<dt><strong>_LIBCPP_HAS_THREAD_API_EXTERNAL</strong></dt>
+<dd>This macro is defined when libc++ should use the <code class="docutils literal notranslate"><span class="pre"><__external_threading></span></code>
+header to provide the internal threading API. This macro overrides
+<code class="docutils literal notranslate"><span class="pre">_LIBCPP_HAS_THREAD_API_PTHREAD</span></code>.</dd>
+<dt><strong>_LIBCPP_HAS_THREAD_API_PTHREAD</strong></dt>
+<dd>This macro is defined when libc++ should use POSIX threads to implement the
+internal threading API.</dd>
+<dt><strong>_LIBCPP_HAS_THREAD_API_WIN32</strong></dt>
+<dd>This macro is defined when libc++ should use Win32 threads to implement the
+internal threading API.</dd>
+<dt><strong>_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL</strong></dt>
+<dd>This macro is defined when libc++ expects the definitions of the internal
+threading API to be provided by an external library. When defined
+<code class="docutils literal notranslate"><span class="pre"><__threading_support></span></code> will only provide the forward declarations and
+typedefs for the internal threading API.</dd>
+<dt><strong>_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL</strong></dt>
+<dd>This macro is used to build an external threading library using the
+<code class="docutils literal notranslate"><span class="pre"><__threading_support></span></code>. Specifically it exposes the threading API
+definitions in <code class="docutils literal notranslate"><span class="pre"><__threading_support></span></code> as non-inline definitions meant to
+be compiled into a library.</dd>
+</dl>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="VisibilityMacros.html">Symbol Visibility Macros</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="FileTimeType.html">File Time Type</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/VisibilityMacros.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/VisibilityMacros.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/VisibilityMacros.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/DesignDocs/VisibilityMacros.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,257 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Symbol Visibility Macros — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="../_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="Threading Support API" href="ThreadingSupportAPI.html" />
+ <link rel="prev" title="Libc++ ABI stability" href="ABIVersioning.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="../index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Symbol Visibility Macros</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="ABIVersioning.html">Libc++ ABI stability</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="ThreadingSupportAPI.html">Threading Support API</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="symbol-visibility-macros">
+<h1>Symbol Visibility Macros<a class="headerlink" href="#symbol-visibility-macros" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
+<li><a class="reference internal" href="#visibility-macros" id="id2">Visibility Macros</a></li>
+<li><a class="reference internal" href="#links" id="id3">Links</a></li>
+</ul>
+</div>
+<div class="section" id="overview">
+<h2><a class="toc-backref" href="#id1">Overview</a><a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
+<p>Libc++ uses various âvisibilityâ macros in order to provide a stable ABI in
+both the library and the headers. These macros work by changing the
+visibility and inlining characteristics of the symbols they are applied to.</p>
+</div>
+<div class="section" id="visibility-macros">
+<h2><a class="toc-backref" href="#id2">Visibility Macros</a><a class="headerlink" href="#visibility-macros" title="Permalink to this headline">¶</a></h2>
+<dl class="docutils">
+<dt><strong>_LIBCPP_HIDDEN</strong></dt>
+<dd>Mark a symbol as hidden so it will not be exported from shared libraries.</dd>
+<dt><strong>_LIBCPP_FUNC_VIS</strong></dt>
+<dd>Mark a symbol as being exported by the libc++ library. This attribute must
+be applied to the declaration of all functions exported by the libc++ dylib.</dd>
+<dt><strong>_LIBCPP_EXPORTED_FROM_ABI</strong></dt>
+<dd>Mark a symbol as being exported by the libc++ library. This attribute may
+only be applied to objects defined in the libc++ runtime library. On Windows,
+this macro applies <cite>dllimport</cite>/<cite>dllexport</cite> to the symbol, and on other
+platforms it gives the symbol default visibility.</dd>
+<dt><strong>_LIBCPP_OVERRIDABLE_FUNC_VIS</strong></dt>
+<dd><p class="first">Mark a symbol as being exported by the libc++ library, but allow it to be
+overridden locally. On non-Windows, this is equivalent to <cite>_LIBCPP_FUNC_VIS</cite>.
+This macro is applied to all <cite>operator new</cite> and <cite>operator delete</cite> overloads.</p>
+<p class="last"><strong>Windows Behavior</strong>: Any symbol marked <cite>dllimport</cite> cannot be overridden
+locally, since <cite>dllimport</cite> indicates the symbol should be bound to a separate
+DLL. All <cite>operator new</cite> and <cite>operator delete</cite> overloads are required to be
+locally overridable, and therefore must not be marked <cite>dllimport</cite>. On Windows,
+this macro therefore expands to <cite>__declspec(dllexport)</cite> when building the
+library and has an empty definition otherwise.</p>
+</dd>
+<dt><strong>_LIBCPP_HIDE_FROM_ABI</strong></dt>
+<dd>Mark a function as not being part of the ABI of any final linked image that
+uses it.</dd>
+<dt><strong>_LIBCPP_HIDE_FROM_ABI_AFTER_V1</strong></dt>
+<dd><p class="first">Mark a function as being hidden from the ABI (per <cite>_LIBCPP_HIDE_FROM_ABI</cite>)
+when libc++ is built with an ABI version after ABI v1. This macro is used to
+maintain ABI compatibility for symbols that have been historically exported
+by libc++ in v1 of the ABI, but that we donât want to export in the future.</p>
+<p class="last">This macro works as follows. When we build libc++, we either hide the symbol
+from the ABI (if the symbol is not part of the ABI in the version weâre
+building), or we leave it included. From user code (i.e. when weâre not
+building libc++), the macro always marks symbols as internal so that programs
+built using new libc++ headers stop relying on symbols that are removed from
+the ABI in a future version. Each time we release a new stable version of the
+ABI, we should create a new _LIBCPP_HIDE_FROM_ABI_AFTER_XXX macro, and we can
+use it to start removing symbols from the ABI after that stable version.</p>
+</dd>
+<dt><strong>_LIBCPP_HIDE_FROM_ABI_PER_TU</strong></dt>
+<dd><p class="first">This macro controls whether symbols hidden from the ABI with <cite>_LIBCPP_HIDE_FROM_ABI</cite>
+are local to each translation unit in addition to being local to each final
+linked image. This macro is defined to either 0 or 1. When it is defined to
+1, translation units compiled with different versions of libc++ can be linked
+together, since all non ABI-facing functions are local to each translation unit.
+This allows static archives built with different versions of libc++ to be linked
+together. This also means that functions marked with <cite>_LIBCPP_HIDE_FROM_ABI</cite>
+are not guaranteed to have the same address across translation unit boundaries.</p>
+<p>When the macro is defined to 0, there is no guarantee that translation units
+compiled with different versions of libc++ can interoperate. However, this
+leads to code size improvements, since non ABI-facing functions can be
+deduplicated across translation unit boundaries.</p>
+<p class="last">This macro can be defined by users to control the behavior they want from
+libc++. The default value of this macro (0 or 1) is controlled by whether
+<cite>_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT</cite> is defined, which is intended to
+be used by vendors only (see below).</p>
+</dd>
+<dt><strong>_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT</strong></dt>
+<dd><p class="first">This macro controls the default value for <cite>_LIBCPP_HIDE_FROM_ABI_PER_TU</cite>.
+When the macro is defined, per TU ABI insulation is enabled by default, and
+<cite>_LIBCPP_HIDE_FROM_ABI_PER_TU</cite> is defined to 1 unless overridden by users.
+Otherwise, per TU ABI insulation is disabled by default, and
+<cite>_LIBCPP_HIDE_FROM_ABI_PER_TU</cite> is defined to 0 unless overridden by users.</p>
+<p>This macro is intended for vendors to control whether they want to ship
+libc++ with per TU ABI insulation enabled by default. Users can always
+control the behavior they want by defining <cite>_LIBCPP_HIDE_FROM_ABI_PER_TU</cite>
+appropriately.</p>
+<p class="last">By default, this macro is not defined, which means that per TU ABI insulation
+is not provided unless explicitly overridden by users.</p>
+</dd>
+<dt><strong>_LIBCPP_TYPE_VIS</strong></dt>
+<dd>Mark a typeâs typeinfo, vtable and members as having default visibility.
+This attribute cannot be used on class templates.</dd>
+<dt><strong>_LIBCPP_TEMPLATE_VIS</strong></dt>
+<dd><p class="first">Mark a typeâs typeinfo and vtable as having default visibility.
+This macro has no effect on the visibility of the typeâs member functions.</p>
+<p><strong>GCC Behavior</strong>: GCC does not support Clangâs <cite>type_visibility(â¦)</cite>
+attribute. With GCC the <cite>visibility(â¦)</cite> attribute is used and member
+functions are affected.</p>
+<p class="last"><strong>Windows Behavior</strong>: DLLs do not support dllimport/export on class templates.
+The macro has an empty definition on this platform.</p>
+</dd>
+<dt><strong>_LIBCPP_ENUM_VIS</strong></dt>
+<dd><p class="first">Mark the typeinfo of an enum as having default visibility. This attribute
+should be applied to all enum declarations.</p>
+<p><strong>Windows Behavior</strong>: DLLs do not support importing or exporting enumeration
+typeinfo. The macro has an empty definition on this platform.</p>
+<p class="last"><strong>GCC Behavior</strong>: GCC un-hides the typeinfo for enumerations by default, even
+if <cite>-fvisibility=hidden</cite> is specified. Additionally applying a visibility
+attribute to an enum class results in a warning. The macro has an empty
+definition with GCC.</p>
+</dd>
+<dt><strong>_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS</strong></dt>
+<dd><p class="first">Mark the member functions, typeinfo, and vtable of the type named in
+a <cite>_LIBCPP_EXTERN_TEMPLATE</cite> declaration as being exported by the libc++ library.
+This attribute must be specified on all extern class template declarations.</p>
+<p>This macro is used to override the <cite>_LIBCPP_TEMPLATE_VIS</cite> attribute
+specified on the primary template and to export the member functions produced
+by the explicit instantiation in the dylib.</p>
+<p><strong>GCC Behavior</strong>: GCC ignores visibility attributes applied the type in
+extern template declarations and applying an attribute results in a warning.
+However since <cite>_LIBCPP_TEMPLATE_VIS</cite> is the same as
+<cite>__attribute__((visibility(âdefaultâ))</cite> the visibility is already correct.
+The macro has an empty definition with GCC.</p>
+<p class="last"><strong>Windows Behavior</strong>: <cite>extern template</cite> and <cite>dllexport</cite> are fundamentally
+incompatible <em>on a class template</em> on Windows; the former suppresses
+instantiation, while the latter forces it. Specifying both on the same
+declaration makes the class template be instantiated, which is not desirable
+inside headers. This macro therefore expands to <cite>dllimport</cite> outside of libc++
+but nothing inside of it (rather than expanding to <cite>dllexport</cite>); instead, the
+explicit instantiations themselves are marked as exported. Note that this
+applies <em>only</em> to extern <em>class</em> templates. Extern <em>function</em> templates obey
+regular import/export semantics, and applying <cite>dllexport</cite> directly to the
+extern template declaration (i.e. using <cite>_LIBCPP_FUNC_VIS</cite>) is the correct
+thing to do for them.</p>
+</dd>
+<dt><strong>_LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS</strong></dt>
+<dd><p class="first">Mark the member functions, typeinfo, and vtable of an explicit instantiation
+of a class template as being exported by the libc++ library. This attribute
+must be specified on all class template explicit instantiations.</p>
+<p class="last">It is only necessary to mark the explicit instantiation itself (as opposed to
+the extern template declaration) as exported on Windows, as discussed above.
+On all other platforms, this macro has an empty definition.</p>
+</dd>
+<dt><strong>_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS</strong></dt>
+<dd><p class="first">Mark a symbol as hidden so it will not be exported from shared libraries. This
+is intended specifically for method templates of either classes marked with
+<cite>_LIBCPP_TYPE_VIS</cite> or classes with an extern template instantiation
+declaration marked with <cite>_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS</cite>.</p>
+<p>When building libc++ with hidden visibility, we want explicit template
+instantiations to export members, which is consistent with existing Windows
+behavior. We also want classes annotated with <cite>_LIBCPP_TYPE_VIS</cite> to export
+their members, which is again consistent with existing Windows behavior.
+Both these changes are necessary for clients to be able to link against a
+libc++ DSO built with hidden visibility without encountering missing symbols.</p>
+<p>An unfortunate side effect, however, is that method templates of classes
+either marked <cite>_LIBCPP_TYPE_VIS</cite> or with extern template instantiation
+declarations marked with <cite>_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS</cite> also get default
+visibility when instantiated. These methods are often implicitly instantiated
+inside other libraries which use the libc++ headers, and will therefore end up
+being exported from those libraries, since those implicit instantiations will
+receive default visibility. This is not acceptable for libraries that wish to
+control their visibility, and led to PR30642.</p>
+<p class="last">Consequently, all such problematic method templates are explicitly marked
+either hidden (via this macro) or inline, so that they donât leak into client
+libraries. The problematic methods were found by running
+<a class="reference external" href="https://github.com/smeenai/bad-visibility-finder">bad-visibility-finder</a>
+against the libc++ headers after making <cite>_LIBCPP_TYPE_VIS</cite> and
+<cite>_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS</cite> expand to default visibility.</p>
+</dd>
+<dt><strong>_LIBCPP_EXCEPTION_ABI</strong></dt>
+<dd>Mark the member functions, typeinfo, and vtable of the type as being exported
+by the libc++ library. This macro must be applied to all <em>exception types</em>.
+Exception types should be defined directly in namespace <cite>std</cite> and not the
+versioning namespace. This allows throwing and catching some exception types
+between libc++ and libstdc++.</dd>
+<dt><strong>_LIBCPP_INTERNAL_LINKAGE</strong></dt>
+<dd>Mark the affected entity as having internal linkage (i.e. the <cite>static</cite>
+keyword in C). This is only a best effort: when the <cite>internal_linkage</cite>
+attribute is not available, we fall back to forcing the function to be
+inlined, which approximates internal linkage since an externally visible
+symbol is never generated for that function. This is an internal macro
+used as an implementation detail by other visibility macros. Never mark
+a function or a class with this macro directly.</dd>
+<dt><strong>_LIBCPP_ALWAYS_INLINE</strong></dt>
+<dd>Forces inlining of the function it is applied to. For visibility purposes,
+this macro is used to make sure that an externally visible symbol is never
+generated in an object file when the <cite>internal_linkage</cite> attribute is not
+available. This is an internal macro used by other visibility macros, and
+it should not be used directly.</dd>
+</dl>
+</div>
+<div class="section" id="links">
+<h2><a class="toc-backref" href="#id3">Links</a><a class="headerlink" href="#links" title="Permalink to this headline">¶</a></h2>
+<ul class="simple">
+<li><a class="reference external" href="http://lists.llvm.org/pipermail/cfe-dev/2013-July/030610.html">[cfe-dev] Visibility in libc++ - 1</a></li>
+<li><a class="reference external" href="http://lists.llvm.org/pipermail/cfe-dev/2013-August/031195.html">[cfe-dev] Visibility in libc++ - 2</a></li>
+<li><a class="reference external" href="http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20130805/085461.html">[libcxx] Visibility fixes for Windows</a></li>
+</ul>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="ABIVersioning.html">Libc++ ABI stability</a>
+ ::
+ <a class="uplink" href="../index.html">Contents</a>
+ ::
+ <a href="ThreadingSupportAPI.html">Threading Support API</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/FeatureTestMacroTable.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/FeatureTestMacroTable.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/FeatureTestMacroTable.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/FeatureTestMacroTable.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,346 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Feature Test Macro Support — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+ <link rel="next" title="Availability Markup" href="DesignDocs/AvailabilityMarkup.html" />
+ <link rel="prev" title="Testing libc++" href="TestingLibcxx.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Feature Test Macro Support</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="TestingLibcxx.html">Testing libc++</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="DesignDocs/AvailabilityMarkup.html">Availability Markup</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="feature-test-macro-support">
+<span id="featuretestmacrotable"></span><h1>Feature Test Macro Support<a class="headerlink" href="#feature-test-macro-support" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#overview" id="id2">Overview</a></li>
+<li><a class="reference internal" href="#status" id="id3">Status</a></li>
+</ul>
+</div>
+<div class="section" id="overview">
+<h2><a class="toc-backref" href="#id2">Overview</a><a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
+<p>This file documents the feature test macros currently supported by libc++.</p>
+</div>
+<div class="section" id="status">
+<span id="feature-status"></span><h2><a class="toc-backref" href="#id3">Status</a><a class="headerlink" href="#status" title="Permalink to this headline">¶</a></h2>
+<table border="1" class="docutils" id="id1">
+<caption><span class="caption-text">Current Status
+ :name: feature-status-table
+ :widths: auto</span><a class="headerlink" href="#id1" title="Permalink to this table">¶</a></caption>
+<colgroup>
+<col width="74%" />
+<col width="26%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Macro Name</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td colspan="2"><strong>C++ 14</strong></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_chrono_udls</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_complex_udls</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201309L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_exchange_function</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_generic_associative_lookup</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_integer_sequence</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_integral_constant_callable</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_is_final</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201402L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_is_null_pointer</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201309L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_make_reverse_iterator</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201402L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_make_unique</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_null_iterators</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_quoted_string_io</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_result_of_sfinae</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201210L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_robust_nonmodifying_seq_ops</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_shared_timed_mutex</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201402L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_string_udls</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_transformation_trait_aliases</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_transparent_operators</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201210L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_tuple_element_t</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201402L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_tuples_by_type</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201304L</span></code></td>
+</tr>
+<tr class="row-odd"><td colspan="2"><strong>C++ 17</strong></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_addressof_constexpr</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_allocator_traits_is_always_equal</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201411L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_any</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_apply</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_array_constexpr</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_as_const</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201510L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_atomic_is_always_lock_free</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_bool_constant</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201505L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_boyer_moore_searcher</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_byte</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_chrono</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201611L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_clamp</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_enable_shared_from_this</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_execution</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_filesystem</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201703L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_gcd_lcm</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_hardware_interference_size</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201703L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_has_unique_object_representations</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_hypot</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_incomplete_container_elements</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201505L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_invoke</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201411L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_is_aggregate</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201703L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_is_invocable</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201703L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_is_swappable</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_launder</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_logical_traits</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201510L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_make_from_tuple</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_map_try_emplace</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201411L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_math_special_functions</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_memory_resource</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_node_extract</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_nonmember_container_access</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201411L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_not_fn</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_optional</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_parallel_algorithm</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_raw_memory_algorithms</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_sample</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201603L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_scoped_lock</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201703L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_shared_mutex</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201505L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_shared_ptr_arrays</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_shared_ptr_weak_type</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_string_view</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_to_chars</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_transparent_operators</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201510L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_type_trait_variable_templates</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201510L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_uncaught_exceptions</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201411L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_unordered_map_try_emplace</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201411L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_variant</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201606L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_void_t</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201411L</span></code></td>
+</tr>
+<tr class="row-odd"><td colspan="2"><strong>C++ 2a</strong></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_atomic_ref</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_bind_front</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_bit_cast</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_char8_t</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201811L</span></code></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_concepts</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_constexpr_misc</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_constexpr_swap_algorithms</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_destroying_delete</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_erase_if</span></code></td>
+<td><code class="docutils literal notranslate"><span class="pre">201811L</span></code></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_generic_unordered_lookup</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_is_constant_evaluated</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_list_remove_return_type</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_ranges</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__cpp_lib_three_way_comparison</span></code></td>
+<td><em>unimplemented</em></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="TestingLibcxx.html">Testing libc++</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="DesignDocs/AvailabilityMarkup.html">Availability Markup</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/ReleaseNotes.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/ReleaseNotes.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/ReleaseNotes.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/ReleaseNotes.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,110 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Libc++ 8.0.0 Release Notes — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+ <link rel="next" title="Using libc++" href="UsingLibcxx.html" />
+ <link rel="prev" title="âlibc++â C++ Standard Library" href="index.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Libc++ 8.0.0 Release Notes</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="index.html">âlibc++â C++ Standard Library</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="UsingLibcxx.html">Using libc++</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="libc-8-0-0-release-notes">
+<h1>Libc++ 8.0.0 Release Notes<a class="headerlink" href="#libc-8-0-0-release-notes" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
+<li><a class="reference internal" href="#what-s-new-in-libc-8-0-0" id="id2">Whatâs New in Libc++ 8.0.0?</a><ul>
+<li><a class="reference internal" href="#api-changes" id="id3">API Changes</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<p>Written by the <a class="reference external" href="https://libcxx.llvm.org">Libc++ Team</a></p>
+<div class="section" id="introduction">
+<h2><a class="toc-backref" href="#id1">Introduction</a><a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
+<p>This document contains the release notes for the libc++ C++ Standard Library,
+part of the LLVM Compiler Infrastructure, release 8.0.0. Here we describe the
+status of libc++ in some detail, including major improvements from the previous
+release and new feature work. For the general LLVM release notes, see <a class="reference external" href="https://llvm.org/docs/ReleaseNotes.html">the LLVM
+documentation</a>. All LLVM releases may
+be downloaded from the <a class="reference external" href="https://releases.llvm.org/">LLVM releases web site</a>.</p>
+<p>For more information about libc++, please see the <a class="reference external" href="https://libcxx.llvm.org">Libc++ Web Site</a> or the <a class="reference external" href="https://llvm.org">LLVM Web Site</a>.</p>
+</div>
+<div class="section" id="what-s-new-in-libc-8-0-0">
+<h2><a class="toc-backref" href="#id2">Whatâs New in Libc++ 8.0.0?</a><a class="headerlink" href="#what-s-new-in-libc-8-0-0" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="api-changes">
+<h3><a class="toc-backref" href="#id3">API Changes</a><a class="headerlink" href="#api-changes" title="Permalink to this headline">¶</a></h3>
+<ul class="simple">
+<li>Building libc++ for Mac OSX 10.6 is not supported anymore.</li>
+<li>Starting with LLVM 8.0.0, users that wish to link together translation units
+built with different versions of libc++âs headers into the same final linked
+image MUST define the _LIBCPP_HIDE_FROM_ABI_PER_TU macro to 1 when building
+those translation units. Not defining _LIBCPP_HIDE_FROM_ABI_PER_TU to 1 and
+linking translation units built with different versions of libc++âs headers
+together may lead to ODR violations and ABI issues. On the flipside, code
+size improvements should be expected for everyone not defining the macro.</li>
+<li>Starting with LLVM 8.0.0, std::dynarray has been removed from the library.
+std::dynarray was a feature proposed for C++14 that was pulled from the
+Standard at the last minute and was never standardized. Since there are no
+plans to standardize this facility it is being removed.</li>
+<li>Starting with LLVM 8.0.0, std::bad_array_length has been removed from the
+library. std::bad_array_length was a feature proposed for C++14 alongside
+std::dynarray, but it never actually made it into the C++ Standard. There
+are no plans to standardize this feature at this time. Formally speaking,
+this removal constitutes an ABI break because the symbols were shipped in
+the shared library. However, on macOS systems, the feature was not usable
+because it was hidden behind availability annotations. We do not expect
+any actual breakage to happen from this change.</li>
+</ul>
+</div>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="index.html">âlibc++â C++ Standard Library</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="UsingLibcxx.html">Using libc++</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/TestingLibcxx.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/TestingLibcxx.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/TestingLibcxx.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/TestingLibcxx.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,328 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Testing libc++ — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+ <link rel="next" title="Feature Test Macro Support" href="FeatureTestMacroTable.html" />
+ <link rel="prev" title="Building libc++" href="BuildingLibcxx.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Testing libc++</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="BuildingLibcxx.html">Building libc++</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="FeatureTestMacroTable.html">Feature Test Macro Support</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="testing-libc">
+<h1>Testing libc++<a class="headerlink" href="#testing-libc" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#getting-started" id="id1">Getting Started</a><ul>
+<li><a class="reference internal" href="#setting-up-the-environment" id="id2">Setting up the Environment</a></li>
+<li><a class="reference internal" href="#example-usage" id="id3">Example Usage</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#lit-options" id="id4">LIT Options</a><ul>
+<li><a class="reference internal" href="#command-line-options" id="id5">Command Line Options</a></li>
+<li><a class="reference internal" href="#environment-variables" id="id6">Environment Variables</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#benchmarks" id="id7">Benchmarks</a><ul>
+<li><a class="reference internal" href="#building-benchmarks" id="id8">Building Benchmarks</a></li>
+<li><a class="reference internal" href="#running-benchmarks" id="id9">Running Benchmarks</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="getting-started">
+<h2><a class="toc-backref" href="#id1">Getting Started</a><a class="headerlink" href="#getting-started" title="Permalink to this headline">¶</a></h2>
+<p>libc++ uses LIT to configure and run its tests. The primary way to run the
+libc++ tests is by using make check-libcxx. However since libc++ can be used
+in any number of possible configurations it is important to customize the way
+LIT builds and runs the tests. This guide provides information on how to use
+LIT directly to test libc++.</p>
+<p>Please see the <a class="reference external" href="http://llvm.org/docs/CommandGuide/lit.html">Lit Command Guide</a> for more information about LIT.</p>
+<div class="section" id="setting-up-the-environment">
+<h3><a class="toc-backref" href="#id2">Setting up the Environment</a><a class="headerlink" href="#setting-up-the-environment" title="Permalink to this headline">¶</a></h3>
+<p>After building libc++ you must setup your environment to test libc++ using
+LIT.</p>
+<ol class="arabic">
+<li><p class="first">Create a shortcut to the actual lit executable so that you can invoke it
+easily from the command line.</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nb">alias</span> <span class="nv">lit</span><span class="o">=</span><span class="s1">'python path/to/llvm/utils/lit/lit.py'</span>
+</pre></div>
+</div>
+</li>
+<li><p class="first">Tell LIT where to find your build configuration.</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nb">export</span> <span class="nv">LIBCXX_SITE_CONFIG</span><span class="o">=</span>path/to/build-libcxx/test/lit.site.cfg
+</pre></div>
+</div>
+</li>
+</ol>
+</div>
+<div class="section" id="example-usage">
+<h3><a class="toc-backref" href="#id3">Example Usage</a><a class="headerlink" href="#example-usage" title="Permalink to this headline">¶</a></h3>
+<p>Once you have your environment set up and you have built libc++ you can run
+parts of the libc++ test suite by simply running <cite>lit</cite> on a specified test or
+directory. For example:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nb">cd</span> path/to/src/libcxx
+$ lit -sv test/std/re <span class="c1"># Run all of the std::regex tests</span>
+$ lit -sv test/std/depr/depr.c.headers/stdlib_h.pass.cpp <span class="c1"># Run a single test</span>
+$ lit -sv test/std/atomics test/std/threads <span class="c1"># Test std::thread and std::atomic</span>
+</pre></div>
+</div>
+<p>Sometimes youâll want to change the way LIT is running the tests. Custom options
+can be specified using the <cite>âparam=<name>=<val></cite> flag. The most common option
+youâll want to change is the standard dialect (ie -std=c++XX). By default the
+test suite will select the newest C++ dialect supported by the compiler and use
+that. However if you want to manually specify the option like so:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ lit -sv test/std/containers <span class="c1"># Run the tests with the newest -std</span>
+$ lit -sv --param<span class="o">=</span><span class="nv">std</span><span class="o">=</span>c++03 test/std/containers <span class="c1"># Run the tests in C++03</span>
+</pre></div>
+</div>
+<p>Occasionally youâll want to add extra compile or link flags when testing.
+You can do this as follows:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ lit -sv --param<span class="o">=</span><span class="nv">compile_flags</span><span class="o">=</span><span class="s1">'-Wcustom-warning'</span>
+$ lit -sv --param<span class="o">=</span><span class="nv">link_flags</span><span class="o">=</span><span class="s1">'-L/custom/library/path'</span>
+</pre></div>
+</div>
+<p>Some other common examples include:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># Specify a custom compiler.</span>
+$ lit -sv --param<span class="o">=</span><span class="nv">cxx_under_test</span><span class="o">=</span>/opt/bin/g++ test/std
+
+<span class="c1"># Enable warnings in the test suite</span>
+$ lit -sv --param<span class="o">=</span><span class="nv">enable_warnings</span><span class="o">=</span><span class="nb">true</span> test/std
+
+<span class="c1"># Use UBSAN when running the tests.</span>
+$ lit -sv --param<span class="o">=</span><span class="nv">use_sanitizer</span><span class="o">=</span>Undefined
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="lit-options">
+<h2><a class="toc-backref" href="#id4">LIT Options</a><a class="headerlink" href="#lit-options" title="Permalink to this headline">¶</a></h2>
+<p><strong class="program">lit</strong> [<em>options</em>â¦] [<em>filenames</em>â¦]</p>
+<div class="section" id="command-line-options">
+<h3><a class="toc-backref" href="#id5">Command Line Options</a><a class="headerlink" href="#command-line-options" title="Permalink to this headline">¶</a></h3>
+<p>To use these options you pass them on the LIT command line as âparam NAME or
+âparam NAME=VALUE. Some options have default values specified during CMakeâs
+configuration. Passing the option on the command line will override the default.</p>
+<dl class="option">
+<dt id="cmdoption-lit-arg-cxx-under-test">
+<code class="descname">cxx_under_test</code><code class="descclassname">=<path/to/compiler></code><a class="headerlink" href="#cmdoption-lit-arg-cxx-under-test" title="Permalink to this definition">¶</a></dt>
+<dd><p>Specify the compiler used to build the tests.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-cxx-stdlib-under-test">
+<code class="descname">cxx_stdlib_under_test</code><code class="descclassname">=<stdlib name></code><a class="headerlink" href="#cmdoption-lit-arg-cxx-stdlib-under-test" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Values</strong>: libc++, libstdc++</p>
+<p>Specify the C++ standard library being tested. Unless otherwise specified
+libc++ is used. This option is intended to allow running the libc++ test
+suite against other standard library implementations.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-std">
+<code class="descname">std</code><code class="descclassname">=<standard version></code><a class="headerlink" href="#cmdoption-lit-arg-std" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Values</strong>: c++98, c++03, c++11, c++14, c++17, c++2a</p>
+<p>Change the standard version used when building the tests.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-libcxx-site-config">
+<code class="descname">libcxx_site_config</code><code class="descclassname">=<path/to/lit.site.cfg></code><a class="headerlink" href="#cmdoption-lit-arg-libcxx-site-config" title="Permalink to this definition">¶</a></dt>
+<dd><p>Specify the site configuration to use when running the tests. This option
+overrides the environment variable LIBCXX_SITE_CONFIG.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-cxx-headers">
+<code class="descname">cxx_headers</code><code class="descclassname">=<path/to/headers></code><a class="headerlink" href="#cmdoption-lit-arg-cxx-headers" title="Permalink to this definition">¶</a></dt>
+<dd><p>Specify the c++ standard library headers that are tested. By default the
+headers in the source tree are used.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-cxx-library-root">
+<code class="descname">cxx_library_root</code><code class="descclassname">=<path/to/lib/></code><a class="headerlink" href="#cmdoption-lit-arg-cxx-library-root" title="Permalink to this definition">¶</a></dt>
+<dd><p>Specify the directory of the libc++ library to be tested. By default the
+library folder of the build directory is used. This option cannot be used
+when use_system_cxx_lib is provided.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-cxx-runtime-root">
+<code class="descname">cxx_runtime_root</code><code class="descclassname">=<path/to/lib/></code><a class="headerlink" href="#cmdoption-lit-arg-cxx-runtime-root" title="Permalink to this definition">¶</a></dt>
+<dd><p>Specify the directory of the libc++ library to use at runtime. This directory
+is not added to the linkers search path. This can be used to compile tests
+against one version of libc++ and run them using another. The default value
+for this option is <cite>cxx_library_root</cite>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-use-system-cxx-lib">
+<code class="descname">use_system_cxx_lib</code><code class="descclassname">=<bool></code><a class="headerlink" href="#cmdoption-lit-arg-use-system-cxx-lib" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Default</strong>: False</p>
+<p>Enable or disable testing against the installed version of libc++ library.
+Note: This does not use the installed headers.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-use-lit-shell">
+<code class="descname">use_lit_shell</code><code class="descclassname">=<bool></code><a class="headerlink" href="#cmdoption-lit-arg-use-lit-shell" title="Permalink to this definition">¶</a></dt>
+<dd><p>Enable or disable the use of LITâs internal shell in ShTests. If the
+environment variable LIT_USE_INTERNAL_SHELL is present then that is used as
+the default value. Otherwise the default value is True on Windows and False
+on every other platform.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-compile-flags">
+<code class="descname">compile_flags</code><code class="descclassname">="<list-of-args>"</code><a class="headerlink" href="#cmdoption-lit-arg-compile-flags" title="Permalink to this definition">¶</a></dt>
+<dd><p>Specify additional compile flags as a space delimited string.
+Note: This options should not be used to change the standard version used.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-link-flags">
+<code class="descname">link_flags</code><code class="descclassname">="<list-of-args>"</code><a class="headerlink" href="#cmdoption-lit-arg-link-flags" title="Permalink to this definition">¶</a></dt>
+<dd><p>Specify additional link flags as a space delimited string.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-debug-level">
+<code class="descname">debug_level</code><code class="descclassname">=<level></code><a class="headerlink" href="#cmdoption-lit-arg-debug-level" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Values</strong>: 0, 1</p>
+<p>Enable the use of debug mode. Level 0 enables assertions and level 1 enables
+assertions and debugging of iterator misuse.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-use-sanitizer">
+<code class="descname">use_sanitizer</code><code class="descclassname">=<sanitizer name></code><a class="headerlink" href="#cmdoption-lit-arg-use-sanitizer" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>Values</strong>: Memory, MemoryWithOrigins, Address, Undefined</p>
+<p>Run the tests using the given sanitizer. If LLVM_USE_SANITIZER was given when
+building libc++ then that sanitizer will be used by default.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cmdoption-lit-arg-color-diagnostics">
+<code class="descname">color_diagnostics</code><code class="descclassname"></code><a class="headerlink" href="#cmdoption-lit-arg-color-diagnostics" title="Permalink to this definition">¶</a></dt>
+<dd><p>Enable the use of colorized compile diagnostics. If the color_diagnostics
+option is specified or the environment variable LIBCXX_COLOR_DIAGNOSTICS is
+present then color diagnostics will be enabled.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="environment-variables">
+<h3><a class="toc-backref" href="#id6">Environment Variables</a><a class="headerlink" href="#environment-variables" title="Permalink to this headline">¶</a></h3>
+<dl class="envvar">
+<dt id="envvar-LIBCXX_SITE_CONFIG=<path/to/lit.site.cfg>">
+<code class="descname">LIBCXX_SITE_CONFIG=<path/to/lit.site.cfg></code><a class="headerlink" href="#envvar-LIBCXX_SITE_CONFIG=<path/to/lit.site.cfg>" title="Permalink to this definition">¶</a></dt>
+<dd><p>Specify the site configuration to use when running the tests.
+Also see <cite>libcxx_site_config</cite>.</p>
+</dd></dl>
+
+<dl class="envvar">
+<dt id="envvar-LIBCXX_COLOR_DIAGNOSTICS">
+<code class="descname">LIBCXX_COLOR_DIAGNOSTICS</code><a class="headerlink" href="#envvar-LIBCXX_COLOR_DIAGNOSTICS" title="Permalink to this definition">¶</a></dt>
+<dd><p>If <code class="docutils literal notranslate"><span class="pre">LIBCXX_COLOR_DIAGNOSTICS</span></code> is defined then the test suite will attempt
+to use color diagnostic outputs from the compiler.
+Also see <cite>color_diagnostics</cite>.</p>
+</dd></dl>
+
+</div>
+</div>
+<div class="section" id="benchmarks">
+<h2><a class="toc-backref" href="#id7">Benchmarks</a><a class="headerlink" href="#benchmarks" title="Permalink to this headline">¶</a></h2>
+<p>Libc++ contains benchmark tests separately from the test of the test suite.
+The benchmarks are written using the <a class="reference external" href="https://github.com/google/benchmark">Google Benchmark</a> library, a copy of which
+is stored in the libc++ repository.</p>
+<p>For more information about using the Google Benchmark library see the
+<a class="reference external" href="https://github.com/google/benchmark">official documentation</a>.</p>
+<div class="section" id="building-benchmarks">
+<h3><a class="toc-backref" href="#id8">Building Benchmarks</a><a class="headerlink" href="#building-benchmarks" title="Permalink to this headline">¶</a></h3>
+<p>The benchmark tests are not built by default. The benchmarks can be built using
+the <code class="docutils literal notranslate"><span class="pre">cxx-benchmarks</span></code> target.</p>
+<p>An example build would look like:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nb">cd</span> build
+$ cmake <span class="o">[</span>options<span class="o">]</span> <path to libcxx sources>
+$ make cxx-benchmarks
+</pre></div>
+</div>
+<p>This will build all of the benchmarks under <code class="docutils literal notranslate"><span class="pre"><libcxx-src>/benchmarks</span></code> to be
+built against the just-built libc++. The compiled tests are output into
+<code class="docutils literal notranslate"><span class="pre">build/benchmarks</span></code>.</p>
+<p>The benchmarks can also be built against the platforms native standard library
+using the <code class="docutils literal notranslate"><span class="pre">-DLIBCXX_BUILD_BENCHMARKS_NATIVE_STDLIB=ON</span></code> CMake option. This
+is useful for comparing the performance of libc++ to other standard libraries.
+The compiled benchmarks are named <code class="docutils literal notranslate"><span class="pre"><test>.libcxx.out</span></code> if they test libc++ and
+<code class="docutils literal notranslate"><span class="pre"><test>.native.out</span></code> otherwise.</p>
+<p>Also See:</p>
+<blockquote>
+<div><ul class="simple">
+<li><a class="reference internal" href="BuildingLibcxx.html#build-instructions"><span class="std std-ref">Building Libc++</span></a></li>
+<li><a class="reference internal" href="BuildingLibcxx.html#cmake-options"><span class="std std-ref">CMake Options</span></a></li>
+</ul>
+</div></blockquote>
+</div>
+<div class="section" id="running-benchmarks">
+<h3><a class="toc-backref" href="#id9">Running Benchmarks</a><a class="headerlink" href="#running-benchmarks" title="Permalink to this headline">¶</a></h3>
+<p>The benchmarks must be run manually by the user. Currently there is no way
+to run them as part of the build.</p>
+<p>For example:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ <span class="nb">cd</span> build/benchmarks
+$ make cxx-benchmarks
+$ ./algorithms.libcxx.out <span class="c1"># Runs all the benchmarks</span>
+$ ./algorithms.libcxx.out --benchmark_filter<span class="o">=</span>BM_Sort.* <span class="c1"># Only runs the sort benchmarks</span>
+</pre></div>
+</div>
+<p>For more information about running benchmarks see <a class="reference external" href="https://github.com/google/benchmark">Google Benchmark</a>.</p>
+</div>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="BuildingLibcxx.html">Building libc++</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="FeatureTestMacroTable.html">Feature Test Macro Support</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/UsingLibcxx.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/UsingLibcxx.html?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/UsingLibcxx.html (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/UsingLibcxx.html Wed Mar 20 02:13:27 2019
@@ -0,0 +1,358 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Using libc++ — libc++ 8.0 documentation</title>
+ <link rel="stylesheet" href="_static/haiku.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+ <link rel="next" title="Building libc++" href="BuildingLibcxx.html" />
+ <link rel="prev" title="Libc++ 8.0.0 Release Notes" href="ReleaseNotes.html" />
+ </head><body>
+ <div class="header" role="banner"><h1 class="heading"><a href="index.html">
+ <span>libc++ 8.0 documentation</span></a></h1>
+ <h2 class="heading"><span>Using libc++</span></h2>
+ </div>
+ <div class="topnav" role="navigation" aria-label="top navigation">
+
+ <p>
+ « <a href="ReleaseNotes.html">Libc++ 8.0.0 Release Notes</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="BuildingLibcxx.html">Building libc++</a> »
+ </p>
+
+ </div>
+ <div class="content">
+
+
+ <div class="section" id="using-libc">
+<h1>Using libc++<a class="headerlink" href="#using-libc" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#getting-started" id="id1">Getting Started</a></li>
+<li><a class="reference internal" href="#using-filesystem-and-libc-fs" id="id2">Using <code class="docutils literal notranslate"><span class="pre"><filesystem></span></code> and libc++fs</a></li>
+<li><a class="reference internal" href="#using-libc-experimental-and-experimental" id="id3">Using libc++experimental and <code class="docutils literal notranslate"><span class="pre"><experimental/...></span></code></a></li>
+<li><a class="reference internal" href="#using-libc-on-linux" id="id4">Using libc++ on Linux</a><ul>
+<li><a class="reference internal" href="#using-libc-with-gcc" id="id5">Using libc++ with GCC</a></li>
+<li><a class="reference internal" href="#gdb-pretty-printers-for-libc" id="id6">GDB Pretty printers for libc++</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#libc-configuration-macros" id="id7">Libc++ Configuration Macros</a><ul>
+<li><a class="reference internal" href="#c-17-specific-configuration-macros" id="id8">C++17 Specific Configuration Macros</a></li>
+<li><a class="reference internal" href="#c-2a-specific-configuration-macros" id="id9">C++2a Specific Configuration Macros:</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#libc-extensions" id="id10">Libc++ Extensions</a><ul>
+<li><a class="reference internal" href="#extended-applications-of-nodiscard" id="id11">Extended applications of <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code></a><ul>
+<li><a class="reference internal" href="#entities-declared-with-libcpp-nodiscard-ext" id="id12">Entities declared with <code class="docutils literal notranslate"><span class="pre">_LIBCPP_NODISCARD_EXT</span></code></a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="getting-started">
+<h2><a class="toc-backref" href="#id1">Getting Started</a><a class="headerlink" href="#getting-started" title="Permalink to this headline">¶</a></h2>
+<p>If you already have libc++ installed you can use it with clang.</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ clang++ -stdlib<span class="o">=</span>libc++ test.cpp
+$ clang++ -std<span class="o">=</span>c++11 -stdlib<span class="o">=</span>libc++ test.cpp
+</pre></div>
+</div>
+<p>On OS X and FreeBSD libc++ is the default standard library
+and the <code class="docutils literal notranslate"><span class="pre">-stdlib=libc++</span></code> is not required.</p>
+<p id="alternate-libcxx">If you want to select an alternate installation of libc++ you
+can use the following options.</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ clang++ -std<span class="o">=</span>c++11 -stdlib<span class="o">=</span>libc++ -nostdinc++ <span class="se">\</span>
+ -I<libcxx-install-prefix>/include/c++/v1 <span class="se">\</span>
+ -L<libcxx-install-prefix>/lib <span class="se">\</span>
+ -Wl,-rpath,<libcxx-install-prefix>/lib <span class="se">\</span>
+ test.cpp
+</pre></div>
+</div>
+<p>The option <code class="docutils literal notranslate"><span class="pre">-Wl,-rpath,<libcxx-install-prefix>/lib</span></code> adds a runtime library
+search path. Meaning that the systems dynamic linker will look for libc++ in
+<code class="docutils literal notranslate"><span class="pre"><libcxx-install-prefix>/lib</span></code> whenever the program is run. Alternatively the
+environment variable <code class="docutils literal notranslate"><span class="pre">LD_LIBRARY_PATH</span></code> (<code class="docutils literal notranslate"><span class="pre">DYLD_LIBRARY_PATH</span></code> on OS X) can
+be used to change the dynamic linkers search paths after a program is compiled.</p>
+<p>An example of using <code class="docutils literal notranslate"><span class="pre">LD_LIBRARY_PATH</span></code>:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ clang++ -stdlib<span class="o">=</span>libc++ -nostdinc++ <span class="se">\</span>
+ -I<libcxx-install-prefix>/include/c++/v1
+ -L<libcxx-install-prefix>/lib <span class="se">\</span>
+ test.cpp -o
+$ ./a.out <span class="c1"># Searches for libc++ in the systems library paths.</span>
+$ <span class="nb">export</span> <span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span><libcxx-install-prefix>/lib
+$ ./a.out <span class="c1"># Searches for libc++ along LD_LIBRARY_PATH</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="using-filesystem-and-libc-fs">
+<h2><a class="toc-backref" href="#id2">Using <code class="docutils literal notranslate"><span class="pre"><filesystem></span></code> and libc++fs</a><a class="headerlink" href="#using-filesystem-and-libc-fs" title="Permalink to this headline">¶</a></h2>
+<p>Libc++ provides the implementation of the filesystem library in a separate
+library. Users of <code class="docutils literal notranslate"><span class="pre"><filesystem></span></code> and <code class="docutils literal notranslate"><span class="pre"><experimental/filesystem></span></code> are
+required to link <code class="docutils literal notranslate"><span class="pre">-lc++fs</span></code>.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Prior to libc++ 7.0, users of <code class="docutils literal notranslate"><span class="pre"><experimental/filesystem></span></code> were required
+to link libc++experimental.</p>
+</div>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">The Filesystem library is still experimental in nature. As such normal
+guarantees about ABI stability and backwards compatibility do not yet apply
+to it. In the future, this restriction will be removed.</p>
+</div>
+</div>
+<div class="section" id="using-libc-experimental-and-experimental">
+<h2><a class="toc-backref" href="#id3">Using libc++experimental and <code class="docutils literal notranslate"><span class="pre"><experimental/...></span></code></a><a class="headerlink" href="#using-libc-experimental-and-experimental" title="Permalink to this headline">¶</a></h2>
+<p>Libc++ provides implementations of experimental technical specifications
+in a separate library, <code class="docutils literal notranslate"><span class="pre">libc++experimental.a</span></code>. Users of <code class="docutils literal notranslate"><span class="pre"><experimental/...></span></code>
+headers may be required to link <code class="docutils literal notranslate"><span class="pre">-lc++experimental</span></code>.</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ clang++ -std<span class="o">=</span>c++14 -stdlib<span class="o">=</span>libc++ test.cpp -lc++experimental
+</pre></div>
+</div>
+<p>Libc++experimental.a may not always be available, even when libc++ is already
+installed. For information on building libc++experimental from source see
+<a class="reference internal" href="BuildingLibcxx.html#build-instructions"><span class="std std-ref">Building Libc++</span></a> and
+<a class="reference internal" href="BuildingLibcxx.html#libc-experimental-options"><span class="std std-ref">libc++experimental CMake Options</span></a>.</p>
+<p>Note that as of libc++ 7.0 using the <code class="docutils literal notranslate"><span class="pre"><experimental/filesystem></span></code> requires linking
+libc++fs instead of libc++experimental.</p>
+<p>Also see the <a class="reference external" href="http://libcxx.llvm.org/ts1z_status.html">Experimental Library Implementation Status</a>
+page.</p>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<dl class="last docutils">
+<dt>Experimental libraries are Experimental.</dt>
+<dd><ul class="first last simple">
+<li>The contents of the <code class="docutils literal notranslate"><span class="pre"><experimental/...></span></code> headers and <code class="docutils literal notranslate"><span class="pre">libc++experimental.a</span></code>
+library will not remain compatible between versions.</li>
+<li>No guarantees of API or ABI stability are provided.</li>
+</ul>
+</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="using-libc-on-linux">
+<h2><a class="toc-backref" href="#id4">Using libc++ on Linux</a><a class="headerlink" href="#using-libc-on-linux" title="Permalink to this headline">¶</a></h2>
+<p>On Linux libc++ can typically be used with only â-stdlib=libc++â. However
+some libc++ installations require the user manually link libc++abi themselves.
+If you are running into linker errors when using libc++ try adding â-lc++abiâ
+to the link line. For example:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ clang++ -stdlib<span class="o">=</span>libc++ test.cpp -lc++ -lc++abi -lm -lc -lgcc_s -lgcc
+</pre></div>
+</div>
+<p>Alternately, you could just add libc++abi to your libraries list, which in
+most situations will give the same result:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ clang++ -stdlib<span class="o">=</span>libc++ test.cpp -lc++abi
+</pre></div>
+</div>
+<div class="section" id="using-libc-with-gcc">
+<h3><a class="toc-backref" href="#id5">Using libc++ with GCC</a><a class="headerlink" href="#using-libc-with-gcc" title="Permalink to this headline">¶</a></h3>
+<p>GCC does not provide a way to switch from libstdc++ to libc++. You must manually
+configure the compile and link commands.</p>
+<p>In particular you must tell GCC to remove the libstdc++ include directories
+using <code class="docutils literal notranslate"><span class="pre">-nostdinc++</span></code> and to not link libstdc++.so using <code class="docutils literal notranslate"><span class="pre">-nodefaultlibs</span></code>.</p>
+<p>Note that <code class="docutils literal notranslate"><span class="pre">-nodefaultlibs</span></code> removes all of the standard system libraries and
+not just libstdc++ so they must be manually linked. For example:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ g++ -nostdinc++ -I<libcxx-install-prefix>/include/c++/v1 <span class="se">\</span>
+ test.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc
+</pre></div>
+</div>
+</div>
+<div class="section" id="gdb-pretty-printers-for-libc">
+<h3><a class="toc-backref" href="#id6">GDB Pretty printers for libc++</a><a class="headerlink" href="#gdb-pretty-printers-for-libc" title="Permalink to this headline">¶</a></h3>
+<p>GDB does not support pretty-printing of libc++ symbols by default. Unfortunately
+libc++ does not provide pretty-printers itself. However there are 3rd
+party implementations available and although they are not officially
+supported by libc++ they may be useful to users.</p>
+<p>Known 3rd Party Implementations Include:</p>
+<ul class="simple">
+<li><a class="reference external" href="https://github.com/koutheir/libcxx-pretty-printers">Koutheirâs libc++ pretty-printers</a>.</li>
+</ul>
+</div>
+</div>
+<div class="section" id="libc-configuration-macros">
+<h2><a class="toc-backref" href="#id7">Libc++ Configuration Macros</a><a class="headerlink" href="#libc-configuration-macros" title="Permalink to this headline">¶</a></h2>
+<p>Libc++ provides a number of configuration macros which can be used to enable
+or disable extended libc++ behavior, including enabling âdebug modeâ or
+thread safety annotations.</p>
+<dl class="docutils">
+<dt><strong>_LIBCPP_DEBUG</strong>:</dt>
+<dd>See <a class="reference internal" href="DesignDocs/DebugMode.html#using-debug-mode"><span class="std std-ref">Using Debug Mode</span></a> for more information.</dd>
+<dt><strong>_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS</strong>:</dt>
+<dd>This macro is used to enable -Wthread-safety annotations on libc++âs
+<code class="docutils literal notranslate"><span class="pre">std::mutex</span></code> and <code class="docutils literal notranslate"><span class="pre">std::lock_guard</span></code>. By default these annotations are
+disabled and must be manually enabled by the user.</dd>
+<dt><strong>_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS</strong>:</dt>
+<dd>This macro is used to disable all visibility annotations inside libc++.
+Defining this macro and then building libc++ with hidden visibility gives a
+build of libc++ which does not export any symbols, which can be useful when
+building statically for inclusion into another library.</dd>
+<dt><strong>_LIBCPP_DISABLE_EXTERN_TEMPLATE</strong>:</dt>
+<dd>This macro is used to disable extern template declarations in the libc++
+headers. The intended use case is for clients who wish to use the libc++
+headers without taking a dependency on the libc++ library itself.</dd>
+<dt><strong>_LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION</strong>:</dt>
+<dd><p class="first">This macro is used to re-enable an extension in <cite>std::tuple</cite> which allowed
+it to be implicitly constructed from fewer initializers than contained
+elements. Elements without an initializer are default constructed. For example:</p>
+<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span><span class="o">></span> <span class="n">foo</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="p">{</span><span class="s">"hello world"</span><span class="p">,</span> <span class="mi">42</span><span class="p">};</span> <span class="c1">// default constructs error_code</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Since libc++ 4.0 this extension has been disabled by default. This macro
+may be defined to re-enable it in order to support existing code that depends
+on the extension. New use of this extension should be discouraged.
+See <a class="reference external" href="http://llvm.org/PR27374">PR 27374</a> for more information.</p>
+<p>Note: The âreduced-arity-initializationâ extension is still offered but only
+for explicit conversions. Example:</p>
+<div class="last highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">auto</span> <span class="nf">foo</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">using</span> <span class="n">Tup</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span><span class="o">></span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">Tup</span><span class="p">{</span><span class="s">"hello world"</span><span class="p">,</span> <span class="mi">42</span><span class="p">};</span> <span class="c1">// explicit constructor called. OK.</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</dd>
+<dt><strong>_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS</strong>:</dt>
+<dd><p class="first">This macro disables the additional diagnostics generated by libc++ using the
+<cite>diagnose_if</cite> attribute. These additional diagnostics include checks for:</p>
+<blockquote class="last">
+<div><ul class="simple">
+<li>Giving <cite>set</cite>, <cite>map</cite>, <cite>multiset</cite>, <cite>multimap</cite> and their <cite>unordered_</cite>
+counterparts a comparator which is not const callable.</li>
+<li>Giving an unordered associative container a hasher that is not const
+callable.</li>
+</ul>
+</div></blockquote>
+</dd>
+<dt><strong>_LIBCPP_NO_VCRUNTIME</strong>:</dt>
+<dd><p class="first">Microsoftâs C and C++ headers are fairly entangled, and some of their C++
+headers are fairly hard to avoid. In particular, <cite>vcruntime_new.h</cite> gets pulled
+in from a lot of other headers and provides definitions which clash with
+libc++ headers, such as <cite>nothrow_t</cite> (note that <cite>nothrow_t</cite> is a struct, so
+thereâs no way for libc++ to provide a compatible definition, since you canât
+have multiple definitions).</p>
+<p class="last">By default, libc++ solves this problem by deferring to Microsoftâs vcruntime
+headers where needed. However, it may be undesirable to depend on vcruntime
+headers, since they may not always be available in cross-compilation setups,
+or they may clash with other headers. The <cite>_LIBCPP_NO_VCRUNTIME</cite> macro
+prevents libc++ from depending on vcruntime headers. Consequently, it also
+prevents libc++ headers from being interoperable with vcruntime headers (from
+the aforementioned clashes), so users of this macro are promising to not
+attempt to combine libc++ headers with the problematic vcruntime headers. This
+macro also currently prevents certain <cite>operator new</cite>/<cite>operator delete</cite>
+replacement scenarios from working, e.g. replacing <cite>operator new</cite> and
+expecting a non-replaced <cite>operator new[]</cite> to call the replaced <cite>operator new</cite>.</p>
+</dd>
+<dt><strong>_LIBCPP_ENABLE_NODISCARD</strong>:</dt>
+<dd>Allow the library to add <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> attributes to entities not specified
+as <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> by the current language dialect. This includes
+backporting applications of <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> from newer dialects and
+additional extended applications at the discretion of the library. All
+additional applications of <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> are disabled by default.
+See <a class="reference internal" href="#nodiscard-extension"><span class="std std-ref">Extended Applications of [[nodiscard]]</span></a> for
+more information.</dd>
+<dt><strong>_LIBCPP_DISABLE_NODISCARD_EXT</strong>:</dt>
+<dd>This macro prevents the library from applying <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> to entities
+purely as an extension. See <a class="reference internal" href="#nodiscard-extension"><span class="std std-ref">Extended Applications of [[nodiscard]]</span></a>
+for more information.</dd>
+<dt><strong>_LIBCPP_ENABLE_DEPRECATION_WARNINGS</strong>:</dt>
+<dd>This macro enables warnings when using deprecated components. For example,
+when compiling in C++11 mode, using <cite>std::auto_ptr</cite> with the macro defined
+will trigger a warning saying that <cite>std::auto_ptr</cite> is deprecated. By default,
+this macro is not defined.</dd>
+</dl>
+<div class="section" id="c-17-specific-configuration-macros">
+<h3><a class="toc-backref" href="#id8">C++17 Specific Configuration Macros</a><a class="headerlink" href="#c-17-specific-configuration-macros" title="Permalink to this headline">¶</a></h3>
+<dl class="docutils">
+<dt><strong>_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES</strong>:</dt>
+<dd>This macro is used to re-enable all the features removed in C++17. The effect
+is equivalent to manually defining each macro listed below.</dd>
+<dt><strong>_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS</strong>:</dt>
+<dd>This macro is used to re-enable the <cite>set_unexpected</cite>, <cite>get_unexpected</cite>, and
+<cite>unexpected</cite> functions, which were removed in C++17.</dd>
+<dt><strong>_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR</strong>:</dt>
+<dd>This macro is used to re-enable <cite>std::auto_ptr</cite> in C++17.</dd>
+</dl>
+</div>
+<div class="section" id="c-2a-specific-configuration-macros">
+<h3><a class="toc-backref" href="#id9">C++2a Specific Configuration Macros:</a><a class="headerlink" href="#c-2a-specific-configuration-macros" title="Permalink to this headline">¶</a></h3>
+<dl class="docutils">
+<dt><strong>_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17</strong>:</dt>
+<dd>This macro can be used to disable diagnostics emitted from functions marked
+<code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> in dialects after C++17. See <a class="reference internal" href="#nodiscard-extension"><span class="std std-ref">Extended Applications of [[nodiscard]]</span></a>
+for more information.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="libc-extensions">
+<h2><a class="toc-backref" href="#id10">Libc++ Extensions</a><a class="headerlink" href="#libc-extensions" title="Permalink to this headline">¶</a></h2>
+<p>This section documents various extensions provided by libc++, how theyâre
+provided, and any information regarding how to use them.</p>
+<div class="section" id="extended-applications-of-nodiscard">
+<span id="nodiscard-extension"></span><h3><a class="toc-backref" href="#id11">Extended applications of <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code></a><a class="headerlink" href="#extended-applications-of-nodiscard" title="Permalink to this headline">¶</a></h3>
+<p>The <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> attribute is intended to help users find bugs where
+function return values are ignored when they shouldnât be. After C++17 the
+C++ standard has started to declared such library functions as <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code>.
+However, this application is limited and applies only to dialects after C++17.
+Users who want help diagnosing misuses of STL functions may desire a more
+liberal application of <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code>.</p>
+<p>For this reason libc++ provides an extension that does just that! The
+extension must be enabled by defining <code class="docutils literal notranslate"><span class="pre">_LIBCPP_ENABLE_NODISCARD</span></code>. The extended
+applications of <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> takes two forms:</p>
+<ol class="arabic simple">
+<li>Backporting <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> to entities declared as such by the
+standard in newer dialects, but not in the present one.</li>
+<li>Extended applications of <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code>, at the libraries discretion,
+applied to entities never declared as such by the standard.</li>
+</ol>
+<p>Users may also opt-out of additional applications <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> using
+additional macros.</p>
+<p>Applications of the first form, which backport <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> from a newer
+dialect may be disabled using macros specific to the dialect it was added. For
+example <code class="docutils literal notranslate"><span class="pre">_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17</span></code>.</p>
+<p>Applications of the second form, which are pure extensions, may be disabled
+by defining <code class="docutils literal notranslate"><span class="pre">_LIBCPP_DISABLE_NODISCARD_EXT</span></code>.</p>
+<div class="section" id="entities-declared-with-libcpp-nodiscard-ext">
+<h4><a class="toc-backref" href="#id12">Entities declared with <code class="docutils literal notranslate"><span class="pre">_LIBCPP_NODISCARD_EXT</span></code></a><a class="headerlink" href="#entities-declared-with-libcpp-nodiscard-ext" title="Permalink to this headline">¶</a></h4>
+<p>This section lists all extended applications of <code class="docutils literal notranslate"><span class="pre">[[nodiscard]]</span></code> to entities
+which no dialect declares as such (See the second form described above).</p>
+<ul class="simple">
+<li><code class="docutils literal notranslate"><span class="pre">get_temporary_buffer</span></code></li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+
+
+ </div>
+ <div class="bottomnav" role="navigation" aria-label="bottom navigation">
+
+ <p>
+ « <a href="ReleaseNotes.html">Libc++ 8.0.0 Release Notes</a>
+ ::
+ <a class="uplink" href="index.html">Contents</a>
+ ::
+ <a href="BuildingLibcxx.html">Building libc++</a> »
+ </p>
+
+ </div>
+
+ <div class="footer" role="contentinfo">
+ © Copyright 2011-2018, LLVM Project.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.5.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/BuildingLibcxx.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/BuildingLibcxx.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/BuildingLibcxx.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/BuildingLibcxx.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,554 @@
+.. _BuildingLibcxx:
+
+===============
+Building libc++
+===============
+
+.. contents::
+ :local:
+
+.. _build instructions:
+
+Getting Started
+===============
+
+On Mac OS 10.7 (Lion) and later, the easiest way to get this library is to install
+Xcode 4.2 or later. However if you want to install tip-of-trunk from here
+(getting the bleeding edge), read on.
+
+The basic steps needed to build libc++ are:
+
+#. Checkout LLVM:
+
+ * ``cd where-you-want-llvm-to-live``
+ * ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm``
+
+#. Checkout libc++:
+
+ * ``cd where-you-want-llvm-to-live``
+ * ``cd llvm/projects``
+ * ``svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx``
+
+#. Checkout libc++abi:
+
+ * ``cd where-you-want-llvm-to-live``
+ * ``cd llvm/projects``
+ * ``svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi``
+
+#. Configure and build libc++ with libc++abi:
+
+ CMake is the only supported configuration system.
+
+ Clang is the preferred compiler when building and using libc++.
+
+ * ``cd where you want to build llvm``
+ * ``mkdir build``
+ * ``cd build``
+ * ``cmake -G <generator> [options] <path to llvm sources>``
+
+ For more information about configuring libc++ see :ref:`CMake Options`.
+
+ * ``make cxx`` --- will build libc++ and libc++abi.
+ * ``make check-cxx check-cxxabi`` --- will run the test suites.
+
+ Shared libraries for libc++ and libc++ abi should now be present in llvm/build/lib.
+ See :ref:`using an alternate libc++ installation <alternate libcxx>`
+
+#. **Optional**: Install libc++ and libc++abi
+
+ If your system already provides a libc++ installation it is important to be
+ careful not to replace it. Remember Use the CMake option ``CMAKE_INSTALL_PREFIX`` to
+ select a safe place to install libc++.
+
+ * ``make install-cxx install-cxxabi`` --- Will install the libraries and the headers
+
+ .. warning::
+ * Replacing your systems libc++ installation could render the system non-functional.
+ * Mac OS X will not boot without a valid copy of ``libc++.1.dylib`` in ``/usr/lib``.
+
+
+The instructions are for building libc++ on
+FreeBSD, Linux, or Mac using `libc++abi`_ as the C++ ABI library.
+On Linux, it is also possible to use :ref:`libsupc++ <libsupcxx>` or libcxxrt.
+
+It is sometimes beneficial to build outside of the LLVM tree. An out-of-tree
+build would look like this:
+
+.. code-block:: bash
+
+ $ cd where-you-want-libcxx-to-live
+ $ # Check out llvm, libc++ and libc++abi.
+ $ ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm``
+ $ ``svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx``
+ $ ``svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi``
+ $ cd where-you-want-to-build
+ $ mkdir build && cd build
+ $ export CC=clang CXX=clang++
+ $ cmake -DLLVM_PATH=path/to/llvm \
+ -DLIBCXX_CXX_ABI=libcxxabi \
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxabi/include \
+ path/to/libcxx
+ $ make
+ $ make check-libcxx # optional
+
+
+Experimental Support for Windows
+--------------------------------
+
+The Windows support requires building with clang-cl as cl does not support one
+required extension: `#include_next`. Furthermore, VS 2015 or newer (19.00) is
+required. In the case of clang-cl, we need to specify the "MS Compatibility
+Version" as it defaults to 2014 (18.00).
+
+CMake + Visual Studio
+~~~~~~~~~~~~~~~~~~~~~
+
+Building with Visual Studio currently does not permit running tests. However,
+it is the simplest way to build.
+
+.. code-block:: batch
+
+ > cmake -G "Visual Studio 14 2015" ^
+ -T "LLVM-vs2014" ^
+ -DLIBCXX_ENABLE_SHARED=YES ^
+ -DLIBCXX_ENABLE_STATIC=NO ^
+ -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO ^
+ \path\to\libcxx
+ > cmake --build .
+
+CMake + ninja
+~~~~~~~~~~~~~
+
+Building with ninja is required for development to enable tests.
+Unfortunately, doing so requires additional configuration as we cannot
+just specify a toolset.
+
+.. code-block:: batch
+
+ > cmake -G Ninja ^
+ -DCMAKE_MAKE_PROGRAM=/path/to/ninja ^
+ -DCMAKE_SYSTEM_NAME=Windows ^
+ -DCMAKE_C_COMPILER=clang-cl ^
+ -DCMAKE_C_FLAGS="-fms-compatibility-version=19.00 --target=i686--windows" ^
+ -DCMAKE_CXX_COMPILER=clang-cl ^
+ -DCMAKE_CXX_FLAGS="-fms-compatibility-version=19.00 --target=i686--windows" ^
+ -DLLVM_PATH=/path/to/llvm/tree ^
+ -DLIBCXX_ENABLE_SHARED=YES ^
+ -DLIBCXX_ENABLE_STATIC=NO ^
+ -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO ^
+ \path\to\libcxx
+ > /path/to/ninja cxx
+ > /path/to/ninja check-cxx
+
+Note that the paths specified with backward slashes must use the `\\` as the
+directory separator as clang-cl may otherwise parse the path as an argument.
+
+.. _`libc++abi`: http://libcxxabi.llvm.org/
+
+
+.. _CMake Options:
+
+CMake Options
+=============
+
+Here are some of the CMake variables that are used often, along with a
+brief explanation and LLVM-specific notes. For full documentation, check the
+CMake docs or execute ``cmake --help-variable VARIABLE_NAME``.
+
+**CMAKE_BUILD_TYPE**:STRING
+ Sets the build type for ``make`` based generators. Possible values are
+ Release, Debug, RelWithDebInfo and MinSizeRel. On systems like Visual Studio
+ the user sets the build type with the IDE settings.
+
+**CMAKE_INSTALL_PREFIX**:PATH
+ Path where LLVM will be installed if "make install" is invoked or the
+ "INSTALL" target is built.
+
+**CMAKE_CXX_COMPILER**:STRING
+ The C++ compiler to use when building and testing libc++.
+
+
+.. _libcxx-specific options:
+
+libc++ specific options
+-----------------------
+
+.. option:: LIBCXX_INSTALL_LIBRARY:BOOL
+
+ **Default**: ``ON``
+
+ Toggle the installation of the library portion of libc++.
+
+.. option:: LIBCXX_INSTALL_HEADERS:BOOL
+
+ **Default**: ``ON``
+
+ Toggle the installation of the libc++ headers.
+
+.. option:: LIBCXX_ENABLE_ASSERTIONS:BOOL
+
+ **Default**: ``ON``
+
+ Build libc++ with assertions enabled.
+
+.. option:: LIBCXX_BUILD_32_BITS:BOOL
+
+ **Default**: ``OFF``
+
+ Build libc++ as a 32 bit library. Also see `LLVM_BUILD_32_BITS`.
+
+.. option:: LIBCXX_ENABLE_SHARED:BOOL
+
+ **Default**: ``ON``
+
+ Build libc++ as a shared library. Either `LIBCXX_ENABLE_SHARED` or
+ `LIBCXX_ENABLE_STATIC` has to be enabled.
+
+.. option:: LIBCXX_ENABLE_STATIC:BOOL
+
+ **Default**: ``ON``
+
+ Build libc++ as a static library. Either `LIBCXX_ENABLE_SHARED` or
+ `LIBCXX_ENABLE_STATIC` has to be enabled.
+
+.. option:: LIBCXX_LIBDIR_SUFFIX:STRING
+
+ Extra suffix to append to the directory where libraries are to be installed.
+ This option overrides `LLVM_LIBDIR_SUFFIX`.
+
+.. option:: LIBCXX_INSTALL_PREFIX:STRING
+
+ **Default**: ``""``
+
+ Define libc++ destination prefix.
+
+.. option:: LIBCXX_HERMETIC_STATIC_LIBRARY:BOOL
+
+ **Default**: ``OFF``
+
+ Do not export any symbols from the static libc++ library. This is useful when
+ This is useful when the static libc++ library is being linked into shared
+ libraries that may be used in with other shared libraries that use different
+ C++ library. We want to avoid avoid exporting any libc++ symbols in that case.
+
+.. _libc++experimental options:
+
+libc++experimental Specific Options
+------------------------------------
+
+.. option:: LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL
+
+ **Default**: ``ON``
+
+ Build and test libc++experimental.a.
+
+.. option:: LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY:BOOL
+
+ **Default**: ``LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY AND LIBCXX_INSTALL_LIBRARY``
+
+ Install libc++experimental.a alongside libc++.
+
+
+.. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL
+
+ **Default**: ``ON``
+
+ Build filesystem as a standalone library libc++fs.a.
+
+.. option:: LIBCXX_INSTALL_FILESYSTEM_LIBRARY:BOOL
+
+ **Default**: ``LIBCXX_ENABLE_FILESYSTEM AND LIBCXX_INSTALL_LIBRARY``
+
+ Install libc++fs.a alongside libc++.
+
+.. _ABI Library Specific Options:
+
+ABI Library Specific Options
+----------------------------
+
+.. option:: LIBCXX_CXX_ABI:STRING
+
+ **Values**: ``none``, ``libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``.
+
+ Select the ABI library to build libc++ against.
+
+.. option:: LIBCXX_CXX_ABI_INCLUDE_PATHS:PATHS
+
+ Provide additional search paths for the ABI library headers.
+
+.. option:: LIBCXX_CXX_ABI_LIBRARY_PATH:PATH
+
+ Provide the path to the ABI library that libc++ should link against.
+
+.. option:: LIBCXX_ENABLE_STATIC_ABI_LIBRARY:BOOL
+
+ **Default**: ``OFF``
+
+ If this option is enabled, libc++ will try and link the selected ABI library
+ statically.
+
+.. option:: LIBCXX_ENABLE_ABI_LINKER_SCRIPT:BOOL
+
+ **Default**: ``ON`` by default on UNIX platforms other than Apple unless
+ 'LIBCXX_ENABLE_STATIC_ABI_LIBRARY' is ON. Otherwise the default value is ``OFF``.
+
+ This option generate and installs a linker script as ``libc++.so`` which
+ links the correct ABI library.
+
+.. option:: LIBCXXABI_USE_LLVM_UNWINDER:BOOL
+
+ **Default**: ``OFF``
+
+ Build and use the LLVM unwinder. Note: This option can only be used when
+ libc++abi is the C++ ABI library used.
+
+
+libc++ Feature Options
+----------------------
+
+.. option:: LIBCXX_ENABLE_EXCEPTIONS:BOOL
+
+ **Default**: ``ON``
+
+ Build libc++ with exception support.
+
+.. option:: LIBCXX_ENABLE_RTTI:BOOL
+
+ **Default**: ``ON``
+
+ Build libc++ with run time type information.
+
+.. option:: LIBCXX_INCLUDE_BENCHMARKS:BOOL
+
+ **Default**: ``ON``
+
+ Build the libc++ benchmark tests and the Google Benchmark library needed
+ to support them.
+
+.. option:: LIBCXX_BENCHMARK_TEST_ARGS:STRING
+
+ **Default**: ``--benchmark_min_time=0.01``
+
+ A semicolon list of arguments to pass when running the libc++ benchmarks using the
+ ``check-cxx-benchmarks`` rule. By default we run the benchmarks for a very short amount of time,
+ since the primary use of ``check-cxx-benchmarks`` is to get test and sanitizer coverage, not to
+ get accurate measurements.
+
+.. option:: LIBCXX_BENCHMARK_NATIVE_STDLIB:STRING
+
+ **Default**:: ``""``
+
+ **Values**:: ``libc++``, ``libstdc++``
+
+ Build the libc++ benchmark tests and Google Benchmark library against the
+ specified standard library on the platform. On linux this can be used to
+ compare libc++ to libstdc++ by building the benchmark tests against both
+ standard libraries.
+
+.. option:: LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN:STRING
+
+ Use the specified GCC toolchain and standard library when building the native
+ stdlib benchmark tests.
+
+.. option:: LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT:BOOL
+
+ **Default**: ``OFF``
+
+ Pick the default for whether to constrain ABI-unstable symbols to
+ each individual translation unit. This setting controls whether
+ `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined by default --
+ see the documentation of that macro for details.
+
+
+libc++ ABI Feature Options
+--------------------------
+
+The following options allow building libc++ for a different ABI version.
+
+.. option:: LIBCXX_ABI_VERSION:STRING
+
+ **Default**: ``1``
+
+ Defines the target ABI version of libc++.
+
+.. option:: LIBCXX_ABI_UNSTABLE:BOOL
+
+ **Default**: ``OFF``
+
+ Build the "unstable" ABI version of libc++. Includes all ABI changing features
+ on top of the current stable version.
+
+.. option:: LIBCXX_ABI_NAMESPACE:STRING
+
+ **Default**: ``__n`` where ``n`` is the current ABI version.
+
+ This option defines the name of the inline ABI versioning namespace. It can be used for building
+ custom versions of libc++ with unique symbol names in order to prevent conflicts or ODR issues
+ with other libc++ versions.
+
+ .. warning::
+ When providing a custom namespace, it's the users responsibility to ensure the name won't cause
+ conflicts with other names defined by libc++, both now and in the future. In particular, inline
+ namespaces of the form ``__[0-9]+`` are strictly reserved by libc++ and may not be used by users.
+ Doing otherwise could cause conflicts and hinder libc++ ABI evolution.
+
+.. option:: LIBCXX_ABI_DEFINES:STRING
+
+ **Default**: ``""``
+
+ A semicolon-separated list of ABI macros to persist in the site config header.
+ See ``include/__config`` for the list of ABI macros.
+
+.. _LLVM-specific variables:
+
+LLVM-specific options
+---------------------
+
+.. option:: LLVM_LIBDIR_SUFFIX:STRING
+
+ Extra suffix to append to the directory where libraries are to be
+ installed. On a 64-bit architecture, one could use ``-DLLVM_LIBDIR_SUFFIX=64``
+ to install libraries to ``/usr/lib64``.
+
+.. option:: LLVM_BUILD_32_BITS:BOOL
+
+ Build 32-bits executables and libraries on 64-bits systems. This option is
+ available only on some 64-bits unix systems. Defaults to OFF.
+
+.. option:: LLVM_LIT_ARGS:STRING
+
+ Arguments given to lit. ``make check`` and ``make clang-test`` are affected.
+ By default, ``'-sv --no-progress-bar'`` on Visual C++ and Xcode, ``'-sv'`` on
+ others.
+
+
+Using Alternate ABI libraries
+=============================
+
+
+.. _libsupcxx:
+
+Using libsupc++ on Linux
+------------------------
+
+You will need libstdc++ in order to provide libsupc++.
+
+Figure out where the libsupc++ headers are on your system. On Ubuntu this
+is ``/usr/include/c++/<version>`` and ``/usr/include/c++/<version>/<target-triple>``
+
+You can also figure this out by running
+
+.. code-block:: bash
+
+ $ echo | g++ -Wp,-v -x c++ - -fsyntax-only
+ ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
+ ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/include"
+ #include "..." search starts here:
+ #include <...> search starts here:
+ /usr/include/c++/4.7
+ /usr/include/c++/4.7/x86_64-linux-gnu
+ /usr/include/c++/4.7/backward
+ /usr/lib/gcc/x86_64-linux-gnu/4.7/include
+ /usr/local/include
+ /usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed
+ /usr/include/x86_64-linux-gnu
+ /usr/include
+ End of search list.
+
+Note that the first two entries happen to be what we are looking for. This
+may not be correct on other platforms.
+
+We can now run CMake:
+
+.. code-block:: bash
+
+ $ CC=clang CXX=clang++ cmake -G "Unix Makefiles" \
+ -DLIBCXX_CXX_ABI=libstdc++ \
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/" \
+ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr \
+ <libc++-source-dir>
+
+
+You can also substitute ``-DLIBCXX_CXX_ABI=libsupc++``
+above, which will cause the library to be linked to libsupc++ instead
+of libstdc++, but this is only recommended if you know that you will
+never need to link against libstdc++ in the same executable as libc++.
+GCC ships libsupc++ separately but only as a static library. If a
+program also needs to link against libstdc++, it will provide its
+own copy of libsupc++ and this can lead to subtle problems.
+
+.. code-block:: bash
+
+ $ make cxx
+ $ make install
+
+You can now run clang with -stdlib=libc++.
+
+
+.. _libcxxrt_ref:
+
+Using libcxxrt on Linux
+------------------------
+
+You will need to keep the source tree of `libcxxrt`_ available
+on your build machine and your copy of the libcxxrt shared library must
+be placed where your linker will find it.
+
+We can now run CMake like:
+
+.. code-block:: bash
+
+ $ CC=clang CXX=clang++ cmake -G "Unix Makefiles" \
+ -DLIBCXX_CXX_ABI=libcxxrt \
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxrt-sources/src \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ <libc++-source-directory>
+ $ make cxx
+ $ make install
+
+Unfortunately you can't simply run clang with "-stdlib=libc++" at this point, as
+clang is set up to link for libc++ linked to libsupc++. To get around this
+you'll have to set up your linker yourself (or patch clang). For example,
+
+.. code-block:: bash
+
+ $ clang++ -stdlib=libc++ helloworld.cpp \
+ -nodefaultlibs -lc++ -lcxxrt -lm -lc -lgcc_s -lgcc
+
+Alternately, you could just add libcxxrt to your libraries list, which in most
+situations will give the same result:
+
+.. code-block:: bash
+
+ $ clang++ -stdlib=libc++ helloworld.cpp -lcxxrt
+
+.. _`libcxxrt`: https://github.com/pathscale/libcxxrt/
+
+
+Using a local ABI library installation
+---------------------------------------
+
+.. warning::
+ This is not recommended in almost all cases.
+
+These instructions should only be used when you can't install your ABI library.
+
+Normally you must link libc++ against a ABI shared library that the
+linker can find. If you want to build and test libc++ against an ABI
+library not in the linker's path you needq to set
+``-DLIBCXX_CXX_ABI_LIBRARY_PATH=/path/to/abi/lib`` when configuring CMake.
+
+An example build using libc++abi would look like:
+
+.. code-block:: bash
+
+ $ CC=clang CXX=clang++ cmake \
+ -DLIBCXX_CXX_ABI=libc++abi \
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/path/to/libcxxabi/include" \
+ -DLIBCXX_CXX_ABI_LIBRARY_PATH="/path/to/libcxxabi-build/lib" \
+ path/to/libcxx
+ $ make
+
+When testing libc++ LIT will automatically link against the proper ABI
+library.
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/ABIVersioning.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/ABIVersioning.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/ABIVersioning.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/ABIVersioning.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,17 @@
+
+====================
+Libc++ ABI stability
+====================
+
+Libc++ aims to preserve stable ABI to avoid subtle bugs when code built to the old ABI
+is linked with the code build to the new ABI. At the same time, libc++ allows ABI-breaking
+improvements and bugfixes for the scenarios when ABI change is not a issue.
+
+To support both cases, libc++ allows specifying the ABI version at the
+build time. The version is defined with a cmake option
+LIBCXX_ABI_VERSION. Another option LIBCXX_ABI_UNSTABLE can be used to
+include all present ABI breaking features. These options translate
+into C++ macro definitions _LIBCPP_ABI_VERSION, _LIBCPP_ABI_UNSTABLE.
+
+Any ABI-changing feature is placed under it's own macro, _LIBCPP_ABI_XXX, which is enabled
+based on the value of _LIBCPP_ABI_VERSION. _LIBCPP_ABI_UNSTABLE, if set, enables all features at once.
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/AvailabilityMarkup.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/AvailabilityMarkup.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/AvailabilityMarkup.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/AvailabilityMarkup.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,99 @@
+===================
+Availability Markup
+===================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+Libc++ is used as a system library on macOS and iOS (amongst others). In order
+for users to be able to compile a binary that is intended to be deployed to an
+older version of the platform, clang provides the
+`availability attribute <https://clang.llvm.org/docs/AttributeReference.html#availability>`_
+that can be placed on declarations to describe the lifecycle of a symbol in the
+library.
+
+Design
+======
+
+When a new feature is introduced that requires dylib support, a macro should be
+created in include/__config to mark this feature as unavailable for all the
+systems. For example::
+
+ // Define availability macros.
+ #if defined(_LIBCPP_USE_AVAILABILITY_APPLE)
+ # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
+ #else if defined(_LIBCPP_USE_AVAILABILITY_SOME_OTHER_VENDOR)
+ # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
+ #else
+ # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
+ #endif
+
+When the library is updated by the platform vendor, the markup can be updated.
+For example::
+
+ #define _LIBCPP_AVAILABILITY_SHARED_MUTEX \
+ __attribute__((availability(macosx,strict,introduced=10.12))) \
+ __attribute__((availability(ios,strict,introduced=10.0))) \
+ __attribute__((availability(tvos,strict,introduced=10.0))) \
+ __attribute__((availability(watchos,strict,introduced=3.0)))
+
+In the source code, the macro can be added on a class if the full class requires
+type info from the library for example::
+
+ _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
+ class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
+ : public std::logic_error {
+
+or on a particular symbol:
+
+ _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
+
+
+Testing
+=======
+
+Some parameters can be passed to lit to run the test-suite and exercise the
+availability.
+
+* The `platform` parameter controls the deployment target. For example lit can
+ be invoked with `--param=platform=macosx10.8`. Default is the current host.
+* The `use_system_cxx_lib` parameter indicates to use another library than the
+ just built one. Invoking lit with `--param=use_system_cxx_lib=true` will run
+ the test-suite against the host system library. Alternatively a path to the
+ directory containing a specific prebuilt libc++ can be used, for example:
+ `--param=use_system_cxx_lib=/path/to/macOS/10.8/`.
+
+Tests can be marked as XFAIL based on multiple features made available by lit:
+
+
+* if `--param=platform=macosx10.8` is passed, the following features will be available:
+
+ - availability
+ - availability=x86_64
+ - availability=macosx
+ - availability=x86_64-macosx
+ - availability=x86_64-apple-macosx10.8
+ - availability=macosx10.8
+
+ This feature is used to XFAIL a test that *is* using a class or a method marked
+ as unavailable *and* that is expected to *fail* if deployed on an older system.
+
+* if `use_system_cxx_lib` and `--param=platform=macosx10.8` are passed to lit,
+ the following features will also be available:
+
+ - with_system_cxx_lib
+ - with_system_cxx_lib=x86_64
+ - with_system_cxx_lib=macosx
+ - with_system_cxx_lib=x86_64-macosx
+ - with_system_cxx_lib=x86_64-apple-macosx10.8
+ - with_system_cxx_lib=macosx10.8
+
+ This feature is used to XFAIL a test that is *not* using a class or a method
+ marked as unavailable *but* that is expected to fail if deployed on an older
+ system. For example, if the test exhibits a bug in the libc on a particular
+ system version, or if the test uses a symbol that is not available on an
+ older version of the dylib (but for which there is no availability markup,
+ otherwise the XFAIL should use `availability` above).
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/CapturingConfigInfo.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/CapturingConfigInfo.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/CapturingConfigInfo.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/CapturingConfigInfo.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,88 @@
+=======================================================
+Capturing configuration information during installation
+=======================================================
+
+.. contents::
+ :local:
+
+The Problem
+===========
+
+Currently the libc++ supports building the library with a number of different
+configuration options. Unfortunately all of that configuration information is
+lost when libc++ is installed. In order to support "persistent"
+configurations libc++ needs a mechanism to capture the configuration options
+in the INSTALLED headers.
+
+
+Design Goals
+============
+
+* The solution should not INSTALL any additional headers. We don't want an extra
+ #include slowing everybody down.
+
+* The solution should not unduly affect libc++ developers. The problem is limited
+ to installed versions of libc++ and the solution should be as well.
+
+* The solution should not modify any existing headers EXCEPT during installation.
+ It makes developers lives harder if they have to regenerate the libc++ headers
+ every time they are modified.
+
+* The solution should not make any of the libc++ headers dependent on
+ files generated by the build system. The headers should be able to compile
+ out of the box without any modification.
+
+* The solution should not have ANY effect on users who don't need special
+ configuration options. The vast majority of users will never need this so it
+ shouldn't cost them.
+
+
+The Solution
+============
+
+When you first configure libc++ using CMake we check to see if we need to
+capture any options. If we haven't been given any "persistent" options then
+we do NOTHING.
+
+Otherwise we create a custom installation rule that modifies the installed __config
+header. The rule first generates a dummy "__config_site" header containing the required
+#defines. The contents of the dummy header are then prepended to the installed
+__config header. By manually prepending the files we avoid the cost of an
+extra #include and we allow the __config header to be ignorant of the extra
+configuration all together. An example "__config" header generated when
+-DLIBCXX_ENABLE_THREADS=OFF is given to CMake would look something like:
+
+.. code-block:: cpp
+
+ //===----------------------------------------------------------------------===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file is dual licensed under the MIT and the University of Illinois Open
+ // Source Licenses. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #ifndef _LIBCPP_CONFIG_SITE
+ #define _LIBCPP_CONFIG_SITE
+
+ /* #undef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE */
+ /* #undef _LIBCPP_HAS_NO_STDIN */
+ /* #undef _LIBCPP_HAS_NO_STDOUT */
+ #define _LIBCPP_HAS_NO_THREADS
+ /* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */
+ /* #undef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS */
+
+ #endif
+ // -*- C++ -*-
+ //===--------------------------- __config ---------------------------------===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file is dual licensed under the MIT and the University of Illinois Open
+ // Source Licenses. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #ifndef _LIBCPP_CONFIG
+ #define _LIBCPP_CONFIG
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/DebugMode.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/DebugMode.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/DebugMode.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/DebugMode.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,100 @@
+==========
+Debug Mode
+==========
+
+.. contents::
+ :local:
+
+.. _using-debug-mode:
+
+Using Debug Mode
+================
+
+Libc++ provides a debug mode that enables assertions meant to detect incorrect
+usage of the standard library. By default these assertions are disabled but
+they can be enabled using the ``_LIBCPP_DEBUG`` macro.
+
+**_LIBCPP_DEBUG** Macro
+-----------------------
+
+**_LIBCPP_DEBUG**:
+ This macro is used to enable assertions and iterator debugging checks within
+ libc++. By default it is undefined.
+
+ **Values**: ``0``, ``1``
+
+ Defining ``_LIBCPP_DEBUG`` to ``0`` or greater enables most of libc++'s
+ assertions. Defining ``_LIBCPP_DEBUG`` to ``1`` enables "iterator debugging"
+ which provides additional assertions about the validity of iterators used by
+ the program.
+
+ Note that this option has no effect on libc++'s ABI
+
+**_LIBCPP_DEBUG_USE_EXCEPTIONS**:
+ When this macro is defined ``_LIBCPP_ASSERT`` failures throw
+ ``__libcpp_debug_exception`` instead of aborting. Additionally this macro
+ disables exception specifications on functions containing ``_LIBCPP_ASSERT``
+ checks. This allows assertion failures to correctly throw through these
+ functions.
+
+Handling Assertion Failures
+---------------------------
+
+When a debug assertion fails the assertion handler is called via the
+``std::__libcpp_debug_function`` function pointer. It is possible to override
+this function pointer using a different handler function. Libc++ provides two
+different assertion handlers, the default handler
+``std::__libcpp_abort_debug_handler`` which aborts the program, and
+``std::__libcpp_throw_debug_handler`` which throws an instance of
+``std::__libcpp_debug_exception``. Libc++ can be changed to use the throwing
+assertion handler as follows:
+
+.. code-block:: cpp
+
+ #define _LIBCPP_DEBUG 1
+ #include <string>
+ int main() {
+ std::__libcpp_debug_function = std::__libcpp_throw_debug_function;
+ try {
+ std::string::iterator bad_it;
+ std::string str("hello world");
+ str.insert(bad_it, '!'); // causes debug assertion
+ } catch (std::__libcpp_debug_exception const&) {
+ return EXIT_SUCCESS;
+ }
+ return EXIT_FAILURE;
+ }
+
+Debug Mode Checks
+=================
+
+Libc++'s debug mode offers two levels of checking. The first enables various
+precondition checks throughout libc++. The second additionally enables
+"iterator debugging" which checks the validity of iterators used by the program.
+
+Basic Checks
+============
+
+These checks are enabled when ``_LIBCPP_DEBUG`` is defined to either 0 or 1.
+
+The following checks are enabled by ``_LIBCPP_DEBUG``:
+
+ * FIXME: Update this list
+
+Iterator Debugging Checks
+=========================
+
+These checks are enabled when ``_LIBCPP_DEBUG`` is defined to 1.
+
+The following containers and STL classes support iterator debugging:
+
+ * ``std::string``
+ * ``std::vector<T>`` (``T != bool``)
+ * ``std::list``
+ * ``std::unordered_map``
+ * ``std::unordered_multimap``
+ * ``std::unordered_set``
+ * ``std::unordered_multiset``
+
+The remaining containers do not currently support iterator debugging.
+Patches welcome.
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/FeatureTestMacros.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/FeatureTestMacros.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/FeatureTestMacros.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/FeatureTestMacros.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,44 @@
+===================
+Feature Test Macros
+===================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+Libc++ implements the C++ feature test macros as specified in the C++2a standard,
+and before that in non-normative guiding documents (`See cppreference <https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros>`)
+
+Design
+======
+
+Feature test macros are tricky to track, implement, test, and document correctly.
+They must be available from a list of headers, they may have different values in
+different dialects, and they may or may not be implemented by libc++. In order to
+track all of these conditions correctly and easily, we want a Single Source of
+Truth (SSoT) that defines each feature test macro, its values, the headers it
+lives in, and whether or not is is implemented by libc++. From this SSoA we
+have enough information to automatically generate the `<version>` header,
+the tests, and the documentation.
+
+Therefore we maintain a SSoA in
+`libcxx/test/std/language.support/support.limits/support.limits.general/generate_feature_test_macro_components.py`
+which doubles as a script to generate the following components:
+
+* The `<version>` header.
+* The version tests under `support.limits.general`.
+* Documentation of libc++'s implementation of each macro.
+
+Usage
+=====
+
+The `generate_feature_test_macro_components.py` script is used to track and
+update feature test macros in libc++.
+
+Whenever a feature test macro is added or changed, the table should be updated
+and the script should be re-ran. The script will clobber the existing test files
+and the documentation and it will generate a new `<version>` header as a
+temporary file. The generated `<version>` header should be merged with the
+existing one.
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/FileTimeType.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/FileTimeType.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/FileTimeType.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/FileTimeType.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,494 @@
+==============
+File Time Type
+==============
+
+.. contents::
+ :local:
+
+.. _file-time-type-motivation:
+
+Motivation
+==========
+
+The filesystem library provides interfaces for getting and setting the last
+write time of a file or directory. The interfaces use the ``file_time_type``
+type, which is a specialization of ``chrono::time_point`` for the
+"filesystem clock". According to [fs.filesystem.syn]
+
+ trivial-clock is an implementation-defined type that satisfies the
+ Cpp17TrivialClock requirements ([time.clock.req]) and that is capable of
+ representing and measuring file time values. Implementations should ensure
+ that the resolution and range of file_Âtime_Âtype reflect the operating
+ system dependent resolution and range of file time values.
+
+
+On POSIX systems, file times are represented using the ``timespec`` struct,
+which is defined as follows:
+
+.. code-block:: cpp
+
+ struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+ };
+
+To represent the range and resolution of ``timespec``, we need to (A) have
+nanosecond resolution, and (B) use more than 64 bits (assuming a 64 bit ``time_t``).
+
+As the standard requires us to use the ``chrono`` interface, we have to define
+our own filesystem clock which specifies the period and representation of
+the time points and duration it provides. It will look like this:
+
+.. code-block:: cpp
+
+ struct _FilesystemClock {
+ using period = nano;
+ using rep = TBD; // What is this?
+
+ using duration = chrono::duration<rep, period>;
+ using time_point = chrono::time_point<_FilesystemClock>;
+
+ // ... //
+ };
+
+ using file_time_type = _FilesystemClock::time_point;
+
+
+To get nanosecond resolution, we simply define ``period`` to be ``std::nano``.
+But what type can we use as the arithmetic representation that is capable
+of representing the range of the ``timespec`` struct?
+
+Problems To Consider
+====================
+
+Before considering solutions, let's consider the problems they should solve,
+and how important solving those problems are:
+
+
+Having a Smaller Range than ``timespec``
+----------------------------------------
+
+One solution to the range problem is to simply reduce the resolution of
+``file_time_type`` to be less than that of nanoseconds. This is what libc++'s
+initial implementation of ``file_time_type`` did; it's also what
+``std::system_clock`` does. As a result, it can represent time points about
+292 thousand years on either side of the epoch, as opposed to only 292 years
+at nanosecond resolution.
+
+``timespec`` can represent time points +/- 292 billion years from the epoch
+(just in case you needed a time point 200 billion years before the big bang,
+and with nanosecond resolution).
+
+To get the same range, we would need to drop our resolution to that of seconds
+to come close to having the same range.
+
+This begs the question, is the range problem "really a problem"? Sane usages
+of file time stamps shouldn't exceed +/- 300 years, so should we care to support it?
+
+I believe the answer is yes. We're not designing the filesystem time API, we're
+providing glorified C++ wrappers for it. If the underlying API supports
+a value, then we should too. Our wrappers should not place artificial restrictions
+on users that are not present in the underlying filesystem.
+
+Having a smaller range that the underlying filesystem forces the
+implementation to report ``value_too_large`` errors when it encounters a time
+point that it can't represent. This can cause the call to ``last_write_time``
+to throw in cases where the user was confident the call should succeed. (See below)
+
+
+.. code-block:: cpp
+
+ #include <filesystem>
+ using namespace std::filesystem;
+
+ // Set the times using the system interface.
+ void set_file_times(const char* path, struct timespec ts) {
+ timespec both_times[2];
+ both_times[0] = ts;
+ both_times[1] = ts;
+ int result = ::utimensat(AT_FDCWD, path, both_times, 0);
+ assert(result != -1);
+ }
+
+ // Called elsewhere to set the file time to something insane, and way
+ // out of the 300 year range we might expect.
+ void some_bad_persons_code() {
+ struct timespec new_times;
+ new_times.tv_sec = numeric_limits<time_t>::max();
+ new_times.tv_nsec = 0;
+ set_file_times("/tmp/foo", new_times); // OK, supported by most FSes
+ }
+
+ int main() {
+ path p = "/tmp/foo";
+ file_status st = status(p);
+ if (!exists(st) || !is_regular_file(st))
+ return 1;
+ if ((st.permissions() & perms::others_read) == perms::none)
+ return 1;
+ // It seems reasonable to assume this call should succeed.
+ file_time_type tp = last_write_time(p); // BAD! Throws value_too_large.
+ }
+
+
+Having a Smaller Resolution than ``timespec``
+---------------------------------------------
+
+As mentioned in the previous section, one way to solve the range problem
+is by reducing the resolution. But matching the range of ``timespec`` using a
+64 bit representation requires limiting the resolution to seconds.
+
+So we might ask: Do users "need" nanosecond precision? Is seconds not good enough?
+I limit my consideration of the point to this: Why was it not good enough for
+the underlying system interfaces? If it wasn't good enough for them, then it
+isn't good enough for us. Our job is to match the filesystems range and
+representation, not design it.
+
+
+Having a Larger Range than ``timespec``
+----------------------------------------
+
+We should also consider the opposite problem of having a ``file_time_type``
+that is able to represent a larger range than ``timespec``. At least in
+this case ``last_write_time`` can be used to get and set all possible values
+supported by the underlying filesystem; meaning ``last_write_time(p)`` will
+never throw a overflow error when retrieving a value.
+
+However, this introduces a new problem, where users are allowed to attempt to
+create a time point beyond what the filesystem can represent. Two particular
+values which cause this are ``file_time_type::min()`` and
+``file_time_type::max()``. As a result, the following code would throw:
+
+.. code-block:: cpp
+
+ void test() {
+ last_write_time("/tmp/foo", file_time_type::max()); // Throws
+ last_write_time("/tmp/foo", file_time_type::min()); // Throws.
+ }
+
+Apart from cases explicitly using ``min`` and ``max``, I don't see users taking
+a valid time point, adding a couple hundred billions of years in error,
+and then trying to update a file's write time to that value very often.
+
+Compared to having a smaller range, this problem seems preferable. At least
+now we can represent any time point the filesystem can, so users won't be forced
+to revert back to system interfaces to avoid limitations in the C++ STL.
+
+I posit that we should only consider this concern *after* we have something
+with at least the same range and resolution of the underlying filesystem. The
+latter two problems are much more important to solve.
+
+Potential Solutions And Their Complications
+===========================================
+
+Source Code Portability Across Implementations
+-----------------------------------------------
+
+As we've discussed, ``file_time_type`` needs a representation that uses more
+than 64 bits. The possible solutions include using ``__int128_t``, emulating a
+128 bit integer using a class, or potentially defining a ``timespec`` like
+arithmetic type. All three will allow us to, at minimum, match the range
+and resolution, and the last one might even allow us to match them exactly.
+
+But when considering these potential solutions we need to consider more than
+just the values they can represent. We need to consider the effects they will
+have on users and their code. For example, each of them breaks the following
+code in some way:
+
+.. code-block:: cpp
+
+ // Bug caused by an unexpected 'rep' type returned by count.
+ void print_time(path p) {
+ // __int128_t doesn't have streaming operators, and neither would our
+ // custom arithmetic types.
+ cout << last_write_time(p).time_since_epoch().count() << endl;
+ }
+
+ // Overflow during creation bug.
+ file_time_type timespec_to_file_time_type(struct timespec ts) {
+ // woops! chrono::seconds and chrono::nanoseconds use a 64 bit representation
+ // this may overflow before it's converted to a file_time_type.
+ auto dur = seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec);
+ return file_time_type(dur);
+ }
+
+ file_time_type correct_timespec_to_file_time_type(struct timespec ts) {
+ // This is the correct version of the above example, where we
+ // avoid using the chrono typedefs as they're not sufficient.
+ // Can we expect users to avoid this bug?
+ using fs_seconds = chrono::duration<file_time_type::rep>;
+ using fs_nanoseconds = chrono::duration<file_time_type::rep, nano>;
+ auto dur = fs_seconds(ts.tv_sec) + fs_nanoseconds(tv.tv_nsec);
+ return file_time_type(dur);
+ }
+
+ // Implicit truncation during conversion bug.
+ intmax_t get_time_in_seconds(path p) {
+ using fs_seconds = duration<file_time_type::rep, ratio<1, 1> >;
+ auto tp = last_write_time(p);
+
+ // This works with truncation for __int128_t, but what does it do for
+ // our custom arithmetic types.
+ return duration_cast<fs_seconds>().count();
+ }
+
+
+Each of the above examples would require a user to adjust their filesystem code
+to the particular eccentricities of the representation, hopefully only in such
+a way that the code is still portable across implementations.
+
+At least some of the above issues are unavoidable, no matter what
+representation we choose. But some representations may be quirkier than others,
+and, as I'll argue later, using an actual arithmetic type (``__int128_t``)
+provides the least aberrant behavior.
+
+
+Chrono and ``timespec`` Emulation.
+----------------------------------
+
+One of the options we've considered is using something akin to ``timespec``
+to represent the ``file_time_type``. It only seems natural seeing as that's
+what the underlying system uses, and because it might allow us to match
+the range and resolution exactly. But would it work with chrono? And could
+it still act at all like a ``timespec`` struct?
+
+For ease of consideration, let's consider what the implementation might
+look like.
+
+.. code-block:: cpp
+
+ struct fs_timespec_rep {
+ fs_timespec_rep(long long v)
+ : tv_sec(v / nano::den), tv_nsec(v % nano::den)
+ { }
+ private:
+ time_t tv_sec;
+ long tv_nsec;
+ };
+ bool operator==(fs_timespec_rep, fs_timespec_rep);
+ fs_int128_rep operator+(fs_timespec_rep, fs_timespec_rep);
+ // ... arithmetic operators ... //
+
+The first thing to notice is that we can't construct ``fs_timespec_rep`` like
+a ``timespec`` by passing ``{secs, nsecs}``. Instead we're limited to
+constructing it from a single 64 bit integer.
+
+We also can't allow the user to inspect the ``tv_sec`` or ``tv_nsec`` values
+directly. A ``chrono::duration`` represents its value as a tick period and a
+number of ticks stored using ``rep``. The representation is unaware of the
+tick period it is being used to represent, but ``timespec`` is setup to assume
+a nanosecond tick period; which is the only case where the names ``tv_sec``
+and ``tv_nsec`` match the values they store.
+
+When we convert a nanosecond duration to seconds, ``fs_timespec_rep`` will
+use ``tv_sec`` to represent the number of giga seconds, and ``tv_nsec`` the
+remaining seconds. Let's consider how this might cause a bug were users allowed
+to manipulate the fields directly.
+
+.. code-block:: cpp
+
+ template <class Period>
+ timespec convert_to_timespec(duration<fs_time_rep, Period> dur) {
+ fs_timespec_rep rep = dur.count();
+ return {rep.tv_sec, rep.tv_nsec}; // Oops! Period may not be nanoseconds.
+ }
+
+ template <class Duration>
+ Duration convert_to_duration(timespec ts) {
+ Duration dur({ts.tv_sec, ts.tv_nsec}); // Oops! Period may not be nanoseconds.
+ return file_time_type(dur);
+ file_time_type tp = last_write_time(p);
+ auto dur =
+ }
+
+ time_t extract_seconds(file_time_type tp) {
+ // Converting to seconds is a silly bug, but I could see it happening.
+ using SecsT = chrono::duration<file_time_type::rep, ratio<1, 1>>;
+ auto secs = duration_cast<Secs>(tp.time_since_epoch());
+ // tv_sec is now representing gigaseconds.
+ return secs.count().tv_sec; // Oops!
+ }
+
+Despite ``fs_timespec_rep`` not being usable in any manner resembling
+``timespec``, it still might buy us our goal of matching its range exactly,
+right?
+
+Sort of. Chrono provides a specialization point which specifies the minimum
+and maximum values for a custom representation. It looks like this:
+
+.. code-block:: cpp
+
+ template <>
+ struct duration_values<fs_timespec_rep> {
+ static fs_timespec_rep zero();
+ static fs_timespec_rep min();
+ static fs_timespec_rep max() { // assume friendship.
+ fs_timespec_rep val;
+ val.tv_sec = numeric_limits<time_t>::max();
+ val.tv_nsec = nano::den - 1;
+ return val;
+ }
+ };
+
+Notice that ``duration_values`` doesn't tell the representation what tick
+period it's actually representing. This would indeed correctly limit the range
+of ``duration<fs_timespec_rep, nano>`` to exactly that of ``timespec``. But
+nanoseconds isn't the only tick period it will be used to represent. For
+example:
+
+.. code-block:: cpp
+
+ void test() {
+ using rep = file_time_type::rep;
+ using fs_nsec = duration<rep, nano>;
+ using fs_sec = duration<rep>;
+ fs_nsec nsecs(fs_seconds::max()); // Truncates
+ }
+
+Though the above example may appear silly, I think it follows from the incorrect
+notion that using a ``timespec`` rep in chrono actually makes it act as if it
+were an actual ``timespec``.
+
+Interactions with 32 bit ``time_t``
+-----------------------------------
+
+Up until now we've only be considering cases where ``time_t`` is 64 bits, but what
+about 32 bit systems/builds where ``time_t`` is 32 bits? (this is the common case
+for 32 bit builds).
+
+When ``time_t`` is 32 bits, we can implement ``file_time_type`` simply using 64-bit
+``long long``. There is no need to get either ``__int128_t`` or ``timespec`` emulation
+involved. And nor should we, as it would suffer from the numerous complications
+described by this paper.
+
+Obviously our implementation for 32-bit builds should act as similarly to the
+64-bit build as possible. Code which compiles in one, should compile in the other.
+This consideration is important when choosing between ``__int128_t`` and
+emulating ``timespec``. The solution which provides the most uniformity with
+the least eccentricity is the preferable one.
+
+Summary
+=======
+
+The ``file_time_type`` time point is used to represent the write times for files.
+Its job is to act as part of a C++ wrapper for less ideal system interfaces. The
+underlying filesystem uses the ``timespec`` struct for the same purpose.
+
+However, the initial implementation of ``file_time_type`` could not represent
+either the range or resolution of ``timespec``, making it unsuitable. Fixing
+this requires an implementation which uses more than 64 bits to store the
+time point.
+
+We primarily considered two solutions: Using ``__int128_t`` and using a
+arithmetic emulation of ``timespec``. Each has its pros and cons, and both
+come with more than one complication.
+
+The Potential Solutions
+-----------------------
+
+``long long`` - The Status Quo
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pros:
+
+* As a type ``long long`` plays the nicest with others:
+
+ * It works with streaming operators and other library entities which support
+ builtin integer types, but don't support ``__int128_t``.
+ * Its the representation used by chrono's ``nanosecond`` and ``second`` typedefs.
+
+Cons:
+
+* It cannot provide the same resolution as ``timespec`` unless we limit it
+ to a range of +/- 300 years from the epoch.
+* It cannot provide the same range as ``timespec`` unless we limit its resolution
+ to seconds.
+* ``last_write_time`` has to report an error when the time reported by the filesystem
+ is unrepresentable.
+
+__int128_t
+~~~~~~~~~~~
+
+Pros:
+
+* It is an integer type.
+* It makes the implementation simple and efficient.
+* Acts exactly like other arithmetic types.
+* Can be implicitly converted to a builtin integer type by the user.
+
+ * This is important for doing things like:
+
+ .. code-block:: cpp
+
+ void c_interface_using_time_t(const char* p, time_t);
+
+ void foo(path p) {
+ file_time_type tp = last_write_time(p);
+ time_t secs = duration_cast<seconds>(tp.time_since_epoch()).count();
+ c_interface_using_time_t(p.c_str(), secs);
+ }
+
+Cons:
+
+* It isn't always available (but on 64 bit machines, it normally is).
+* It causes ``file_time_type`` to have a larger range than ``timespec``.
+* It doesn't always act the same as other builtin integer types. For example
+ with ``cout`` or ``to_string``.
+* Allows implicit truncation to 64 bit integers.
+* It can be implicitly converted to a builtin integer type by the user,
+ truncating its value.
+
+Arithmetic ``timespec`` Emulation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pros:
+
+* It has the exact same range and resolution of ``timespec`` when representing
+ a nanosecond tick period.
+* It's always available, unlike ``__int128_t``.
+
+Cons:
+
+* It has a larger range when representing any period longer than a nanosecond.
+* Doesn't actually allow users to use it like a ``timespec``.
+* The required representation of using ``tv_sec`` to store the giga tick count
+ and ``tv_nsec`` to store the remainder adds nothing over a 128 bit integer,
+ but complicates a lot.
+* It isn't a builtin integer type, and can't be used anything like one.
+* Chrono can be made to work with it, but not nicely.
+* Emulating arithmetic classes come with their own host of problems regarding
+ overload resolution (Each operator needs three SFINAE constrained versions of
+ it in order to act like builtin integer types).
+* It offers little over simply using ``__int128_t``.
+* It acts the most differently than implementations using an actual integer type,
+ which has a high chance of breaking source compatibility.
+
+
+Selected Solution - Using ``__int128_t``
+=========================================
+
+The solution I selected for libc++ is using ``__int128_t`` when available,
+and otherwise falling back to using ``long long`` with nanosecond precision.
+
+When ``__int128_t`` is available, or when ``time_t`` is 32-bits, the implementation
+provides same resolution and a greater range than ``timespec``. Otherwise
+it still provides the same resolution, but is limited to a range of +/- 300
+years. This final case should be rather rare, as ``__int128_t``
+is normally available in 64-bit builds, and ``time_t`` is normally 32-bits
+during 32-bit builds.
+
+Although falling back to ``long long`` and nanosecond precision is less than
+ideal, it also happens to be the implementation provided by both libstdc++
+and MSVC. (So that makes it better, right?)
+
+Although the ``timespec`` emulation solution is feasible and would largely
+do what we want, it comes with too many complications, potential problems
+and discrepancies when compared to "normal" chrono time points and durations.
+
+An emulation of a builtin arithmetic type using a class is never going to act
+exactly the same, and the difference will be felt by users. It's not reasonable
+to expect them to tolerate and work around these differences. And once
+we commit to an ABI it will be too late to change. Committing to this seems
+risky.
+
+Therefore, ``__int128_t`` seems like the better solution.
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/ThreadingSupportAPI.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/ThreadingSupportAPI.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/ThreadingSupportAPI.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/ThreadingSupportAPI.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,83 @@
+=====================
+Threading Support API
+=====================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+Libc++ supports using multiple different threading models and configurations
+to implement the threading parts of libc++, including ``<thread>`` and ``<mutex>``.
+These different models provide entirely different interfaces from each
+other. To address this libc++ wraps the underlying threading API in a new and
+consistent API, which it uses internally to implement threading primitives.
+
+The ``<__threading_support>`` header is where libc++ defines its internal
+threading interface. It contains forward declarations of the internal threading
+interface as well as definitions for the interface.
+
+External Threading API and the ``<__external_threading>`` header
+================================================================
+
+In order to support vendors with custom threading API's libc++ allows the
+entire internal threading interface to be provided by an external,
+vendor provided, header.
+
+When ``_LIBCPP_HAS_THREAD_API_EXTERNAL`` is defined the ``<__threading_support>``
+header simply forwards to the ``<__external_threading>`` header (which must exist).
+It is expected that the ``<__external_threading>`` header provide the exact
+interface normally provided by ``<__threading_support>``.
+
+External Threading Library
+==========================
+
+libc++ can be compiled with its internal threading API delegating to an external
+library. Such a configuration is useful for library vendors who wish to
+distribute a thread-agnostic libc++ library, where the users of the library are
+expected to provide the implementation of the libc++ internal threading API.
+
+On a production setting, this would be achieved through a custom
+``<__external_threading>`` header, which declares the libc++ internal threading
+API but leaves out the implementation.
+
+The ``-DLIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY`` option allows building libc++ in
+such a configuration while allowing it to be tested on a platform that supports
+any of the threading systems (e.g. pthread) supported in ``__threading_support``
+header. Therefore, the main purpose of this option is to allow testing of this
+particular configuration of the library without being tied to a vendor-specific
+threading system. This option is only meant to be used by libc++ library
+developers.
+
+Threading Configuration Macros
+==============================
+
+**_LIBCPP_HAS_NO_THREADS**
+ This macro is defined when libc++ is built without threading support. It
+ should not be manually defined by the user.
+
+**_LIBCPP_HAS_THREAD_API_EXTERNAL**
+ This macro is defined when libc++ should use the ``<__external_threading>``
+ header to provide the internal threading API. This macro overrides
+ ``_LIBCPP_HAS_THREAD_API_PTHREAD``.
+
+**_LIBCPP_HAS_THREAD_API_PTHREAD**
+ This macro is defined when libc++ should use POSIX threads to implement the
+ internal threading API.
+
+**_LIBCPP_HAS_THREAD_API_WIN32**
+ This macro is defined when libc++ should use Win32 threads to implement the
+ internal threading API.
+
+**_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL**
+ This macro is defined when libc++ expects the definitions of the internal
+ threading API to be provided by an external library. When defined
+ ``<__threading_support>`` will only provide the forward declarations and
+ typedefs for the internal threading API.
+
+**_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL**
+ This macro is used to build an external threading library using the
+ ``<__threading_support>``. Specifically it exposes the threading API
+ definitions in ``<__threading_support>`` as non-inline definitions meant to
+ be compiled into a library.
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/VisibilityMacros.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/VisibilityMacros.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/VisibilityMacros.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/DesignDocs/VisibilityMacros.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,218 @@
+========================
+Symbol Visibility Macros
+========================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+Libc++ uses various "visibility" macros in order to provide a stable ABI in
+both the library and the headers. These macros work by changing the
+visibility and inlining characteristics of the symbols they are applied to.
+
+Visibility Macros
+=================
+
+**_LIBCPP_HIDDEN**
+ Mark a symbol as hidden so it will not be exported from shared libraries.
+
+**_LIBCPP_FUNC_VIS**
+ Mark a symbol as being exported by the libc++ library. This attribute must
+ be applied to the declaration of all functions exported by the libc++ dylib.
+
+**_LIBCPP_EXPORTED_FROM_ABI**
+ Mark a symbol as being exported by the libc++ library. This attribute may
+ only be applied to objects defined in the libc++ runtime library. On Windows,
+ this macro applies `dllimport`/`dllexport` to the symbol, and on other
+ platforms it gives the symbol default visibility.
+
+**_LIBCPP_OVERRIDABLE_FUNC_VIS**
+ Mark a symbol as being exported by the libc++ library, but allow it to be
+ overridden locally. On non-Windows, this is equivalent to `_LIBCPP_FUNC_VIS`.
+ This macro is applied to all `operator new` and `operator delete` overloads.
+
+ **Windows Behavior**: Any symbol marked `dllimport` cannot be overridden
+ locally, since `dllimport` indicates the symbol should be bound to a separate
+ DLL. All `operator new` and `operator delete` overloads are required to be
+ locally overridable, and therefore must not be marked `dllimport`. On Windows,
+ this macro therefore expands to `__declspec(dllexport)` when building the
+ library and has an empty definition otherwise.
+
+**_LIBCPP_HIDE_FROM_ABI**
+ Mark a function as not being part of the ABI of any final linked image that
+ uses it.
+
+**_LIBCPP_HIDE_FROM_ABI_AFTER_V1**
+ Mark a function as being hidden from the ABI (per `_LIBCPP_HIDE_FROM_ABI`)
+ when libc++ is built with an ABI version after ABI v1. This macro is used to
+ maintain ABI compatibility for symbols that have been historically exported
+ by libc++ in v1 of the ABI, but that we don't want to export in the future.
+
+ This macro works as follows. When we build libc++, we either hide the symbol
+ from the ABI (if the symbol is not part of the ABI in the version we're
+ building), or we leave it included. From user code (i.e. when we're not
+ building libc++), the macro always marks symbols as internal so that programs
+ built using new libc++ headers stop relying on symbols that are removed from
+ the ABI in a future version. Each time we release a new stable version of the
+ ABI, we should create a new _LIBCPP_HIDE_FROM_ABI_AFTER_XXX macro, and we can
+ use it to start removing symbols from the ABI after that stable version.
+
+**_LIBCPP_HIDE_FROM_ABI_PER_TU**
+ This macro controls whether symbols hidden from the ABI with `_LIBCPP_HIDE_FROM_ABI`
+ are local to each translation unit in addition to being local to each final
+ linked image. This macro is defined to either 0 or 1. When it is defined to
+ 1, translation units compiled with different versions of libc++ can be linked
+ together, since all non ABI-facing functions are local to each translation unit.
+ This allows static archives built with different versions of libc++ to be linked
+ together. This also means that functions marked with `_LIBCPP_HIDE_FROM_ABI`
+ are not guaranteed to have the same address across translation unit boundaries.
+
+ When the macro is defined to 0, there is no guarantee that translation units
+ compiled with different versions of libc++ can interoperate. However, this
+ leads to code size improvements, since non ABI-facing functions can be
+ deduplicated across translation unit boundaries.
+
+ This macro can be defined by users to control the behavior they want from
+ libc++. The default value of this macro (0 or 1) is controlled by whether
+ `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined, which is intended to
+ be used by vendors only (see below).
+
+**_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT**
+ This macro controls the default value for `_LIBCPP_HIDE_FROM_ABI_PER_TU`.
+ When the macro is defined, per TU ABI insulation is enabled by default, and
+ `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 1 unless overridden by users.
+ Otherwise, per TU ABI insulation is disabled by default, and
+ `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 0 unless overridden by users.
+
+ This macro is intended for vendors to control whether they want to ship
+ libc++ with per TU ABI insulation enabled by default. Users can always
+ control the behavior they want by defining `_LIBCPP_HIDE_FROM_ABI_PER_TU`
+ appropriately.
+
+ By default, this macro is not defined, which means that per TU ABI insulation
+ is not provided unless explicitly overridden by users.
+
+**_LIBCPP_TYPE_VIS**
+ Mark a type's typeinfo, vtable and members as having default visibility.
+ This attribute cannot be used on class templates.
+
+**_LIBCPP_TEMPLATE_VIS**
+ Mark a type's typeinfo and vtable as having default visibility.
+ This macro has no effect on the visibility of the type's member functions.
+
+ **GCC Behavior**: GCC does not support Clang's `type_visibility(...)`
+ attribute. With GCC the `visibility(...)` attribute is used and member
+ functions are affected.
+
+ **Windows Behavior**: DLLs do not support dllimport/export on class templates.
+ The macro has an empty definition on this platform.
+
+
+**_LIBCPP_ENUM_VIS**
+ Mark the typeinfo of an enum as having default visibility. This attribute
+ should be applied to all enum declarations.
+
+ **Windows Behavior**: DLLs do not support importing or exporting enumeration
+ typeinfo. The macro has an empty definition on this platform.
+
+ **GCC Behavior**: GCC un-hides the typeinfo for enumerations by default, even
+ if `-fvisibility=hidden` is specified. Additionally applying a visibility
+ attribute to an enum class results in a warning. The macro has an empty
+ definition with GCC.
+
+**_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS**
+ Mark the member functions, typeinfo, and vtable of the type named in
+ a `_LIBCPP_EXTERN_TEMPLATE` declaration as being exported by the libc++ library.
+ This attribute must be specified on all extern class template declarations.
+
+ This macro is used to override the `_LIBCPP_TEMPLATE_VIS` attribute
+ specified on the primary template and to export the member functions produced
+ by the explicit instantiation in the dylib.
+
+ **GCC Behavior**: GCC ignores visibility attributes applied the type in
+ extern template declarations and applying an attribute results in a warning.
+ However since `_LIBCPP_TEMPLATE_VIS` is the same as
+ `__attribute__((visibility("default"))` the visibility is already correct.
+ The macro has an empty definition with GCC.
+
+ **Windows Behavior**: `extern template` and `dllexport` are fundamentally
+ incompatible *on a class template* on Windows; the former suppresses
+ instantiation, while the latter forces it. Specifying both on the same
+ declaration makes the class template be instantiated, which is not desirable
+ inside headers. This macro therefore expands to `dllimport` outside of libc++
+ but nothing inside of it (rather than expanding to `dllexport`); instead, the
+ explicit instantiations themselves are marked as exported. Note that this
+ applies *only* to extern *class* templates. Extern *function* templates obey
+ regular import/export semantics, and applying `dllexport` directly to the
+ extern template declaration (i.e. using `_LIBCPP_FUNC_VIS`) is the correct
+ thing to do for them.
+
+**_LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS**
+ Mark the member functions, typeinfo, and vtable of an explicit instantiation
+ of a class template as being exported by the libc++ library. This attribute
+ must be specified on all class template explicit instantiations.
+
+ It is only necessary to mark the explicit instantiation itself (as opposed to
+ the extern template declaration) as exported on Windows, as discussed above.
+ On all other platforms, this macro has an empty definition.
+
+**_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS**
+ Mark a symbol as hidden so it will not be exported from shared libraries. This
+ is intended specifically for method templates of either classes marked with
+ `_LIBCPP_TYPE_VIS` or classes with an extern template instantiation
+ declaration marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS`.
+
+ When building libc++ with hidden visibility, we want explicit template
+ instantiations to export members, which is consistent with existing Windows
+ behavior. We also want classes annotated with `_LIBCPP_TYPE_VIS` to export
+ their members, which is again consistent with existing Windows behavior.
+ Both these changes are necessary for clients to be able to link against a
+ libc++ DSO built with hidden visibility without encountering missing symbols.
+
+ An unfortunate side effect, however, is that method templates of classes
+ either marked `_LIBCPP_TYPE_VIS` or with extern template instantiation
+ declarations marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` also get default
+ visibility when instantiated. These methods are often implicitly instantiated
+ inside other libraries which use the libc++ headers, and will therefore end up
+ being exported from those libraries, since those implicit instantiations will
+ receive default visibility. This is not acceptable for libraries that wish to
+ control their visibility, and led to PR30642.
+
+ Consequently, all such problematic method templates are explicitly marked
+ either hidden (via this macro) or inline, so that they don't leak into client
+ libraries. The problematic methods were found by running
+ `bad-visibility-finder <https://github.com/smeenai/bad-visibility-finder>`_
+ against the libc++ headers after making `_LIBCPP_TYPE_VIS` and
+ `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` expand to default visibility.
+
+**_LIBCPP_EXCEPTION_ABI**
+ Mark the member functions, typeinfo, and vtable of the type as being exported
+ by the libc++ library. This macro must be applied to all *exception types*.
+ Exception types should be defined directly in namespace `std` and not the
+ versioning namespace. This allows throwing and catching some exception types
+ between libc++ and libstdc++.
+
+**_LIBCPP_INTERNAL_LINKAGE**
+ Mark the affected entity as having internal linkage (i.e. the `static`
+ keyword in C). This is only a best effort: when the `internal_linkage`
+ attribute is not available, we fall back to forcing the function to be
+ inlined, which approximates internal linkage since an externally visible
+ symbol is never generated for that function. This is an internal macro
+ used as an implementation detail by other visibility macros. Never mark
+ a function or a class with this macro directly.
+
+**_LIBCPP_ALWAYS_INLINE**
+ Forces inlining of the function it is applied to. For visibility purposes,
+ this macro is used to make sure that an externally visible symbol is never
+ generated in an object file when the `internal_linkage` attribute is not
+ available. This is an internal macro used by other visibility macros, and
+ it should not be used directly.
+
+Links
+=====
+
+* `[cfe-dev] Visibility in libc++ - 1 <http://lists.llvm.org/pipermail/cfe-dev/2013-July/030610.html>`_
+* `[cfe-dev] Visibility in libc++ - 2 <http://lists.llvm.org/pipermail/cfe-dev/2013-August/031195.html>`_
+* `[libcxx] Visibility fixes for Windows <http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20130805/085461.html>`_
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/FeatureTestMacroTable.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/FeatureTestMacroTable.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/FeatureTestMacroTable.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/FeatureTestMacroTable.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,200 @@
+.. _FeatureTestMacroTable:
+
+==========================
+Feature Test Macro Support
+==========================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+This file documents the feature test macros currently supported by libc++.
+
+.. _feature-status:
+
+Status
+======
+
+.. table:: Current Status
+ :name: feature-status-table
+ :widths: auto
+
+ ================================================= =================
+ Macro Name Value
+ ================================================= =================
+ **C++ 14**
+ -------------------------------------------------------------------
+ ``__cpp_lib_chrono_udls`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_complex_udls`` ``201309L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_exchange_function`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_generic_associative_lookup`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_integer_sequence`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_integral_constant_callable`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_final`` ``201402L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_null_pointer`` ``201309L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_make_reverse_iterator`` ``201402L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_make_unique`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_null_iterators`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_quoted_string_io`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_result_of_sfinae`` ``201210L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_robust_nonmodifying_seq_ops`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_shared_timed_mutex`` ``201402L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_string_udls`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_transformation_trait_aliases`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_transparent_operators`` ``201210L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_tuple_element_t`` ``201402L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_tuples_by_type`` ``201304L``
+ ------------------------------------------------- -----------------
+ **C++ 17**
+ -------------------------------------------------------------------
+ ``__cpp_lib_addressof_constexpr`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_allocator_traits_is_always_equal`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_any`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_apply`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_array_constexpr`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_as_const`` ``201510L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_atomic_is_always_lock_free`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_bool_constant`` ``201505L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_boyer_moore_searcher`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_byte`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_chrono`` ``201611L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_clamp`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_enable_shared_from_this`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_execution`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_filesystem`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_gcd_lcm`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_hardware_interference_size`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_has_unique_object_representations`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_hypot`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_incomplete_container_elements`` ``201505L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_invoke`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_aggregate`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_invocable`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_swappable`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_launder`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_logical_traits`` ``201510L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_make_from_tuple`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_map_try_emplace`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_math_special_functions`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_memory_resource`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_node_extract`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_nonmember_container_access`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_not_fn`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_optional`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_parallel_algorithm`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_raw_memory_algorithms`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_sample`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_scoped_lock`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_shared_mutex`` ``201505L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_shared_ptr_arrays`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_shared_ptr_weak_type`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_string_view`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_to_chars`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_transparent_operators`` ``201510L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_type_trait_variable_templates`` ``201510L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_uncaught_exceptions`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_unordered_map_try_emplace`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_variant`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_void_t`` ``201411L``
+ ------------------------------------------------- -----------------
+ **C++ 2a**
+ -------------------------------------------------------------------
+ ``__cpp_lib_atomic_ref`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_bind_front`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_bit_cast`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_char8_t`` ``201811L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_concepts`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_constexpr_misc`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_constexpr_swap_algorithms`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_destroying_delete`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_erase_if`` ``201811L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_generic_unordered_lookup`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_constant_evaluated`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_list_remove_return_type`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_ranges`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_three_way_comparison`` *unimplemented*
+ ================================================= =================
+
+
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/ReleaseNotes.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/ReleaseNotes.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/ReleaseNotes.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/ReleaseNotes.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,48 @@
+==========================
+Libc++ 8.0.0 Release Notes
+==========================
+
+.. contents::
+ :local:
+ :depth: 2
+
+Written by the `Libc++ Team <https://libcxx.llvm.org>`_
+
+Introduction
+============
+
+This document contains the release notes for the libc++ C++ Standard Library,
+part of the LLVM Compiler Infrastructure, release 8.0.0. Here we describe the
+status of libc++ in some detail, including major improvements from the previous
+release and new feature work. For the general LLVM release notes, see `the LLVM
+documentation <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM releases may
+be downloaded from the `LLVM releases web site <https://releases.llvm.org/>`_.
+
+For more information about libc++, please see the `Libc++ Web Site
+<https://libcxx.llvm.org>`_ or the `LLVM Web Site <https://llvm.org>`_.
+
+What's New in Libc++ 8.0.0?
+===========================
+
+API Changes
+-----------
+- Building libc++ for Mac OSX 10.6 is not supported anymore.
+- Starting with LLVM 8.0.0, users that wish to link together translation units
+ built with different versions of libc++'s headers into the same final linked
+ image MUST define the _LIBCPP_HIDE_FROM_ABI_PER_TU macro to 1 when building
+ those translation units. Not defining _LIBCPP_HIDE_FROM_ABI_PER_TU to 1 and
+ linking translation units built with different versions of libc++'s headers
+ together may lead to ODR violations and ABI issues. On the flipside, code
+ size improvements should be expected for everyone not defining the macro.
+- Starting with LLVM 8.0.0, std::dynarray has been removed from the library.
+ std::dynarray was a feature proposed for C++14 that was pulled from the
+ Standard at the last minute and was never standardized. Since there are no
+ plans to standardize this facility it is being removed.
+- Starting with LLVM 8.0.0, std::bad_array_length has been removed from the
+ library. std::bad_array_length was a feature proposed for C++14 alongside
+ std::dynarray, but it never actually made it into the C++ Standard. There
+ are no plans to standardize this feature at this time. Formally speaking,
+ this removal constitutes an ABI break because the symbols were shipped in
+ the shared library. However, on macOS systems, the feature was not usable
+ because it was hidden behind availability annotations. We do not expect
+ any actual breakage to happen from this change.
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/TestingLibcxx.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/TestingLibcxx.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/TestingLibcxx.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/TestingLibcxx.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,257 @@
+==============
+Testing libc++
+==============
+
+.. contents::
+ :local:
+
+Getting Started
+===============
+
+libc++ uses LIT to configure and run its tests. The primary way to run the
+libc++ tests is by using make check-libcxx. However since libc++ can be used
+in any number of possible configurations it is important to customize the way
+LIT builds and runs the tests. This guide provides information on how to use
+LIT directly to test libc++.
+
+Please see the `Lit Command Guide`_ for more information about LIT.
+
+.. _LIT Command Guide: http://llvm.org/docs/CommandGuide/lit.html
+
+Setting up the Environment
+--------------------------
+
+After building libc++ you must setup your environment to test libc++ using
+LIT.
+
+#. Create a shortcut to the actual lit executable so that you can invoke it
+ easily from the command line.
+
+ .. code-block:: bash
+
+ $ alias lit='python path/to/llvm/utils/lit/lit.py'
+
+#. Tell LIT where to find your build configuration.
+
+ .. code-block:: bash
+
+ $ export LIBCXX_SITE_CONFIG=path/to/build-libcxx/test/lit.site.cfg
+
+Example Usage
+-------------
+
+Once you have your environment set up and you have built libc++ you can run
+parts of the libc++ test suite by simply running `lit` on a specified test or
+directory. For example:
+
+.. code-block:: bash
+
+ $ cd path/to/src/libcxx
+ $ lit -sv test/std/re # Run all of the std::regex tests
+ $ lit -sv test/std/depr/depr.c.headers/stdlib_h.pass.cpp # Run a single test
+ $ lit -sv test/std/atomics test/std/threads # Test std::thread and std::atomic
+
+Sometimes you'll want to change the way LIT is running the tests. Custom options
+can be specified using the `--param=<name>=<val>` flag. The most common option
+you'll want to change is the standard dialect (ie -std=c++XX). By default the
+test suite will select the newest C++ dialect supported by the compiler and use
+that. However if you want to manually specify the option like so:
+
+.. code-block:: bash
+
+ $ lit -sv test/std/containers # Run the tests with the newest -std
+ $ lit -sv --param=std=c++03 test/std/containers # Run the tests in C++03
+
+Occasionally you'll want to add extra compile or link flags when testing.
+You can do this as follows:
+
+.. code-block:: bash
+
+ $ lit -sv --param=compile_flags='-Wcustom-warning'
+ $ lit -sv --param=link_flags='-L/custom/library/path'
+
+Some other common examples include:
+
+.. code-block:: bash
+
+ # Specify a custom compiler.
+ $ lit -sv --param=cxx_under_test=/opt/bin/g++ test/std
+
+ # Enable warnings in the test suite
+ $ lit -sv --param=enable_warnings=true test/std
+
+ # Use UBSAN when running the tests.
+ $ lit -sv --param=use_sanitizer=Undefined
+
+
+LIT Options
+===========
+
+:program:`lit` [*options*...] [*filenames*...]
+
+Command Line Options
+--------------------
+
+To use these options you pass them on the LIT command line as --param NAME or
+--param NAME=VALUE. Some options have default values specified during CMake's
+configuration. Passing the option on the command line will override the default.
+
+.. program:: lit
+
+.. option:: cxx_under_test=<path/to/compiler>
+
+ Specify the compiler used to build the tests.
+
+.. option:: cxx_stdlib_under_test=<stdlib name>
+
+ **Values**: libc++, libstdc++
+
+ Specify the C++ standard library being tested. Unless otherwise specified
+ libc++ is used. This option is intended to allow running the libc++ test
+ suite against other standard library implementations.
+
+.. option:: std=<standard version>
+
+ **Values**: c++98, c++03, c++11, c++14, c++17, c++2a
+
+ Change the standard version used when building the tests.
+
+.. option:: libcxx_site_config=<path/to/lit.site.cfg>
+
+ Specify the site configuration to use when running the tests. This option
+ overrides the environment variable LIBCXX_SITE_CONFIG.
+
+.. option:: cxx_headers=<path/to/headers>
+
+ Specify the c++ standard library headers that are tested. By default the
+ headers in the source tree are used.
+
+.. option:: cxx_library_root=<path/to/lib/>
+
+ Specify the directory of the libc++ library to be tested. By default the
+ library folder of the build directory is used. This option cannot be used
+ when use_system_cxx_lib is provided.
+
+
+.. option:: cxx_runtime_root=<path/to/lib/>
+
+ Specify the directory of the libc++ library to use at runtime. This directory
+ is not added to the linkers search path. This can be used to compile tests
+ against one version of libc++ and run them using another. The default value
+ for this option is `cxx_library_root`.
+
+.. option:: use_system_cxx_lib=<bool>
+
+ **Default**: False
+
+ Enable or disable testing against the installed version of libc++ library.
+ Note: This does not use the installed headers.
+
+.. option:: use_lit_shell=<bool>
+
+ Enable or disable the use of LIT's internal shell in ShTests. If the
+ environment variable LIT_USE_INTERNAL_SHELL is present then that is used as
+ the default value. Otherwise the default value is True on Windows and False
+ on every other platform.
+
+.. option:: compile_flags="<list-of-args>"
+
+ Specify additional compile flags as a space delimited string.
+ Note: This options should not be used to change the standard version used.
+
+.. option:: link_flags="<list-of-args>"
+
+ Specify additional link flags as a space delimited string.
+
+.. option:: debug_level=<level>
+
+ **Values**: 0, 1
+
+ Enable the use of debug mode. Level 0 enables assertions and level 1 enables
+ assertions and debugging of iterator misuse.
+
+.. option:: use_sanitizer=<sanitizer name>
+
+ **Values**: Memory, MemoryWithOrigins, Address, Undefined
+
+ Run the tests using the given sanitizer. If LLVM_USE_SANITIZER was given when
+ building libc++ then that sanitizer will be used by default.
+
+.. option:: color_diagnostics
+
+ Enable the use of colorized compile diagnostics. If the color_diagnostics
+ option is specified or the environment variable LIBCXX_COLOR_DIAGNOSTICS is
+ present then color diagnostics will be enabled.
+
+
+Environment Variables
+---------------------
+
+.. envvar:: LIBCXX_SITE_CONFIG=<path/to/lit.site.cfg>
+
+ Specify the site configuration to use when running the tests.
+ Also see `libcxx_site_config`.
+
+.. envvar:: LIBCXX_COLOR_DIAGNOSTICS
+
+ If ``LIBCXX_COLOR_DIAGNOSTICS`` is defined then the test suite will attempt
+ to use color diagnostic outputs from the compiler.
+ Also see `color_diagnostics`.
+
+Benchmarks
+==========
+
+Libc++ contains benchmark tests separately from the test of the test suite.
+The benchmarks are written using the `Google Benchmark`_ library, a copy of which
+is stored in the libc++ repository.
+
+For more information about using the Google Benchmark library see the
+`official documentation <https://github.com/google/benchmark>`_.
+
+.. _`Google Benchmark`: https://github.com/google/benchmark
+
+Building Benchmarks
+-------------------
+
+The benchmark tests are not built by default. The benchmarks can be built using
+the ``cxx-benchmarks`` target.
+
+An example build would look like:
+
+.. code-block:: bash
+
+ $ cd build
+ $ cmake [options] <path to libcxx sources>
+ $ make cxx-benchmarks
+
+This will build all of the benchmarks under ``<libcxx-src>/benchmarks`` to be
+built against the just-built libc++. The compiled tests are output into
+``build/benchmarks``.
+
+The benchmarks can also be built against the platforms native standard library
+using the ``-DLIBCXX_BUILD_BENCHMARKS_NATIVE_STDLIB=ON`` CMake option. This
+is useful for comparing the performance of libc++ to other standard libraries.
+The compiled benchmarks are named ``<test>.libcxx.out`` if they test libc++ and
+``<test>.native.out`` otherwise.
+
+Also See:
+
+ * :ref:`Building Libc++ <build instructions>`
+ * :ref:`CMake Options`
+
+Running Benchmarks
+------------------
+
+The benchmarks must be run manually by the user. Currently there is no way
+to run them as part of the build.
+
+For example:
+
+.. code-block:: bash
+
+ $ cd build/benchmarks
+ $ make cxx-benchmarks
+ $ ./algorithms.libcxx.out # Runs all the benchmarks
+ $ ./algorithms.libcxx.out --benchmark_filter=BM_Sort.* # Only runs the sort benchmarks
+
+For more information about running benchmarks see `Google Benchmark`_.
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/UsingLibcxx.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/UsingLibcxx.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/UsingLibcxx.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/UsingLibcxx.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,317 @@
+============
+Using libc++
+============
+
+.. contents::
+ :local:
+
+Getting Started
+===============
+
+If you already have libc++ installed you can use it with clang.
+
+.. code-block:: bash
+
+ $ clang++ -stdlib=libc++ test.cpp
+ $ clang++ -std=c++11 -stdlib=libc++ test.cpp
+
+On OS X and FreeBSD libc++ is the default standard library
+and the ``-stdlib=libc++`` is not required.
+
+.. _alternate libcxx:
+
+If you want to select an alternate installation of libc++ you
+can use the following options.
+
+.. code-block:: bash
+
+ $ clang++ -std=c++11 -stdlib=libc++ -nostdinc++ \
+ -I<libcxx-install-prefix>/include/c++/v1 \
+ -L<libcxx-install-prefix>/lib \
+ -Wl,-rpath,<libcxx-install-prefix>/lib \
+ test.cpp
+
+The option ``-Wl,-rpath,<libcxx-install-prefix>/lib`` adds a runtime library
+search path. Meaning that the systems dynamic linker will look for libc++ in
+``<libcxx-install-prefix>/lib`` whenever the program is run. Alternatively the
+environment variable ``LD_LIBRARY_PATH`` (``DYLD_LIBRARY_PATH`` on OS X) can
+be used to change the dynamic linkers search paths after a program is compiled.
+
+An example of using ``LD_LIBRARY_PATH``:
+
+.. code-block:: bash
+
+ $ clang++ -stdlib=libc++ -nostdinc++ \
+ -I<libcxx-install-prefix>/include/c++/v1
+ -L<libcxx-install-prefix>/lib \
+ test.cpp -o
+ $ ./a.out # Searches for libc++ in the systems library paths.
+ $ export LD_LIBRARY_PATH=<libcxx-install-prefix>/lib
+ $ ./a.out # Searches for libc++ along LD_LIBRARY_PATH
+
+
+Using ``<filesystem>`` and libc++fs
+====================================
+
+Libc++ provides the implementation of the filesystem library in a separate
+library. Users of ``<filesystem>`` and ``<experimental/filesystem>`` are
+required to link ``-lc++fs``.
+
+.. note::
+ Prior to libc++ 7.0, users of ``<experimental/filesystem>`` were required
+ to link libc++experimental.
+
+.. warning::
+ The Filesystem library is still experimental in nature. As such normal
+ guarantees about ABI stability and backwards compatibility do not yet apply
+ to it. In the future, this restriction will be removed.
+
+
+Using libc++experimental and ``<experimental/...>``
+=====================================================
+
+Libc++ provides implementations of experimental technical specifications
+in a separate library, ``libc++experimental.a``. Users of ``<experimental/...>``
+headers may be required to link ``-lc++experimental``.
+
+.. code-block:: bash
+
+ $ clang++ -std=c++14 -stdlib=libc++ test.cpp -lc++experimental
+
+Libc++experimental.a may not always be available, even when libc++ is already
+installed. For information on building libc++experimental from source see
+:ref:`Building Libc++ <build instructions>` and
+:ref:`libc++experimental CMake Options <libc++experimental options>`.
+
+Note that as of libc++ 7.0 using the ``<experimental/filesystem>`` requires linking
+libc++fs instead of libc++experimental.
+
+Also see the `Experimental Library Implementation Status <http://libcxx.llvm.org/ts1z_status.html>`__
+page.
+
+.. warning::
+ Experimental libraries are Experimental.
+ * The contents of the ``<experimental/...>`` headers and ``libc++experimental.a``
+ library will not remain compatible between versions.
+ * No guarantees of API or ABI stability are provided.
+
+Using libc++ on Linux
+=====================
+
+On Linux libc++ can typically be used with only '-stdlib=libc++'. However
+some libc++ installations require the user manually link libc++abi themselves.
+If you are running into linker errors when using libc++ try adding '-lc++abi'
+to the link line. For example:
+
+.. code-block:: bash
+
+ $ clang++ -stdlib=libc++ test.cpp -lc++ -lc++abi -lm -lc -lgcc_s -lgcc
+
+Alternately, you could just add libc++abi to your libraries list, which in
+most situations will give the same result:
+
+.. code-block:: bash
+
+ $ clang++ -stdlib=libc++ test.cpp -lc++abi
+
+
+Using libc++ with GCC
+---------------------
+
+GCC does not provide a way to switch from libstdc++ to libc++. You must manually
+configure the compile and link commands.
+
+In particular you must tell GCC to remove the libstdc++ include directories
+using ``-nostdinc++`` and to not link libstdc++.so using ``-nodefaultlibs``.
+
+Note that ``-nodefaultlibs`` removes all of the standard system libraries and
+not just libstdc++ so they must be manually linked. For example:
+
+.. code-block:: bash
+
+ $ g++ -nostdinc++ -I<libcxx-install-prefix>/include/c++/v1 \
+ test.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc
+
+
+GDB Pretty printers for libc++
+------------------------------
+
+GDB does not support pretty-printing of libc++ symbols by default. Unfortunately
+libc++ does not provide pretty-printers itself. However there are 3rd
+party implementations available and although they are not officially
+supported by libc++ they may be useful to users.
+
+Known 3rd Party Implementations Include:
+
+* `Koutheir's libc++ pretty-printers <https://github.com/koutheir/libcxx-pretty-printers>`_.
+
+
+Libc++ Configuration Macros
+===========================
+
+Libc++ provides a number of configuration macros which can be used to enable
+or disable extended libc++ behavior, including enabling "debug mode" or
+thread safety annotations.
+
+**_LIBCPP_DEBUG**:
+ See :ref:`using-debug-mode` for more information.
+
+**_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS**:
+ This macro is used to enable -Wthread-safety annotations on libc++'s
+ ``std::mutex`` and ``std::lock_guard``. By default these annotations are
+ disabled and must be manually enabled by the user.
+
+**_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS**:
+ This macro is used to disable all visibility annotations inside libc++.
+ Defining this macro and then building libc++ with hidden visibility gives a
+ build of libc++ which does not export any symbols, which can be useful when
+ building statically for inclusion into another library.
+
+**_LIBCPP_DISABLE_EXTERN_TEMPLATE**:
+ This macro is used to disable extern template declarations in the libc++
+ headers. The intended use case is for clients who wish to use the libc++
+ headers without taking a dependency on the libc++ library itself.
+
+**_LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION**:
+ This macro is used to re-enable an extension in `std::tuple` which allowed
+ it to be implicitly constructed from fewer initializers than contained
+ elements. Elements without an initializer are default constructed. For example:
+
+ .. code-block:: cpp
+
+ std::tuple<std::string, int, std::error_code> foo() {
+ return {"hello world", 42}; // default constructs error_code
+ }
+
+
+ Since libc++ 4.0 this extension has been disabled by default. This macro
+ may be defined to re-enable it in order to support existing code that depends
+ on the extension. New use of this extension should be discouraged.
+ See `PR 27374 <http://llvm.org/PR27374>`_ for more information.
+
+ Note: The "reduced-arity-initialization" extension is still offered but only
+ for explicit conversions. Example:
+
+ .. code-block:: cpp
+
+ auto foo() {
+ using Tup = std::tuple<std::string, int, std::error_code>;
+ return Tup{"hello world", 42}; // explicit constructor called. OK.
+ }
+
+**_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS**:
+ This macro disables the additional diagnostics generated by libc++ using the
+ `diagnose_if` attribute. These additional diagnostics include checks for:
+
+ * Giving `set`, `map`, `multiset`, `multimap` and their `unordered_`
+ counterparts a comparator which is not const callable.
+ * Giving an unordered associative container a hasher that is not const
+ callable.
+
+**_LIBCPP_NO_VCRUNTIME**:
+ Microsoft's C and C++ headers are fairly entangled, and some of their C++
+ headers are fairly hard to avoid. In particular, `vcruntime_new.h` gets pulled
+ in from a lot of other headers and provides definitions which clash with
+ libc++ headers, such as `nothrow_t` (note that `nothrow_t` is a struct, so
+ there's no way for libc++ to provide a compatible definition, since you can't
+ have multiple definitions).
+
+ By default, libc++ solves this problem by deferring to Microsoft's vcruntime
+ headers where needed. However, it may be undesirable to depend on vcruntime
+ headers, since they may not always be available in cross-compilation setups,
+ or they may clash with other headers. The `_LIBCPP_NO_VCRUNTIME` macro
+ prevents libc++ from depending on vcruntime headers. Consequently, it also
+ prevents libc++ headers from being interoperable with vcruntime headers (from
+ the aforementioned clashes), so users of this macro are promising to not
+ attempt to combine libc++ headers with the problematic vcruntime headers. This
+ macro also currently prevents certain `operator new`/`operator delete`
+ replacement scenarios from working, e.g. replacing `operator new` and
+ expecting a non-replaced `operator new[]` to call the replaced `operator new`.
+
+**_LIBCPP_ENABLE_NODISCARD**:
+ Allow the library to add ``[[nodiscard]]`` attributes to entities not specified
+ as ``[[nodiscard]]`` by the current language dialect. This includes
+ backporting applications of ``[[nodiscard]]`` from newer dialects and
+ additional extended applications at the discretion of the library. All
+ additional applications of ``[[nodiscard]]`` are disabled by default.
+ See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>` for
+ more information.
+
+**_LIBCPP_DISABLE_NODISCARD_EXT**:
+ This macro prevents the library from applying ``[[nodiscard]]`` to entities
+ purely as an extension. See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>`
+ for more information.
+
+**_LIBCPP_ENABLE_DEPRECATION_WARNINGS**:
+ This macro enables warnings when using deprecated components. For example,
+ when compiling in C++11 mode, using `std::auto_ptr` with the macro defined
+ will trigger a warning saying that `std::auto_ptr` is deprecated. By default,
+ this macro is not defined.
+
+C++17 Specific Configuration Macros
+-----------------------------------
+**_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES**:
+ This macro is used to re-enable all the features removed in C++17. The effect
+ is equivalent to manually defining each macro listed below.
+
+**_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS**:
+ This macro is used to re-enable the `set_unexpected`, `get_unexpected`, and
+ `unexpected` functions, which were removed in C++17.
+
+**_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR**:
+ This macro is used to re-enable `std::auto_ptr` in C++17.
+
+C++2a Specific Configuration Macros:
+------------------------------------
+**_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17**:
+ This macro can be used to disable diagnostics emitted from functions marked
+ ``[[nodiscard]]`` in dialects after C++17. See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>`
+ for more information.
+
+
+Libc++ Extensions
+=================
+
+This section documents various extensions provided by libc++, how they're
+provided, and any information regarding how to use them.
+
+.. _nodiscard extension:
+
+Extended applications of ``[[nodiscard]]``
+------------------------------------------
+
+The ``[[nodiscard]]`` attribute is intended to help users find bugs where
+function return values are ignored when they shouldn't be. After C++17 the
+C++ standard has started to declared such library functions as ``[[nodiscard]]``.
+However, this application is limited and applies only to dialects after C++17.
+Users who want help diagnosing misuses of STL functions may desire a more
+liberal application of ``[[nodiscard]]``.
+
+For this reason libc++ provides an extension that does just that! The
+extension must be enabled by defining ``_LIBCPP_ENABLE_NODISCARD``. The extended
+applications of ``[[nodiscard]]`` takes two forms:
+
+1. Backporting ``[[nodiscard]]`` to entities declared as such by the
+ standard in newer dialects, but not in the present one.
+
+2. Extended applications of ``[[nodiscard]]``, at the libraries discretion,
+ applied to entities never declared as such by the standard.
+
+Users may also opt-out of additional applications ``[[nodiscard]]`` using
+additional macros.
+
+Applications of the first form, which backport ``[[nodiscard]]`` from a newer
+dialect may be disabled using macros specific to the dialect it was added. For
+example ``_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17``.
+
+Applications of the second form, which are pure extensions, may be disabled
+by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``.
+
+
+Entities declared with ``_LIBCPP_NODISCARD_EXT``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This section lists all extended applications of ``[[nodiscard]]`` to entities
+which no dialect declares as such (See the second form described above).
+
+* ``get_temporary_buffer``
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/index.rst.txt
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/index.rst.txt?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/index.rst.txt (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_sources/index.rst.txt Wed Mar 20 02:13:27 2019
@@ -0,0 +1,194 @@
+.. _index:
+
+=============================
+"libc++" C++ Standard Library
+=============================
+
+Overview
+========
+
+libc++ is a new implementation of the C++ standard library, targeting C++11 and
+above.
+
+* Features and Goals
+
+ * Correctness as defined by the C++11 standard.
+ * Fast execution.
+ * Minimal memory use.
+ * Fast compile times.
+ * ABI compatibility with gcc's libstdc++ for some low-level features
+ such as exception objects, rtti and memory allocation.
+ * Extensive unit tests.
+
+* Design and Implementation:
+
+ * Extensive unit tests
+ * Internal linker model can be dumped/read to textual format
+ * Additional linking features can be plugged in as "passes"
+ * OS specific and CPU specific code factored out
+
+
+Getting Started with libc++
+---------------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ ReleaseNotes
+ UsingLibcxx
+ BuildingLibcxx
+ TestingLibcxx
+
+
+.. toctree::
+ :hidden:
+
+ FeatureTestMacroTable
+
+Current Status
+--------------
+
+After its initial introduction, many people have asked "why start a new
+library instead of contributing to an existing library?" (like Apache's
+libstdcxx, GNU's libstdc++, STLport, etc). There are many contributing
+reasons, but some of the major ones are:
+
+* From years of experience (including having implemented the standard
+ library before), we've learned many things about implementing
+ the standard containers which require ABI breakage and fundamental changes
+ to how they are implemented. For example, it is generally accepted that
+ building std::string using the "short string optimization" instead of
+ using Copy On Write (COW) is a superior approach for multicore
+ machines (particularly in C++11, which has rvalue references). Breaking
+ ABI compatibility with old versions of the library was
+ determined to be critical to achieving the performance goals of
+ libc++.
+
+* Mainline libstdc++ has switched to GPL3, a license which the developers
+ of libc++ cannot use. libstdc++ 4.2 (the last GPL2 version) could be
+ independently extended to support C++11, but this would be a fork of the
+ codebase (which is often seen as worse for a project than starting a new
+ independent one). Another problem with libstdc++ is that it is tightly
+ integrated with G++ development, tending to be tied fairly closely to the
+ matching version of G++.
+
+* STLport and the Apache libstdcxx library are two other popular
+ candidates, but both lack C++11 support. Our experience (and the
+ experience of libstdc++ developers) is that adding support for C++11 (in
+ particular rvalue references and move-only types) requires changes to
+ almost every class and function, essentially amounting to a rewrite.
+ Faced with a rewrite, we decided to start from scratch and evaluate every
+ design decision from first principles based on experience.
+ Further, both projects are apparently abandoned: STLport 5.2.1 was
+ released in Oct'08, and STDCXX 4.2.1 in May'08.
+
+Platform and Compiler Support
+-----------------------------
+
+libc++ is known to work on the following platforms, using gcc and
+clang.
+Note that functionality provided by ``<atomic>`` is only functional with clang
+and GCC.
+
+============ ==================== ============ ========================
+OS Arch Compilers ABI Library
+============ ==================== ============ ========================
+Mac OS X i386, x86_64 Clang, GCC libc++abi
+FreeBSD 10+ i386, x86_64, ARM Clang, GCC libcxxrt, libc++abi
+Linux i386, x86_64 Clang, GCC libc++abi
+============ ==================== ============ ========================
+
+The following minimum compiler versions are strongly recommended.
+
+* Clang 3.5 and above
+* GCC 4.7 and above.
+
+Anything older *may* work.
+
+C++ Dialect Support
+---------------------
+
+* C++11 - Complete
+* `C++14 - Complete <http://libcxx.llvm.org/cxx1y_status.html>`__
+* `C++17 - In Progress <http://libcxx.llvm.org/cxx1z_status.html>`__
+* `Post C++14 Technical Specifications - In Progress <http://libcxx.llvm.org/ts1z_status.html>`__
+* :ref:`C++ Feature Test Macro Status <feature-status>`
+
+Notes and Known Issues
+----------------------
+
+This list contains known issues with libc++
+
+* Building libc++ with ``-fno-rtti`` is not supported. However
+ linking against it with ``-fno-rtti`` is supported.
+* On OS X v10.8 and older the CMake option ``-DLIBCXX_LIBCPPABI_VERSION=""``
+ must be used during configuration.
+
+
+A full list of currently open libc++ bugs can be `found here`__.
+
+.. __: https://bugs.llvm.org/buglist.cgi?component=All%20Bugs&product=libc%2B%2B&query_format=advanced&resolution=---&order=changeddate%20DESC%2Cassigned_to%20DESC%2Cbug_status%2Cpriority%2Cbug_id&list_id=74184
+
+Design Documents
+----------------
+
+.. toctree::
+ :maxdepth: 1
+
+ DesignDocs/AvailabilityMarkup
+ DesignDocs/DebugMode
+ DesignDocs/CapturingConfigInfo
+ DesignDocs/ABIVersioning
+ DesignDocs/VisibilityMacros
+ DesignDocs/ThreadingSupportAPI
+ DesignDocs/FileTimeType
+ DesignDocs/FeatureTestMacros
+
+* `<atomic> design <http://libcxx.llvm.org/atomic_design.html>`_
+* `<type_traits> design <http://libcxx.llvm.org/type_traits_design.html>`_
+* `Notes by Marshall Clow`__
+
+.. __: https://cplusplusmusings.wordpress.com/2012/07/05/clang-and-standard-libraries-on-mac-os-x/
+
+Build Bots and Test Coverage
+----------------------------
+
+* `LLVM Buildbot Builders <http://lab.llvm.org:8011/console>`_
+* `Apple Jenkins Builders <http://lab.llvm.org:8080/green/view/Libcxx/>`_
+* `Windows Appveyor Builders <https://ci.appveyor.com/project/llvm-mirror/libcxx>`_
+* `Code Coverage Results <http://efcs.ca/libcxx-coverage>`_
+
+Getting Involved
+================
+
+First please review our `Developer's Policy <http://llvm.org/docs/DeveloperPolicy.html>`__
+and `Getting started with LLVM <http://llvm.org/docs/GettingStarted.html>`__.
+
+**Bug Reports**
+
+If you think you've found a bug in libc++, please report it using
+the `LLVM Bugzilla`_. If you're not sure, you
+can post a message to the `libcxx-dev mailing list`_ or on IRC.
+
+**Patches**
+
+If you want to contribute a patch to libc++, the best place for that is
+`Phabricator <http://llvm.org/docs/Phabricator.html>`_. Please add `libcxx-commits` as a subscriber.
+Also make sure you are subscribed to the `libcxx-commits mailing list <http://lists.llvm.org/mailman/listinfo/libcxx-commits>`_.
+
+**Discussion and Questions**
+
+Send discussions and questions to the
+`libcxx-dev mailing list <http://lists.llvm.org/mailman/listinfo/libcxx-dev>`_.
+
+
+
+Quick Links
+===========
+* `LLVM Homepage <http://llvm.org/>`_
+* `libc++abi Homepage <http://libcxxabi.llvm.org/>`_
+* `LLVM Bugzilla <https://bugs.llvm.org/>`_
+* `libcxx-commits Mailing List`_
+* `libcxx-dev Mailing List`_
+* `Browse libc++ -- SVN <http://llvm.org/svn/llvm-project/libcxx/trunk/>`_
+* `Browse libc++ -- ViewVC <http://llvm.org/viewvc/llvm-project/libcxx/trunk/>`_
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/ajax-loader.gif
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/ajax-loader.gif?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/ajax-loader.gif
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/alert_info_32.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/alert_info_32.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/alert_info_32.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/alert_warning_32.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/alert_warning_32.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/alert_warning_32.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/basic.css
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/basic.css?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_static/basic.css (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_static/basic.css Wed Mar 20 02:13:27 2019
@@ -0,0 +1,665 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+ clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+ width: 100%;
+ font-size: 90%;
+}
+
+div.related h3 {
+ display: none;
+}
+
+div.related ul {
+ margin: 0;
+ padding: 0 0 0 10px;
+ list-style: none;
+}
+
+div.related li {
+ display: inline;
+}
+
+div.related li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+ padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+ float: left;
+ width: 230px;
+ margin-left: -100%;
+ font-size: 90%;
+ word-wrap: break-word;
+ overflow-wrap : break-word;
+}
+
+div.sphinxsidebar ul {
+ list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+ margin-left: 20px;
+ list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+ margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+ float: left;
+ width: 80%;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+ float: left;
+ width: 20%;
+ border-left: none;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+
+img {
+ border: 0;
+ max-width: 100%;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+ margin: 10px 0 0 20px;
+ padding: 0;
+}
+
+ul.search li {
+ padding: 5px 0 5px 20px;
+ background-image: url(file.png);
+ background-repeat: no-repeat;
+ background-position: 0 7px;
+}
+
+ul.search li a {
+ font-weight: bold;
+}
+
+ul.search li div.context {
+ color: #888;
+ margin: 2px 0 0 30px;
+ text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+ font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+ width: 90%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+ width: 100%;
+}
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable ul {
+ margin-top: 0;
+ margin-bottom: 0;
+ list-style-type: none;
+}
+
+table.indextable > tbody > tr > td > ul {
+ padding-left: 0em;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+div.modindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+/* -- domain module index --------------------------------------------------- */
+
+table.modindextable td {
+ padding: 2px;
+ border-collapse: collapse;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+div.body {
+ min-width: 59em;
+ max-width: 70em;
+}
+
+div.body p, div.body dd, div.body li, div.body blockquote {
+ -moz-hyphens: auto;
+ -ms-hyphens: auto;
+ -webkit-hyphens: auto;
+ hyphens: auto;
+}
+
+a.headerlink {
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink,
+caption:hover > a.headerlink,
+p.caption:hover > a.headerlink,
+div.code-block-caption:hover > a.headerlink {
+ visibility: visible;
+}
+
+div.body p.caption {
+ text-align: inherit;
+}
+
+div.body td {
+ text-align: left;
+}
+
+.first {
+ margin-top: 0 !important;
+}
+
+p.rubric {
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+ clear: left;
+ float: left;
+ margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+ clear: right;
+ float: right;
+ margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.align-right {
+ text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+ margin: 0 0 0.5em 1em;
+ border: 1px solid #ddb;
+ padding: 7px 7px 0 7px;
+ background-color: #ffe;
+ width: 40%;
+ float: right;
+}
+
+p.sidebar-title {
+ font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+ border: 1px solid #ccc;
+ padding: 7px 7px 0 7px;
+ margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ padding: 7px;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+ border: 0;
+ border-collapse: collapse;
+}
+
+table.align-center {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table caption span.caption-number {
+ font-style: italic;
+}
+
+table caption span.caption-text {
+}
+
+table.docutils td, table.docutils th {
+ padding: 1px 8px 1px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+table.footnote td, table.footnote th {
+ border: 0 !important;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+table.citation td {
+ border-bottom: none;
+}
+
+/* -- figures --------------------------------------------------------------- */
+
+div.figure {
+ margin: 0.5em;
+ padding: 0.5em;
+}
+
+div.figure p.caption {
+ padding: 0.3em;
+}
+
+div.figure p.caption span.caption-number {
+ font-style: italic;
+}
+
+div.figure p.caption span.caption-text {
+}
+
+/* -- field list styles ----------------------------------------------------- */
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+.field-list ul {
+ margin: 0;
+ padding-left: 1em;
+}
+
+.field-list p {
+ margin: 0;
+}
+
+.field-name {
+ -moz-hyphens: manual;
+ -ms-hyphens: manual;
+ -webkit-hyphens: manual;
+ hyphens: manual;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+ list-style: decimal;
+}
+
+ol.loweralpha {
+ list-style: lower-alpha;
+}
+
+ol.upperalpha {
+ list-style: upper-alpha;
+}
+
+ol.lowerroman {
+ list-style: lower-roman;
+}
+
+ol.upperroman {
+ list-style: upper-roman;
+}
+
+dl {
+ margin-bottom: 15px;
+}
+
+dd p {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+dt:target, span.highlighted {
+ background-color: #fbe54e;
+}
+
+rect.highlighted {
+ fill: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.sig-paren {
+ font-size: larger;
+}
+
+.versionmodified {
+ font-style: italic;
+}
+
+.system-message {
+ background-color: #fda;
+ padding: 5px;
+ border: 3px solid red;
+}
+
+.footnote:target {
+ background-color: #ffa;
+}
+
+.line-block {
+ display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.line-block .line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+ font-family: sans-serif;
+}
+
+.accelerator {
+ text-decoration: underline;
+}
+
+.classifier {
+ font-style: oblique;
+}
+
+abbr, acronym {
+ border-bottom: dotted 1px;
+ cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+ overflow: auto;
+ overflow-y: hidden; /* fixes display issues on Chrome browsers */
+}
+
+span.pre {
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ -webkit-hyphens: none;
+ hyphens: none;
+}
+
+td.linenos pre {
+ padding: 5px 0px;
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ margin-left: 0.5em;
+}
+
+table.highlighttable td {
+ padding: 0 0.5em 0 0.5em;
+}
+
+div.code-block-caption {
+ padding: 2px 5px;
+ font-size: small;
+}
+
+div.code-block-caption code {
+ background-color: transparent;
+}
+
+div.code-block-caption + div > div.highlight > pre {
+ margin-top: 0;
+}
+
+div.code-block-caption span.caption-number {
+ padding: 0.1em 0.3em;
+ font-style: italic;
+}
+
+div.code-block-caption span.caption-text {
+}
+
+div.literal-block-wrapper {
+ padding: 1em 1em 0;
+}
+
+div.literal-block-wrapper div.highlight {
+ margin: 0;
+}
+
+code.descname {
+ background-color: transparent;
+ font-weight: bold;
+ font-size: 1.2em;
+}
+
+code.descclassname {
+ background-color: transparent;
+}
+
+code.xref, a code {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
+ background-color: transparent;
+}
+
+.viewcode-link {
+ float: right;
+}
+
+.viewcode-back {
+ float: right;
+ font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+ margin: -1px -10px;
+ padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+ vertical-align: middle;
+}
+
+div.body div.math p {
+ text-align: center;
+}
+
+span.eqno {
+ float: right;
+}
+
+span.eqno a.headerlink {
+ position: relative;
+ left: 0px;
+ z-index: 1;
+}
+
+div.math:hover a.headerlink {
+ visibility: visible;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+ at media print {
+ div.document,
+ div.documentwrapper,
+ div.bodywrapper {
+ margin: 0 !important;
+ width: 100%;
+ }
+
+ div.sphinxsidebar,
+ div.related,
+ div.footer,
+ #top-link {
+ display: none;
+ }
+}
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/bg-page.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/bg-page.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/bg-page.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/bullet_orange.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/bullet_orange.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/bullet_orange.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/comment-bright.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/comment-bright.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/comment-bright.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/comment-close.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/comment-close.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/comment-close.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/comment.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/comment.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/comment.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/doctools.js
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/doctools.js?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_static/doctools.js (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_static/doctools.js Wed Mar 20 02:13:27 2019
@@ -0,0 +1,313 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for all documentation.
+ *
+ * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+if (!window.console || !console.firebug) {
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
+ "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
+ "profile", "profileEnd"];
+ window.console = {};
+ for (var i = 0; i < names.length; ++i)
+ window.console[names[i]] = function() {};
+}
+ */
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+ return decodeURIComponent(x).replace(/\+/g, ' ');
+};
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+ if (typeof s === 'undefined')
+ s = document.location.search;
+ var parts = s.substr(s.indexOf('?') + 1).split('&');
+ var result = {};
+ for (var i = 0; i < parts.length; i++) {
+ var tmp = parts[i].split('=', 2);
+ var key = jQuery.urldecode(tmp[0]);
+ var value = jQuery.urldecode(tmp[1]);
+ if (key in result)
+ result[key].push(value);
+ else
+ result[key] = [value];
+ }
+ return result;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+ function highlight(node, addItems) {
+ if (node.nodeType === 3) {
+ var val = node.nodeValue;
+ var pos = val.toLowerCase().indexOf(text);
+ if (pos >= 0 &&
+ !jQuery(node.parentNode).hasClass(className) &&
+ !jQuery(node.parentNode).hasClass("nohighlight")) {
+ var span;
+ var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
+ if (isInSVG) {
+ span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
+ } else {
+ span = document.createElement("span");
+ span.className = className;
+ }
+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+ node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+ document.createTextNode(val.substr(pos + text.length)),
+ node.nextSibling));
+ node.nodeValue = val.substr(0, pos);
+ if (isInSVG) {
+ var bbox = span.getBBox();
+ var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+ rect.x.baseVal.value = bbox.x;
+ rect.y.baseVal.value = bbox.y;
+ rect.width.baseVal.value = bbox.width;
+ rect.height.baseVal.value = bbox.height;
+ rect.setAttribute('class', className);
+ var parentOfText = node.parentNode.parentNode;
+ addItems.push({
+ "parent": node.parentNode,
+ "target": rect});
+ }
+ }
+ }
+ else if (!jQuery(node).is("button, select, textarea")) {
+ jQuery.each(node.childNodes, function() {
+ highlight(this, addItems);
+ });
+ }
+ }
+ var addItems = [];
+ var result = this.each(function() {
+ highlight(this, addItems);
+ });
+ for (var i = 0; i < addItems.length; ++i) {
+ jQuery(addItems[i].parent).before(addItems[i].target);
+ }
+ return result;
+};
+
+/*
+ * backward compatibility for jQuery.browser
+ * This will be supported until firefox bug is fixed.
+ */
+if (!jQuery.browser) {
+ jQuery.uaMatch = function(ua) {
+ ua = ua.toLowerCase();
+
+ var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
+ /(webkit)[ \/]([\w.]+)/.exec(ua) ||
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
+ /(msie) ([\w.]+)/.exec(ua) ||
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
+ [];
+
+ return {
+ browser: match[ 1 ] || "",
+ version: match[ 2 ] || "0"
+ };
+ };
+ jQuery.browser = {};
+ jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
+}
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+ init : function() {
+ this.fixFirefoxAnchorBug();
+ this.highlightSearchWords();
+ this.initIndexTable();
+
+ },
+
+ /**
+ * i18n support
+ */
+ TRANSLATIONS : {},
+ PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
+ LOCALE : 'unknown',
+
+ // gettext and ngettext don't access this so that the functions
+ // can safely bound to a different name (_ = Documentation.gettext)
+ gettext : function(string) {
+ var translated = Documentation.TRANSLATIONS[string];
+ if (typeof translated === 'undefined')
+ return string;
+ return (typeof translated === 'string') ? translated : translated[0];
+ },
+
+ ngettext : function(singular, plural, n) {
+ var translated = Documentation.TRANSLATIONS[singular];
+ if (typeof translated === 'undefined')
+ return (n == 1) ? singular : plural;
+ return translated[Documentation.PLURALEXPR(n)];
+ },
+
+ addTranslations : function(catalog) {
+ for (var key in catalog.messages)
+ this.TRANSLATIONS[key] = catalog.messages[key];
+ this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+ this.LOCALE = catalog.locale;
+ },
+
+ /**
+ * add context elements like header anchor links
+ */
+ addContextElements : function() {
+ $('div[id] > :header:first').each(function() {
+ $('<a class="headerlink">\u00B6</a>').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this headline')).
+ appendTo(this);
+ });
+ $('dt[id]').each(function() {
+ $('<a class="headerlink">\u00B6</a>').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this definition')).
+ appendTo(this);
+ });
+ },
+
+ /**
+ * workaround a firefox stupidity
+ * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
+ */
+ fixFirefoxAnchorBug : function() {
+ if (document.location.hash && $.browser.mozilla)
+ window.setTimeout(function() {
+ document.location.href += '';
+ }, 10);
+ },
+
+ /**
+ * highlight the search words provided in the url in the text
+ */
+ highlightSearchWords : function() {
+ var params = $.getQueryParameters();
+ var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+ if (terms.length) {
+ var body = $('div.body');
+ if (!body.length) {
+ body = $('body');
+ }
+ window.setTimeout(function() {
+ $.each(terms, function() {
+ body.highlightText(this.toLowerCase(), 'highlighted');
+ });
+ }, 10);
+ $('<p class="highlight-link"><a href="javascript:Documentation.' +
+ 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
+ .appendTo($('#searchbox'));
+ }
+ },
+
+ /**
+ * init the domain index toggle buttons
+ */
+ initIndexTable : function() {
+ var togglers = $('img.toggler').click(function() {
+ var src = $(this).attr('src');
+ var idnum = $(this).attr('id').substr(7);
+ $('tr.cg-' + idnum).toggle();
+ if (src.substr(-9) === 'minus.png')
+ $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+ else
+ $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+ }).css('display', '');
+ if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
+ togglers.click();
+ }
+ },
+
+ /**
+ * helper function to hide the search marks again
+ */
+ hideSearchWords : function() {
+ $('#searchbox .highlight-link').fadeOut(300);
+ $('span.highlighted').removeClass('highlighted');
+ },
+
+ /**
+ * make the url absolute
+ */
+ makeURL : function(relativeURL) {
+ return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+ },
+
+ /**
+ * get the current relative url
+ */
+ getCurrentURL : function() {
+ var path = document.location.pathname;
+ var parts = path.split(/\//);
+ $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+ if (this === '..')
+ parts.pop();
+ });
+ var url = parts.join('/');
+ return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+ },
+
+ initOnKeyListeners: function() {
+ $(document).keyup(function(event) {
+ var activeElementType = document.activeElement.tagName;
+ // don't navigate when in search box or textarea
+ if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {
+ switch (event.keyCode) {
+ case 37: // left
+ var prevHref = $('link[rel="prev"]').prop('href');
+ if (prevHref) {
+ window.location.href = prevHref;
+ return false;
+ }
+ case 39: // right
+ var nextHref = $('link[rel="next"]').prop('href');
+ if (nextHref) {
+ window.location.href = nextHref;
+ return false;
+ }
+ }
+ }
+ });
+ }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+ Documentation.init();
+});
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/documentation_options.js
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/documentation_options.js?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_static/documentation_options.js (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_static/documentation_options.js Wed Mar 20 02:13:27 2019
@@ -0,0 +1,9 @@
+var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
+ VERSION: '8.0',
+ LANGUAGE: 'None',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true,
+ SOURCELINK_SUFFIX: '.txt'
+};
\ No newline at end of file
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/down-pressed.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/down-pressed.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/down-pressed.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/down.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/down.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/down.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/file.png
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/file.png?rev=356539&view=auto
==============================================================================
Binary file - no diff available.
Propchange: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/file.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: www-releases/trunk/8.0.0/projects/libcxx/docs/_static/haiku.css
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.0/projects/libcxx/docs/_static/haiku.css?rev=356539&view=auto
==============================================================================
--- www-releases/trunk/8.0.0/projects/libcxx/docs/_static/haiku.css (added)
+++ www-releases/trunk/8.0.0/projects/libcxx/docs/_static/haiku.css Wed Mar 20 02:13:27 2019
@@ -0,0 +1,376 @@
+/*
+ * haiku.css_t
+ * ~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- haiku theme.
+ *
+ * Adapted from http://haiku-os.org/docs/Haiku-doc.css.
+ * Original copyright message:
+ *
+ * Copyright 2008-2009, Haiku. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ * Francois Revol <revol at free.fr>
+ * Stephan Assmus <superstippi at gmx.de>
+ * Braden Ewing <brewin at gmail.com>
+ * Humdinger <humdingerb at gmail.com>
+ *
+ * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+ at import url("basic.css");
+
+html {
+ margin: 0px;
+ padding: 0px;
+ background: #FFF url(bg-page.png) top left repeat-x;
+}
+
+body {
+ line-height: 1.5;
+ margin: auto;
+ padding: 0px;
+ font-family: "DejaVu Sans", Arial, Helvetica, sans-serif;
+ min-width: 59em;
+ max-width: 70em;
+ color: #333333;
+}
+
+div.footer {
+ padding: 8px;
+ font-size: 11px;
+ text-align: center;
+ letter-spacing: 0.5px;
+}
+
+/* link colors and text decoration */
+
+a:link {
+ font-weight: bold;
+ text-decoration: none;
+ color: #dc3c01;
+}
+
+a:visited {
+ font-weight: bold;
+ text-decoration: none;
+ color: #892601;
+}
+
+a:hover, a:active {
+ text-decoration: underline;
+ color: #ff4500;
+}
+
+/* Some headers act as anchors, don't give them a hover effect */
+
+h1 a:hover, a:active {
+ text-decoration: none;
+ color: #0c3762;
+}
+
+h2 a:hover, a:active {
+ text-decoration: none;
+ color: #0c3762;
+}
+
+h3 a:hover, a:active {
+ text-decoration: none;
+ color: #0c3762;
+}
+
+h4 a:hover, a:active {
+ text-decoration: none;
+ color: #0c3762;
+}
+
+a.headerlink {
+ color: #a7ce38;
+ padding-left: 5px;
+}
+
+a.headerlink:hover {
+ color: #a7ce38;
+}
+
+/* basic text elements */
+
+div.content {
+ margin-top: 20px;
+ margin-left: 40px;
+ margin-right: 40px;
+ margin-bottom: 50px;
+ font-size: 0.9em;
+}
+
+/* heading and navigation */
+
+div.header {
+ position: relative;
+ left: 0px;
+ top: 0px;
+ height: 85px;
+ /* background: #eeeeee; */
+ padding: 0 40px;
+}
+div.header h1 {
+ font-size: 1.6em;
+ font-weight: normal;
+ letter-spacing: 1px;
+ color: #0c3762;
+ border: 0;
+ margin: 0;
+ padding-top: 15px;
+}
+div.header h1 a {
+ font-weight: normal;
+ color: #0c3762;
+}
+div.header h2 {
+ font-size: 1.3em;
+ font-weight: normal;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ color: #aaa;
+ border: 0;
+ margin-top: -3px;
+ padding: 0;
+}
+
+div.header img.rightlogo {
+ float: right;
+}
+
+
+div.title {
+ font-size: 1.3em;
+ font-weight: bold;
+ color: #0c3762;
+ border-bottom: dotted thin #e0e0e0;
+ margin-bottom: 25px;
+}
+div.topnav {
+ /* background: #e0e0e0; */
+}
+div.topnav p {
+ margin-top: 0;
+ margin-left: 40px;
+ margin-right: 40px;
+ margin-bottom: 0px;
+ text-align: right;
+ font-size: 0.8em;
+}
+div.bottomnav {
+ background: #eeeeee;
+}
+div.bottomnav p {
+ margin-right: 40px;
+ text-align: right;
+ font-size: 0.8em;
+}
+
+a.uplink {
+ font-weight: normal;
+}
+
+
+/* contents box */
+
+table.index {
+ margin: 0px 0px 30px 30px;
+ padding: 1px;
+ border-width: 1px;
+ border-style: dotted;
+ border-color: #e0e0e0;
+}
+table.index tr.heading {
+ background-color: #e0e0e0;
+ text-align: center;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+table.index tr.index {
+ background-color: #eeeeee;
+}
+table.index td {
+ padding: 5px 20px;
+}
+
+table.index a:link, table.index a:visited {
+ font-weight: normal;
+ text-decoration: none;
+ color: #dc3c01;
+}
+table.index a:hover, table.index a:active {
+ text-decoration: underline;
+ color: #ff4500;
+}
+
+
+/* Haiku User Guide styles and layout */
+
+/* Rounded corner boxes */
+/* Common declarations */
+div.admonition {
+ -webkit-border-radius: 10px;
+ -khtml-border-radius: 10px;
+ -moz-border-radius: 10px;
+ border-radius: 10px;
+ border-style: dotted;
+ border-width: thin;
+ border-color: #dcdcdc;
+ padding: 10px 15px 10px 15px;
+ margin-bottom: 15px;
+ margin-top: 15px;
+}
+div.note {
+ padding: 10px 15px 10px 80px;
+ background: #e4ffde url(alert_info_32.png) 15px 15px no-repeat;
+ min-height: 42px;
+}
+div.warning {
+ padding: 10px 15px 10px 80px;
+ background: #fffbc6 url(alert_warning_32.png) 15px 15px no-repeat;
+ min-height: 42px;
+}
+div.seealso {
+ background: #e4ffde;
+}
+
+/* More layout and styles */
+h1 {
+ font-size: 1.3em;
+ font-weight: bold;
+ color: #0c3762;
+ border-bottom: dotted thin #e0e0e0;
+ margin-top: 30px;
+}
+
+h2 {
+ font-size: 1.2em;
+ font-weight: normal;
+ color: #0c3762;
+ border-bottom: dotted thin #e0e0e0;
+ margin-top: 30px;
+}
+
+h3 {
+ font-size: 1.1em;
+ font-weight: normal;
+ color: #0c3762;
+ margin-top: 30px;
+}
+
+h4 {
+ font-size: 1.0em;
+ font-weight: normal;
+ color: #0c3762;
+ margin-top: 30px;
+}
+
+p {
+ text-align: justify;
+}
+
+p.last {
+ margin-bottom: 0;
+}
+
+ol {
+ padding-left: 20px;
+}
+
+ul {
+ padding-left: 5px;
+ margin-top: 3px;
+}
+
+li {
+ line-height: 1.3;
+}
+
+div.content ul > li {
+ -moz-background-clip:border;
+ -moz-background-inline-policy:continuous;
+ -moz-background-origin:padding;
+ background: transparent url(bullet_orange.png) no-repeat scroll left 0.45em;
+ list-style-image: none;
+ list-style-type: none;
+ padding: 0 0 0 1.666em;
+ margin-bottom: 3px;
+}
+
+td {
+ vertical-align: top;
+}
+
+code {
+ background-color: #e2e2e2;
+ font-size: 1.0em;
+ font-family: monospace;
+}
+
+pre {
+ border-color: #0c3762;
+ border-style: dotted;
+ border-width: thin;
+ margin: 0 0 12px 0;
+ padding: 0.8em;
+ background-color: #f0f0f0;
+}
+
+hr {
+ border-top: 1px solid #ccc;
+ border-bottom: 0;
+ border-right: 0;
+ border-left: 0;
+ margin-bottom: 10px;
+ margin-top: 20px;
+}
+
+/* printer only pretty stuff */
+ at media print {
+ .noprint {
+ display: none;
+ }
+ /* for acronyms we want their definitions inlined at print time */
+ acronym[title]:after {
+ font-size: small;
+ content: " (" attr(title) ")";
+ font-style: italic;
+ }
+ /* and not have mozilla dotted underline */
+ acronym {
+ border: none;
+ }
+ div.topnav, div.bottomnav, div.header, table.index {
+ display: none;
+ }
+ div.content {
+ margin: 0px;
+ padding: 0px;
+ }
+ html {
+ background: #FFF;
+ }
+}
+
+.viewcode-back {
+ font-family: "DejaVu Sans", Arial, Helvetica, sans-serif;
+}
+
+div.viewcode-block:target {
+ background-color: #f4debf;
+ border-top: 1px solid #ac9;
+ border-bottom: 1px solid #ac9;
+ margin: -1px -10px;
+ padding: 0 12px;
+}
+
+/* math display */
+div.math p {
+ text-align: center;
+}
\ No newline at end of file
More information about the llvm-commits
mailing list