Page 1 of 1

How to configure clangd to not assume it knows where functions are defined

Posted: Tue Nov 03, 2026 2:00 am
by MarkD
Hi,
I posted this to reddit /cpp_questions, but nobody had a solution. Most did not understand freestanding implementations. I was wondering if anyone here has a solution.

I use VS Code on Ubuntu on Windows (WSL). I program in C++ and recently switched from Intellisense to clangd and like many of the improvements. However, I'm having an issue with how clangd assumes functions like printf come from <cstdio>. This is an issue as I'm building a hobby OS and need to provide my own versions of common functions like printf.

I'm using the g++ 15.2.0 cross compiler built with --disable-hosted-libstdcxx. I use -ffreestanding -nostdlib -fno-builtin. I provide my own implementation of common functions like printf. I have installed clangd-23 and have created (using bear) a compile_commands.json file. When I mouse over a call to printf in my code, I get a popup showing that printf is provided by <cstdio> which I never #include and doesn't exist. Also it flags the header file "system/stdout.hpp" which defines my printf as unused. How do I configure clangd and VS Code to correctly identify my header file as the source of my printf?

My .clangd contains

Code: Select all

CompileFlags:
  Add:
    - "-ffreestanding"
    - "-nostdlib"
    - "-fno-builtin"
    - "-D__float128=long double" # Otherwise clangd gets error in <stddef.h>
    - "-D__SIZEOF_FLOAT128__=16" # when BuiltinHeaders: QueryDriver is specified
                                 # Sigh. This breaks <limits>
  BuiltinHeaders: QueryDriver
My settings.json contains

Code: Select all

    "C_Cpp.intelliSenseEngine": "disabled",
    "clangd.path": "/usr/bin/clangd-23",
    "clangd.arguments": [
        "--background-index",
        "--compile-commands-dir=${workspaceFolder}/build",
        "--query-driver=/home/mark/dev/toolchain/i686-elf-15.2.0/bin/i686-elf-g++",
    ]
Thanks.