xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
15ffd83dbSDimitry Andric //===-- NameSearchContext.cpp ---------------------------------------------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric 
95ffd83dbSDimitry Andric #include "NameSearchContext.h"
105ffd83dbSDimitry Andric #include "ClangUtil.h"
1181ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
125ffd83dbSDimitry Andric 
135ffd83dbSDimitry Andric using namespace clang;
145ffd83dbSDimitry Andric using namespace lldb_private;
155ffd83dbSDimitry Andric 
AddVarDecl(const CompilerType & type)165ffd83dbSDimitry Andric clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
175ffd83dbSDimitry Andric   assert(type && "Type for variable must be valid!");
185ffd83dbSDimitry Andric 
195ffd83dbSDimitry Andric   if (!type.IsValid())
205ffd83dbSDimitry Andric     return nullptr;
215ffd83dbSDimitry Andric 
22bdd1243dSDimitry Andric   auto lldb_ast = type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
235ffd83dbSDimitry Andric   if (!lldb_ast)
245ffd83dbSDimitry Andric     return nullptr;
255ffd83dbSDimitry Andric 
265ffd83dbSDimitry Andric   IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
275ffd83dbSDimitry Andric 
285ffd83dbSDimitry Andric   clang::ASTContext &ast = lldb_ast->getASTContext();
295ffd83dbSDimitry Andric 
305ffd83dbSDimitry Andric   clang::NamedDecl *Decl = VarDecl::Create(
315ffd83dbSDimitry Andric       ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
325ffd83dbSDimitry Andric       SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);
335ffd83dbSDimitry Andric   m_decls.push_back(Decl);
345ffd83dbSDimitry Andric 
355ffd83dbSDimitry Andric   return Decl;
365ffd83dbSDimitry Andric }
375ffd83dbSDimitry Andric 
AddFunDecl(const CompilerType & type,bool extern_c)385ffd83dbSDimitry Andric clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
395ffd83dbSDimitry Andric                                                 bool extern_c) {
405ffd83dbSDimitry Andric   assert(type && "Type for variable must be valid!");
415ffd83dbSDimitry Andric 
425ffd83dbSDimitry Andric   if (!type.IsValid())
435ffd83dbSDimitry Andric     return nullptr;
445ffd83dbSDimitry Andric 
455ffd83dbSDimitry Andric   if (m_function_types.count(type))
465ffd83dbSDimitry Andric     return nullptr;
475ffd83dbSDimitry Andric 
48bdd1243dSDimitry Andric   auto lldb_ast = type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
495ffd83dbSDimitry Andric   if (!lldb_ast)
505ffd83dbSDimitry Andric     return nullptr;
515ffd83dbSDimitry Andric 
525ffd83dbSDimitry Andric   m_function_types.insert(type);
535ffd83dbSDimitry Andric 
545ffd83dbSDimitry Andric   QualType qual_type(ClangUtil::GetQualType(type));
555ffd83dbSDimitry Andric 
565ffd83dbSDimitry Andric   clang::ASTContext &ast = lldb_ast->getASTContext();
575ffd83dbSDimitry Andric 
585ffd83dbSDimitry Andric   const bool isInlineSpecified = false;
595ffd83dbSDimitry Andric   const bool hasWrittenPrototype = true;
605ffd83dbSDimitry Andric   const bool isConstexprSpecified = false;
615ffd83dbSDimitry Andric 
625ffd83dbSDimitry Andric   clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
635ffd83dbSDimitry Andric 
645ffd83dbSDimitry Andric   if (extern_c) {
65*5f757f3fSDimitry Andric     context = LinkageSpecDecl::Create(ast, context, SourceLocation(),
66*5f757f3fSDimitry Andric                                       SourceLocation(),
67*5f757f3fSDimitry Andric                                       clang::LinkageSpecLanguageIDs::C, false);
68349cc55cSDimitry Andric     // FIXME: The LinkageSpecDecl here should be added to m_decl_context.
695ffd83dbSDimitry Andric   }
705ffd83dbSDimitry Andric 
715ffd83dbSDimitry Andric   // Pass the identifier info for functions the decl_name is needed for
725ffd83dbSDimitry Andric   // operators
735ffd83dbSDimitry Andric   clang::DeclarationName decl_name =
745ffd83dbSDimitry Andric       m_decl_name.getNameKind() == DeclarationName::Identifier
755ffd83dbSDimitry Andric           ? m_decl_name.getAsIdentifierInfo()
765ffd83dbSDimitry Andric           : m_decl_name;
775ffd83dbSDimitry Andric 
785ffd83dbSDimitry Andric   clang::FunctionDecl *func_decl = FunctionDecl::Create(
795ffd83dbSDimitry Andric       ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
80349cc55cSDimitry Andric       nullptr, SC_Extern, /*UsesFPIntrin=*/false, isInlineSpecified, hasWrittenPrototype,
81e8d8bef9SDimitry Andric       isConstexprSpecified ? ConstexprSpecKind::Constexpr
82e8d8bef9SDimitry Andric                            : ConstexprSpecKind::Unspecified);
835ffd83dbSDimitry Andric 
845ffd83dbSDimitry Andric   // We have to do more than just synthesize the FunctionDecl.  We have to
855ffd83dbSDimitry Andric   // synthesize ParmVarDecls for all of the FunctionDecl's arguments.  To do
865ffd83dbSDimitry Andric   // this, we raid the function's FunctionProtoType for types.
875ffd83dbSDimitry Andric 
885ffd83dbSDimitry Andric   const FunctionProtoType *func_proto_type =
895ffd83dbSDimitry Andric       qual_type.getTypePtr()->getAs<FunctionProtoType>();
905ffd83dbSDimitry Andric 
915ffd83dbSDimitry Andric   if (func_proto_type) {
925ffd83dbSDimitry Andric     unsigned NumArgs = func_proto_type->getNumParams();
935ffd83dbSDimitry Andric     unsigned ArgIndex;
945ffd83dbSDimitry Andric 
955ffd83dbSDimitry Andric     SmallVector<ParmVarDecl *, 5> parm_var_decls;
965ffd83dbSDimitry Andric 
975ffd83dbSDimitry Andric     for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
985ffd83dbSDimitry Andric       QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
995ffd83dbSDimitry Andric 
1005ffd83dbSDimitry Andric       parm_var_decls.push_back(
1015ffd83dbSDimitry Andric           ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
1025ffd83dbSDimitry Andric                               SourceLocation(), SourceLocation(), nullptr,
1035ffd83dbSDimitry Andric                               arg_qual_type, nullptr, SC_Static, nullptr));
1045ffd83dbSDimitry Andric     }
1055ffd83dbSDimitry Andric 
1065ffd83dbSDimitry Andric     func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
1075ffd83dbSDimitry Andric   } else {
10881ad6265SDimitry Andric     Log *log = GetLog(LLDBLog::Expressions);
1095ffd83dbSDimitry Andric 
1105ffd83dbSDimitry Andric     LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
1115ffd83dbSDimitry Andric   }
1125ffd83dbSDimitry Andric 
1135ffd83dbSDimitry Andric   // If this is an operator (e.g. operator new or operator==), only insert the
1145ffd83dbSDimitry Andric   // declaration we inferred from the symbol if we can provide the correct
1155ffd83dbSDimitry Andric   // number of arguments. We shouldn't really inject random decl(s) for
1165ffd83dbSDimitry Andric   // functions that are analyzed semantically in a special way, otherwise we
1175ffd83dbSDimitry Andric   // will crash in clang.
1185ffd83dbSDimitry Andric   clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
1195ffd83dbSDimitry Andric   if (func_proto_type &&
1205ffd83dbSDimitry Andric       TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
1215ffd83dbSDimitry Andric     if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
1225ffd83dbSDimitry Andric             false, op_kind, func_proto_type->getNumParams()))
1235ffd83dbSDimitry Andric       return nullptr;
1245ffd83dbSDimitry Andric   }
1255ffd83dbSDimitry Andric   m_decls.push_back(func_decl);
1265ffd83dbSDimitry Andric 
1275ffd83dbSDimitry Andric   return func_decl;
1285ffd83dbSDimitry Andric }
1295ffd83dbSDimitry Andric 
AddGenericFunDecl()1305ffd83dbSDimitry Andric clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
1315ffd83dbSDimitry Andric   FunctionProtoType::ExtProtoInfo proto_info;
1325ffd83dbSDimitry Andric 
1335ffd83dbSDimitry Andric   proto_info.Variadic = true;
1345ffd83dbSDimitry Andric 
1355ffd83dbSDimitry Andric   QualType generic_function_type(
1365ffd83dbSDimitry Andric       GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result
1375ffd83dbSDimitry Andric                                       ArrayRef<QualType>(), // argument types
1385ffd83dbSDimitry Andric                                       proto_info));
1395ffd83dbSDimitry Andric 
1405ffd83dbSDimitry Andric   return AddFunDecl(m_clang_ts.GetType(generic_function_type), true);
1415ffd83dbSDimitry Andric }
1425ffd83dbSDimitry Andric 
1435ffd83dbSDimitry Andric clang::NamedDecl *
AddTypeDecl(const CompilerType & clang_type)1445ffd83dbSDimitry Andric NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
1455ffd83dbSDimitry Andric   if (ClangUtil::IsClangType(clang_type)) {
1465ffd83dbSDimitry Andric     QualType qual_type = ClangUtil::GetQualType(clang_type);
1475ffd83dbSDimitry Andric 
1485ffd83dbSDimitry Andric     if (const TypedefType *typedef_type =
1495ffd83dbSDimitry Andric             llvm::dyn_cast<TypedefType>(qual_type)) {
1505ffd83dbSDimitry Andric       TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
1515ffd83dbSDimitry Andric 
1525ffd83dbSDimitry Andric       m_decls.push_back(typedef_name_decl);
1535ffd83dbSDimitry Andric 
1545ffd83dbSDimitry Andric       return (NamedDecl *)typedef_name_decl;
1555ffd83dbSDimitry Andric     } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
1565ffd83dbSDimitry Andric       TagDecl *tag_decl = tag_type->getDecl();
1575ffd83dbSDimitry Andric 
1585ffd83dbSDimitry Andric       m_decls.push_back(tag_decl);
1595ffd83dbSDimitry Andric 
1605ffd83dbSDimitry Andric       return tag_decl;
1615ffd83dbSDimitry Andric     } else if (const ObjCObjectType *objc_object_type =
1625ffd83dbSDimitry Andric                    qual_type->getAs<ObjCObjectType>()) {
1635ffd83dbSDimitry Andric       ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
1645ffd83dbSDimitry Andric 
1655ffd83dbSDimitry Andric       m_decls.push_back((NamedDecl *)interface_decl);
1665ffd83dbSDimitry Andric 
1675ffd83dbSDimitry Andric       return (NamedDecl *)interface_decl;
1685ffd83dbSDimitry Andric     }
1695ffd83dbSDimitry Andric   }
1705ffd83dbSDimitry Andric   return nullptr;
1715ffd83dbSDimitry Andric }
1725ffd83dbSDimitry Andric 
AddLookupResult(clang::DeclContextLookupResult result)1735ffd83dbSDimitry Andric void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
1745ffd83dbSDimitry Andric   for (clang::NamedDecl *decl : result)
1755ffd83dbSDimitry Andric     m_decls.push_back(decl);
1765ffd83dbSDimitry Andric }
1775ffd83dbSDimitry Andric 
AddNamedDecl(clang::NamedDecl * decl)1785ffd83dbSDimitry Andric void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
1795ffd83dbSDimitry Andric   m_decls.push_back(decl);
1805ffd83dbSDimitry Andric }
181