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