mirror of
https://github.com/intel/llvm.git
synced 2026-02-08 00:50:03 +08:00
[lldb][NFC] Move NameSearchContext to own header/source files
The class is large enough to be in its own file. This patch also removes the cyclic dependency between ClangASTSource <-> NameSearchContext.
This commit is contained in:
@@ -271,7 +271,6 @@ class WatchpointList;
|
||||
class WatchpointOptions;
|
||||
struct CompilerContext;
|
||||
struct LineEntry;
|
||||
struct NameSearchContext;
|
||||
struct PropertyDefinition;
|
||||
struct ScriptSummaryFormat;
|
||||
struct StringSummaryFormat;
|
||||
|
||||
@@ -26,6 +26,7 @@ add_lldb_library(lldbPluginExpressionParserClang
|
||||
CxxModuleHandler.cpp
|
||||
IRForTarget.cpp
|
||||
IRDynamicChecks.cpp
|
||||
NameSearchContext.cpp
|
||||
|
||||
DEPENDS
|
||||
${tablegen_deps}
|
||||
|
||||
@@ -140,7 +140,7 @@ bool ClangASTSource::FindExternalVisibleDeclsByName(
|
||||
case DeclarationName::ObjCMultiArgSelector: {
|
||||
llvm::SmallVector<NamedDecl *, 1> method_decls;
|
||||
|
||||
NameSearchContext method_search_context(*this, method_decls,
|
||||
NameSearchContext method_search_context(*m_clang_ast_context, method_decls,
|
||||
clang_decl_name, decl_ctx);
|
||||
|
||||
FindObjCMethodDecls(method_search_context);
|
||||
@@ -183,8 +183,8 @@ bool ClangASTSource::FindExternalVisibleDeclsByName(
|
||||
// printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth,
|
||||
// uniqued_const_decl_name);
|
||||
llvm::SmallVector<NamedDecl *, 4> name_decls;
|
||||
NameSearchContext name_search_context(*this, name_decls, clang_decl_name,
|
||||
decl_ctx);
|
||||
NameSearchContext name_search_context(*m_clang_ast_context, name_decls,
|
||||
clang_decl_name, decl_ctx);
|
||||
FindExternalVisibleDecls(name_search_context);
|
||||
SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, name_decls);
|
||||
// --g_depth;
|
||||
@@ -1760,170 +1760,3 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
|
||||
|
||||
return m_clang_ast_context->GetType(copied_qual_type);
|
||||
}
|
||||
|
||||
clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
|
||||
assert(type && "Type for variable must be valid!");
|
||||
|
||||
if (!type.IsValid())
|
||||
return nullptr;
|
||||
|
||||
TypeSystemClang *lldb_ast =
|
||||
llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
|
||||
if (!lldb_ast)
|
||||
return nullptr;
|
||||
|
||||
IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
|
||||
|
||||
clang::ASTContext &ast = lldb_ast->getASTContext();
|
||||
|
||||
clang::NamedDecl *Decl = VarDecl::Create(
|
||||
ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
|
||||
SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);
|
||||
m_decls.push_back(Decl);
|
||||
|
||||
return Decl;
|
||||
}
|
||||
|
||||
clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
|
||||
bool extern_c) {
|
||||
assert(type && "Type for variable must be valid!");
|
||||
|
||||
if (!type.IsValid())
|
||||
return nullptr;
|
||||
|
||||
if (m_function_types.count(type))
|
||||
return nullptr;
|
||||
|
||||
TypeSystemClang *lldb_ast =
|
||||
llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
|
||||
if (!lldb_ast)
|
||||
return nullptr;
|
||||
|
||||
m_function_types.insert(type);
|
||||
|
||||
QualType qual_type(ClangUtil::GetQualType(type));
|
||||
|
||||
clang::ASTContext &ast = lldb_ast->getASTContext();
|
||||
|
||||
const bool isInlineSpecified = false;
|
||||
const bool hasWrittenPrototype = true;
|
||||
const bool isConstexprSpecified = false;
|
||||
|
||||
clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
|
||||
|
||||
if (extern_c) {
|
||||
context = LinkageSpecDecl::Create(
|
||||
ast, context, SourceLocation(), SourceLocation(),
|
||||
clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
|
||||
}
|
||||
|
||||
// Pass the identifier info for functions the decl_name is needed for
|
||||
// operators
|
||||
clang::DeclarationName decl_name =
|
||||
m_decl_name.getNameKind() == DeclarationName::Identifier
|
||||
? m_decl_name.getAsIdentifierInfo()
|
||||
: m_decl_name;
|
||||
|
||||
clang::FunctionDecl *func_decl = FunctionDecl::Create(
|
||||
ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
|
||||
nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype,
|
||||
isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
|
||||
|
||||
// We have to do more than just synthesize the FunctionDecl. We have to
|
||||
// synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
|
||||
// this, we raid the function's FunctionProtoType for types.
|
||||
|
||||
const FunctionProtoType *func_proto_type =
|
||||
qual_type.getTypePtr()->getAs<FunctionProtoType>();
|
||||
|
||||
if (func_proto_type) {
|
||||
unsigned NumArgs = func_proto_type->getNumParams();
|
||||
unsigned ArgIndex;
|
||||
|
||||
SmallVector<ParmVarDecl *, 5> parm_var_decls;
|
||||
|
||||
for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
|
||||
QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
|
||||
|
||||
parm_var_decls.push_back(
|
||||
ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
|
||||
SourceLocation(), SourceLocation(), nullptr,
|
||||
arg_qual_type, nullptr, SC_Static, nullptr));
|
||||
}
|
||||
|
||||
func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
|
||||
} else {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
||||
|
||||
LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
|
||||
}
|
||||
|
||||
// If this is an operator (e.g. operator new or operator==), only insert the
|
||||
// declaration we inferred from the symbol if we can provide the correct
|
||||
// number of arguments. We shouldn't really inject random decl(s) for
|
||||
// functions that are analyzed semantically in a special way, otherwise we
|
||||
// will crash in clang.
|
||||
clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
|
||||
if (func_proto_type &&
|
||||
TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
|
||||
if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
|
||||
false, op_kind, func_proto_type->getNumParams()))
|
||||
return nullptr;
|
||||
}
|
||||
m_decls.push_back(func_decl);
|
||||
|
||||
return func_decl;
|
||||
}
|
||||
|
||||
clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
|
||||
FunctionProtoType::ExtProtoInfo proto_info;
|
||||
|
||||
proto_info.Variadic = true;
|
||||
|
||||
QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType(
|
||||
m_ast_source.m_ast_context->UnknownAnyTy, // result
|
||||
ArrayRef<QualType>(), // argument types
|
||||
proto_info));
|
||||
|
||||
return AddFunDecl(
|
||||
m_ast_source.m_clang_ast_context->GetType(generic_function_type), true);
|
||||
}
|
||||
|
||||
clang::NamedDecl *
|
||||
NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
|
||||
if (ClangUtil::IsClangType(clang_type)) {
|
||||
QualType qual_type = ClangUtil::GetQualType(clang_type);
|
||||
|
||||
if (const TypedefType *typedef_type =
|
||||
llvm::dyn_cast<TypedefType>(qual_type)) {
|
||||
TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
|
||||
|
||||
m_decls.push_back(typedef_name_decl);
|
||||
|
||||
return (NamedDecl *)typedef_name_decl;
|
||||
} else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
|
||||
TagDecl *tag_decl = tag_type->getDecl();
|
||||
|
||||
m_decls.push_back(tag_decl);
|
||||
|
||||
return tag_decl;
|
||||
} else if (const ObjCObjectType *objc_object_type =
|
||||
qual_type->getAs<ObjCObjectType>()) {
|
||||
ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
|
||||
|
||||
m_decls.push_back((NamedDecl *)interface_decl);
|
||||
|
||||
return (NamedDecl *)interface_decl;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
|
||||
for (clang::NamedDecl *decl : result)
|
||||
m_decls.push_back(decl);
|
||||
}
|
||||
|
||||
void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
|
||||
m_decls.push_back(decl);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <set>
|
||||
|
||||
#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
|
||||
#include "Plugins/ExpressionParser/Clang/NameSearchContext.h"
|
||||
#include "lldb/Symbol/CompilerType.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
@@ -382,105 +383,6 @@ protected:
|
||||
std::set<const char *> m_active_lookups;
|
||||
};
|
||||
|
||||
/// \class NameSearchContext ClangASTSource.h
|
||||
/// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a
|
||||
/// single name lookup
|
||||
///
|
||||
/// LLDB needs to create Decls for entities it finds. This class communicates
|
||||
/// what name is being searched for and provides helper functions to construct
|
||||
/// Decls given appropriate type information.
|
||||
struct NameSearchContext {
|
||||
/// The AST source making the request.
|
||||
ClangASTSource &m_ast_source;
|
||||
/// The list of declarations already constructed.
|
||||
llvm::SmallVectorImpl<clang::NamedDecl *> &m_decls;
|
||||
/// The mapping of all namespaces found for this request back to their
|
||||
/// modules.
|
||||
ClangASTImporter::NamespaceMapSP m_namespace_map;
|
||||
/// The name being looked for.
|
||||
const clang::DeclarationName &m_decl_name;
|
||||
/// The DeclContext to put declarations into.
|
||||
const clang::DeclContext *m_decl_context;
|
||||
/// All the types of functions that have been reported, so we don't
|
||||
/// report conflicts.
|
||||
llvm::SmallSet<CompilerType, 5> m_function_types;
|
||||
|
||||
struct {
|
||||
bool variable : 1;
|
||||
bool function_with_type_info : 1;
|
||||
bool function : 1;
|
||||
bool local_vars_nsp : 1;
|
||||
bool type : 1;
|
||||
} m_found;
|
||||
|
||||
/// Constructor
|
||||
///
|
||||
/// Initializes class variables.
|
||||
///
|
||||
/// \param[in] astSource
|
||||
/// A reference to the AST source making a request.
|
||||
///
|
||||
/// \param[in] decls
|
||||
/// A reference to a list into which new Decls will be placed. This
|
||||
/// list is typically empty when the function is called.
|
||||
///
|
||||
/// \param[in] name
|
||||
/// The name being searched for (always an Identifier).
|
||||
///
|
||||
/// \param[in] dc
|
||||
/// The DeclContext to register Decls in.
|
||||
NameSearchContext(ClangASTSource &astSource,
|
||||
llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
|
||||
clang::DeclarationName &name, const clang::DeclContext *dc)
|
||||
: m_ast_source(astSource), m_decls(decls), m_decl_name(name),
|
||||
m_decl_context(dc) {
|
||||
memset(&m_found, 0, sizeof(m_found));
|
||||
}
|
||||
|
||||
/// Create a VarDecl with the name being searched for and the provided type
|
||||
/// and register it in the right places.
|
||||
///
|
||||
/// \param[in] type
|
||||
/// The opaque QualType for the VarDecl being registered.
|
||||
clang::NamedDecl *AddVarDecl(const CompilerType &type);
|
||||
|
||||
/// Create a FunDecl with the name being searched for and the provided type
|
||||
/// and register it in the right places.
|
||||
///
|
||||
/// \param[in] type
|
||||
/// The opaque QualType for the FunDecl being registered.
|
||||
///
|
||||
/// \param[in] extern_c
|
||||
/// If true, build an extern "C" linkage specification for this.
|
||||
clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
|
||||
|
||||
/// Create a FunDecl with the name being searched for and generic type (i.e.
|
||||
/// intptr_t NAME_GOES_HERE(...)) and register it in the right places.
|
||||
clang::NamedDecl *AddGenericFunDecl();
|
||||
|
||||
/// Create a TypeDecl with the name being searched for and the provided type
|
||||
/// and register it in the right places.
|
||||
///
|
||||
/// \param[in] compiler_type
|
||||
/// The opaque QualType for the TypeDecl being registered.
|
||||
clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
|
||||
|
||||
/// Add Decls from the provided DeclContextLookupResult to the list of
|
||||
/// results.
|
||||
///
|
||||
/// \param[in] result
|
||||
/// The DeclContextLookupResult, usually returned as the result
|
||||
/// of querying a DeclContext.
|
||||
void AddLookupResult(clang::DeclContextLookupResult result);
|
||||
|
||||
/// Add a NamedDecl to the list of results.
|
||||
///
|
||||
/// \param[in] decl
|
||||
/// The NamedDecl, usually returned as the result
|
||||
/// of querying a DeclContext.
|
||||
void AddNamedDecl(clang::NamedDecl *decl);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
|
||||
|
||||
179
lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
Normal file
179
lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
//===-- NameSearchContext.cpp ---------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "NameSearchContext.h"
|
||||
#include "ClangUtil.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace lldb_private;
|
||||
|
||||
clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
|
||||
assert(type && "Type for variable must be valid!");
|
||||
|
||||
if (!type.IsValid())
|
||||
return nullptr;
|
||||
|
||||
TypeSystemClang *lldb_ast =
|
||||
llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
|
||||
if (!lldb_ast)
|
||||
return nullptr;
|
||||
|
||||
IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
|
||||
|
||||
clang::ASTContext &ast = lldb_ast->getASTContext();
|
||||
|
||||
clang::NamedDecl *Decl = VarDecl::Create(
|
||||
ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
|
||||
SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);
|
||||
m_decls.push_back(Decl);
|
||||
|
||||
return Decl;
|
||||
}
|
||||
|
||||
clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
|
||||
bool extern_c) {
|
||||
assert(type && "Type for variable must be valid!");
|
||||
|
||||
if (!type.IsValid())
|
||||
return nullptr;
|
||||
|
||||
if (m_function_types.count(type))
|
||||
return nullptr;
|
||||
|
||||
TypeSystemClang *lldb_ast =
|
||||
llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
|
||||
if (!lldb_ast)
|
||||
return nullptr;
|
||||
|
||||
m_function_types.insert(type);
|
||||
|
||||
QualType qual_type(ClangUtil::GetQualType(type));
|
||||
|
||||
clang::ASTContext &ast = lldb_ast->getASTContext();
|
||||
|
||||
const bool isInlineSpecified = false;
|
||||
const bool hasWrittenPrototype = true;
|
||||
const bool isConstexprSpecified = false;
|
||||
|
||||
clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
|
||||
|
||||
if (extern_c) {
|
||||
context = LinkageSpecDecl::Create(
|
||||
ast, context, SourceLocation(), SourceLocation(),
|
||||
clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
|
||||
}
|
||||
|
||||
// Pass the identifier info for functions the decl_name is needed for
|
||||
// operators
|
||||
clang::DeclarationName decl_name =
|
||||
m_decl_name.getNameKind() == DeclarationName::Identifier
|
||||
? m_decl_name.getAsIdentifierInfo()
|
||||
: m_decl_name;
|
||||
|
||||
clang::FunctionDecl *func_decl = FunctionDecl::Create(
|
||||
ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
|
||||
nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype,
|
||||
isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
|
||||
|
||||
// We have to do more than just synthesize the FunctionDecl. We have to
|
||||
// synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
|
||||
// this, we raid the function's FunctionProtoType for types.
|
||||
|
||||
const FunctionProtoType *func_proto_type =
|
||||
qual_type.getTypePtr()->getAs<FunctionProtoType>();
|
||||
|
||||
if (func_proto_type) {
|
||||
unsigned NumArgs = func_proto_type->getNumParams();
|
||||
unsigned ArgIndex;
|
||||
|
||||
SmallVector<ParmVarDecl *, 5> parm_var_decls;
|
||||
|
||||
for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
|
||||
QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
|
||||
|
||||
parm_var_decls.push_back(
|
||||
ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
|
||||
SourceLocation(), SourceLocation(), nullptr,
|
||||
arg_qual_type, nullptr, SC_Static, nullptr));
|
||||
}
|
||||
|
||||
func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
|
||||
} else {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
||||
|
||||
LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
|
||||
}
|
||||
|
||||
// If this is an operator (e.g. operator new or operator==), only insert the
|
||||
// declaration we inferred from the symbol if we can provide the correct
|
||||
// number of arguments. We shouldn't really inject random decl(s) for
|
||||
// functions that are analyzed semantically in a special way, otherwise we
|
||||
// will crash in clang.
|
||||
clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
|
||||
if (func_proto_type &&
|
||||
TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
|
||||
if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
|
||||
false, op_kind, func_proto_type->getNumParams()))
|
||||
return nullptr;
|
||||
}
|
||||
m_decls.push_back(func_decl);
|
||||
|
||||
return func_decl;
|
||||
}
|
||||
|
||||
clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
|
||||
FunctionProtoType::ExtProtoInfo proto_info;
|
||||
|
||||
proto_info.Variadic = true;
|
||||
|
||||
QualType generic_function_type(
|
||||
GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result
|
||||
ArrayRef<QualType>(), // argument types
|
||||
proto_info));
|
||||
|
||||
return AddFunDecl(m_clang_ts.GetType(generic_function_type), true);
|
||||
}
|
||||
|
||||
clang::NamedDecl *
|
||||
NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
|
||||
if (ClangUtil::IsClangType(clang_type)) {
|
||||
QualType qual_type = ClangUtil::GetQualType(clang_type);
|
||||
|
||||
if (const TypedefType *typedef_type =
|
||||
llvm::dyn_cast<TypedefType>(qual_type)) {
|
||||
TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
|
||||
|
||||
m_decls.push_back(typedef_name_decl);
|
||||
|
||||
return (NamedDecl *)typedef_name_decl;
|
||||
} else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
|
||||
TagDecl *tag_decl = tag_type->getDecl();
|
||||
|
||||
m_decls.push_back(tag_decl);
|
||||
|
||||
return tag_decl;
|
||||
} else if (const ObjCObjectType *objc_object_type =
|
||||
qual_type->getAs<ObjCObjectType>()) {
|
||||
ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
|
||||
|
||||
m_decls.push_back((NamedDecl *)interface_decl);
|
||||
|
||||
return (NamedDecl *)interface_decl;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
|
||||
for (clang::NamedDecl *decl : result)
|
||||
m_decls.push_back(decl);
|
||||
}
|
||||
|
||||
void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
|
||||
m_decls.push_back(decl);
|
||||
}
|
||||
125
lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h
Normal file
125
lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h
Normal file
@@ -0,0 +1,125 @@
|
||||
//===-- NameSearchContext.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H
|
||||
#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H
|
||||
|
||||
#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
|
||||
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
|
||||
#include "lldb/Symbol/CompilerType.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
/// \class NameSearchContext ClangASTSource.h
|
||||
/// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a
|
||||
/// single name lookup
|
||||
///
|
||||
/// LLDB needs to create Decls for entities it finds. This class communicates
|
||||
/// what name is being searched for and provides helper functions to construct
|
||||
/// Decls given appropriate type information.
|
||||
struct NameSearchContext {
|
||||
/// The type system of the AST from which the lookup originated.
|
||||
TypeSystemClang &m_clang_ts;
|
||||
/// The list of declarations already constructed.
|
||||
llvm::SmallVectorImpl<clang::NamedDecl *> &m_decls;
|
||||
/// The mapping of all namespaces found for this request back to their
|
||||
/// modules.
|
||||
ClangASTImporter::NamespaceMapSP m_namespace_map;
|
||||
/// The name being looked for.
|
||||
const clang::DeclarationName &m_decl_name;
|
||||
/// The DeclContext to put declarations into.
|
||||
const clang::DeclContext *m_decl_context;
|
||||
/// All the types of functions that have been reported, so we don't
|
||||
/// report conflicts.
|
||||
llvm::SmallSet<CompilerType, 5> m_function_types;
|
||||
|
||||
struct {
|
||||
bool variable : 1;
|
||||
bool function_with_type_info : 1;
|
||||
bool function : 1;
|
||||
bool local_vars_nsp : 1;
|
||||
bool type : 1;
|
||||
} m_found;
|
||||
|
||||
/// Constructor
|
||||
///
|
||||
/// Initializes class variables.
|
||||
///
|
||||
/// \param[in] astSource
|
||||
/// A reference to the AST source making a request.
|
||||
///
|
||||
/// \param[in] decls
|
||||
/// A reference to a list into which new Decls will be placed. This
|
||||
/// list is typically empty when the function is called.
|
||||
///
|
||||
/// \param[in] name
|
||||
/// The name being searched for (always an Identifier).
|
||||
///
|
||||
/// \param[in] dc
|
||||
/// The DeclContext to register Decls in.
|
||||
NameSearchContext(TypeSystemClang &clang_ts,
|
||||
llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
|
||||
clang::DeclarationName &name, const clang::DeclContext *dc)
|
||||
: m_clang_ts(clang_ts), m_decls(decls), m_decl_name(name),
|
||||
m_decl_context(dc) {
|
||||
memset(&m_found, 0, sizeof(m_found));
|
||||
}
|
||||
|
||||
/// Create a VarDecl with the name being searched for and the provided type
|
||||
/// and register it in the right places.
|
||||
///
|
||||
/// \param[in] type
|
||||
/// The opaque QualType for the VarDecl being registered.
|
||||
clang::NamedDecl *AddVarDecl(const CompilerType &type);
|
||||
|
||||
/// Create a FunDecl with the name being searched for and the provided type
|
||||
/// and register it in the right places.
|
||||
///
|
||||
/// \param[in] type
|
||||
/// The opaque QualType for the FunDecl being registered.
|
||||
///
|
||||
/// \param[in] extern_c
|
||||
/// If true, build an extern "C" linkage specification for this.
|
||||
clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
|
||||
|
||||
/// Create a FunDecl with the name being searched for and generic type (i.e.
|
||||
/// intptr_t NAME_GOES_HERE(...)) and register it in the right places.
|
||||
clang::NamedDecl *AddGenericFunDecl();
|
||||
|
||||
/// Create a TypeDecl with the name being searched for and the provided type
|
||||
/// and register it in the right places.
|
||||
///
|
||||
/// \param[in] compiler_type
|
||||
/// The opaque QualType for the TypeDecl being registered.
|
||||
clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
|
||||
|
||||
/// Add Decls from the provided DeclContextLookupResult to the list of
|
||||
/// results.
|
||||
///
|
||||
/// \param[in] result
|
||||
/// The DeclContextLookupResult, usually returned as the result
|
||||
/// of querying a DeclContext.
|
||||
void AddLookupResult(clang::DeclContextLookupResult result);
|
||||
|
||||
/// Add a NamedDecl to the list of results.
|
||||
///
|
||||
/// \param[in] decl
|
||||
/// The NamedDecl, usually returned as the result
|
||||
/// of querying a DeclContext.
|
||||
void AddNamedDecl(clang::NamedDecl *decl);
|
||||
|
||||
private:
|
||||
clang::ASTContext &GetASTContext() const {
|
||||
return m_clang_ts.getASTContext();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H
|
||||
@@ -88,7 +88,7 @@ TEST_F(ClangExpressionDeclMapTest, TestUnknownIdentifierLookup) {
|
||||
clang::DeclarationName name =
|
||||
clang_utils::getDeclarationName(*target_ast, "foo");
|
||||
const clang::DeclContext *dc = target_ast->GetTranslationUnitDecl();
|
||||
NameSearchContext search(*decl_map, decls, name, dc);
|
||||
NameSearchContext search(*target_ast, decls, name, dc);
|
||||
|
||||
decl_map->FindExternalVisibleDecls(search);
|
||||
|
||||
@@ -111,7 +111,7 @@ TEST_F(ClangExpressionDeclMapTest, TestPersistentDeclLookup) {
|
||||
clang::DeclarationName name =
|
||||
clang_utils::getDeclarationName(*target_ast, decl_name);
|
||||
const clang::DeclContext *dc = target_ast->GetTranslationUnitDecl();
|
||||
NameSearchContext search(*decl_map, decls, name, dc);
|
||||
NameSearchContext search(*target_ast, decls, name, dc);
|
||||
|
||||
// Search and check that we found $persistent_class.
|
||||
decl_map->FindExternalVisibleDecls(search);
|
||||
|
||||
Reference in New Issue
Block a user