<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/70585>70585</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [C++20] [Modules] Clang didn't generate the virtual table to the unit containing the key function 
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:modules
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
            ChuanqiXu9
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          ChuanqiXu9
      </td>
    </tr>
</table>

<pre>
    Reproducer:

```
// layer1.cppm
export module foo:layer1;
struct Fruit {
    virtual ~Fruit() = default;
    virtual void eval() = 0;
};
struct Banana : public Fruit {
    Banana() {}
    void eval() override;
};

// layer2.cppm
export module foo:layer2;
import :layer1;
export void layer2_fun() {
    Banana *b = new Banana();
 b->eval();
}
void Banana::eval() {
}
```

Compiler layer2.cppm with:

```
clang++ -std=c++20 layer1.cppm --precompile -o foo-layer1.pcm
clang++ -std=c++20 layer2.cppm -fprebuilt-module-path=. -S -emit-llvm -o -
```

Then we can't see anything about the definition of virtual table. This violates the [itanium ABI 5.2.3](https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vague-vtable):

> The virtual table for a class is emitted in the same object containing the definition of its key function, i.e. the first non-pure virtual function that is not inline at the point of class definition. 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVMuO4zYQ_Br60pAgk5YfBx38WAM55JLMIbeAlFpWJxSp8OGZueTbF5Q048csFgsMNFar2FVdXaD0ni4GsWLlgXF-7KI0_9Ffccc4Z-VpIWPorKtu9YWyzXv1Bw7ONrFGx8SeFSdWfDzXxfw3vfIz42fQ8h3dMq-HoZ_q-DZYF6C3TdQIrbVM7CcQE4cJ4oOLdYCzixSAbeYqAMCVXIhSw__jN8a3jO-AiRM02Mqow2eLe_DVUgN4lfoOX3wi2eb0THyQRhoJTOxhiEpT_SMpE-ij5eaQ-tyonyjtFZ2jBn_I-tUv_it-8c8G1I-Qr0bOZ0c105m_22juND9NA4zv1eiPwdeHCW_GqoyJb7fRHiYaf4xs81mxZ2J_b_3mGf2cmvF5tP1AGt29G_BKoft55GotzYXxA-MHyHxomDjV0ysv7oMIWTY4rCcSyGxyNZu_D3X_q81mXVk7OFSRdMimJWWDTEpPOWR_QoY9hUzra5-Isp8M_dKhgVeEWhrGNwE8IkjzHjoyF5DKxgChw5R0MhTIGrDtZ8aDVBpzeOnIw5WslgH9CGflgYI0FHvYH36DMue5YOWJ8W0XwuCToWPwZlBWv71lUlF-odBFlZNl_DzXGD-nL13oNePiKi8Rs-tIPObgcTPiG7x0-KgPWutAQq2l90AekjUBGyAzSvWyR7DqH6wD1NYESSaN_nVoCh7-xXdoo6lTjfEjUI75CG3J-QDGmmyI7ibgAwuhkyGRGxuAjCaDICdnB0smpP6TwBtnDoumEs1O7OQCq-V6ty3Xq6UQi67CulB1yxu5Wqkd8l2j2rKRpVLleqvEtllQxQsulgXfFRvOlyLftEVRlGq9bXC7qzeKrQrsJek8ZSS37rIg7yNWm6LclgstFWo_X9FTJMV-ipmf72lXpZOZihfPVoUmH_ytV6Cgxxv--JFdVp5SKH6fe5QnOKa20FAz5e6CBp0MOHryuL9gx2I09GVD9_uARXS6eszXnKfa9oyfk7z5XzY4mzaeIpjm9oyfx9G_BwAA__-4qgaO">