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