[Lldb-commits] [lldb] [WIP] [lldb][TypeSystemClang] Create clang::SourceLocation from DWARF and attach to AST (PR #127829)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Wed Feb 19 09:24:38 PST 2025


https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/127829

>From 1aabc8a93ffac06755cbaf5e6c1fa8913cd63729 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at 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 68b389059b1bee5401f6173351c16c59b7286f69 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at 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      | 48 ++++++++++++++-----
 .../TypeSystem/Clang/TypeSystemClang.h        | 46 +++++++++++-------
 5 files changed, 74 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..c9a2c33567aaf 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 &param_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,11 @@ 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);
+    // FIXME: we should pass the location of the parameter not the function
+    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 +7829,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 +7971,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 &param_type,
-                             int storage, bool add_decl = false);
+  clang::ParmVarDecl *CreateParameterDeclaration(
+      clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+      const char *name, const CompilerType &param_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 c998ea306fbe5d15e62bbe16b8a3b6d1ed07098e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at 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 c9a2c33567aaf..cb203d7a83cbc 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -9945,3 +9945,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;



More information about the lldb-commits mailing list