This patch causes the various AST dump commands (`target modules dump
ast`/`target dump typesystem`) to be color-highlighted. I added a `bool
show_color` parameter to `SymbolFile::DumpClangAST` and
`TypeSystem::Dump`. In `TypeSystemClang` I temporarily sets the
`getShowColors` flag on the owned Clang AST (using an RAII helper) for
the duration of the AST dump. We use `Debugger::GetUseColors` to decide
whether to color the AST dump.
This is a major change on how we represent nested name qualifications in
the AST.
* The nested name specifier itself and how it's stored is changed. The
prefixes for types are handled within the type hierarchy, which makes
canonicalization for them super cheap, no memory allocation required.
Also translating a type into nested name specifier form becomes a no-op.
An identifier is stored as a DependentNameType. The nested name
specifier gains a lightweight handle class, to be used instead of
passing around pointers, which is similar to what is implemented for
TemplateName. There is still one free bit available, and this handle can
be used within a PointerUnion and PointerIntPair, which should keep
bit-packing aficionados happy.
* The ElaboratedType node is removed, all type nodes in which it could
previously apply to can now store the elaborated keyword and name
qualifier, tail allocating when present.
* TagTypes can now point to the exact declaration found when producing
these, as opposed to the previous situation of there only existing one
TagType per entity. This increases the amount of type sugar retained,
and can have several applications, for example in tracking module
ownership, and other tools which care about source file origins, such as
IWYU. These TagTypes are lazily allocated, in order to limit the
increase in AST size.
This patch offers a great performance benefit.
It greatly improves compilation time for
[stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for
`test_on2.cpp` in that project, which is the slowest compiling test,
this patch improves `-c` compilation time by about 7.2%, with the
`-fsyntax-only` improvement being at ~12%.
This has great results on compile-time-tracker as well:

This patch also further enables other optimziations in the future, and
will reduce the performance impact of template specialization resugaring
when that lands.
It has some other miscelaneous drive-by fixes.
About the review: Yes the patch is huge, sorry about that. Part of the
reason is that I started by the nested name specifier part, before the
ElaboratedType part, but that had a huge performance downside, as
ElaboratedType is a big performance hog. I didn't have the steam to go
back and change the patch after the fact.
There is also a lot of internal API changes, and it made sense to remove
ElaboratedType in one go, versus removing it from one type at a time, as
that would present much more churn to the users. Also, the nested name
specifier having a different API avoids missing changes related to how
prefixes work now, which could make existing code compile but not work.
How to review: The important changes are all in
`clang/include/clang/AST` and `clang/lib/AST`, with also important
changes in `clang/lib/Sema/TreeTransform.h`.
The rest and bulk of the changes are mostly consequences of the changes
in API.
PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just
for easier to rebasing. I plan to rename it back after this lands.
Fixes#136624
Fixes https://github.com/llvm/llvm-project/issues/43179
Fixes https://github.com/llvm/llvm-project/issues/68670
Fixes https://github.com/llvm/llvm-project/issues/92757
Languages other than C/C++ don't necessarily emit mangled names in the
`UniqueName` field of type records. Rust specifically emits a unique ID
that doesn't contain the name.
For example, `(i32, i32)` is emitted as
```llvm
!266 = !DICompositeType(
tag: DW_TAG_structure_type, name: "tuple$<i32,i32>", file: !9, size: 64, align: 32,
elements: !267, templateParams: !17, identifier: "19122721b0632fe96c0dd37477674472"
)
```
which results in
```
0x1091 | LF_STRUCTURE [size = 72, hash = 0x1AC67] `tuple$<i32,i32>`
unique name: `19122721b0632fe96c0dd37477674472`
vtable: <no type>, base list: <no type>, field list: 0x1090
options: has unique name, sizeof 8
```
In C++ with Clang and MSVC, a structure similar to this would result in
```
0x136F | LF_STRUCTURE [size = 44, hash = 0x30BE2] `MyTuple`
unique name: `.?AUMyTuple@@`
vtable: <no type>, base list: <no type>, field list: 0x136E
options: has unique name, sizeof 8
```
With this PR, if a `UniqueName` is encountered that couldn't be parsed,
it will fall back to using the undecorated (→ do the same as if the
unique name is empty/unavailable).
I'm not sure how to test this. Maybe compiling the LLVM IR that rustc
emits?
Fixes#152051.
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*`.
Depends on https://github.com/llvm/llvm-project/pull/142163
This patch makes the `-ast-dump-filter` Clang option available to the
`target modules dump ast` command. This allows us to selectively dump
parts of the AST by name.
The AST can quickly grow way too large to skim on the console. This will
aid in debugging AST related issues.
Example:
```
(lldb) target modules dump ast --filter func
Dumping clang ast for 48 modules.
Dumping func:
FunctionDecl 0xc4b785008 <<invalid sloc>> <invalid sloc> func 'void (int)' extern
|-ParmVarDecl 0xc4b7853d8 <<invalid sloc>> <invalid sloc> x 'int'
`-AsmLabelAttr 0xc4b785358 <<invalid sloc>> Implicit "_Z4funcIiEvT_"
Dumping func<int>:
FunctionDecl 0xc4b7850b8 <<invalid sloc>> <invalid sloc> func<int> 'void (int)' implicit_instantiation extern
|-TemplateArgument type 'int'
| `-BuiltinType 0xc4b85b110 'int'
`-ParmVarDecl 0xc4b7853d8 <<invalid sloc>> <invalid sloc> x 'int'
```
The majority of this patch is adjust the `Dump` API. The main change in
behaviour is in `TypeSystemClang::Dump`, where we now use the
`ASTPrinter` for dumping the `TranslationUnitDecl`. This is where the
`-ast-dump-filter` functionality lives in Clang.
Original PR: #130537
Originally reverted due to revert of dependent commit. Relanding with no
changes.
This changes the MemberPointerType representation to use a
NestedNameSpecifier instead of a Type to represent the base class.
Since the qualifiers are always parsed as nested names, there was an
impedance mismatch when converting these back and forth into types, and
this led to issues in preserving sugar.
The nested names are indeed a better match for these, as the differences
which a QualType can represent cannot be expressed syntatically, and
they represent the use case more exactly, being either dependent or
referring to a CXXRecord, unqualified.
This patch also makes the MemberPointerType able to represent sugar for
a {up/downcast}cast conversion of the base class, although for now the
underlying type is canonical, as preserving the sugar up to that point
requires further work.
As usual, includes a few drive-by fixes in order to make use of the
improvements.
Original PR: #130537
Reland after updating lldb too.
This changes the MemberPointerType representation to use a
NestedNameSpecifier instead of a Type to represent the base class.
Since the qualifiers are always parsed as nested names, there was an
impedance mismatch when converting these back and forth into types, and
this led to issues in preserving sugar.
The nested names are indeed a better match for these, as the differences
which a QualType can represent cannot be expressed syntatically, and
they represent the use case more exactly, being either dependent or
referring to a CXXRecord, unqualified.
This patch also makes the MemberPointerType able to represent sugar for
a {up/downcast}cast conversion of the base class, although for now the
underlying type is canonical, as preserving the sugar up to that point
requires further work.
As usual, includes a few drive-by fixes in order to make use of the
improvements.
While sifting through this part of the code I noticed that when we parse
C++ methods, `DWARFASTParserClang` creates two sets of `ParmVarDecls`,
one in `ParseChildParameters` and once in `AddMethodToCXXRecordType`.
The former is unused when we're dealing with methods. Moreover, the
`ParmVarDecls` we created in `ParseChildParameters` were created with an
incorrect `clang::DeclContext` (namely the DeclContext of the function,
and not the function itself). In Clang, there's
`ParmVarDecl::setOwningFunction` to adjust the DeclContext of a
parameter if the parameter was created before the FunctionDecl. But we
never used it.
This patch removes the `ParmVarDecl` creation from
`ParseChildParameters` and instead creates a
`TypeSystemClang::CreateParameterDeclarations` that ensures we set the
DeclContext correctly.
Note there is one differences in how `ParmVarDecl`s would be created
now: we won't set a ClangASTMetadata entry for any of the parameters. I
don't think this was ever actually useful for parameter DIEs anyway.
This wasn't causing any concrete issues (that I know of), but was quite
surprising. And this way of setting the parameters seems easier to
reason about (in my opinion).
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.
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.
I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
This reverts commit d81cdb49d74064e88843733e7da92db865943509.
This refactoring was waiting on converting LLVM to C++17.
Leave StringView.h and cleanup around for subsequent cleanup.
Additional fixes for missing std::string_view conversions for MSVC.
Reviewed By: MaskRay, DavidSpickett, ayzhao
Differential Revision: https://reviews.llvm.org/D148546
This reverts commit 3e559509b426b6aae735a7f57dbdaed1041d2622 and e0c4ffa796b553fa78c638a9584c05ac21fe07d5.
This still breaks Windows builds.
In addition, `#include <llvm/ADT/StringViewExtras.h>` in
llvm/include/llvm/Demangle/ItaniumDemangle.h is a library layering violation
(LLVMDemangle is the lowest LLVM library and cannot depend on LLVMSupport).
This refactoring was waiting on converting LLVM to C++17.
Leave StringView.h and cleanup around for subsequent cleanup.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D148384
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
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
When a process gets restarted TypeSystem objects associated with it
may get deleted, and any CompilerType objects holding on to a
reference to that type system are a use-after-free in waiting. Because
of the SBAPI, we don't have tight control over where CompilerTypes go
and when they are used. This is particularly a problem in the Swift
plugin, where the scratch TypeSystem can be restarted while the
process is still running. The Swift plugin has a lock to prevent
abuse, but where there's a lock there can be bugs.
This patch changes CompilerType to store a std::weak_ptr<TypeSystem>.
Most of the std::weak_ptr<TypeSystem>* uglyness is hidden by
introducing a wrapper class CompilerType::WrappedTypeSystem that has a
dyn_cast_or_null() method. The only sites that need to know about the
weak pointer implementation detail are the ones that deal with
creating TypeSystems.
rdar://101505232
Differential Revision: https://reviews.llvm.org/D136650
1. When we evaluating an expression multiple times and the searching scope is translation unit, ParseDeclsForContext iterates the type info and symbol info multiple times, though only the debug info is parsed once. Using llvm::call_once to make it only iterating and parsing once.
2. When evaluating an expression with identifier whose parent scope is a namespace, ParseDeclsForContext needs to search the entire type info to complete those records whose name is prefixed with the namespace's name and the entire symbol info to to parse functions and non-local variables. Caching parsed namespaces to avoid unnecessary searching.
Reviewed By: labath
Differential Revision: https://reviews.llvm.org/D136006
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
Removed `GetParentDeclContextForSymbol` as this is not necesssary. We can get
the demangled names from CVSymbol and then using it to create tag decl or
namespace decl. This also fixed a bug when icf applied.
Differential Revision: https://reviews.llvm.org/D133243
llvm::codeview::visitMemberRecordStream in CompleteTagDecl will call
GetOrCreateType create type if not seen before, which inserts new entries
into m_decl_to_status. This may invalidates status which is a reference to
std::pair::second from DenseMapIterator.
llvm::codeview::visitMemberRecordStream expects to receive an array ref that's FieldListRecord's Data not a CVType's data which has 4 more bytes preceeding. The first 2 bytes indicate the size of the FieldListRecord, and following 2 bytes is always 0x1203. Inside llvm::codeview::visitMemberRecordStream, it iterates to the data to check if first two bytes matching some type record kinds. If the size coincidentally matches one type kind, it will start parsing from there and causing crash.
1. If array element type is a tag decl, complete it.
2. Fix few places where `asTag` should be used instead of `asClass()`.
3. Handle the case that `PdbAstBuilder::CreateFunctionDecl` return nullptr mainly due to an existing workaround (`m_cxx_record_map`).
4. `FindMembersSize` should never return error as this would cause early exiting in `CVTypeVisitor::visitFieldListMemberStream` and then cause assertion failure.
5. In some pdbs from C++ runtime libraries have S_LPROC32 followed directly by S_LOCAL and the local variable location is a S_DEFRANGE_FRAMEPOINTER_REL. There is no information about base frame register in this case, ignoring it by returning RegisterId::NONE.
6. Add a TODO when S_DEFRANGE_SUBFIELD_REGISTER describes the variable location of a pointer type. For now, just ignoring it if the variable is pointer.
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
This creates inline functions decls in the TUs where the funcitons are inlined and local variable decls inside those functions.
Reviewed By: labath
Differential Revision: https://reviews.llvm.org/D121967
`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
This is a split of D113724. Calling `TypeSystemClang::AddMethodToCXXRecordType`
to create function decls for class methods.
Differential Revision: https://reviews.llvm.org/D113930
This adds the `target dump typesystem'`command which dumps the TypeSystem of the
target itself (aka the 'scratch TypeSystem'). This is similar to `target modules
dump ast` which dumps the AST of lldb::Modules associated with a selected
target.
Unlike `target modules dump ast`, the new command is not a subcommand of `target
modules dump` as it's not touching the modules of a target at all. Also unlike
`target modules dump ast` I tried to keep the implementation language-neutral,
so this patch moves our Clang `Dump` to the `TypeSystem` interface so it will
also dump the state of any future/downstream scratch TypeSystems (e.g., Swift).
That's also why the command just refers to a 'typesystem' instead of an 'ast'
(which is only how Clang is necessarily modelling the internal TypeSystem
state).
The main motivation for this patch is that I need to write some tests that check
for duplicates in the ScratchTypeSystemClang of a target. There is currently no
way to check for this at the moment (beside measuring memory consumption of
course). It's probably also useful for debugging LLDB itself.
Reviewed By: labath
Differential Revision: https://reviews.llvm.org/D111936