xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1*5ffd83dbSDimitry Andric //===-- NameSearchContext.cpp ---------------------------------------------===//
2*5ffd83dbSDimitry Andric //
3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5ffd83dbSDimitry Andric //
7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
8*5ffd83dbSDimitry Andric 
9*5ffd83dbSDimitry Andric #include "NameSearchContext.h"
10*5ffd83dbSDimitry Andric #include "ClangUtil.h"
11*5ffd83dbSDimitry Andric 
12*5ffd83dbSDimitry Andric using namespace clang;
13*5ffd83dbSDimitry Andric using namespace lldb_private;
14*5ffd83dbSDimitry Andric 
15*5ffd83dbSDimitry Andric clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
16*5ffd83dbSDimitry Andric   assert(type && "Type for variable must be valid!");
17*5ffd83dbSDimitry Andric 
18*5ffd83dbSDimitry Andric   if (!type.IsValid())
19*5ffd83dbSDimitry Andric     return nullptr;
20*5ffd83dbSDimitry Andric 
21*5ffd83dbSDimitry Andric   TypeSystemClang *lldb_ast =
22*5ffd83dbSDimitry Andric       llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
23*5ffd83dbSDimitry Andric   if (!lldb_ast)
24*5ffd83dbSDimitry Andric     return nullptr;
25*5ffd83dbSDimitry Andric 
26*5ffd83dbSDimitry Andric   IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
27*5ffd83dbSDimitry Andric 
28*5ffd83dbSDimitry Andric   clang::ASTContext &ast = lldb_ast->getASTContext();
29*5ffd83dbSDimitry Andric 
30*5ffd83dbSDimitry Andric   clang::NamedDecl *Decl = VarDecl::Create(
31*5ffd83dbSDimitry Andric       ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
32*5ffd83dbSDimitry Andric       SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);
33*5ffd83dbSDimitry Andric   m_decls.push_back(Decl);
34*5ffd83dbSDimitry Andric 
35*5ffd83dbSDimitry Andric   return Decl;
36*5ffd83dbSDimitry Andric }
37*5ffd83dbSDimitry Andric 
38*5ffd83dbSDimitry Andric clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
39*5ffd83dbSDimitry Andric                                                 bool extern_c) {
40*5ffd83dbSDimitry Andric   assert(type && "Type for variable must be valid!");
41*5ffd83dbSDimitry Andric 
42*5ffd83dbSDimitry Andric   if (!type.IsValid())
43*5ffd83dbSDimitry Andric     return nullptr;
44*5ffd83dbSDimitry Andric 
45*5ffd83dbSDimitry Andric   if (m_function_types.count(type))
46*5ffd83dbSDimitry Andric     return nullptr;
47*5ffd83dbSDimitry Andric 
48*5ffd83dbSDimitry Andric   TypeSystemClang *lldb_ast =
49*5ffd83dbSDimitry Andric       llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
50*5ffd83dbSDimitry Andric   if (!lldb_ast)
51*5ffd83dbSDimitry Andric     return nullptr;
52*5ffd83dbSDimitry Andric 
53*5ffd83dbSDimitry Andric   m_function_types.insert(type);
54*5ffd83dbSDimitry Andric 
55*5ffd83dbSDimitry Andric   QualType qual_type(ClangUtil::GetQualType(type));
56*5ffd83dbSDimitry Andric 
57*5ffd83dbSDimitry Andric   clang::ASTContext &ast = lldb_ast->getASTContext();
58*5ffd83dbSDimitry Andric 
59*5ffd83dbSDimitry Andric   const bool isInlineSpecified = false;
60*5ffd83dbSDimitry Andric   const bool hasWrittenPrototype = true;
61*5ffd83dbSDimitry Andric   const bool isConstexprSpecified = false;
62*5ffd83dbSDimitry Andric 
63*5ffd83dbSDimitry Andric   clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
64*5ffd83dbSDimitry Andric 
65*5ffd83dbSDimitry Andric   if (extern_c) {
66*5ffd83dbSDimitry Andric     context = LinkageSpecDecl::Create(
67*5ffd83dbSDimitry Andric         ast, context, SourceLocation(), SourceLocation(),
68*5ffd83dbSDimitry Andric         clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
69*5ffd83dbSDimitry Andric   }
70*5ffd83dbSDimitry Andric 
71*5ffd83dbSDimitry Andric   // Pass the identifier info for functions the decl_name is needed for
72*5ffd83dbSDimitry Andric   // operators
73*5ffd83dbSDimitry Andric   clang::DeclarationName decl_name =
74*5ffd83dbSDimitry Andric       m_decl_name.getNameKind() == DeclarationName::Identifier
75*5ffd83dbSDimitry Andric           ? m_decl_name.getAsIdentifierInfo()
76*5ffd83dbSDimitry Andric           : m_decl_name;
77*5ffd83dbSDimitry Andric 
78*5ffd83dbSDimitry Andric   clang::FunctionDecl *func_decl = FunctionDecl::Create(
79*5ffd83dbSDimitry Andric       ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
80*5ffd83dbSDimitry Andric       nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype,
81*5ffd83dbSDimitry Andric       isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
82*5ffd83dbSDimitry Andric 
83*5ffd83dbSDimitry Andric   // We have to do more than just synthesize the FunctionDecl.  We have to
84*5ffd83dbSDimitry Andric   // synthesize ParmVarDecls for all of the FunctionDecl's arguments.  To do
85*5ffd83dbSDimitry Andric   // this, we raid the function's FunctionProtoType for types.
86*5ffd83dbSDimitry Andric 
87*5ffd83dbSDimitry Andric   const FunctionProtoType *func_proto_type =
88*5ffd83dbSDimitry Andric       qual_type.getTypePtr()->getAs<FunctionProtoType>();
89*5ffd83dbSDimitry Andric 
90*5ffd83dbSDimitry Andric   if (func_proto_type) {
91*5ffd83dbSDimitry Andric     unsigned NumArgs = func_proto_type->getNumParams();
92*5ffd83dbSDimitry Andric     unsigned ArgIndex;
93*5ffd83dbSDimitry Andric 
94*5ffd83dbSDimitry Andric     SmallVector<ParmVarDecl *, 5> parm_var_decls;
95*5ffd83dbSDimitry Andric 
96*5ffd83dbSDimitry Andric     for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
97*5ffd83dbSDimitry Andric       QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
98*5ffd83dbSDimitry Andric 
99*5ffd83dbSDimitry Andric       parm_var_decls.push_back(
100*5ffd83dbSDimitry Andric           ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
101*5ffd83dbSDimitry Andric                               SourceLocation(), SourceLocation(), nullptr,
102*5ffd83dbSDimitry Andric                               arg_qual_type, nullptr, SC_Static, nullptr));
103*5ffd83dbSDimitry Andric     }
104*5ffd83dbSDimitry Andric 
105*5ffd83dbSDimitry Andric     func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
106*5ffd83dbSDimitry Andric   } else {
107*5ffd83dbSDimitry Andric     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
108*5ffd83dbSDimitry Andric 
109*5ffd83dbSDimitry Andric     LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
110*5ffd83dbSDimitry Andric   }
111*5ffd83dbSDimitry Andric 
112*5ffd83dbSDimitry Andric   // If this is an operator (e.g. operator new or operator==), only insert the
113*5ffd83dbSDimitry Andric   // declaration we inferred from the symbol if we can provide the correct
114*5ffd83dbSDimitry Andric   // number of arguments. We shouldn't really inject random decl(s) for
115*5ffd83dbSDimitry Andric   // functions that are analyzed semantically in a special way, otherwise we
116*5ffd83dbSDimitry Andric   // will crash in clang.
117*5ffd83dbSDimitry Andric   clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
118*5ffd83dbSDimitry Andric   if (func_proto_type &&
119*5ffd83dbSDimitry Andric       TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
120*5ffd83dbSDimitry Andric     if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
121*5ffd83dbSDimitry Andric             false, op_kind, func_proto_type->getNumParams()))
122*5ffd83dbSDimitry Andric       return nullptr;
123*5ffd83dbSDimitry Andric   }
124*5ffd83dbSDimitry Andric   m_decls.push_back(func_decl);
125*5ffd83dbSDimitry Andric 
126*5ffd83dbSDimitry Andric   return func_decl;
127*5ffd83dbSDimitry Andric }
128*5ffd83dbSDimitry Andric 
129*5ffd83dbSDimitry Andric clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
130*5ffd83dbSDimitry Andric   FunctionProtoType::ExtProtoInfo proto_info;
131*5ffd83dbSDimitry Andric 
132*5ffd83dbSDimitry Andric   proto_info.Variadic = true;
133*5ffd83dbSDimitry Andric 
134*5ffd83dbSDimitry Andric   QualType generic_function_type(
135*5ffd83dbSDimitry Andric       GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result
136*5ffd83dbSDimitry Andric                                       ArrayRef<QualType>(), // argument types
137*5ffd83dbSDimitry Andric                                       proto_info));
138*5ffd83dbSDimitry Andric 
139*5ffd83dbSDimitry Andric   return AddFunDecl(m_clang_ts.GetType(generic_function_type), true);
140*5ffd83dbSDimitry Andric }
141*5ffd83dbSDimitry Andric 
142*5ffd83dbSDimitry Andric clang::NamedDecl *
143*5ffd83dbSDimitry Andric NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
144*5ffd83dbSDimitry Andric   if (ClangUtil::IsClangType(clang_type)) {
145*5ffd83dbSDimitry Andric     QualType qual_type = ClangUtil::GetQualType(clang_type);
146*5ffd83dbSDimitry Andric 
147*5ffd83dbSDimitry Andric     if (const TypedefType *typedef_type =
148*5ffd83dbSDimitry Andric             llvm::dyn_cast<TypedefType>(qual_type)) {
149*5ffd83dbSDimitry Andric       TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
150*5ffd83dbSDimitry Andric 
151*5ffd83dbSDimitry Andric       m_decls.push_back(typedef_name_decl);
152*5ffd83dbSDimitry Andric 
153*5ffd83dbSDimitry Andric       return (NamedDecl *)typedef_name_decl;
154*5ffd83dbSDimitry Andric     } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
155*5ffd83dbSDimitry Andric       TagDecl *tag_decl = tag_type->getDecl();
156*5ffd83dbSDimitry Andric 
157*5ffd83dbSDimitry Andric       m_decls.push_back(tag_decl);
158*5ffd83dbSDimitry Andric 
159*5ffd83dbSDimitry Andric       return tag_decl;
160*5ffd83dbSDimitry Andric     } else if (const ObjCObjectType *objc_object_type =
161*5ffd83dbSDimitry Andric                    qual_type->getAs<ObjCObjectType>()) {
162*5ffd83dbSDimitry Andric       ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
163*5ffd83dbSDimitry Andric 
164*5ffd83dbSDimitry Andric       m_decls.push_back((NamedDecl *)interface_decl);
165*5ffd83dbSDimitry Andric 
166*5ffd83dbSDimitry Andric       return (NamedDecl *)interface_decl;
167*5ffd83dbSDimitry Andric     }
168*5ffd83dbSDimitry Andric   }
169*5ffd83dbSDimitry Andric   return nullptr;
170*5ffd83dbSDimitry Andric }
171*5ffd83dbSDimitry Andric 
172*5ffd83dbSDimitry Andric void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
173*5ffd83dbSDimitry Andric   for (clang::NamedDecl *decl : result)
174*5ffd83dbSDimitry Andric     m_decls.push_back(decl);
175*5ffd83dbSDimitry Andric }
176*5ffd83dbSDimitry Andric 
177*5ffd83dbSDimitry Andric void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
178*5ffd83dbSDimitry Andric   m_decls.push_back(decl);
179*5ffd83dbSDimitry Andric }
180