clangd
clangd copied to clipboard
Unexpected forward declare on defining pointer/reference
Have a header:
#pragma once
namespace NS
{
struct MyStructToFWD {};
}
Have another header:
#pragma once
namespace NS
{
struct NewStruct
{
MyStruct^
};
}
Do autocomplete at the ^. The intention here is to write the following:
#pragma once
namespace NS
{
struct NewStruct
{
MyStructToFWD *str;
};
}
Result, the auto-completion causes the first header to be included. I would expect the include cleaner to indicate this include is unneeded, though it does not.
Expected result: Whenever auto-completing on (class|struct) Something^, only the name should be added, not the include.
System information
Output of clangd --version: 19
Editor/LSP plugin: VS Code
Operating system: Windows
This has a similar challenge to https://github.com/clangd/clangd/issues/639: the user might be declaring a variable of pointer/reference type, but they might be declaring a variable of value type as well, and we don't know at the point at which completion is invoked. In the latter scenario, we'd end up with an error diagnostic due to the type being incomplete.
I guess this is the difference between standard C (also valid in C++) and standard C++. For C, you have to write struct S s; in order to use S, while C++ only needs S s;. The situations in C++ where you need the include after writing struct/class seem quite limited to me. (I've only seen it once due to a C header)
I'm still processing this issue. What I'm currently thinking of is: (ignoring feasibility)
- maybe includes shouldn't be added as part of the auto-complete. Instead they can be added on
:and;when the context is clear - we might need an explicit action to add an include for a symbol
For C, you have to write
struct S s;in order to use S, while C++ only needsS s;.
I understand that, but I'm not sure how it's relevant to the scenario at issue here:
#pragma once namespace NS { struct NewStruct { MyStruct^ }; }Do autocomplete at the ^.
Here, you might be writing MyStruct* field; or MyStruct field;. Neither involve the struct keyword, but one of them requires the include.