brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · 794b194 Raw
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