LLDB  mainline
NameSearchContext.cpp
Go to the documentation of this file.
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "NameSearchContext.h"
10 #include "ClangUtil.h"
11 
12 using namespace clang;
13 using namespace lldb_private;
14 
15 clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
16  assert(type && "Type for variable must be valid!");
17 
18  if (!type.IsValid())
19  return nullptr;
20 
21  TypeSystemClang *lldb_ast =
22  llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
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 
38 clang::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  TypeSystemClang *lldb_ast =
49  llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
50  if (!lldb_ast)
51  return nullptr;
52 
53  m_function_types.insert(type);
54 
55  QualType qual_type(ClangUtil::GetQualType(type));
56 
57  clang::ASTContext &ast = lldb_ast->getASTContext();
58 
59  const bool isInlineSpecified = false;
60  const bool hasWrittenPrototype = true;
61  const bool isConstexprSpecified = false;
62 
63  clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
64 
65  if (extern_c) {
66  context = LinkageSpecDecl::Create(
67  ast, context, SourceLocation(), SourceLocation(),
68  clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
69  // FIXME: The LinkageSpecDecl here should be added to m_decl_context.
70  }
71 
72  // Pass the identifier info for functions the decl_name is needed for
73  // operators
74  clang::DeclarationName decl_name =
75  m_decl_name.getNameKind() == DeclarationName::Identifier
76  ? m_decl_name.getAsIdentifierInfo()
77  : m_decl_name;
78 
79  clang::FunctionDecl *func_decl = FunctionDecl::Create(
80  ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
81  nullptr, SC_Extern, /*UsesFPIntrin=*/false, isInlineSpecified, hasWrittenPrototype,
82  isConstexprSpecified ? ConstexprSpecKind::Constexpr
83  : ConstexprSpecKind::Unspecified);
84 
85  // We have to do more than just synthesize the FunctionDecl. We have to
86  // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
87  // this, we raid the function's FunctionProtoType for types.
88 
89  const FunctionProtoType *func_proto_type =
90  qual_type.getTypePtr()->getAs<FunctionProtoType>();
91 
92  if (func_proto_type) {
93  unsigned NumArgs = func_proto_type->getNumParams();
94  unsigned ArgIndex;
95 
96  SmallVector<ParmVarDecl *, 5> parm_var_decls;
97 
98  for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
99  QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
100 
101  parm_var_decls.push_back(
102  ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
103  SourceLocation(), SourceLocation(), nullptr,
104  arg_qual_type, nullptr, SC_Static, nullptr));
105  }
106 
107  func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
108  } else {
110 
111  LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
112  }
113 
114  // If this is an operator (e.g. operator new or operator==), only insert the
115  // declaration we inferred from the symbol if we can provide the correct
116  // number of arguments. We shouldn't really inject random decl(s) for
117  // functions that are analyzed semantically in a special way, otherwise we
118  // will crash in clang.
119  clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
120  if (func_proto_type &&
121  TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
122  if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
123  false, op_kind, func_proto_type->getNumParams()))
124  return nullptr;
125  }
126  m_decls.push_back(func_decl);
127 
128  return func_decl;
129 }
130 
131 clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
132  FunctionProtoType::ExtProtoInfo proto_info;
133 
134  proto_info.Variadic = true;
135 
136  QualType generic_function_type(
137  GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result
138  ArrayRef<QualType>(), // argument types
139  proto_info));
140 
141  return AddFunDecl(m_clang_ts.GetType(generic_function_type), true);
142 }
143 
144 clang::NamedDecl *
145 NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
146  if (ClangUtil::IsClangType(clang_type)) {
147  QualType qual_type = ClangUtil::GetQualType(clang_type);
148 
149  if (const TypedefType *typedef_type =
150  llvm::dyn_cast<TypedefType>(qual_type)) {
151  TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
152 
153  m_decls.push_back(typedef_name_decl);
154 
155  return (NamedDecl *)typedef_name_decl;
156  } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
157  TagDecl *tag_decl = tag_type->getDecl();
158 
159  m_decls.push_back(tag_decl);
160 
161  return tag_decl;
162  } else if (const ObjCObjectType *objc_object_type =
163  qual_type->getAs<ObjCObjectType>()) {
164  ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
165 
166  m_decls.push_back((NamedDecl *)interface_decl);
167 
168  return (NamedDecl *)interface_decl;
169  }
170  }
171  return nullptr;
172 }
173 
174 void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
175  for (clang::NamedDecl *decl : result)
176  m_decls.push_back(decl);
177 }
178 
179 void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
180  m_decls.push_back(decl);
181 }
lldb_private::TypeSystemClang::getASTContext
clang::ASTContext & getASTContext()
Returns the clang::ASTContext instance managed by this TypeSystemClang.
Definition: TypeSystemClang.cpp:692
ClangUtil.h
LIBLLDB_LOG_EXPRESSIONS
#define LIBLLDB_LOG_EXPRESSIONS
Definition: Logging.h:22
NameSearchContext.h
lldb_private::GetLogIfAllCategoriesSet
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
lldb_private::CompilerType::IsValid
bool IsValid() const
Definition: CompilerType.h:72
lldb_private::CompilerType::GetTypeSystem
TypeSystem * GetTypeSystem() const
Accessors.
Definition: CompilerType.h:162
LLDB_LOG
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:242
clang
Definition: ASTResultSynthesizer.h:15
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::TypeSystemClang
A TypeSystem implementation based on Clang.
Definition: TypeSystemClang.h:106
lldb_private::Log
Definition: Log.h:49