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