40 Commits

Author SHA1 Message Date
Nerixyz
fb9a0cd278
[LLDB][NativePDB] Ignore indirect virtual bases (#185735)
When a class indirectly inherits from a class with virtual bases, it
will get an `LF_IVBCLASS` record in its fieldlist, even though it
doesn't directly inherit that class.

In the following example, `UserUser` inherits from `User`, which
virtually inherits from `VBase`:

```cpp
struct User : public virtual VBase {};
struct UserUser : public User {};
```

For this we get
```
  0x1015 | LF_FIELDLIST [size = 72]
           - LF_BCLASS
             type = 0x1002 (-> 0x102A), offset = 0, attrs = public
           - LF_IVBCLASS
             base = 0x1003, vbptr = 0x1005, vbptr offset = 0, vtable index = 1
             attrs = public (...)
  0x1016 | LF_STRUCTURE [size = 48] `UserUser`
           unique name: `.?AUUserUser@@`
           vtable: <no type>, base list: <no type>, field list: 0x1015
           options: has ctor / dtor | has unique name | overloaded operator | overloaded operator=, sizeof 16
  0x1029 | LF_FIELDLIST [size = 56]
           - LF_VBCLASS
             base = 0x1003, vbptr = 0x1005, vbptr offset = 0, vtable index = 1
             attrs = public (...)
  0x102A | LF_STRUCTURE [size = 40] `User`
           unique name: `.?AUUser@@`
           vtable: <no type>, base list: <no type>, field list: 0x1029
           options: has ctor / dtor | has unique name | overloaded operator | overloaded operator=, sizeof 16
```

If I understand correctly, then `LF_IVBCLASS` indicates that if this
class (e.g. `UserUser`) is created as the most derived object, it will
host the class (e.g. `VBase`).
The VS debugger actually shows this as a separate field. LLDB on the
other hand doesn't, so I removed it.

---------

Co-authored-by: Zequan Wu <zequanwu@google.com>
2026-03-11 12:19:15 +01:00
Michael Buch
3bd7dc3d65
[lldb][TypeSystem][NFC] Remove unused AccessType parameters to TypeSystemClang APIs (#183023)
In https://github.com/llvm/llvm-project/pull/182956 we stopped using the
access specifiers and unconditionally set all access to `AS_public`.
This patch is a follow-up cleanup to remove all the `AccessType`
parameters of the `TypeSystemClang` APIs (which since
https://github.com/llvm/llvm-project/pull/182956 are never used)
2026-02-25 08:05:12 +00:00
Leonard Grey
21b36423c5
[LLDB][NativePDB] Introduce PdbAstBuilderClang (#175840)
This changes `PdbAstBuilder` to a language-neutral abstract interface
and moves all of its functionality to the `PdbAstBuilderClang` derived
class.

All Clang-specific methods with external callers are now public methods
on `PdbAstBuilderClang`. `TypeSystemClang` and `UdtRecordCompleter` use
`PdbAstBuilderClang` directly.

Did my best to clean up includes and unused methods.

RFC for context:

https://discourse.llvm.org/t/rfc-lldb-make-pdbastbuilder-language-agnostic/89117
2026-01-14 18:28:09 -05:00
Leonard Grey
14af55c53a
[LLDB][PDB] NFC: Change ToCompilerDecl(Context) signature (#175052)
Follow-up to https://github.com/llvm/llvm-project/pull/173111

`ToCompilerDeclContext` and `ToCompilerDecl` take their arguments as
references, but all callers are pointers. This changes the signature to
take pointers, then addresses the comments at
https://github.com/llvm/llvm-project/pull/173111#discussion_r2673140167
2026-01-08 14:44:31 -05:00
Leonard Grey
39dd1fd5e1
[LLDB][NativePDB] NFC: Add language-agnostic interface to PdbAstBuilder (#173111)
This change implements part of
https://discourse.llvm.org/t/rfc-lldb-make-pdbastbuilder-language-agnostic/89117,
the goal of which is make `PdbAstBuilder` language-agnostic.

It adds several new interface methods to `PdbAstBuilder` which allow
`SymbolFileNativePDB` to interact with it without using Clang-specific
types. These new methods would make up much of the interface of a future
abstract `PdbAstBuilder`. `SymbolFileNativePDB` is updated to use these.

The old Clang-specific methods were renamed if used by
`UdtRecordCompleter` or internally, or removed where possible.
2026-01-08 13:23:55 -05:00
nerix
9de41eef6e
[LLDB][NativePDB] Create typedefs in structs (#169248)
Typedef/using declarations in structs and classes were not created with
the native PDB plugin. The following would only create `Foo` and
`Foo::Bar`:
```cpp
struct Foo {
    struct Bar {};
    using Baz = Bar;
    using Int = int;
};
```

With this PR, they're created. One complication is that typedefs and
nested types show up identical. The example from above gives:
```
  0x1006 | LF_FIELDLIST [size = 40, hash = 0x2E844]
           - LF_NESTTYPE [name = `Bar`, parent = 0x1002]
           - LF_NESTTYPE [name = `Baz`, parent = 0x1002]
           - LF_NESTTYPE [name = `Int`, parent = 0x0074 (int)]
```

To distinguish nested types and typedefs, we check if the parent of a
type is equal to the current one (`parent(0x1002) == 0x1006`) and if the
basename matches the nested type name.
2025-12-14 15:42:57 +01:00
nerix
6f44be6f3e
[LLDB][NativePDB] Use original struct name when searching for constants (#166845)
We used to search for constants using the name we parsed. For C++, this
would mean using the demangled struct name (from the unique name). This
name is not always equal to the one used for the struct's name by the
compiler. For example:

```
  0x105E | LF_STRUCTURE [size = 120, hash = 0xF38F] ``anonymous namespace'::Anonymous<A::B::C<void> >::D`
           unique name: `.?AUD@?$Anonymous@U?$C@X@B@A@@@?A0x8C295248@@`
```
We would use the unique name and get to `(anonymous
namespace)::Anonymous<struct A::B::C<void>>::D`. Then, when finding the
constant in the field list, we'd search for `(anonymous
namespace)::Anonymous<struct A::B::C<void>>::D::StaticMember`. This
wouldn't yield any results, because the constant will use the demangled
name as given by the compiler.

With this PR, we use the struct's name as given in the PDB and append
the member name.
2025-12-12 15:33:38 +01:00
nerix
3c162ba247
[LLDB][NativePDB] Add non-overlapping fields in root struct (#166243)
When anonymous unions are used in a struct or vice versa, their fields
are merged into the parent record when using PDB. LLDB tries to recreate
the original definition of the record _with_ the anonymous
unions/structs.

For tagged unions (like `std::optional`) where the tag followed the
anonymous union, the result was suboptimal:

```cpp
// input:
struct Foo {
  union {
    Bar b;
    char c;
  };
  bool tag;
};

// reconstructed:
struct Foo {
  union {
    Bar b;
    struct {
      char c;
      bool tag;
    };
  };
};
```

Once the algorithm is in some nested union, it can't get out.

In the above case, we can get to the correct reconstructed record if we
always add fields that don't overlap others in the root struct. So when
we see `tag`, we'll see that it comes after all other fields, so it's
possible to add it in the root `Foo`.
2025-11-05 19:07:44 +01:00
Michael Buch
7410f6d31d
[lldb][TypeSystemClang] Make AsmLabel parameter a llvm::StringRef (#151355)
Split out from https://github.com/llvm/llvm-project/pull/148877

This patch prepares `TypeSystemClang` APIs to take `AsmLabel`s which
concatenated strings (hence `std::string`) instead of a plain `const
char*`.
2025-07-31 07:11:30 +01:00
Michael Buch
3ac5f5e1fc
[lldb][TypeSystem] Pass ClangASTMetadata by-value when creating record/objc types (#102296)
This is a follow-up to https://github.com/llvm/llvm-project/pull/102161
where we changed the `GetMetadata`/`SetMetadata` APIs to pass
`ClangASTMetadata` by-value, instead of `ClangASTMetadata *`, which
wasn't a very friendly API.

This patch continues from there and changes
`CreateRecordType`/`CreateObjCClass` to take the metadata by-value as
well.

As a drive-by change, I also changed `DelayedAddObjCClassProperty` to
store the metadata by-value, instead of in a `std::unique_ptr`, which
AFAICT, was done solely due to the TypeSystemClang APIs taking the
metadata by pointer. This meant we could also get rid of the
user-provided copy constructors.
2024-08-07 13:05:45 +01:00
Zequan Wu
cde1ae4c14 [lldb][NativePDB] Fix uninitialized values found by msan. 2024-05-28 11:12:21 -04:00
Vlad Serebrennikov
edd690b02e
[clang][NFC] Refactor TagTypeKind (#71160)
This patch converts TagTypeKind into scoped enum. Among other benefits,
this allows us to forward-declare it where necessary.
2023-11-03 21:45:39 +04:00
Kazu Hirata
2fe8327406 [lldb] Use std::optional instead of llvm::Optional (NFC)
This patch replaces (llvm::|)Optional< with std::optional<.  I'll post
a separate patch to clean up the "using" declarations, #include
"llvm/ADT/Optional.h", etc.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-07 14:18:35 -08:00
Kazu Hirata
f190ce625a [lldb] Add #include <optional> (NFC)
This patch adds #include <optional> to those files containing
llvm::Optional<...> or Optional<...>.

I'll post a separate patch to actually replace llvm::Optional with
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-07 13:43:00 -08:00
Zequan Wu
6435fe699c [LLDB][NativePDB] Forcefully complete a record type if it has empty debug info and is required to have complete type.
It's required in following situations:
1. As a base class.
2. As a data member.
3. As an array element type.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D134066
2022-11-16 11:17:07 -08:00
Zequan Wu
d3492ed016 [LLDB][NativePDB] Fix struct layout when it has anonymous unions.
Previously, lldb mistook fields in anonymous union in a struct as the direct
field of the struct, which causes lldb crashes due to multiple fields sharing
the same offset in a struct. This patch fixes it.

MSVC generated pdb doesn't have the debug info entity representing a anonymous
union in a struct. It looks like the following:
```
struct S {
union {
  char c;
  int i;
};
};

0x1004 | LF_FIELDLIST [size = 40]
         - LF_MEMBER [name = `c`, Type = 0x0070 (char), offset = 0, attrs = public]
         - LF_MEMBER [name = `i`, Type = 0x0074 (int), offset = 0, attrs = public]
0x1005 | LF_STRUCTURE [size = 32] `S`
         unique name: `.?AUS@@`
         vtable: <no type>, base list: <no type>, field list: 0x1004
```
Clang generated pdb is similar, though due to the [[ https://github.com/llvm/llvm-project/issues/57999 | bug ]],
it's not more useful than the debug info above. But that's not very relavent,
lldb should still be able to understand MSVC geneerated pdb.
```
0x1003 | LF_UNION [size = 60] `S::<unnamed-tag>`
         unique name: `.?AT<unnamed-type-$S1>@S@@`
         field list: <no type>
         options: forward ref (= 0x1003) | has unique name | is nested, sizeof 0
0x1004 | LF_FIELDLIST [size = 40]
         - LF_MEMBER [name = `c`, Type = 0x0070 (char), offset = 0, attrs = public]
         - LF_MEMBER [name = `i`, Type = 0x0074 (int), offset = 0, attrs = public]
         - LF_NESTTYPE [name = ``, parent = 0x1003]
0x1005 | LF_STRUCTURE [size = 32] `S`
         unique name: `.?AUS@@`
         vtable: <no type>, base list: <no type>, field list: 0x1004
         options: contains nested class | has unique name, sizeof 4
0x1006 | LF_FIELDLIST [size = 28]
         - LF_MEMBER [name = `c`, Type = 0x0070 (char), offset = 0, attrs = public]
         - LF_MEMBER [name = `i`, Type = 0x0074 (int), offset = 0, attrs = public]
0x1007 | LF_UNION [size = 60] `S::<unnamed-tag>`
         unique name: `.?AT<unnamed-type-$S1>@S@@`
         field list: 0x1006
         options: has unique name | is nested | sealed, sizeof
```
This patch delays the FieldDecl creation when travesing LF_FIELDLIST so we know
if there are multiple fields are in the same offsets and are able to group them
into different anonymous unions based on offsets. Nested anonymous union will
be flatten into one anonymous union, because we simply don't have that info, but
they are equivalent in terms of union layout.

Differential Revision: https://reviews.llvm.org/D134849
2022-10-13 12:43:45 -07:00
Zequan Wu
d434f43720 [LLDB][NativePDB] Add class/union layout bit size.
Missing it causes lldb to crash or give incorrect result.

Differential Revision: https://reviews.llvm.org/D134656
2022-09-27 11:41:55 -07:00
Zequan Wu
a3e60044d7 [LLDB][NativePDB] Let native pdb use class layout in debug info.
Before, class layout in native pdb is not hooked up in [[https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp#L9375-L9380 | here]].
This changes hooked it up by refactoring SymbolFileNativePDB and PdbAstBuilder.
PdbIndex (corresponds to a single pdb file) is removed from PdbAstBuilder, so it
can only be accessed via SymbolFileNativePDB and we can construct PdbAstBuilder
with just TypeSystemClang.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D134509
2022-09-27 11:01:32 -07:00
Kazu Hirata
0916d96d12 Don't use Optional::hasValue (NFC) 2022-06-20 20:17:57 -07:00
Kazu Hirata
aa88161b37 [lldb] Use value_or instead of getValueOr (NFC) 2022-06-19 09:12:01 -07:00
Kazu Hirata
4969a6924d Use llvm::less_first (NFC) 2022-06-04 21:23:18 -07:00
Zequan Wu
5c9f3ec4ad [LLDB][NativePDB] Check for missing type info to avoid crash.
NativePDB often assumes that all debug info are available.
This is one step to make it more pervasive.

Differential Revision: https://reviews.llvm.org/D125844
2022-05-25 13:19:27 -07:00
Zequan Wu
583223cd5e [LLDB][NativePDB] Don't complete static members' types when completing a record type.
`UdtRecordCompleter` shouldn't complete static members' types. static members' types are going to be completed when the types are called in `SymbolFile::CompleteType`.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D121030
2022-03-15 14:06:54 -07:00
Pavel Labath
c34698a811 [lldb] Rename Logging.h to LLDBLog.h and clean up includes
Most of our code was including Log.h even though that is not where the
"lldb" log channel is defined (Log.h defines the generic logging
infrastructure). This worked because Log.h included Logging.h, even
though it should.

After the recent refactor, it became impossible the two files include
each other in this direction (the opposite inclusion is needed), so this
patch removes the workaround that was put in place and cleans up all
files to include the right thing. It also renames the file to LLDBLog to
better reflect its purpose.
2022-02-03 14:47:01 +01:00
Pavel Labath
a007a6d844 [lldb] Convert "LLDB" log channel to the new API 2022-02-02 14:13:08 +01:00
Zequan Wu
a3a8ed33a1 [LLDB][NativePDB] Fix function decl creation for class methods
This is a split of D113724. Calling `TypeSystemClang::AddMethodToCXXRecordType`
to create function decls for class methods.

Differential Revision: https://reviews.llvm.org/D113930
2021-12-07 10:41:28 -08:00
Aleksandr Urakov
895529cfd8 [lldb][PDB] Constexpr static member values as AST literals
Summary:
When evaluating an expression referencing a constexpr static member variable, an
error is issued because the PDB does not specify a symbol with an address that
can be relocated against.

Rather than attempt to resolve the variable's value within the IR execution, the
values of all constants can be looked up and incorporated into the AST of the
record type as a literal, mirroring the original compiler AST.

This change applies to DIA and native PDB loaders.

Patch By: jackoalan

Reviewers: aleksandr.urakov, jasonmolenda, zturner, jdoerfert, teemperor

Reviewed By: aleksandr.urakov

Subscribers: sstefan1, lldb-commits, llvm-commits, #lldb

Tags: #lldb, #llvm

Differential Revision: https://reviews.llvm.org/D82160
2020-06-25 11:27:16 +03:00
Alex Langford
8be30215fe [lldb] Move clang-based files out of Symbol
Summary:
This change represents the move of ClangASTImporter, ClangASTMetadata,
ClangExternalASTSourceCallbacks, ClangUtil, CxxModuleHandler, and
TypeSystemClang from lldbSource to lldbPluginExpressionParserClang.h

This explicitly removes knowledge of clang internals from lldbSymbol,
moving towards a more generic core implementation of lldb.

Reviewers: JDevlieghere, davide, aprantl, teemperor, clayborg, labath, jingham, shafik

Subscribers: emaste, mgorny, arphaman, jfb, usaxena95, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D73661
2020-01-31 12:20:10 -08:00
Raphael Isemann
6e3b0cc2fb [lldb][NFC] Rename ClangASTContext to TypeSystemClang
Summary:
This commit renames ClangASTContext to TypeSystemClang to better reflect what this class is actually supposed to do
(implement the TypeSystem interface for Clang). It also gets rid of the very confusing situation that we have both a
`clang::ASTContext` and a `ClangASTContext` in clang (which sometimes causes Clang people to think I'm fiddling
with Clang's ASTContext when I'm actually just doing LLDB work).

I also have plans to potentially have multiple clang::ASTContext instances associated with one ClangASTContext so
the ASTContext naming will then become even more confusing to people.

Reviewers: #lldb, aprantl, shafik, clayborg, labath, JDevlieghere, davide, espindola, jdoerfert, xiaobai

Reviewed By: clayborg, labath, xiaobai

Subscribers: wuzish, emaste, nemanjai, mgorny, kbarton, MaskRay, arphaman, jfb, usaxena95, jingham, xiaobai, abidh, JDevlieghere, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D72684
2020-01-23 10:09:14 +01:00
Raphael Isemann
b852b3c982 [lldb][NFC] Rename ClangASTImporter::InsertRecordDecl to SetRecordLayout and document it
This function is just setting the layout for the given RecordDecl so
the current name is not very descriptive. Also add some documentation for it.
2019-12-17 15:56:07 +01:00
Reid Kleckner
e10d00419a [codeview] Remove Type member from CVRecord
Summary:
Now CVType and CVSymbol are effectively type-safe wrappers around
ArrayRef<uint8_t>. Make the kind() accessor load it from the
RecordPrefix, which is the same for types and symbols.

Reviewers: zturner, aganea

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D60018

llvm-svn: 357658
2019-04-04 00:28:48 +00:00
Aleksandr Urakov
eaa0ad672e [NativePDB] Process virtual bases in the correct order
Summary:
This patch makes virtual bases to be added in the correct order to the bases
list. It is important because `VTableContext` (`MicrosoftVTableContext` in our
case) uses then the order of virtual bases in the list to restore the virtual
table indexes. These indexes are used then to resolve the layout of the virtual
bases.

We haven't enough information about offsets of virtual bases regarding to the
object (moreover, in a common case we can't rely on such information, see the
example here: https://reviews.llvm.org/D53506#1272306 ), but there should be
enough information to restore the layout of the virtual bases from the indexes
in runtime. After D53506 this information is used whenever possible, so there
should be no problems with virtual bases' fields reading.

Reviewers: zturner, rnk, stella.stamenova

Subscribers: abidh, teemperor, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D56904

llvm-svn: 353806
2019-02-12 08:17:11 +00:00
Aleksandr Urakov
ee7c61f10e [NativePDB] Add basic support of methods recostruction in AST
Summary:
This patch adds the basic support of methods reconstruction by native PDB
plugin. It contains only most obvious changes (it processes LF_ONEMETHOD and
LF_METHOD records), some things still remain unsolved:

- mangled names retrieving;
- support of template methods.

Reviewers: zturner, labath, lemo, stella.stamenova

Reviewed by: zturner

Differential Revision: https://reviews.llvm.org/D56126

llvm-svn: 352464
2019-01-29 09:32:23 +00:00
Zachary Turner
594c85e95f [NativePDB] Decouple AST reconstruction from lldb Symbol creation.
Previously the code that parsed debug info to create lldb's Symbol
objects such as Variable, Type, Function, etc was tightly coupled
to the AST reconstruction code.  This made it difficult / impossible
to implement functions such as ParseDeclsForContext() that were only
supposed to be operating on clang AST's.  By splitting these apart,
the logic becomes much cleaner and we have a clear separation of
responsibilities.

llvm-svn: 349383
2018-12-17 19:43:33 +00:00
Zachary Turner
6284aee9f8 [NativePDB] Rewrite the PdbSymUid to use our own custom namespacing scheme.
Originally we created our 64-bit UID scheme by using the first byte as
sort of a "tag" to represent what kind of symbol this was, and we
re-used the PDB_SymType enumeration for this.  For native pdb support,
this is not really the right abstraction layer, because what we really
want is something that tells us *how* to find the symbol.  This means,
specifically, is in the globals stream / public stream / module stream /
TPI stream / etc, and for whichever one it is in, where is it within
that stream?

A good example of why the old namespacing scheme was insufficient is
that it is more or less impossible to create a uid for a field list
member of a class/struction/union/enum that tells you how to locate
the original record.

With this new scheme, the first byte is no longer a PDB_SymType enum
but a new enum created specifically to identify where in the PDB
this record lives.  This gives us much better flexibility in
what kinds of symbols the uids can identify.

llvm-svn: 347018
2018-11-16 02:42:32 +00:00
Zachary Turner
d2ee4c6ddb [NativePDB] Add support for bitfield records.
Bitfields are represented as LF_MEMBER records whose TypeIndex
points to an LF_BITFIELD record that describes the bit width,
bit offset, and underlying type of the bitfield.  All we need to
do is resolve these when resolving record types.

llvm-svn: 346511
2018-11-09 16:29:19 +00:00
Shafik Yaghmour
8c5ec1ff46 Refactor ClangASTContext::AddEnumerationValueToEnumerationType() to remove redundant parameter which can be calculated from other parameter.
rdar://problem/43822994

Differential Revision: https://reviews.llvm.org/D54003

llvm-svn: 346428
2018-11-08 18:42:00 +00:00
Zachary Turner
970f38ead6 [NFC] Refactor SetBaseClasses and DeleteBaseClasses.
We currently had a 2-step process where we had to call
SetBaseClassesForType and DeleteBaseClasses.  Every single caller
followed this exact 2-step process, and there was manual memory
management going on with raw pointers.  We can do better than this
by storing a vector of unique_ptrs and passing this around.
This makes for a cleaner API, and we only need to call one method
so there is no possibility of a user forgetting to call
DeleteBaseClassSpecifiers.

In addition to this, it also makes for a *simpler* API.  Part of
why I wanted to do this is because when I was implementing the native
PDB interface I had to spend some time understanding exactly what I
was deleting and why.  ClangAST has significant mental overhead
associated with it, and reducing the API surface can go along
way to making it simpler for people to understand.

Differential Revision: https://reviews.llvm.org/D53590

llvm-svn: 345312
2018-10-25 20:44:56 +00:00
Zachary Turner
a3e2ea1c4a Change two methods from const char* to StringRef [NFC].
llvm-svn: 345055
2018-10-23 17:22:02 +00:00
Zachary Turner
2f7efbc9ce [NativePDB] Add basic support for tag types to the native pdb plugin.
This adds support to LLDB for named types (class, struct, union, and
enum).  This is true cross platform support, and hits the PDB file
directly without a dependency on Windows.  Tests are added which
compile a program with certain interesting types and then use
load the target in LLDB and use "type lookup -- <TypeName>" to
dump the layout of the type in LLDB without a running process.

Currently only fields are parsed -- we do not parse methods.  Also
we don't deal with bitfields or virtual bases correctly.  Those
will make good followups.

Differential Revision: https://reviews.llvm.org/D53511

llvm-svn: 345047
2018-10-23 16:37:53 +00:00