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