1//===-- NameSearchContext.cpp ---------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "NameSearchContext.h"
10#include "ClangUtil.h"
11#include "lldb/Utility/LLDBLog.h"
12
13using namespace clang;
14using namespace lldb_private;
15
16clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
17 assert(type && "Type for variable must be valid!");
18
19 if (!type.IsValid())
20 return nullptr;
21
22 auto lldb_ast = type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
23 if (!lldb_ast)
24 return nullptr;
25
26 IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
27
28 clang::ASTContext &ast = lldb_ast->getASTContext();
29
30 clang::NamedDecl *Decl = VarDecl::Create(
31 C&: ast, DC: const_cast<DeclContext *>(m_decl_context), StartLoc: SourceLocation(),
32 IdLoc: SourceLocation(), Id: ii, T: ClangUtil::GetQualType(ct: type), TInfo: nullptr, S: SC_Static);
33 m_decls.push_back(Elt: Decl);
34
35 return Decl;
36}
37
38clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
39 bool extern_c) {
40 assert(type && "Type for variable must be valid!");
41
42 if (!type.IsValid())
43 return nullptr;
44
45 if (m_function_types.count(V: type))
46 return nullptr;
47
48 auto lldb_ast = type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
49 if (!lldb_ast)
50 return nullptr;
51
52 m_function_types.insert(V: type);
53
54 QualType qual_type(ClangUtil::GetQualType(ct: type));
55
56 clang::ASTContext &ast = lldb_ast->getASTContext();
57
58 const bool isInlineSpecified = false;
59 const bool hasWrittenPrototype = true;
60 const bool isConstexprSpecified = false;
61
62 clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
63
64 if (extern_c) {
65 context = LinkageSpecDecl::Create(C&: ast, DC: context, ExternLoc: SourceLocation(),
66 LangLoc: SourceLocation(),
67 Lang: clang::LinkageSpecLanguageIDs::C, HasBraces: false);
68 // FIXME: The LinkageSpecDecl here should be added to m_decl_context.
69 }
70
71 // Pass the identifier info for functions the decl_name is needed for
72 // operators
73 clang::DeclarationName decl_name =
74 m_decl_name.getNameKind() == DeclarationName::Identifier
75 ? m_decl_name.getAsIdentifierInfo()
76 : m_decl_name;
77
78 clang::FunctionDecl *func_decl = FunctionDecl::Create(
79 C&: ast, DC: context, StartLoc: SourceLocation(), NLoc: SourceLocation(), N: decl_name, T: qual_type,
80 TInfo: nullptr, SC: SC_Extern, /*UsesFPIntrin=*/false, isInlineSpecified, hasWrittenPrototype,
81 ConstexprKind: isConstexprSpecified ? ConstexprSpecKind::Constexpr
82 : ConstexprSpecKind::Unspecified);
83
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.
87
88 const FunctionProtoType *func_proto_type =
89 qual_type.getTypePtr()->getAs<FunctionProtoType>();
90
91 if (func_proto_type) {
92 unsigned NumArgs = func_proto_type->getNumParams();
93 unsigned ArgIndex;
94
95 SmallVector<ParmVarDecl *, 5> parm_var_decls;
96
97 for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
98 QualType arg_qual_type(func_proto_type->getParamType(i: ArgIndex));
99
100 parm_var_decls.push_back(
101 Elt: ParmVarDecl::Create(C&: ast, DC: const_cast<DeclContext *>(context),
102 StartLoc: SourceLocation(), IdLoc: SourceLocation(), Id: nullptr,
103 T: arg_qual_type, TInfo: nullptr, S: SC_Static, DefArg: nullptr));
104 }
105
106 func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
107 } else {
108 Log *log = GetLog(mask: LLDBLog::Expressions);
109
110 LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
111 }
112
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(name: decl_name.getAsString().c_str(), op_kind)) {
121 if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
122 is_method: false, op_kind, num_params: func_proto_type->getNumParams()))
123 return nullptr;
124 }
125 m_decls.push_back(func_decl);
126
127 return func_decl;
128}
129
130clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
131 FunctionProtoType::ExtProtoInfo proto_info;
132
133 proto_info.Variadic = true;
134
135 QualType generic_function_type(
136 GetASTContext().getFunctionType(ResultTy: GetASTContext().UnknownAnyTy, // result
137 Args: ArrayRef<QualType>(), // argument types
138 EPI: proto_info));
139
140 return AddFunDecl(type: m_clang_ts.GetType(qt: generic_function_type), extern_c: true);
141}
142
143clang::NamedDecl *
144NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
145 if (ClangUtil::IsClangType(ct: clang_type)) {
146 QualType qual_type = ClangUtil::GetQualType(ct: clang_type);
147
148 if (const TypedefType *typedef_type =
149 llvm::dyn_cast<TypedefType>(Val&: qual_type)) {
150 TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
151
152 m_decls.push_back(typedef_name_decl);
153
154 return (NamedDecl *)typedef_name_decl;
155 } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
156 TagDecl *tag_decl = tag_type->getDecl();
157
158 m_decls.push_back(tag_decl);
159
160 return tag_decl;
161 } else if (const ObjCObjectType *objc_object_type =
162 qual_type->getAs<ObjCObjectType>()) {
163 ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
164
165 m_decls.push_back(Elt: (NamedDecl *)interface_decl);
166
167 return (NamedDecl *)interface_decl;
168 }
169 }
170 return nullptr;
171}
172
173void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
174 for (clang::NamedDecl *decl : result)
175 m_decls.push_back(Elt: decl);
176}
177
178void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
179 m_decls.push_back(Elt: decl);
180}
181

source code of lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp