https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/127829
This patch revives https://reviews.llvm.org/D78095 with some changes. This patch uses the `DW_AT_decl_XXX` DWARF attributes to create `clang::SourceLocation`s and attach them to the Clang decls that LLDB creates. The primary motivation for this is better expression evaluator diagnostics. Instead of: ``` (lldb) expr func() ˄ ╰─ error: no matching function for call to 'func' note: note: candidate function not viable: requires 1 argument, but 0 were provided note: note: candidate function not viable: requires 1 argument, but 0 were provided note: note: candidate function not viable: requires single argument 'x', but no arguments were provided note: note: candidate function not viable: requires single argument 'y', but no arguments were provided note: note: candidate function not viable: requires 2 arguments, but 0 were provided ``` We would see: ``` (lldb) expr func() ˄ ╰─ error: no matching function for call to 'func' note: /Users/michaelbuch/source-locs/lib.h:4:1: candidate function not viable: requires 1 argument, but 0 were provided 4 | void func(char const* c, char) {}; void func(bool) {} | ^ note: /Users/michaelbuch/source-locs/lib.h:4:1: candidate function not viable: requires 2 arguments, but 0 were provided 4 | void func(char const* c, char) {}; void func(bool) {} | ^ note: /Users/michaelbuch/source-locs/main.cpp:5:1: candidate function not viable: requires single argument 'x', but no arguments were provided 5 | void func(int x) { var = 6; } | ^ note: /Users/michaelbuch/source-locs/main.cpp:6:1: candidate function not viable: requires single argument 'y', but no arguments were provided 6 | void func(float y) { var = 6; } | ^ ``` There's a couple of quirks in the output still, mainly because Clang we doesn't emit `DW_AT_decl_column`, so Clang has to place the caret on column `1`. But this is something we can probably configure (either as a pre-requisite to this patch or as a follow-up). This is currently WIP. It's lacking tests and we probably also want to make sure we only use the file `DW_AT_decl_file` hasn't changed since the debug-info was generated (i think there's some checksum we can use for this, like we do in the SupportFiles?). Just looking for early concerns/feedback. I split up the patch into 3 separate commits: 1. Commit 1: makes sure each ASTContext that LLDB creates (apart from the scratch AST), has a `MainFileID`. LLDB will pretend that this dummy file is the main source file, and all other FileIDs (those that we create in commit 3) are included into it 2. Commit 2: makes sure we call `setLocation` in all the appropriate places. 3. Implements `GetLocForDecl` which turns a `lldb_private::Declaration` into `clang::SourceLocation` The three main differences to https://reviews.llvm.org/D78095 are: 1. we no longer hide this feature behind a flag 2. the original patch didn't yet support using `DW_AT_decl_file` for displaying source snippets 3. we no longer have a separate `clang::TextDiagnosticPrinter` for printing these source snippets. In theory it would be nice to do this, because we could configure it separately (e.g., to hide the column number). I didn't carry that over because (1) setting `ShowCarets` to `false` causes the source snippet to not be printed (probably something we could change in Clang), and (2) we somehow need to differentiate whether a `FileID` was created by LLDB versus Clang, which got tricky because we need to have cross-`DWARFASTParserClang` state, which also meant that we have to copy over this metadata to the expression context. All of that didn't seem worth it, but we could definitely add this back >From 1aabc8a93ffac06755cbaf5e6c1fa8913cd63729 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Wed, 19 Feb 2025 12:47:30 +0000 Subject: [PATCH 1/3] [lldb][TypeSystemClang] Create MainFileID for TypeSystemClang ASTContexts --- .../TypeSystem/Clang/TypeSystemClang.cpp | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 1e0c7f0514941..563961b9a4971 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -13,6 +13,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" #include <mutex> #include <memory> @@ -361,6 +362,39 @@ static void SetMemberOwningModule(clang::Decl *member, } } +/// Creates a dummy main file for the given SourceManager. +/// This file only serves as a container for include locations to other +/// FileIDs that are put into this type system (either by the ASTImporter +/// or when TypeSystemClang generates source locations for declarations). +/// This file is not reflected to disk. +static clang::FileID CreateDummyMainFile(clang::SourceManager &sm, + clang::FileManager &fm) { + llvm::StringRef main_file_path = "<LLDB Dummy Main File>"; + // The file contents are empty and should never be seen by the user. The new + // line is just there to not throw off any line counting logic that might + // expect files to end with a newline. + llvm::StringRef main_file_contents = "\n"; + const time_t mod_time = 0; + const off_t file_size = static_cast<off_t>(main_file_contents.size()); + + // Create a virtual FileEntry for our dummy file. + auto fe = fm.getVirtualFileRef(main_file_path, file_size, mod_time); + + // Overwrite the file buffer with our empty file contents. + llvm::SmallVector<char, 64> buffer; + buffer.append(main_file_contents.begin(), main_file_contents.end()); + auto file_contents = std::make_unique<llvm::SmallVectorMemoryBuffer>( + std::move(buffer), main_file_path); + sm.overrideFileContents(fe, std::move(file_contents)); + + // Create the actual file id for the FileEntry and set it as the main file. + clang::FileID fid = + sm.createFileID(fe, SourceLocation(), clang::SrcMgr::C_User); + sm.setMainFileID(fid); + + return fid; +} + char TypeSystemClang::ID; bool TypeSystemClang::IsOperator(llvm::StringRef name, @@ -692,6 +726,11 @@ void TypeSystemClang::CreateASTContext() { m_diagnostic_consumer_up = std::make_unique<NullDiagnosticConsumer>(); m_ast_up->getDiagnostics().setClient(m_diagnostic_consumer_up.get(), false); + // Set up the MainFileID of this ASTContext. All other FileIDs created + // by this TypeSystem will act as-if included into this dummy main file. + auto fid = CreateDummyMainFile(*m_source_manager_up, *m_file_manager_up); + assert(m_ast_up->getSourceManager().getMainFileID() == fid); + // This can be NULL if we don't know anything about the architecture or if // the target for an architecture isn't enabled in the llvm/clang that we // built >From f7a2ce31947b3b9e97e954205d7a587bb03c530c Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Wed, 19 Feb 2025 13:37:01 +0000 Subject: [PATCH 2/3] [lldb][TypeSystemClang] Set location on functions, parameters, enums and structures --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 10 ++-- .../SymbolFile/NativePDB/PdbAstBuilder.cpp | 2 +- .../Plugins/SymbolFile/PDB/PDBASTParser.cpp | 3 +- .../TypeSystem/Clang/TypeSystemClang.cpp | 47 ++++++++++++++----- .../TypeSystem/Clang/TypeSystemClang.h | 46 +++++++++++------- 5 files changed, 73 insertions(+), 35 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 2d4d22559963f..abf3b22b0ae15 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1372,7 +1372,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, GetOwningClangModule(die), name, clang_type, attrs.storage, - attrs.is_inline); + attrs.is_inline, attrs.decl); std::free(name_buf); if (has_template_params) { @@ -1382,11 +1382,11 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type, - attrs.storage, attrs.is_inline); + attrs.storage, attrs.is_inline, attrs.decl); clang::FunctionTemplateDecl *func_template_decl = m_ast.CreateFunctionTemplateDecl( containing_decl_ctx, GetOwningClangModule(die), - template_function_decl, template_param_infos); + template_function_decl, template_param_infos, attrs.decl); m_ast.CreateFunctionTemplateSpecializationInfo( template_function_decl, func_template_decl, template_param_infos); } @@ -1858,7 +1858,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl( containing_decl_ctx, GetOwningClangModule(die), class_template_decl, - tag_decl_kind, template_param_infos); + tag_decl_kind, template_param_infos, attrs.decl); clang_type = m_ast.CreateClassTemplateSpecializationType(class_specialization_decl); @@ -1870,7 +1870,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, clang_type = m_ast.CreateRecordType( containing_decl_ctx, GetOwningClangModule(die), attrs.accessibility, attrs.name.GetCString(), tag_decl_kind, attrs.class_language, metadata, - attrs.exports_symbols); + attrs.exports_symbols, attrs.decl); } TypeSP type_sp = dwarf->MakeType( diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 5d4b22d08b111..ecb1a7dc571b4 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -1128,7 +1128,7 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, CompilerType param_type_ct = m_clang.GetType(qt); clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration( &function_decl, OptionalClangModuleID(), param_name.str().c_str(), - param_type_ct, clang::SC_None, true); + param_type_ct, clang::SC_None, clang::SourceLocation(), true); lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0); m_uid_to_decl[toOpaqueUid(param_uid)] = param; diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index c6dd72e22fb4c..e98ccf87cc2f7 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -969,7 +969,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration( decl, OptionalClangModuleID(), nullptr, - arg_type->GetForwardCompilerType(), clang::SC_None, true); + arg_type->GetForwardCompilerType(), clang::SC_None, + clang::SourceLocation(), true); if (param) params.push_back(param); } diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 563961b9a4971..cf3be07dd092f 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -1282,7 +1282,7 @@ CompilerType TypeSystemClang::CreateRecordType( clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, AccessType access_type, llvm::StringRef name, int kind, LanguageType language, std::optional<ClangASTMetadata> metadata, - bool exports_symbols) { + bool exports_symbols, const Declaration &declaration) { ASTContext &ast = getASTContext(); if (decl_ctx == nullptr) @@ -1337,6 +1337,10 @@ CompilerType TypeSystemClang::CreateRecordType( decl->setAnonymousStructOrUnion(true); } + auto location = GetLocForDecl(declaration); + decl->setLocStart(location); + decl->setLocation(location); + if (metadata) SetMetadata(decl, *metadata); @@ -1454,7 +1458,8 @@ static TemplateParameterList *CreateTemplateParameterList( clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, clang::FunctionDecl *func_decl, - const TemplateParameterInfos &template_param_infos) { + const TemplateParameterInfos &template_param_infos, + const Declaration &declaration) { // /// Create a function template node. ASTContext &ast = getASTContext(); @@ -1468,6 +1473,7 @@ clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( func_tmpl_decl->setDeclName(func_decl->getDeclName()); func_tmpl_decl->setTemplateParameters(template_param_list); func_tmpl_decl->init(func_decl); + func_tmpl_decl->setLocation(GetLocForDecl(declaration)); SetOwningModule(func_tmpl_decl, owning_module); for (size_t i = 0, template_param_decl_count = template_param_decls.size(); @@ -1693,7 +1699,8 @@ ClassTemplateSpecializationDecl * TypeSystemClang::CreateClassTemplateSpecializationDecl( DeclContext *decl_ctx, OptionalClangModuleID owning_module, ClassTemplateDecl *class_template_decl, int kind, - const TemplateParameterInfos &template_param_infos) { + const TemplateParameterInfos &template_param_infos, + const Declaration &declaration) { ASTContext &ast = getASTContext(); llvm::SmallVector<clang::TemplateArgument, 2> args( template_param_infos.Size() + @@ -1728,6 +1735,8 @@ TypeSystemClang::CreateClassTemplateSpecializationDecl( class_template_specialization_decl->setSpecializationKind( TSK_ExplicitSpecialization); + class_template_specialization_decl->setLocation(GetLocForDecl(declaration)); + return class_template_specialization_decl; } @@ -2188,7 +2197,8 @@ std::string TypeSystemClang::GetTypeNameForDecl(const NamedDecl *named_decl, FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, llvm::StringRef name, const CompilerType &function_clang_type, - clang::StorageClass storage, bool is_inline) { + clang::StorageClass storage, bool is_inline, + const Declaration &declaration) { FunctionDecl *func_decl = nullptr; ASTContext &ast = getASTContext(); if (!decl_ctx) @@ -2209,6 +2219,11 @@ FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( func_decl->setConstexprKind(isConstexprSpecified ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified); + + const clang::SourceLocation location = GetLocForDecl(declaration); + func_decl->setLocation(location); + func_decl->setRangeEnd(location); + SetOwningModule(func_decl, owning_module); decl_ctx->addDecl(func_decl); @@ -2258,7 +2273,7 @@ CompilerType TypeSystemClang::CreateFunctionType( ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, const char *name, const CompilerType ¶m_type, int storage, - bool add_decl) { + clang::SourceLocation loc, bool add_decl) { ASTContext &ast = getASTContext(); auto *decl = ParmVarDecl::CreateDeserialized(ast, GlobalDeclID()); decl->setDeclContext(decl_ctx); @@ -2266,6 +2281,7 @@ ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( decl->setDeclName(&ast.Idents.get(name)); decl->setType(ClangUtil::GetQualType(param_type)); decl->setStorageClass(static_cast<clang::StorageClass>(storage)); + decl->setLocation(loc); SetOwningModule(decl, owning_module); if (add_decl) decl_ctx->addDecl(decl); @@ -2355,10 +2371,10 @@ CompilerType TypeSystemClang::CreateEnumerationType( OptionalClangModuleID owning_module, const Declaration &decl, const CompilerType &integer_clang_type, bool is_scoped, std::optional<clang::EnumExtensibilityAttr::Kind> enum_kind) { - // TODO: Do something intelligent with the Declaration object passed in - // like maybe filling in the SourceLocation with it... ASTContext &ast = getASTContext(); + auto location = GetLocForDecl(decl); + // TODO: ask about these... // const bool IsFixed = false; EnumDecl *enum_decl = EnumDecl::CreateDeserialized(ast, GlobalDeclID()); @@ -2368,6 +2384,8 @@ CompilerType TypeSystemClang::CreateEnumerationType( enum_decl->setScoped(is_scoped); enum_decl->setScopedUsingClassTag(is_scoped); enum_decl->setFixed(false); + enum_decl->setLocation(location); + enum_decl->setLocStart(location); SetOwningModule(enum_decl, owning_module); if (decl_ctx) decl_ctx->addDecl(enum_decl); @@ -7794,10 +7812,10 @@ TypeSystemClang::CreateParameterDeclarations( llvm::StringRef name = !parameter_names.empty() ? parameter_names[param_index] : ""; - auto *param = - CreateParameterDeclaration(func, /*owning_module=*/{}, name.data(), - GetType(prototype.getParamType(param_index)), - clang::SC_None, /*add_decl=*/false); + auto *param = CreateParameterDeclaration( + func, /*owning_module=*/{}, name.data(), + GetType(prototype.getParamType(param_index)), clang::SC_None, + func->getLocation(), /*add_decl=*/false); assert(param); params.push_back(param); @@ -7810,7 +7828,8 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType( lldb::opaque_compiler_type_t type, llvm::StringRef name, const char *mangled_name, const CompilerType &method_clang_type, lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline, - bool is_explicit, bool is_attr_used, bool is_artificial) { + bool is_explicit, bool is_attr_used, bool is_artificial, + const Declaration &declaration) { if (!type || !method_clang_type.IsValid() || name.empty()) return nullptr; @@ -7951,6 +7970,10 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType( cxx_method_decl->setParams(CreateParameterDeclarations( cxx_method_decl, *method_function_prototype, /*parameter_names=*/{})); + const clang::SourceLocation location = GetLocForDecl(declaration); + cxx_method_decl->setLocation(location); + cxx_method_decl->setRangeEnd(location); + AddAccessSpecifierDecl(cxx_record_decl, getASTContext(), GetCXXRecordDeclAccess(cxx_record_decl), access_specifier); diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 99d9becffd128..1e3b5a46e86d3 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -326,13 +326,12 @@ class TypeSystemClang : public TypeSystem { bool is_framework = false, bool is_explicit = false); - CompilerType - CreateRecordType(clang::DeclContext *decl_ctx, - OptionalClangModuleID owning_module, - lldb::AccessType access_type, llvm::StringRef name, int kind, - lldb::LanguageType language, - std::optional<ClangASTMetadata> metadata = std::nullopt, - bool exports_symbols = false); + CompilerType CreateRecordType( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + lldb::AccessType access_type, llvm::StringRef name, int kind, + lldb::LanguageType language, + std::optional<ClangASTMetadata> metadata = std::nullopt, + bool exports_symbols = false, const Declaration &declaration = {}); class TemplateParameterInfos { public: @@ -420,7 +419,8 @@ class TypeSystemClang : public TypeSystem { clang::FunctionTemplateDecl *CreateFunctionTemplateDecl( clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, - clang::FunctionDecl *func_decl, const TemplateParameterInfos &infos); + clang::FunctionDecl *func_decl, const TemplateParameterInfos &infos, + const Declaration &declaration); void CreateFunctionTemplateSpecializationInfo( clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template, @@ -437,7 +437,7 @@ class TypeSystemClang : public TypeSystem { clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl( clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, clang::ClassTemplateDecl *class_template_decl, int kind, - const TemplateParameterInfos &infos); + const TemplateParameterInfos &infos, const Declaration &declaration); CompilerType CreateClassTemplateSpecializationType(clang::ClassTemplateSpecializationDecl * @@ -476,7 +476,8 @@ class TypeSystemClang : public TypeSystem { clang::FunctionDecl *CreateFunctionDeclaration( clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, llvm::StringRef name, const CompilerType &function_Type, - clang::StorageClass storage, bool is_inline); + clang::StorageClass storage, bool is_inline, + const Declaration &declaration = {}); CompilerType CreateFunctionType(const CompilerType &result_type, const CompilerType *args, @@ -484,11 +485,10 @@ class TypeSystemClang : public TypeSystem { clang::CallingConv cc = clang::CC_C, clang::RefQualifierKind ref_qual = clang::RQ_None); - clang::ParmVarDecl * - CreateParameterDeclaration(clang::DeclContext *decl_ctx, - OptionalClangModuleID owning_module, - const char *name, const CompilerType ¶m_type, - int storage, bool add_decl = false); + clang::ParmVarDecl *CreateParameterDeclaration( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + const char *name, const CompilerType ¶m_type, int storage, + clang::SourceLocation loc, bool add_decl = false); CompilerType CreateBlockPointerType(const CompilerType &function_type); @@ -996,7 +996,8 @@ class TypeSystemClang : public TypeSystem { lldb::opaque_compiler_type_t type, llvm::StringRef name, const char *mangled_name, const CompilerType &method_type, lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline, - bool is_explicit, bool is_attr_used, bool is_artificial); + bool is_explicit, bool is_attr_used, bool is_artificial, + const Declaration &declaration = {}); void AddMethodOverridesForCXXRecordType(lldb::opaque_compiler_type_t type); @@ -1188,6 +1189,19 @@ class TypeSystemClang : public TypeSystem { std::optional<uint64_t> GetObjCBitSize(clang::QualType qual_type, ExecutionContextScope *exe_scope); + /// Turns the given \c decl into a \c clang::SourceLocation. + /// + /// Will create a \c FileID in this \c DWARFASTParserClang's \c ASTContext + /// if necessary. + /// + /// If no \c FileID could be found/created, returns an empty \c + /// SourceLocation. + /// + /// FIXME: currently a no-op. + clang::SourceLocation GetLocForDecl(const lldb_private::Declaration &decl) { + return {}; + } + // Classes that inherit from TypeSystemClang can see and modify these std::string m_target_triple; std::unique_ptr<clang::ASTContext> m_ast_up; >From 5dae80a41893b9cfe489118a3c45087de4486321 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Wed, 19 Feb 2025 16:42:37 +0000 Subject: [PATCH 3/3] [lldb][TypeSystemClang] Create FileIDs/SourceLocations from DWARF --- .../TypeSystem/Clang/TypeSystemClang.cpp | 30 +++++++++++++++++++ .../TypeSystem/Clang/TypeSystemClang.h | 6 +--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index cf3be07dd092f..e03bb8b952e39 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -9944,3 +9944,33 @@ void TypeSystemClang::LogCreation() const { LLDB_LOG(log, "Created new TypeSystem for (ASTContext*){0:x} '{1}'", &getASTContext(), getDisplayName()); } + +clang::SourceLocation TypeSystemClang::GetLocForDecl(const Declaration &decl) { + // If the Declaration is invalid there is nothing to do. + if (!decl.IsValid()) + return {}; + + clang::SourceManager &sm = getASTContext().getSourceManager(); + clang::FileManager &fm = sm.getFileManager(); + + auto fe = fm.getFileRef(decl.GetFile().GetPath()); + if (!fe) + return {}; + + clang::FileID fid = sm.translateFile(*fe); + if (fid.isInvalid()) { + // We see the file for the first time, so create a dummy file for it now. + + // Connect the new dummy file to the main file via some fake include + // location. This is necessary as all file's in the SourceManager need to be + // reachable via an include chain from the main file. + SourceLocation ToIncludeLocOrFakeLoc; + assert(sm.getMainFileID().isValid()); + ToIncludeLocOrFakeLoc = sm.getLocForStartOfFile(sm.getMainFileID()); + fid = sm.createFileID(*fe, ToIncludeLocOrFakeLoc, clang::SrcMgr::C_User); + } + + // Clang requires column numbers to be >= 1.. + return sm.translateLineCol(fid, decl.GetLine(), + std::max<uint16_t>(decl.GetColumn(), 1)); +} diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 1e3b5a46e86d3..f59eaee6705f9 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -1196,11 +1196,7 @@ class TypeSystemClang : public TypeSystem { /// /// If no \c FileID could be found/created, returns an empty \c /// SourceLocation. - /// - /// FIXME: currently a no-op. - clang::SourceLocation GetLocForDecl(const lldb_private::Declaration &decl) { - return {}; - } + clang::SourceLocation GetLocForDecl(const lldb_private::Declaration &decl); // Classes that inherit from TypeSystemClang can see and modify these std::string m_target_triple; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits