Intellisense index rebuild omits some include directories

I have this project that used to work fine in vscode at some point

Now when I open it in vscode it throws lots of squigglies caused by intellisense not able to find symbols.
Interestingly navigation still works and it can find declaration just fine. But autocomplete doesn’t work and I have lots of linter errors (squigglies). Microsoft eh?

But platformio is also to blame because when I look into c_cpp_properties.json file it is missing some directories.
For instance “includePath” list has
C:/Users/user/.platformio/packages/framework-arduinoststm32-maple/STM32F1/system/libmaple/stm32f1/include
but doesn’t have
C:/Users/user/.platformio/packages/framework-arduinoststm32-maple/STM32F1/system/libmaple/stm32f1/include/series
and if I add it manually then after a restart or intellisense db reset and some cajoling intellisense finally recognizes GPIOB->regs->CRL.

But if I run platformio rebuild index it removes the folder and intellisense is not happy again
image

Microsoft docs state that includePath is NOT recursive while browse IS which explains how declaration can be found and navigation works but autocomplete doesnt work and errors still pop up.

What can I do about this to fix it permanently? Is this a bug in platformio include index generator?

The c_cpp_properties.json file is not to be edited directly since it gets generated by PlatformIO based on its configuration (platformio.ini plus build_flags in there) and the builder script for the specific framework. It is expected that manual user changes are lost on a rebuild.

The builder script is invoked in

which then invokes e.g. C:\Users\<user>\.platformio\packages\framework-arduinoststm32-maple\tools\platformio-build-stm32f1.py.

The script adds the following paths the build system (which later end up in the c_cpp_properties.json, too)

env.Append(
    ASFLAGS=env.get("CCFLAGS", [])[:],

    CPPPATH=[
        join(FRAMEWORK_DIR, "cores", "maple"),
        join(FRAMEWORK_DIR, "system", "libmaple"),
        join(FRAMEWORK_DIR, "system", "libmaple", "include"),
        join(FRAMEWORK_DIR, "system", "libmaple", "stm32f1", "include"),
        join(FRAMEWORK_DIR, "system", "libmaple", "usb", "stm32f1"),
        join(FRAMEWORK_DIR, "system", "libmaple", "usb", "usb_lib"),
    ],

so system/libmaple/stm32f1/include/series is not in those paths.

Now it’s the question whether it should be. And to that, the answer should be no, since the core itself specifies

So it itself doesn’t add the series subfolder to the include list.

Please check that your code does as well not compile in the Arduino IDE with the Maple core, as I would expect.

Then you can either:

  • add #include <series/gpio.h at the top of your code yourself
  • add a build_flags = -I $PROJECT_PACKAGES_DIR/framework-arduinoststm32-maple/STM32F1/system/libmaple/stm32f1/include/series to the platformio.ini and intellisense rebuild so that it’s now in the path, then #include <gpio.h> should work
1 Like

I understand, I only manually edited it to verify that it’s contents was the issue.

It does compile. On travis and locally.

The line you pointed out doesn’t have series explicitly mentioned.

I did some digging in the maple core and these lines look suspicious
https://github.com/rogerclarkmelbourne/Arduino_STM32/blame/master/STM32F1/system/libmaple/include/libmaple/gpio.h#L45-L46
If I replace that include with
#include <series/gpio.h>
then it intellisense picks it up as expected.
Do you think this is the smoking gun? If so I’ll report it there but would appreciate

  1. An explanation of why that breaks intellisense
  2. If I can do anything until the fix is upstream. Having a local change to the core being wiped out on every update is less than ideal.

edit: just noticed your suggestion to add #include <series/gpio.h> myself. I guess that confirms my suspicion that it’s the issue.

My bad, the original line should say, the arduino core does not contain the -I flag for including that directory.

And ehm… that’s interesting. So maybe it’s a quirk of the Microsoft IntelliSense.

Aha. So I suspect that #include <gpio.h>, due to there being sadly 2 actual gpio.h files

  • C:\Users\<user>\.platformio\packages\framework-arduinoststm32-maple\STM32F1\system\libmaple\include\libmaple\gpio.h
  • C:\Users\<user>\.platformio\packages\framework-arduinoststm32-maple\STM32F1\system\libmaple\stm32f1\include\series

it picks up the wrong file in the Microsoft IntelliSense (because maybe the whole framework is in the browse attribute of the c_cpp_properties.json and it searches subfolders) but the right file during compilation, otherwise it wouldn’t build. And that’s also why developers should not have the same filename in a project twice… >.<

So this is an IntelliSense only issue that should be worked-around by that

1 Like

Upon even further inspection: ultimately it’s intellisense issue.

Here is what I am observing. Let’s call libmaple\include\libmaple\gpio.h GPIO1 and libmaple\stm32f1\include\series\gpio.h GPIO2.

No matter how exactly GPIO2 is included in GPIO1, either using
#include <series/gpio.h> or #include “stm32f1/include/series/gpio.h”`

  1. After I load vscode intellisense doesn’t recognize definitions in GPIO2.
  2. If I open GPIO1 in vscode editor and let intellisense parse it, then it recognizes definitions in GPIO2. I can recognize when file gets parsed by seeing code portions wrapped in #ifdef’s that are not defined get dimmed out.
  3. Then if I open GPIO2 in vscode editor and let intellisense parse it … drumroll… it stops recognizing definitions in GPIO2.

What? ¯\_(ツ)_/¯

After that there is no way to get it to recognize those definitions until I reload window and open GPIO1 again.

So the issue is not really in the maple core code, it’s include while weird is legit since /.platformio/packages/framework-arduinoststm32-maple/STM32F1/system/libmaple is in platform include list so stm32f1/include/series/gpio.h should get picked up.

The IntelliSense works in mysterious ways…

This could be posted as an issue at Issues · microsoft/vscode-cpptools · GitHub I think?