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_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
10#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
11
12#include "llvm/ADT/DenseMap.h"
13#include "llvm/ADT/StringRef.h"
14
15#include "lldb/Symbol/ClangASTImporter.h"
16
17#include "PdbIndex.h"
18#include "PdbSymUid.h"
19
20namespace clang {
21class TagDecl;
22class DeclContext;
23class Decl;
24class QualType;
25class FunctionDecl;
26class NamespaceDecl;
27} // namespace clang
28
29namespace llvm {
30namespace codeview {
31class ProcSym;
32}
33} // namespace llvm
34
35namespace lldb_private {
36class ClangASTImporter;
37class ObjectFile;
38
39namespace npdb {
40class PdbIndex;
41struct VariableInfo;
42
43struct DeclStatus {
44  DeclStatus() = default;
45  DeclStatus(lldb::user_id_t uid, bool resolved)
46      : uid(uid), resolved(resolved) {}
47  lldb::user_id_t uid = 0;
48  bool resolved = false;
49};
50
51class PdbAstBuilder {
52public:
53  // Constructors and Destructors
54  PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang);
55
56  lldb_private::CompilerDeclContext GetTranslationUnitDecl();
57
58  llvm::Optional<lldb_private::CompilerDecl>
59  GetOrCreateDeclForUid(PdbSymUid uid);
60  clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
61  clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
62
63  clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id);
64  clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id);
65  clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
66                                          PdbCompilandSymId var_id);
67  clang::VarDecl *GetOrCreateVariableDecl(PdbGlobalSymId var_id);
68  clang::TypedefNameDecl *GetOrCreateTypedefDecl(PdbGlobalSymId id);
69  void ParseDeclsForContext(clang::DeclContext &context);
70
71  clang::QualType GetBasicType(lldb::BasicType type);
72  clang::QualType GetOrCreateType(PdbTypeSymId type);
73
74  bool CompleteTagDecl(clang::TagDecl &tag);
75  bool CompleteType(clang::QualType qt);
76
77  CompilerDecl ToCompilerDecl(clang::Decl &decl);
78  CompilerType ToCompilerType(clang::QualType qt);
79  CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
80  clang::Decl *FromCompilerDecl(CompilerDecl decl);
81  clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
82
83  ClangASTContext &clang() { return m_clang; }
84  ClangASTImporter &importer() { return m_importer; }
85
86  void Dump(Stream &stream);
87
88private:
89  clang::Decl *TryGetDecl(PdbSymUid uid) const;
90
91  using TypeIndex = llvm::codeview::TypeIndex;
92
93  clang::QualType
94  CreatePointerType(const llvm::codeview::PointerRecord &pointer);
95  clang::QualType
96  CreateModifierType(const llvm::codeview::ModifierRecord &modifier);
97  clang::QualType CreateArrayType(const llvm::codeview::ArrayRecord &array);
98  clang::QualType CreateRecordType(PdbTypeSymId id,
99                                   const llvm::codeview::TagRecord &record);
100  clang::QualType CreateEnumType(PdbTypeSymId id,
101                                 const llvm::codeview::EnumRecord &record);
102  clang::QualType
103  CreateFunctionType(TypeIndex args_type_idx, TypeIndex return_type_idx,
104                     llvm::codeview::CallingConvention calling_convention);
105  clang::QualType CreateType(PdbTypeSymId type);
106
107  void CreateFunctionParameters(PdbCompilandSymId func_id,
108                                clang::FunctionDecl &function_decl,
109                                uint32_t param_count);
110  clang::Decl *GetOrCreateSymbolForId(PdbCompilandSymId id);
111  clang::VarDecl *CreateVariableDecl(PdbSymUid uid,
112                                     llvm::codeview::CVSymbol sym,
113                                     clang::DeclContext &scope);
114  clang::DeclContext *
115  GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym);
116
117  clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name,
118                                                 clang::DeclContext &context);
119
120  void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
121  void ParseDeclsForSimpleContext(clang::DeclContext &context);
122  void ParseBlockChildren(PdbCompilandSymId block_id);
123
124  void BuildParentMap();
125  std::pair<clang::DeclContext *, std::string>
126  CreateDeclInfoForType(const llvm::codeview::TagRecord &record, TypeIndex ti);
127  std::pair<clang::DeclContext *, std::string>
128  CreateDeclInfoForUndecoratedName(llvm::StringRef uname);
129  clang::QualType CreateSimpleType(TypeIndex ti);
130
131  PdbIndex &m_index;
132  ClangASTContext &m_clang;
133
134  ClangASTImporter m_importer;
135
136  llvm::DenseMap<TypeIndex, TypeIndex> m_parent_types;
137  llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
138  llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
139  llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
140};
141
142} // namespace npdb
143} // namespace lldb_private
144
145#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
146