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