1 //===-- NameSearchContext.cpp ---------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "NameSearchContext.h"
10 #include "ClangUtil.h"
11 #include "lldb/Utility/LLDBLog.h"
13 using namespace clang
;
14 using namespace lldb_private
;
16 clang::NamedDecl
*NameSearchContext::AddVarDecl(const CompilerType
&type
) {
17 assert(type
&& "Type for variable must be valid!");
22 auto lldb_ast
= type
.GetTypeSystem().dyn_cast_or_null
<TypeSystemClang
>();
26 IdentifierInfo
*ii
= m_decl_name
.getAsIdentifierInfo();
28 clang::ASTContext
&ast
= lldb_ast
->getASTContext();
30 clang::NamedDecl
*Decl
= VarDecl::Create(
31 ast
, const_cast<DeclContext
*>(m_decl_context
), SourceLocation(),
32 SourceLocation(), ii
, ClangUtil::GetQualType(type
), nullptr, SC_Static
);
33 m_decls
.push_back(Decl
);
38 clang::NamedDecl
*NameSearchContext::AddFunDecl(const CompilerType
&type
,
40 assert(type
&& "Type for variable must be valid!");
45 if (m_function_types
.count(type
))
48 auto lldb_ast
= type
.GetTypeSystem().dyn_cast_or_null
<TypeSystemClang
>();
52 m_function_types
.insert(type
);
54 QualType
qual_type(ClangUtil::GetQualType(type
));
56 clang::ASTContext
&ast
= lldb_ast
->getASTContext();
58 const bool isInlineSpecified
= false;
59 const bool hasWrittenPrototype
= true;
60 const bool isConstexprSpecified
= false;
62 clang::DeclContext
*context
= const_cast<DeclContext
*>(m_decl_context
);
65 context
= LinkageSpecDecl::Create(ast
, context
, SourceLocation(),
67 clang::LinkageSpecLanguageIDs::C
, false);
68 // FIXME: The LinkageSpecDecl here should be added to m_decl_context.
71 // Pass the identifier info for functions the decl_name is needed for
73 clang::DeclarationName decl_name
=
74 m_decl_name
.getNameKind() == DeclarationName::Identifier
75 ? m_decl_name
.getAsIdentifierInfo()
78 clang::FunctionDecl
*func_decl
= FunctionDecl::Create(
79 ast
, context
, SourceLocation(), SourceLocation(), decl_name
, qual_type
,
80 nullptr, SC_Extern
, /*UsesFPIntrin=*/false, isInlineSpecified
, hasWrittenPrototype
,
81 isConstexprSpecified
? ConstexprSpecKind::Constexpr
82 : ConstexprSpecKind::Unspecified
);
84 // We have to do more than just synthesize the FunctionDecl. We have to
85 // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
86 // this, we raid the function's FunctionProtoType for types.
88 const FunctionProtoType
*func_proto_type
=
89 qual_type
.getTypePtr()->getAs
<FunctionProtoType
>();
91 if (func_proto_type
) {
92 unsigned NumArgs
= func_proto_type
->getNumParams();
95 SmallVector
<ParmVarDecl
*, 5> parm_var_decls
;
97 for (ArgIndex
= 0; ArgIndex
< NumArgs
; ++ArgIndex
) {
98 QualType
arg_qual_type(func_proto_type
->getParamType(ArgIndex
));
100 parm_var_decls
.push_back(
101 ParmVarDecl::Create(ast
, const_cast<DeclContext
*>(context
),
102 SourceLocation(), SourceLocation(), nullptr,
103 arg_qual_type
, nullptr, SC_Static
, nullptr));
106 func_decl
->setParams(ArrayRef
<ParmVarDecl
*>(parm_var_decls
));
108 Log
*log
= GetLog(LLDBLog::Expressions
);
110 LLDB_LOG(log
, "Function type wasn't a FunctionProtoType");
113 // If this is an operator (e.g. operator new or operator==), only insert the
114 // declaration we inferred from the symbol if we can provide the correct
115 // number of arguments. We shouldn't really inject random decl(s) for
116 // functions that are analyzed semantically in a special way, otherwise we
117 // will crash in clang.
118 clang::OverloadedOperatorKind op_kind
= clang::NUM_OVERLOADED_OPERATORS
;
119 if (func_proto_type
&&
120 TypeSystemClang::IsOperator(decl_name
.getAsString().c_str(), op_kind
)) {
121 if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
122 false, op_kind
, func_proto_type
->getNumParams()))
125 m_decls
.push_back(func_decl
);
130 clang::NamedDecl
*NameSearchContext::AddGenericFunDecl() {
131 FunctionProtoType::ExtProtoInfo proto_info
;
133 proto_info
.Variadic
= true;
135 QualType
generic_function_type(
136 GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy
, // result
137 ArrayRef
<QualType
>(), // argument types
140 return AddFunDecl(m_clang_ts
.GetType(generic_function_type
), true);
144 NameSearchContext::AddTypeDecl(const CompilerType
&clang_type
) {
145 if (ClangUtil::IsClangType(clang_type
)) {
146 QualType qual_type
= ClangUtil::GetQualType(clang_type
);
148 if (const TypedefType
*typedef_type
=
149 llvm::dyn_cast
<TypedefType
>(qual_type
)) {
150 TypedefNameDecl
*typedef_name_decl
= typedef_type
->getDecl();
152 m_decls
.push_back(typedef_name_decl
);
154 return (NamedDecl
*)typedef_name_decl
;
155 } else if (const TagType
*tag_type
= qual_type
->getAs
<TagType
>()) {
156 TagDecl
*tag_decl
= tag_type
->getDecl();
158 m_decls
.push_back(tag_decl
);
161 } else if (const ObjCObjectType
*objc_object_type
=
162 qual_type
->getAs
<ObjCObjectType
>()) {
163 ObjCInterfaceDecl
*interface_decl
= objc_object_type
->getInterface();
165 m_decls
.push_back((NamedDecl
*)interface_decl
);
167 return (NamedDecl
*)interface_decl
;
173 void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result
) {
174 for (clang::NamedDecl
*decl
: result
)
175 m_decls
.push_back(decl
);
178 void NameSearchContext::AddNamedDecl(clang::NamedDecl
*decl
) {
179 m_decls
.push_back(decl
);