Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);

Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
120 changes: 108 additions & 12 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/ExprCXX.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/SmallVectorMemoryBuffer.h"

#include <mutex>
#include <memory>
Expand Down Expand Up @@ -361,6 +363,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,
Expand Down Expand Up @@ -692,6 +727,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
Expand Down Expand Up @@ -1243,7 +1283,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)
Expand Down Expand Up @@ -1298,6 +1338,10 @@ CompilerType TypeSystemClang::CreateRecordType(
decl->setAnonymousStructOrUnion(true);
}

auto location = GetLocForDecl(declaration);
decl->setLocStart(location);
decl->setLocation(location);

if (metadata)
SetMetadata(decl, *metadata);

Expand Down Expand Up @@ -1415,7 +1459,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();

Expand All @@ -1429,6 +1474,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();
Expand Down Expand Up @@ -1654,7 +1700,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() +
Expand Down Expand Up @@ -1689,6 +1736,8 @@ TypeSystemClang::CreateClassTemplateSpecializationDecl(
class_template_specialization_decl->setSpecializationKind(
TSK_ExplicitSpecialization);

class_template_specialization_decl->setLocation(GetLocForDecl(declaration));

return class_template_specialization_decl;
}

Expand Down Expand Up @@ -2149,7 +2198,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)
Expand All @@ -2170,6 +2220,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);

Expand Down Expand Up @@ -2219,14 +2274,15 @@ 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);
if (name && name[0])
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);
Expand Down Expand Up @@ -2316,10 +2372,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());
Expand All @@ -2329,6 +2385,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);
Expand Down Expand Up @@ -7755,10 +7813,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);
Expand All @@ -7771,7 +7830,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;

Expand Down Expand Up @@ -7912,6 +7972,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);
Expand Down Expand Up @@ -9882,3 +9946,35 @@ 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) {
llvm::consumeError(fe.takeError());
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));
}
Loading