Skip to content

Commit 16c0653

Browse files
committed
[lldb][NFC] Extract searching for function SymbolContexts out of ClangExpressionDeclMap::LookupFunction
This code was just creating a new SymbolContextList with any found functions in the front and orders them by how close they are to the current frame. This refactors this code into its own function to make this more obvious. Doesn't do any other changes to the code, so this is NFC.
1 parent 26bf2a5 commit 16c0653

File tree

2 files changed

+116
-92
lines changed

2 files changed

+116
-92
lines changed

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp

Lines changed: 99 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,104 @@ bool ClangExpressionDeclMap::LookupLocalVariable(
11771177
return variable_found;
11781178
}
11791179

1180+
/// Structure to hold the info needed when comparing function
1181+
/// declarations.
1182+
namespace {
1183+
struct FuncDeclInfo {
1184+
ConstString m_name;
1185+
CompilerType m_copied_type;
1186+
uint32_t m_decl_lvl;
1187+
SymbolContext m_sym_ctx;
1188+
};
1189+
} // namespace
1190+
1191+
SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts(
1192+
const SymbolContextList &sc_list,
1193+
const CompilerDeclContext &frame_decl_context) {
1194+
// First, symplify things by looping through the symbol contexts to
1195+
// remove unwanted functions and separate out the functions we want to
1196+
// compare and prune into a separate list. Cache the info needed about
1197+
// the function declarations in a vector for efficiency.
1198+
uint32_t num_indices = sc_list.GetSize();
1199+
SymbolContextList sc_sym_list;
1200+
std::vector<FuncDeclInfo> decl_infos;
1201+
decl_infos.reserve(num_indices);
1202+
clang::DeclContext *frame_decl_ctx =
1203+
(clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
1204+
ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
1205+
frame_decl_context.GetTypeSystem());
1206+
1207+
for (uint32_t index = 0; index < num_indices; ++index) {
1208+
FuncDeclInfo fdi;
1209+
SymbolContext sym_ctx;
1210+
sc_list.GetContextAtIndex(index, sym_ctx);
1211+
1212+
// We don't know enough about symbols to compare them, but we should
1213+
// keep them in the list.
1214+
Function *function = sym_ctx.function;
1215+
if (!function) {
1216+
sc_sym_list.Append(sym_ctx);
1217+
continue;
1218+
}
1219+
// Filter out functions without declaration contexts, as well as
1220+
// class/instance methods, since they'll be skipped in the code that
1221+
// follows anyway.
1222+
CompilerDeclContext func_decl_context = function->GetDeclContext();
1223+
if (!func_decl_context ||
1224+
func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
1225+
continue;
1226+
// We can only prune functions for which we can copy the type.
1227+
CompilerType func_clang_type = function->GetType()->GetFullCompilerType();
1228+
CompilerType copied_func_type = GuardedCopyType(func_clang_type);
1229+
if (!copied_func_type) {
1230+
sc_sym_list.Append(sym_ctx);
1231+
continue;
1232+
}
1233+
1234+
fdi.m_sym_ctx = sym_ctx;
1235+
fdi.m_name = function->GetName();
1236+
fdi.m_copied_type = copied_func_type;
1237+
fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
1238+
if (fdi.m_copied_type && func_decl_context) {
1239+
// Call CountDeclLevels to get the number of parent scopes we have
1240+
// to look through before we find the function declaration. When
1241+
// comparing functions of the same type, the one with a lower count
1242+
// will be closer to us in the lookup scope and shadows the other.
1243+
clang::DeclContext *func_decl_ctx =
1244+
(clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
1245+
fdi.m_decl_lvl = ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx,
1246+
&fdi.m_name, &fdi.m_copied_type);
1247+
}
1248+
decl_infos.emplace_back(fdi);
1249+
}
1250+
1251+
// Loop through the functions in our cache looking for matching types,
1252+
// then compare their scope levels to see which is closer.
1253+
std::multimap<CompilerType, const FuncDeclInfo *> matches;
1254+
for (const FuncDeclInfo &fdi : decl_infos) {
1255+
const CompilerType t = fdi.m_copied_type;
1256+
auto q = matches.find(t);
1257+
if (q != matches.end()) {
1258+
if (q->second->m_decl_lvl > fdi.m_decl_lvl)
1259+
// This function is closer; remove the old set.
1260+
matches.erase(t);
1261+
else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
1262+
// The functions in our set are closer - skip this one.
1263+
continue;
1264+
}
1265+
matches.insert(std::make_pair(t, &fdi));
1266+
}
1267+
1268+
// Loop through our matches and add their symbol contexts to our list.
1269+
SymbolContextList sc_func_list;
1270+
for (const auto &q : matches)
1271+
sc_func_list.Append(q.second->m_sym_ctx);
1272+
1273+
// Rejoin the lists with the functions in front.
1274+
sc_func_list.Append(sc_sym_list);
1275+
return sc_func_list;
1276+
}
1277+
11801278
void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
11811279
lldb::ModuleSP module_sp,
11821280
ConstString name,
@@ -1234,98 +1332,7 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
12341332

12351333
// We can't do this without a compiler decl context for our frame.
12361334
if (frame_decl_context) {
1237-
clang::DeclContext *frame_decl_ctx =
1238-
(clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
1239-
ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
1240-
frame_decl_context.GetTypeSystem());
1241-
1242-
// Structure to hold the info needed when comparing function
1243-
// declarations.
1244-
struct FuncDeclInfo {
1245-
ConstString m_name;
1246-
CompilerType m_copied_type;
1247-
uint32_t m_decl_lvl;
1248-
SymbolContext m_sym_ctx;
1249-
};
1250-
1251-
// First, symplify things by looping through the symbol contexts to
1252-
// remove unwanted functions and separate out the functions we want to
1253-
// compare and prune into a separate list. Cache the info needed about
1254-
// the function declarations in a vector for efficiency.
1255-
SymbolContextList sc_sym_list;
1256-
uint32_t num_indices = sc_list.GetSize();
1257-
std::vector<FuncDeclInfo> fdi_cache;
1258-
fdi_cache.reserve(num_indices);
1259-
for (uint32_t index = 0; index < num_indices; ++index) {
1260-
FuncDeclInfo fdi;
1261-
SymbolContext sym_ctx;
1262-
sc_list.GetContextAtIndex(index, sym_ctx);
1263-
1264-
// We don't know enough about symbols to compare them, but we should
1265-
// keep them in the list.
1266-
Function *function = sym_ctx.function;
1267-
if (!function) {
1268-
sc_sym_list.Append(sym_ctx);
1269-
continue;
1270-
}
1271-
// Filter out functions without declaration contexts, as well as
1272-
// class/instance methods, since they'll be skipped in the code that
1273-
// follows anyway.
1274-
CompilerDeclContext func_decl_context = function->GetDeclContext();
1275-
if (!func_decl_context ||
1276-
func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
1277-
continue;
1278-
// We can only prune functions for which we can copy the type.
1279-
CompilerType func_clang_type =
1280-
function->GetType()->GetFullCompilerType();
1281-
CompilerType copied_func_type = GuardedCopyType(func_clang_type);
1282-
if (!copied_func_type) {
1283-
sc_sym_list.Append(sym_ctx);
1284-
continue;
1285-
}
1286-
1287-
fdi.m_sym_ctx = sym_ctx;
1288-
fdi.m_name = function->GetName();
1289-
fdi.m_copied_type = copied_func_type;
1290-
fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
1291-
if (fdi.m_copied_type && func_decl_context) {
1292-
// Call CountDeclLevels to get the number of parent scopes we have
1293-
// to look through before we find the function declaration. When
1294-
// comparing functions of the same type, the one with a lower count
1295-
// will be closer to us in the lookup scope and shadows the other.
1296-
clang::DeclContext *func_decl_ctx =
1297-
(clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
1298-
fdi.m_decl_lvl = ast->CountDeclLevels(
1299-
frame_decl_ctx, func_decl_ctx, &fdi.m_name, &fdi.m_copied_type);
1300-
}
1301-
fdi_cache.emplace_back(fdi);
1302-
}
1303-
1304-
// Loop through the functions in our cache looking for matching types,
1305-
// then compare their scope levels to see which is closer.
1306-
std::multimap<CompilerType, const FuncDeclInfo *> matches;
1307-
for (const FuncDeclInfo &fdi : fdi_cache) {
1308-
const CompilerType t = fdi.m_copied_type;
1309-
auto q = matches.find(t);
1310-
if (q != matches.end()) {
1311-
if (q->second->m_decl_lvl > fdi.m_decl_lvl)
1312-
// This function is closer; remove the old set.
1313-
matches.erase(t);
1314-
else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
1315-
// The functions in our set are closer - skip this one.
1316-
continue;
1317-
}
1318-
matches.insert(std::make_pair(t, &fdi));
1319-
}
1320-
1321-
// Loop through our matches and add their symbol contexts to our list.
1322-
SymbolContextList sc_func_list;
1323-
for (const auto &q : matches)
1324-
sc_func_list.Append(q.second->m_sym_ctx);
1325-
1326-
// Rejoin the lists with the functions in front.
1327-
sc_list = sc_func_list;
1328-
sc_list.Append(sc_sym_list);
1335+
sc_list = SearchFunctionsInSymbolContexts(sc_list, frame_decl_context);
13291336
}
13301337
}
13311338

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,23 @@ class ClangExpressionDeclMap : public ClangASTSource {
458458
unsigned current_id, SymbolContext &sym_ctx,
459459
CompilerDeclContext &namespace_decl);
460460

461+
/// Searches for functions in the given SymbolContextList.
462+
///
463+
/// \param[in] sc_list
464+
/// The SymbolContextList to search.
465+
///
466+
/// \param[in] frame_decl_context
467+
/// The current DeclContext of the current frame.
468+
///
469+
/// \return
470+
/// A SymbolContextList with any found functions in the front and
471+
/// any unknown SymbolContexts which are not functions in the back.
472+
/// The SymbolContexts for the functions are ordered by how close they are
473+
/// to the DeclContext for the given frame DeclContext.
474+
SymbolContextList SearchFunctionsInSymbolContexts(
475+
const SymbolContextList &sc_list,
476+
const CompilerDeclContext &frame_decl_context);
477+
461478
/// Looks up a function.
462479
///
463480
/// \param[in] context

0 commit comments

Comments
 (0)