Skip to content

Commit

Permalink
Extend FindTypes with CompilerContext to allow filtering by language.
Browse files Browse the repository at this point in the history
This patch is also motivated by the Swift branch and is effectively NFC for the single-TypeSystem llvm.org branch.

In multi-language projects it is extremely common to have, e.g., a
Clang type and a similarly-named rendition of that same type in
another language. When searching for a type It is much cheaper to pass
a set of supported languages to the SymbolFile than having it
materialize every result and then rejecting the materialized types
that have the wrong language.

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

<rdar://problem/54471165>

llvm-svn: 369690
  • Loading branch information
adrian-prantl committed Aug 22, 2019
1 parent 6c6dd6a commit aa3a564
Show file tree
Hide file tree
Showing 25 changed files with 201 additions and 198 deletions.
41 changes: 14 additions & 27 deletions lldb/include/lldb/Core/PluginManager.h
Expand Up @@ -384,10 +384,10 @@ class PluginManager {
GetInstrumentationRuntimeCreateCallbackForPluginName(ConstString name);

// TypeSystem
static bool RegisterPlugin(
ConstString name, const char *description,
TypeSystemCreateInstance create_callback,
TypeSystemEnumerateSupportedLanguages enumerate_languages_callback);
static bool RegisterPlugin(ConstString name, const char *description,
TypeSystemCreateInstance create_callback,
LanguageSet supported_languages_for_types,
LanguageSet supported_languages_for_expressions);

static bool UnregisterPlugin(TypeSystemCreateInstance create_callback);

Expand All @@ -397,18 +397,14 @@ class PluginManager {
static TypeSystemCreateInstance
GetTypeSystemCreateCallbackForPluginName(ConstString name);

static TypeSystemEnumerateSupportedLanguages
GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx);
static LanguageSet GetAllTypeSystemSupportedLanguagesForTypes();

static TypeSystemEnumerateSupportedLanguages
GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
ConstString name);
static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions();

// REPL
static bool
RegisterPlugin(ConstString name, const char *description,
REPLCreateInstance create_callback,
REPLEnumerateSupportedLanguages enumerate_languages_callback);
static bool RegisterPlugin(ConstString name, const char *description,
REPLCreateInstance create_callback,
LanguageSet supported_languages);

static bool UnregisterPlugin(REPLCreateInstance create_callback);

Expand All @@ -417,12 +413,7 @@ class PluginManager {
static REPLCreateInstance
GetREPLCreateCallbackForPluginName(ConstString name);

static REPLEnumerateSupportedLanguages
GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx);

static REPLEnumerateSupportedLanguages
GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
ConstString name);
static LanguageSet GetREPLAllTypeSystemSupportedLanguages();

// Some plug-ins might register a DebuggerInitializeCallback callback when
// registering the plug-in. After a new Debugger instance is created, this
Expand All @@ -440,32 +431,28 @@ class PluginManager {
ConstString description, bool is_global_property);

static lldb::OptionValuePropertiesSP
GetSettingForPlatformPlugin(Debugger &debugger,
ConstString setting_name);
GetSettingForPlatformPlugin(Debugger &debugger, ConstString setting_name);

static bool CreateSettingForPlatformPlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
ConstString description, bool is_global_property);

static lldb::OptionValuePropertiesSP
GetSettingForProcessPlugin(Debugger &debugger,
ConstString setting_name);
GetSettingForProcessPlugin(Debugger &debugger, ConstString setting_name);

static bool CreateSettingForProcessPlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
ConstString description, bool is_global_property);

static lldb::OptionValuePropertiesSP
GetSettingForSymbolFilePlugin(Debugger &debugger,
ConstString setting_name);
GetSettingForSymbolFilePlugin(Debugger &debugger, ConstString setting_name);

static bool CreateSettingForSymbolFilePlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
ConstString description, bool is_global_property);

static lldb::OptionValuePropertiesSP
GetSettingForJITLoaderPlugin(Debugger &debugger,
ConstString setting_name);
GetSettingForJITLoaderPlugin(Debugger &debugger, ConstString setting_name);

static bool CreateSettingForJITLoaderPlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
Expand Down
5 changes: 2 additions & 3 deletions lldb/include/lldb/Symbol/ClangASTContext.h
Expand Up @@ -68,9 +68,8 @@ class ClangASTContext : public TypeSystem {
static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language,
Module *module, Target *target);

static void EnumerateSupportedLanguages(
std::set<lldb::LanguageType> &languages_for_types,
std::set<lldb::LanguageType> &languages_for_expressions);
static LanguageSet GetSupportedLanguagesForTypes();
static LanguageSet GetSupportedLanguagesForExpressions();

static void Initialize();

Expand Down
7 changes: 6 additions & 1 deletion lldb/include/lldb/Symbol/SymbolFile.h
Expand Up @@ -17,6 +17,7 @@
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/lldb-private.h"

#include "llvm/ADT/DenseSet.h"
Expand Down Expand Up @@ -189,7 +190,11 @@ class SymbolFile : public PluginInterface {
bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types);
virtual size_t FindTypes(llvm::ArrayRef<CompilerContext> pattern, bool append,

/// Find types specified by a CompilerContextPattern.
/// \param languages Only return results in these languages.
virtual size_t FindTypes(llvm::ArrayRef<CompilerContext> pattern,
LanguageSet languages, bool append,
TypeMap &types);

virtual void
Expand Down
20 changes: 19 additions & 1 deletion lldb/include/lldb/Symbol/TypeSystem.h
Expand Up @@ -15,6 +15,7 @@
#include <string>

#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"

Expand All @@ -30,7 +31,24 @@ class PDBASTParser;

namespace lldb_private {

// Interface for representing the Type Systems in different languages.
/// A SmallBitVector that represents a set of source languages (\p
/// lldb::LanguageType). Each lldb::LanguageType is represented by
/// the bit with the position of its enumerator. The largest
/// LanguageType is < 64, so this is space-efficient and on 64-bit
/// architectures a LanguageSet can be completely stack-allocated.
struct LanguageSet {
llvm::SmallBitVector bitvector;
LanguageSet() = default;

/// If the set contains a single language only, return it.
llvm::Optional<lldb::LanguageType> GetSingularLanguage();
void Insert(lldb::LanguageType language);
bool Empty() const;
size_t Size() const;
bool operator[](unsigned i) const;
};

/// Interface for representing the Type Systems in different languages.
class TypeSystem : public PluginInterface {
public:
// Intrusive type system that allows us to use llvm casting.
Expand Down
9 changes: 3 additions & 6 deletions lldb/include/lldb/Target/Language.h
Expand Up @@ -266,12 +266,9 @@ class Language : public PluginInterface {

static std::set<lldb::LanguageType> GetSupportedLanguages();

static void GetLanguagesSupportingTypeSystems(
std::set<lldb::LanguageType> &languages,
std::set<lldb::LanguageType> &languages_for_expressions);

static void
GetLanguagesSupportingREPLs(std::set<lldb::LanguageType> &languages);
static LanguageSet GetLanguagesSupportingTypeSystems();
static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions();
static LanguageSet GetLanguagesSupportingREPLs();

protected:
// Classes that inherit from Language can see and modify these
Expand Down
5 changes: 0 additions & 5 deletions lldb/include/lldb/lldb-private-interfaces.h
Expand Up @@ -102,11 +102,6 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error,
lldb::LanguageType language,
Debugger *debugger, Target *target,
const char *repl_options);
typedef void (*TypeSystemEnumerateSupportedLanguages)(
std::set<lldb::LanguageType> &languages_for_types,
std::set<lldb::LanguageType> &languages_for_expressions);
typedef void (*REPLEnumerateSupportedLanguages)(
std::set<lldb::LanguageType> &languages);
typedef int (*ComparisonFunction)(const void *, const void *);
typedef void (*DebuggerInitializeCallback)(Debugger &debugger);

Expand Down
13 changes: 8 additions & 5 deletions lldb/lit/SymbolFile/DWARF/compilercontext.ll
@@ -1,18 +1,21 @@
; Test finding types by CompilerContext.
; RUN: llc %s -filetype=obj -o %t.o
; RUN: lldb-test symbols %t.o -find=type \
; RUN: lldb-test symbols %t.o -find=type --language=C99 \
; RUN: -compiler-context="Module:CModule,Module:SubModule,Struct:FromSubmoduleX" \
; RUN: | FileCheck %s --check-prefix=NORESULTS
; RUN: lldb-test symbols %t.o -find=type \
; RUN: lldb-test symbols %t.o -find=type --language=C++ \
; RUN: -compiler-context="Module:CModule,Module:SubModule,Struct:FromSubmodule" \
; RUN: | FileCheck %s --check-prefix=NORESULTS
; RUN: lldb-test symbols %t.o -find=type --language=C99 \
; RUN: -compiler-context="Module:CModule,Module:SubModule,Struct:FromSubmodule" \
; RUN: | FileCheck %s
; RUN: lldb-test symbols %t.o -find=type \
; RUN: lldb-test symbols %t.o -find=type --language=C99 \
; RUN: -compiler-context="Module:CModule,AnyModule:*,Struct:FromSubmodule" \
; RUN: | FileCheck %s
; RUN: lldb-test symbols %t.o -find=type \
; RUN: lldb-test symbols %t.o -find=type --language=C99 \
; RUN: -compiler-context="AnyModule:*,Struct:FromSubmodule" \
; RUN: | FileCheck %s
; RUN: lldb-test symbols %t.o -find=type \
; RUN: lldb-test symbols %t.o -find=type --language=C99 \
; RUN: -compiler-context="Module:CModule,Module:SubModule,AnyType:FromSubmodule" \
; RUN: | FileCheck %s
;
Expand Down
10 changes: 4 additions & 6 deletions lldb/source/Core/Debugger.cpp
Expand Up @@ -1623,13 +1623,11 @@ Status Debugger::RunREPL(LanguageType language, const char *repl_options) {
FileSpec repl_executable;

if (language == eLanguageTypeUnknown) {
std::set<LanguageType> repl_languages;
LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();

Language::GetLanguagesSupportingREPLs(repl_languages);

if (repl_languages.size() == 1) {
language = *repl_languages.begin();
} else if (repl_languages.empty()) {
if (auto single_lang = repl_languages.GetSingularLanguage()) {
language = *single_lang;
} else if (repl_languages.Empty()) {
err.SetErrorStringWithFormat(
"LLDB isn't configured with REPL support for any languages.");
return err;
Expand Down
87 changes: 31 additions & 56 deletions lldb/source/Core/PluginManager.cpp
Expand Up @@ -2083,12 +2083,11 @@ PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName(
#pragma mark TypeSystem

struct TypeSystemInstance {
TypeSystemInstance() : name(), description(), create_callback(nullptr) {}

ConstString name;
std::string description;
TypeSystemCreateInstance create_callback;
TypeSystemEnumerateSupportedLanguages enumerate_callback;
LanguageSet supported_languages_for_types;
LanguageSet supported_languages_for_expressions;
};

typedef std::vector<TypeSystemInstance> TypeSystemInstances;
Expand All @@ -2103,19 +2102,20 @@ static TypeSystemInstances &GetTypeSystemInstances() {
return g_instances;
}

bool PluginManager::RegisterPlugin(ConstString name,
const char *description,
TypeSystemCreateInstance create_callback,
TypeSystemEnumerateSupportedLanguages
enumerate_supported_languages_callback) {
bool PluginManager::RegisterPlugin(
ConstString name, const char *description,
TypeSystemCreateInstance create_callback,
LanguageSet supported_languages_for_types,
LanguageSet supported_languages_for_expressions) {
if (create_callback) {
TypeSystemInstance instance;
assert((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
instance.enumerate_callback = enumerate_supported_languages_callback;
instance.supported_languages_for_types = supported_languages_for_types;
instance.supported_languages_for_expressions = supported_languages_for_expressions;
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
GetTypeSystemInstances().push_back(instance);
}
Expand Down Expand Up @@ -2163,30 +2163,22 @@ PluginManager::GetTypeSystemCreateCallbackForPluginName(
return nullptr;
}

TypeSystemEnumerateSupportedLanguages
PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
uint32_t idx) {
LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
LanguageSet all;
TypeSystemInstances &instances = GetTypeSystemInstances();
if (idx < instances.size())
return instances[idx].enumerate_callback;
return nullptr;
for (unsigned i = 0; i < instances.size(); ++i)
all.bitvector |= instances[i].supported_languages_for_types.bitvector;
return all;
}

TypeSystemEnumerateSupportedLanguages
PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
ConstString name) {
if (name) {
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances();

TypeSystemInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++pos) {
if (name == pos->name)
return pos->enumerate_callback;
}
}
return nullptr;
LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
LanguageSet all;
TypeSystemInstances &instances = GetTypeSystemInstances();
for (unsigned i = 0; i < instances.size(); ++i)
all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
return all;
}

#pragma mark REPL
Expand All @@ -2197,7 +2189,7 @@ struct REPLInstance {
ConstString name;
std::string description;
REPLCreateInstance create_callback;
REPLEnumerateSupportedLanguages enumerate_languages_callback;
LanguageSet supported_languages;
};

typedef std::vector<REPLInstance> REPLInstances;
Expand All @@ -2212,18 +2204,17 @@ static REPLInstances &GetREPLInstances() {
return g_instances;
}

bool PluginManager::RegisterPlugin(
ConstString name, const char *description,
REPLCreateInstance create_callback,
REPLEnumerateSupportedLanguages enumerate_languages_callback) {
bool PluginManager::RegisterPlugin(ConstString name, const char *description,
REPLCreateInstance create_callback,
LanguageSet supported_languages) {
if (create_callback) {
REPLInstance instance;
assert((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
instance.enumerate_languages_callback = enumerate_languages_callback;
instance.supported_languages = supported_languages;
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
GetREPLInstances().push_back(instance);
}
Expand Down Expand Up @@ -2269,29 +2260,13 @@ PluginManager::GetREPLCreateCallbackForPluginName(ConstString name) {
return nullptr;
}

REPLEnumerateSupportedLanguages
PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
LanguageSet all;
REPLInstances &instances = GetREPLInstances();
if (idx < instances.size())
return instances[idx].enumerate_languages_callback;
return nullptr;
}

REPLEnumerateSupportedLanguages
PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
ConstString name) {
if (name) {
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances();

REPLInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++pos) {
if (name == pos->name)
return pos->enumerate_languages_callback;
}
}
return nullptr;
for (unsigned i = 0; i < instances.size(); ++i)
all.bitvector |= instances[i].supported_languages.bitvector;
return all;
}

#pragma mark PluginManager
Expand Down

0 comments on commit aa3a564

Please sign in to comment.