clangd broke because it can't look through symlinks. compile_commands manipulation does not fix it, clangd configuration does not fix it, a vfs overlay does not fix it, and while a combination of those can fix it with a bind mount in place that's just too cursed to even consider clangd bug: https://github.com/llvm/llvm-project/issues/116877 Change-Id: I8e3e8489548eb3a7aa65ac9d12a5ec8abf814aec
67 lines
2.2 KiB
C++
67 lines
2.2 KiB
C++
#pragma once
|
|
///@file
|
|
|
|
#include <tao/pegtl.hpp>
|
|
|
|
namespace nix::parser {
|
|
|
|
// modified copy of change_state, as the manual suggest for more involved
|
|
// state manipulation. we want to change only the first state parameter,
|
|
// and we care about the *initial* position of a rule application (not the
|
|
// past-the-end position as pegtl change_state provides)
|
|
template<typename NewState>
|
|
struct change_head : tao::pegtl::maybe_nothing
|
|
{
|
|
template<
|
|
typename Rule,
|
|
tao::pegtl::apply_mode A,
|
|
tao::pegtl::rewind_mode M,
|
|
template<typename...> class Action,
|
|
template<typename...> class Control,
|
|
typename ParseInput,
|
|
typename State,
|
|
typename... States
|
|
>
|
|
[[nodiscard]] static bool match(ParseInput & in, State && st, States &&... sts)
|
|
{
|
|
const auto begin = in.iterator();
|
|
|
|
if constexpr (std::is_constructible_v<NewState, State, States...>) {
|
|
NewState s(st, sts...);
|
|
if (tao::pegtl::match<Rule, A, M, Action, Control>(in, s, sts...)) {
|
|
if constexpr (A == tao::pegtl::apply_mode::action) {
|
|
_success<Action<Rule>>(0, begin, in, s, st, sts...);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
} else if constexpr (std::is_default_constructible_v<NewState>) {
|
|
NewState s;
|
|
if (tao::pegtl::match<Rule, A, M, Action, Control>(in, s, sts...)) {
|
|
if constexpr (A == tao::pegtl::apply_mode::action) {
|
|
_success<Action<Rule>>(0, begin, in, s, st, sts...);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
} else {
|
|
static_assert(decltype(sizeof(NewState))(), "unable to instantiate new state");
|
|
}
|
|
}
|
|
|
|
template<typename Target, typename ParseInput, typename... S>
|
|
static void _success(void *, auto & begin, ParseInput & in, S & ... sts)
|
|
{
|
|
const typename ParseInput::action_t at(begin, in);
|
|
Target::success(at, sts...);
|
|
}
|
|
|
|
template<typename Target, typename... S>
|
|
static void _success(decltype(Target::success0(std::declval<S &>()...), 0), auto &, auto &, S & ... sts)
|
|
{
|
|
Target::success0(sts...);
|
|
}
|
|
};
|
|
|
|
}
|