181 lines · cpp
1//===-- NameSearchContext.cpp ---------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "NameSearchContext.h"10#include "ClangUtil.h"11#include "lldb/Utility/LLDBLog.h"12 13using namespace clang;14using namespace lldb_private;15 16clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {17 assert(type && "Type for variable must be valid!");18 19 if (!type.IsValid())20 return nullptr;21 22 auto lldb_ast = type.GetTypeSystem<TypeSystemClang>();23 if (!lldb_ast)24 return nullptr;25 26 IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();27 28 clang::ASTContext &ast = lldb_ast->getASTContext();29 30 clang::NamedDecl *Decl = VarDecl::Create(31 ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),32 SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);33 m_decls.push_back(Decl);34 35 return Decl;36}37 38clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,39 bool extern_c) {40 assert(type && "Type for variable must be valid!");41 42 if (!type.IsValid())43 return nullptr;44 45 if (m_function_types.count(type))46 return nullptr;47 48 auto lldb_ast = type.GetTypeSystem<TypeSystemClang>();49 if (!lldb_ast)50 return nullptr;51 52 m_function_types.insert(type);53 54 QualType qual_type(ClangUtil::GetQualType(type));55 56 clang::ASTContext &ast = lldb_ast->getASTContext();57 58 const bool isInlineSpecified = false;59 const bool hasWrittenPrototype = true;60 const bool isConstexprSpecified = false;61 62 clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);63 64 if (extern_c) {65 context = LinkageSpecDecl::Create(ast, context, SourceLocation(),66 SourceLocation(),67 clang::LinkageSpecLanguageIDs::C, false);68 // FIXME: The LinkageSpecDecl here should be added to m_decl_context.69 }70 71 // Pass the identifier info for functions the decl_name is needed for72 // operators73 clang::DeclarationName decl_name =74 m_decl_name.getNameKind() == DeclarationName::Identifier75 ? m_decl_name.getAsIdentifierInfo()76 : m_decl_name;77 78 clang::FunctionDecl *func_decl = FunctionDecl::Create(79 ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,80 nullptr, SC_Extern, /*UsesFPIntrin=*/false, isInlineSpecified, hasWrittenPrototype,81 isConstexprSpecified ? ConstexprSpecKind::Constexpr82 : ConstexprSpecKind::Unspecified);83 84 // We have to do more than just synthesize the FunctionDecl. We have to85 // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do86 // this, we raid the function's FunctionProtoType for types.87 88 const FunctionProtoType *func_proto_type =89 qual_type.getTypePtr()->getAs<FunctionProtoType>();90 91 if (func_proto_type) {92 unsigned NumArgs = func_proto_type->getNumParams();93 unsigned ArgIndex;94 95 SmallVector<ParmVarDecl *, 5> parm_var_decls;96 97 for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {98 QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));99 100 parm_var_decls.push_back(101 ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),102 SourceLocation(), SourceLocation(), nullptr,103 arg_qual_type, nullptr, SC_Static, nullptr));104 }105 106 func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));107 } else {108 Log *log = GetLog(LLDBLog::Expressions);109 110 LLDB_LOG(log, "Function type wasn't a FunctionProtoType");111 }112 113 // If this is an operator (e.g. operator new or operator==), only insert the114 // declaration we inferred from the symbol if we can provide the correct115 // number of arguments. We shouldn't really inject random decl(s) for116 // functions that are analyzed semantically in a special way, otherwise we117 // will crash in clang.118 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;119 if (func_proto_type &&120 TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {121 if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(122 false, op_kind, func_proto_type->getNumParams()))123 return nullptr;124 }125 m_decls.push_back(func_decl);126 127 return func_decl;128}129 130clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {131 FunctionProtoType::ExtProtoInfo proto_info;132 133 proto_info.Variadic = true;134 135 QualType generic_function_type(136 GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result137 ArrayRef<QualType>(), // argument types138 proto_info));139 140 return AddFunDecl(m_clang_ts.GetType(generic_function_type), true);141}142 143clang::NamedDecl *144NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {145 if (ClangUtil::IsClangType(clang_type)) {146 QualType qual_type = ClangUtil::GetQualType(clang_type);147 148 if (const TypedefType *typedef_type =149 llvm::dyn_cast<TypedefType>(qual_type)) {150 TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();151 152 m_decls.push_back(typedef_name_decl);153 154 return (NamedDecl *)typedef_name_decl;155 } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {156 TagDecl *tag_decl = tag_type->getDecl()->getDefinitionOrSelf();157 158 m_decls.push_back(tag_decl);159 160 return tag_decl;161 } else if (const ObjCObjectType *objc_object_type =162 qual_type->getAs<ObjCObjectType>()) {163 ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();164 165 m_decls.push_back((NamedDecl *)interface_decl);166 167 return (NamedDecl *)interface_decl;168 }169 }170 return nullptr;171}172 173void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {174 for (clang::NamedDecl *decl : result)175 m_decls.push_back(decl);176}177 178void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {179 m_decls.push_back(decl);180}181