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 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 22*bdd1243dSDimitry 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 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 48*bdd1243dSDimitry 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) { 655ffd83dbSDimitry Andric context = LinkageSpecDecl::Create( 665ffd83dbSDimitry Andric ast, context, SourceLocation(), SourceLocation(), 675ffd83dbSDimitry Andric clang::LinkageSpecDecl::LanguageIDs::lang_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 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 * 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 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 1785ffd83dbSDimitry Andric void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) { 1795ffd83dbSDimitry Andric m_decls.push_back(decl); 1805ffd83dbSDimitry Andric } 181