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

    <tr>
        <th>Summary</th>
        <td>
            [[msvc::constexpr]] constructors are not supported
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    `[[msvc::constexpr]]` support was added in #71300.
However, it was lacking support of `[[msvc::constexpr]]` constructors,
because I was not sure how to support them with reasonable changes.

Consider the following test case (from `clang/test/SemaCXX/ms-constexpr.cpp`):

```cpp
struct S2 {
 [[msvc::constexpr]] S2() {}
    [[msvc::constexpr]] bool value() { return true; }
    static constexpr bool check() { [[msvc::constexpr]] return S2{}.value(); }
};
static_assert(S2::check());
```

It's a valid code for MSVC: https://godbolt.org/z/znnaonEhM
However supporting this code in Clang seemed to be difficult:

`S2` fails checks of "literal type" in this callstack:
1. [clang::CXXRecordDecl::isLiteral](https://github.com/llvm/llvm-project/blob/d27897ade53ab6f983e442f24880260eed26238a/clang/include/clang/AST/DeclCXX.h#L1425-L1451)
2. [clang::Type::isLiteralType](https://github.com/llvm/llvm-project/blob/d27897ade53ab6f983e442f24880260eed26238a/clang/lib/AST/Type.cpp#L2795)
3. [CheckLiteralType](https://github.com/llvm/llvm-project/blob/d27897ade53ab6f983e442f24880260eed26238a/clang/lib/AST/ExprConstant.cpp#L2392-L2397)

We have information about `CanEvalMSConstexpr` only in `CheckLiteralType`. Two obvious ugly solutions were:
1. Copy all checks from `clang::CXXRecordDecl::isLiteral` to `CheckLiteralType` - two places shall be maintained.
2. Propagate `CanEvalMSConstexpr` down to `clang::CXXRecordDecl::isLiteral`. We could add bool args for both `clang::CXXRecordDecl::isLiteral` and `clang::Type::isLiteralType`. But I don't think it's reasonable for supporting rare vendor-specific attribute. Or is it?

---

I found another variant of the implementation: let `ASTContext` know about `CanEvalMSConstexpr`, and pass `const ASTContext&` to `clang::CXXRecordDecl::isLiteral`.

In long term, if clang ever switches to new constexpr analyzer (`-fexperimental-new-constant-interpreter`), then (as far as I understand) `CanEvalMSConstexpr` could be moved from `ASTContext` to `clang::interp::Context`. Then `clang::CXXRecordDecl::isLiteral` could accept this context instead of `ASTContext`.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMVk9v47YT_TT0ZWBBoixLPviQOGv8AmTxK9ZBN7eCEkcWG5oUSMpO9tMXQzmOnW2azaUooCgGKb55M3zzR3ivtgZxyYprVtxMxBA665bfbn3z7bYPk9rK5yWbp3H7euf3DcuvWH7VWOMDPvWOFTf0zFPwQ99bF-AgPAgpUYIywHheZnmaJiy9YenV_-wB9-gYX4Eav9SieVRmezptW_g1c3HJDU2wzjO-GvFrbMTgEW4jtrEB_OAQOnuAYE82Qoc7OKjQgUPhrRG1Rmg6Ybboj0TH98oaryQ6OgGt1doeiGtAH6ARHoHxqnV2R5QbLcyW8TVtMr7e4E6sHh4YX-_89EQ_afqe3OML8uvMEi3Ghz6IK6NzsOHAyutxCT4IC2w44xXji3ikvDmeAvjwYG2thr3QA74CgMMwOAPBDcjya7gA9EEE1cAJZ0RoOmwezxA-Mnu0sOEj3-SMwYVF-pFfv8SFLP8hvEcXGK82_Ij9ans8_iaw59G-DYyXHgS5rCQ0VtL1Ovi6-X3F8ivoQug9wfI14-utlbXVIbGO7vcH_RkjrPnSfb1Q9Yu-okQ65UdcZWBF0gCPuENJOqwRpGpb1Qw6_KyDDSd5t0JpPwbUx6TgXKuATmgIzz0yzgl5NCO09kE0jyesLKHQj4qMwVk9PHzDxjp5g40el5S_G_HoLnj1xmUVuqFOGrtjfK31_uXftHf2T2xI4LW2NeNryctqUQqJRS7qebuocpzNeMtnVZXyeYoo-ZznlWB8_ZIhyjR6kHi2crW5Z3xN3FYPD0nHeH6XzXgxvctmRUa3Gb3ib726p0BcOhOX_m2HtKpPThCBmOU8v-PlojixzyP7FV3of4Xrl6feUYkLwoQT53zBp_QuT8zH93eETuxJz611OxGUNSBqOwQqfithvuyF_rpZnTJ8noI1-jk2gXn6k9_zNIH7gwVb75UdPAxb_Qze6oGAPRzQ4bmcV7Z_BqH1S0ZcVt2PNT5PKfH-nghMIRws9Fo06MF3ZKZG2AllglAGZXLS32_O9mIrAr7vtLQHc7T16-QS-I7Q2EFLap1jMRVu62NVqm3oPumrMPLNifdyhWxfDwFuQVrDeEndUZlHUGOJPGuQROWswjnhEPZopHVT32OjWtWACMGpegiYwP8dKE8w-fpcRtPp9KISQ2sHI0EYGzp0sBdOCRPHAOq5atdr3KEJUW9UmjVGwV1t7lfWBHwK5O6jsYcPxEgjB0WlF97H0NAenMHw-atIPnFxF84Y0DbOB24XR5wWIhKM3eGgQtOhJxsGD2e9Uxihn3-go3GCzdNpi089OhX91lODh3GAECZMlQnoeocB3XGO4CuKFE1alfDQCgfCwy0MRqKjMzI24_fUOmqO1G73KE9pdRnen4IysjgG6PRdAveRyKeUehR902AfXrpmBARFNIU8ToQXjJKJXOZykS_EBJfZfLFYpBkv-KRb1tksE6KtsK0WXBaiyEqsi2pWFvOiTNtsopY85XmWZXlWzcqcJ9ksT3NeVIXks7KqkM1S3AmlEyq51PMnyvsBlyXPZouJFjVqH6dlzukW4ybjnIZnt4xluh62ns1SrXzwryhBBX0cs_9hIjqfaoEybJxhY9ahnAxOLz_dLCJFz_g6uvBXAAAA__9CJruZ">