1//===-- PdbAstBuilder.h -----------------------------------*- C++ -*-===//
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#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
10#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
11
12#include "llvm/ADT/DenseMap.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/Support/Threading.h"
15
16#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
17
18#include "PdbIndex.h"
19#include "PdbSymUid.h"
20#include <optional>
21
22namespace clang {
23class TagDecl;
24class DeclContext;
25class Decl;
26class QualType;
27class FunctionDecl;
28class NamespaceDecl;
29} // namespace clang
30
31namespace llvm {
32namespace codeview {
33class ProcSym;
34}
35} // namespace llvm
36
37namespace lldb_private {
38class ClangASTImporter;
39class ObjectFile;
40
41namespace npdb {
42class PdbIndex;
43struct VariableInfo;
44
45struct DeclStatus {
46  DeclStatus() = default;
47  DeclStatus(lldb::user_id_t uid, bool resolved)
48      : uid(uid), resolved(resolved) {}
49  lldb::user_id_t uid = 0;
50  bool resolved = false;
51};
52
53class PdbAstBuilder {
54public:
55  // Constructors and Destructors
56  PdbAstBuilder(TypeSystemClang &clang);
57
58  lldb_private::CompilerDeclContext GetTranslationUnitDecl();
59
60  std::optional<lldb_private::CompilerDecl>
61  GetOrCreateDeclForUid(PdbSymUid uid);
62  clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
63  clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
64
65  clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id);
66  clang::FunctionDecl *
67  GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id);
68  clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id);
69  clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
70                                          PdbCompilandSymId var_id);
71  clang::VarDecl *GetOrCreateVariableDecl(PdbGlobalSymId var_id);
72  clang::TypedefNameDecl *GetOrCreateTypedefDecl(PdbGlobalSymId id);
73  void ParseDeclsForContext(clang::DeclContext &context);
74
75  clang::QualType GetBasicType(lldb::BasicType type);
76  clang::QualType GetOrCreateType(PdbTypeSymId type);
77
78  bool CompleteTagDecl(clang::TagDecl &tag);
79  bool CompleteType(clang::QualType qt);
80
81  CompilerDecl ToCompilerDecl(clang::Decl &decl);
82  CompilerType ToCompilerType(clang::QualType qt);
83  CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
84  clang::Decl *FromCompilerDecl(CompilerDecl decl);
85  clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
86
87  TypeSystemClang &clang() { return m_clang; }
88  ClangASTImporter &GetClangASTImporter() { return m_importer; }
89
90  void Dump(Stream &stream);
91
92private:
93  clang::Decl *TryGetDecl(PdbSymUid uid) const;
94
95  using TypeIndex = llvm::codeview::TypeIndex;
96
97  clang::QualType
98  CreatePointerType(const llvm::codeview::PointerRecord &pointer);
99  clang::QualType
100  CreateModifierType(const llvm::codeview::ModifierRecord &modifier);
101  clang::QualType CreateArrayType(const llvm::codeview::ArrayRecord &array);
102  clang::QualType CreateRecordType(PdbTypeSymId id,
103                                   const llvm::codeview::TagRecord &record);
104  clang::QualType CreateEnumType(PdbTypeSymId id,
105                                 const llvm::codeview::EnumRecord &record);
106  clang::QualType
107  CreateFunctionType(TypeIndex args_type_idx, TypeIndex return_type_idx,
108                     llvm::codeview::CallingConvention calling_convention);
109  clang::QualType CreateType(PdbTypeSymId type);
110
111  void CreateFunctionParameters(PdbCompilandSymId func_id,
112                                clang::FunctionDecl &function_decl,
113                                uint32_t param_count);
114  clang::Decl *GetOrCreateSymbolForId(PdbCompilandSymId id);
115  clang::VarDecl *CreateVariableDecl(PdbSymUid uid,
116                                     llvm::codeview::CVSymbol sym,
117                                     clang::DeclContext &scope);
118  clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name,
119                                                 clang::DeclContext &context);
120  clang::FunctionDecl *CreateFunctionDeclFromId(PdbTypeSymId func_tid,
121                                                PdbCompilandSymId func_sid);
122  clang::FunctionDecl *
123  CreateFunctionDecl(PdbCompilandSymId func_id, llvm::StringRef func_name,
124                     TypeIndex func_ti, CompilerType func_ct,
125                     uint32_t param_count, clang::StorageClass func_storage,
126                     bool is_inline, clang::DeclContext *parent);
127  void ParseNamespace(clang::DeclContext &parent);
128  void ParseAllTypes();
129  void ParseAllFunctionsAndNonLocalVars();
130  void ParseDeclsForSimpleContext(clang::DeclContext &context);
131  void ParseBlockChildren(PdbCompilandSymId block_id);
132
133  std::pair<clang::DeclContext *, std::string>
134  CreateDeclInfoForType(const llvm::codeview::TagRecord &record, TypeIndex ti);
135  std::pair<clang::DeclContext *, std::string>
136  CreateDeclInfoForUndecoratedName(llvm::StringRef uname);
137  clang::QualType CreateSimpleType(TypeIndex ti);
138
139  TypeSystemClang &m_clang;
140
141  ClangASTImporter m_importer;
142  llvm::once_flag m_parse_functions_and_non_local_vars;
143  llvm::once_flag m_parse_all_types;
144  llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
145  llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
146  llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
147
148  // From class/struct's opaque_compiler_type_t to a set containing the pairs of
149  // method's name and CompilerType.
150  llvm::DenseMap<lldb::opaque_compiler_type_t,
151                 llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
152      m_cxx_record_map;
153  llvm::DenseSet<clang::NamespaceDecl *> m_parsed_namespaces;
154};
155
156} // namespace npdb
157} // namespace lldb_private
158
159#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
160