xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
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"
115ffd83dbSDimitry Andric 
125ffd83dbSDimitry Andric using namespace clang;
135ffd83dbSDimitry Andric using namespace lldb_private;
145ffd83dbSDimitry Andric 
155ffd83dbSDimitry Andric clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
165ffd83dbSDimitry Andric   assert(type && "Type for variable must be valid!");
175ffd83dbSDimitry Andric 
185ffd83dbSDimitry Andric   if (!type.IsValid())
195ffd83dbSDimitry Andric     return nullptr;
205ffd83dbSDimitry Andric 
215ffd83dbSDimitry Andric   TypeSystemClang *lldb_ast =
225ffd83dbSDimitry Andric       llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
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 
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 
485ffd83dbSDimitry Andric   TypeSystemClang *lldb_ast =
495ffd83dbSDimitry Andric       llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
505ffd83dbSDimitry Andric   if (!lldb_ast)
515ffd83dbSDimitry Andric     return nullptr;
525ffd83dbSDimitry Andric 
535ffd83dbSDimitry Andric   m_function_types.insert(type);
545ffd83dbSDimitry Andric 
555ffd83dbSDimitry Andric   QualType qual_type(ClangUtil::GetQualType(type));
565ffd83dbSDimitry Andric 
575ffd83dbSDimitry Andric   clang::ASTContext &ast = lldb_ast->getASTContext();
585ffd83dbSDimitry Andric 
595ffd83dbSDimitry Andric   const bool isInlineSpecified = false;
605ffd83dbSDimitry Andric   const bool hasWrittenPrototype = true;
615ffd83dbSDimitry Andric   const bool isConstexprSpecified = false;
625ffd83dbSDimitry Andric 
635ffd83dbSDimitry Andric   clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
645ffd83dbSDimitry Andric 
655ffd83dbSDimitry Andric   if (extern_c) {
665ffd83dbSDimitry Andric     context = LinkageSpecDecl::Create(
675ffd83dbSDimitry Andric         ast, context, SourceLocation(), SourceLocation(),
685ffd83dbSDimitry Andric         clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
69*349cc55cSDimitry Andric     // FIXME: The LinkageSpecDecl here should be added to m_decl_context.
705ffd83dbSDimitry Andric   }
715ffd83dbSDimitry Andric 
725ffd83dbSDimitry Andric   // Pass the identifier info for functions the decl_name is needed for
735ffd83dbSDimitry Andric   // operators
745ffd83dbSDimitry Andric   clang::DeclarationName decl_name =
755ffd83dbSDimitry Andric       m_decl_name.getNameKind() == DeclarationName::Identifier
765ffd83dbSDimitry Andric           ? m_decl_name.getAsIdentifierInfo()
775ffd83dbSDimitry Andric           : m_decl_name;
785ffd83dbSDimitry Andric 
795ffd83dbSDimitry Andric   clang::FunctionDecl *func_decl = FunctionDecl::Create(
805ffd83dbSDimitry Andric       ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
81*349cc55cSDimitry Andric       nullptr, SC_Extern, /*UsesFPIntrin=*/false, isInlineSpecified, hasWrittenPrototype,
82e8d8bef9SDimitry Andric       isConstexprSpecified ? ConstexprSpecKind::Constexpr
83e8d8bef9SDimitry Andric                            : ConstexprSpecKind::Unspecified);
845ffd83dbSDimitry Andric 
855ffd83dbSDimitry Andric   // We have to do more than just synthesize the FunctionDecl.  We have to
865ffd83dbSDimitry Andric   // synthesize ParmVarDecls for all of the FunctionDecl's arguments.  To do
875ffd83dbSDimitry Andric   // this, we raid the function's FunctionProtoType for types.
885ffd83dbSDimitry Andric 
895ffd83dbSDimitry Andric   const FunctionProtoType *func_proto_type =
905ffd83dbSDimitry Andric       qual_type.getTypePtr()->getAs<FunctionProtoType>();
915ffd83dbSDimitry Andric 
925ffd83dbSDimitry Andric   if (func_proto_type) {
935ffd83dbSDimitry Andric     unsigned NumArgs = func_proto_type->getNumParams();
945ffd83dbSDimitry Andric     unsigned ArgIndex;
955ffd83dbSDimitry Andric 
965ffd83dbSDimitry Andric     SmallVector<ParmVarDecl *, 5> parm_var_decls;
975ffd83dbSDimitry Andric 
985ffd83dbSDimitry Andric     for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
995ffd83dbSDimitry Andric       QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
1005ffd83dbSDimitry Andric 
1015ffd83dbSDimitry Andric       parm_var_decls.push_back(
1025ffd83dbSDimitry Andric           ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
1035ffd83dbSDimitry Andric                               SourceLocation(), SourceLocation(), nullptr,
1045ffd83dbSDimitry Andric                               arg_qual_type, nullptr, SC_Static, nullptr));
1055ffd83dbSDimitry Andric     }
1065ffd83dbSDimitry Andric 
1075ffd83dbSDimitry Andric     func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
1085ffd83dbSDimitry Andric   } else {
1095ffd83dbSDimitry Andric     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1105ffd83dbSDimitry Andric 
1115ffd83dbSDimitry Andric     LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
1125ffd83dbSDimitry Andric   }
1135ffd83dbSDimitry Andric 
1145ffd83dbSDimitry Andric   // If this is an operator (e.g. operator new or operator==), only insert the
1155ffd83dbSDimitry Andric   // declaration we inferred from the symbol if we can provide the correct
1165ffd83dbSDimitry Andric   // number of arguments. We shouldn't really inject random decl(s) for
1175ffd83dbSDimitry Andric   // functions that are analyzed semantically in a special way, otherwise we
1185ffd83dbSDimitry Andric   // will crash in clang.
1195ffd83dbSDimitry Andric   clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
1205ffd83dbSDimitry Andric   if (func_proto_type &&
1215ffd83dbSDimitry Andric       TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
1225ffd83dbSDimitry Andric     if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
1235ffd83dbSDimitry Andric             false, op_kind, func_proto_type->getNumParams()))
1245ffd83dbSDimitry Andric       return nullptr;
1255ffd83dbSDimitry Andric   }
1265ffd83dbSDimitry Andric   m_decls.push_back(func_decl);
1275ffd83dbSDimitry Andric 
1285ffd83dbSDimitry Andric   return func_decl;
1295ffd83dbSDimitry Andric }
1305ffd83dbSDimitry Andric 
1315ffd83dbSDimitry Andric clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
1325ffd83dbSDimitry Andric   FunctionProtoType::ExtProtoInfo proto_info;
1335ffd83dbSDimitry Andric 
1345ffd83dbSDimitry Andric   proto_info.Variadic = true;
1355ffd83dbSDimitry Andric 
1365ffd83dbSDimitry Andric   QualType generic_function_type(
1375ffd83dbSDimitry Andric       GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result
1385ffd83dbSDimitry Andric                                       ArrayRef<QualType>(), // argument types
1395ffd83dbSDimitry Andric                                       proto_info));
1405ffd83dbSDimitry Andric 
1415ffd83dbSDimitry Andric   return AddFunDecl(m_clang_ts.GetType(generic_function_type), true);
1425ffd83dbSDimitry Andric }
1435ffd83dbSDimitry Andric 
1445ffd83dbSDimitry Andric clang::NamedDecl *
1455ffd83dbSDimitry Andric NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
1465ffd83dbSDimitry Andric   if (ClangUtil::IsClangType(clang_type)) {
1475ffd83dbSDimitry Andric     QualType qual_type = ClangUtil::GetQualType(clang_type);
1485ffd83dbSDimitry Andric 
1495ffd83dbSDimitry Andric     if (const TypedefType *typedef_type =
1505ffd83dbSDimitry Andric             llvm::dyn_cast<TypedefType>(qual_type)) {
1515ffd83dbSDimitry Andric       TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
1525ffd83dbSDimitry Andric 
1535ffd83dbSDimitry Andric       m_decls.push_back(typedef_name_decl);
1545ffd83dbSDimitry Andric 
1555ffd83dbSDimitry Andric       return (NamedDecl *)typedef_name_decl;
1565ffd83dbSDimitry Andric     } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
1575ffd83dbSDimitry Andric       TagDecl *tag_decl = tag_type->getDecl();
1585ffd83dbSDimitry Andric 
1595ffd83dbSDimitry Andric       m_decls.push_back(tag_decl);
1605ffd83dbSDimitry Andric 
1615ffd83dbSDimitry Andric       return tag_decl;
1625ffd83dbSDimitry Andric     } else if (const ObjCObjectType *objc_object_type =
1635ffd83dbSDimitry Andric                    qual_type->getAs<ObjCObjectType>()) {
1645ffd83dbSDimitry Andric       ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
1655ffd83dbSDimitry Andric 
1665ffd83dbSDimitry Andric       m_decls.push_back((NamedDecl *)interface_decl);
1675ffd83dbSDimitry Andric 
1685ffd83dbSDimitry Andric       return (NamedDecl *)interface_decl;
1695ffd83dbSDimitry Andric     }
1705ffd83dbSDimitry Andric   }
1715ffd83dbSDimitry Andric   return nullptr;
1725ffd83dbSDimitry Andric }
1735ffd83dbSDimitry Andric 
1745ffd83dbSDimitry Andric void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
1755ffd83dbSDimitry Andric   for (clang::NamedDecl *decl : result)
1765ffd83dbSDimitry Andric     m_decls.push_back(decl);
1775ffd83dbSDimitry Andric }
1785ffd83dbSDimitry Andric 
1795ffd83dbSDimitry Andric void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
1805ffd83dbSDimitry Andric   m_decls.push_back(decl);
1815ffd83dbSDimitry Andric }
182