Coverage Report

Created: 2023-09-30 09:22

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