import{_ as s,c as i,o as a,ae as n}from"./chunks/framework.l7bN90nj.js";const k=JSON.parse('{"title":"Header Context","description":"","frontmatter":{},"headers":[],"relativePath":"design/header-context.md","filePath":"en/design/header-context.md"}'),t={name:"design/header-context.md"};function o(l,e,p,c,d,h){return a(),i("div",null,[...e[0]||(e[0]=[n(`<h1 id="header-context" tabindex="-1">Header Context <a class="header-anchor" href="#header-context" aria-label="Permalink to &quot;Header Context&quot;">​</a></h1><p>For clangd to work properly, users often need to provide a <code>compile_commands.json</code> file (hereinafter referred to as CDB file). The basic compilation unit of C++&#39;s traditional compilation model is a source file (e.g., <code>.c</code> and <code>.cpp</code> files), where <code>#include</code> simply pastes and copies the content of header files to the corresponding position in the source file. The aforementioned CDB file stores the compilation commands corresponding to each source file. When you open a source file, clangd will use its corresponding compilation command in the CDB to compile this file.</p><p>Naturally, there&#39;s a question: if the CDB file only contains compilation commands for source files and not header files, how does clangd handle header files? clangd treats header files as source files, and then, according to some rules, such as using the compilation command of the source file in the corresponding directory as the compilation command for that header file. This model is simple and effective, but it ignores some situations.</p><p>Since header files are part of source files, there will be cases where their content differs depending on the content that precedes them in the source file. For example:</p><div class="language-cpp vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">cpp</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// a.h</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#ifdef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> TEST</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">struct</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> X</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { ... };</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#else</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">struct</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Y</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { ... };</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#endif</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// b.cpp</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> TEST</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;a.h&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// c.cpp</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;a.h&quot;</span></span></code></pre></div><p>Obviously, <code>a.h</code> has different states in <code>b.cpp</code> and <code>c.cpp</code> - one defines <code>X</code> and the other defines <code>Y</code>. If we simply treat <code>a.h</code> as a source file, then only <code>Y</code> can be seen.</p><p>A more extreme case is non-self-contained header files, for example:</p><div class="language-cpp vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">cpp</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// a.h</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">struct</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Y</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">    X x;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">};</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// b.cpp</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">struct</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> X</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {};</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;a.h&quot;</span></span></code></pre></div><p><code>a.h</code> itself cannot be compiled, but when embedded in <code>b.cpp</code>, it compiles normally. In this case, clangd will report an error in <code>a.h</code>, unable to find the definition of <code>X</code>. Obviously, this is because it treats <code>a.h</code> as an independent source file. There are many such header files in libstdc++ code, and some popular C++ header-only libraries also have such code, which clangd currently cannot handle.</p><p>clice will support <strong>header context</strong>, supporting automatic and user-initiated switching of header file states, and of course will also support non-self-contained header files. We want to achieve the following effect, using the first piece of code as an example. When you jump from <code>b.cpp</code> to <code>a.h</code>, use <code>b.cpp</code> as the context for <code>a.h</code>. Similarly, when you jump from <code>c.cpp</code> to <code>a.h</code>, use <code>c.cpp</code> as the context for <code>a.h</code>.</p>`,10)])])}const f=s(t,[["render",o]]);export{k as __pageData,f as default};
