Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
Line
Count
Source (jump to first uncovered line)
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
18.8k
clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
16
18.8k
  assert(type && "Type for variable must be valid!");
17
18
18.8k
  if (!type.IsValid())
19
0
    return nullptr;
20
21
18.8k
  TypeSystemClang *lldb_ast =
22
18.8k
      llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
23
18.8k
  if (!lldb_ast)
24
0
    return nullptr;
25
26
18.8k
  IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
27
28
18.8k
  clang::ASTContext &ast = lldb_ast->getASTContext();
29
30
18.8k
  clang::NamedDecl *Decl = VarDecl::Create(
31
18.8k
      ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
32
18.8k
      SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);
33
18.8k
  m_decls.push_back(Decl);
34
35
18.8k
  return Decl;
36
18.8k
}
37
38
clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
39
334
                                                bool extern_c) {
40
334
  assert(type && "Type for variable must be valid!");
41
42
334
  if (!type.IsValid())
43
0
    return nullptr;
44
45
334
  if (m_function_types.count(type))
46
0
    return nullptr;
47
48
334
  TypeSystemClang *lldb_ast =
49
334
      llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
50
334
  if (!lldb_ast)
51
0
    return nullptr;
52
53
334
  m_function_types.insert(type);
54
55
334
  QualType qual_type(ClangUtil::GetQualType(type));
56
57
334
  clang::ASTContext &ast = lldb_ast->getASTContext();
58
59
334
  const bool isInlineSpecified = false;
60
334
  const bool hasWrittenPrototype = true;
61
334
  const bool isConstexprSpecified = false;
62
63
334
  clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
64
65
334
  if (extern_c) {
66
334
    context = LinkageSpecDecl::Create(
67
334
        ast, context, SourceLocation(), SourceLocation(),
68
334
        clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
69
    // FIXME: The LinkageSpecDecl here should be added to m_decl_context.
70
334
  }
71
72
  // Pass the identifier info for functions the decl_name is needed for
73
  // operators
74
334
  clang::DeclarationName decl_name =
75
334
      m_decl_name.getNameKind() == DeclarationName::Identifier
76
334
          ? 
m_decl_name.getAsIdentifierInfo()119
77
334
          : 
m_decl_name215
;
78
79
334
  clang::FunctionDecl *func_decl = FunctionDecl::Create(
80
334
      ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
81
334
      nullptr, SC_Extern, /*UsesFPIntrin=*/false, isInlineSpecified, hasWrittenPrototype,
82
334
      isConstexprSpecified ? 
ConstexprSpecKind::Constexpr0
83
334
                           : 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
334
  const FunctionProtoType *func_proto_type =
90
334
      qual_type.getTypePtr()->getAs<FunctionProtoType>();
91
92
334
  if (func_proto_type) {
93
334
    unsigned NumArgs = func_proto_type->getNumParams();
94
334
    unsigned ArgIndex;
95
96
334
    SmallVector<ParmVarDecl *, 5> parm_var_decls;
97
98
375
    for (ArgIndex = 0; ArgIndex < NumArgs; 
++ArgIndex41
) {
99
41
      QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
100
101
41
      parm_var_decls.push_back(
102
41
          ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
103
41
                              SourceLocation(), SourceLocation(), nullptr,
104
41
                              arg_qual_type, nullptr, SC_Static, nullptr));
105
41
    }
106
107
334
    func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
108
334
  } else {
109
0
    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
110
111
0
    LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
112
0
  }
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
334
  clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
120
334
  if (func_proto_type &&
121
334
      TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
122
215
    if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
123
215
            false, op_kind, func_proto_type->getNumParams()))
124
137
      return nullptr;
125
215
  }
126
197
  m_decls.push_back(func_decl);
127
128
197
  return func_decl;
129
334
}
130
131
292
clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
132
292
  FunctionProtoType::ExtProtoInfo proto_info;
133
134
292
  proto_info.Variadic = true;
135
136
292
  QualType generic_function_type(
137
292
      GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result
138
292
                                      ArrayRef<QualType>(), // argument types
139
292
                                      proto_info));
140
141
292
  return AddFunDecl(m_clang_ts.GetType(generic_function_type), true);
142
292
}
143
144
clang::NamedDecl *
145
991
NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
146
991
  if (ClangUtil::IsClangType(clang_type)) {
147
991
    QualType qual_type = ClangUtil::GetQualType(clang_type);
148
149
991
    if (const TypedefType *typedef_type =
150
991
            llvm::dyn_cast<TypedefType>(qual_type)) {
151
53
      TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
152
153
53
      m_decls.push_back(typedef_name_decl);
154
155
53
      return (NamedDecl *)typedef_name_decl;
156
938
    } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
157
679
      TagDecl *tag_decl = tag_type->getDecl();
158
159
679
      m_decls.push_back(tag_decl);
160
161
679
      return tag_decl;
162
679
    } else 
if (const ObjCObjectType *259
objc_object_type259
=
163
259
                   qual_type->getAs<ObjCObjectType>()) {
164
259
      ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
165
166
259
      m_decls.push_back((NamedDecl *)interface_decl);
167
168
259
      return (NamedDecl *)interface_decl;
169
259
    }
170
991
  }
171
0
  return nullptr;
172
991
}
173
174
0
void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
175
0
  for (clang::NamedDecl *decl : result)
176
0
    m_decls.push_back(decl);
177
0
}
178
179
8.69k
void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
180
8.69k
  m_decls.push_back(decl);
181
8.69k
}