[Lldb-commits] [lldb] [LLDB][NFC] Move CPlusPlusLanguage methods used in Core/Module.cpp to a separated module to break lldb-server dependencies (PR #132274)

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Mon Mar 31 03:27:53 PDT 2025


labath wrote:

> > Global variables are [banned](https://llvm.org/docs/CodingStandards.html#do-not-use-static-constructors) by the coding standards, but I wouldn't be surprised if there were still some around that cause this.
> 
> TypeSystemClang.cpp contains global `char TypeSystemClang::ID;` and its constructor is GC root.

Constructor of what? The `ID` static member? It's initialized to zero (by the linker) so it does not have one. `TypeSystemClang` has a constructor, but it's not a GC root, unless someone actually declares a global variable of that type (and I really hope that's not the case).

Here's a test case that shows that a static member does not prevent a class from being GC-ed:
```
$ head a.h a.cc c.h c.cc m.cc
==> a.h <==
#include "c.h"
const void *i();
const void *f(Big *);


==> a.cc <==
#include "c.h"

const void *i() { return &Big::ID; }
const void *f(Big *b) { return b->fr(); }

==> c.h <==
#define MUL(x) X(x##q) X(x##w) X(x##e) X(x##r) X(x##t) X(x##y) X(x##u) X(x##i)

class Big {
public:
  static char ID;
#define X(x) virtual const void *x();
  MUL(f);
#undef X
};

==> c.cc <==
#include "c.h"

char Big::ID;
#define X(x) const void *Big::x() { return __PRETTY_FUNCTION__; }
MUL(f);

==> m.cc <==
#include "a.h"

extern "C" void _start() {
#ifdef BIG
  Big big;
  f(&big);
#endif
  i();
}
$ g++ m.cc a.cc c.cc -DBIG -o big.out -nostdlib -fno-rtti -ffunction-sections -fdata-sections -Wl,--gc-sections
$ g++ m.cc a.cc c.cc  -o small.out -nostdlib -fno-rtti -ffunction-sections -fdata-sections -Wl,--gc-sections
$ g++ m.cc a.cc c.cc  -o small-nogc.out -nostdlib -fno-rtti -ffunction-sections -fdata-sections 
$ ls -l *.out
-rwxrwx--- 1 14424 Mar 31 12:17 big.out
-rwxrwx--- 1 14424 Mar 31 12:17 small-nogc.out
-rwxrwx--- 1 13808 Mar 31 12:17 small.out
$ nm small.out | grep _ZN3Big
0000000000004000 B _ZN3Big2IDE
$ nm big.out | grep _ZN3Big
0000000000001092 T _ZN3Big2feEv
0000000000001100 T _ZN3Big2fiEv
0000000000001066 T _ZN3Big2fqEv
00000000000010a8 T _ZN3Big2frEv
00000000000010be T _ZN3Big2ftEv
00000000000010ea T _ZN3Big2fuEv
000000000000107c T _ZN3Big2fwEv
00000000000010d4 T _ZN3Big2fyEv
0000000000004000 B _ZN3Big2IDE
```

I think there's something else happening here.


> > Global variables are [banned](https://llvm.org/docs/CodingStandards.html#do-not-use-static-constructors) by the coding standards, but I wouldn't be surprised if there were still some around that cause this.
> 
> Despite being banned, global variables with non-trivial constructors are still widely used for command line options.

That's true, but the command line library is a low level library in llvm, and it doesn't have any dependencies on the rest of llvm, let alone lldb. So, while these globals may cause us to link in some code that we theoretically do not need, I doubt they're responsible for the majority of the bloat.

https://github.com/llvm/llvm-project/pull/132274


More information about the lldb-commits mailing list