| File: | src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp |
| Warning: | line 469, column 58 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | //===-- PDBASTParser.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 "PDBASTParser.h" | |||
| 10 | ||||
| 11 | #include "SymbolFilePDB.h" | |||
| 12 | ||||
| 13 | #include "clang/AST/CharUnits.h" | |||
| 14 | #include "clang/AST/Decl.h" | |||
| 15 | #include "clang/AST/DeclCXX.h" | |||
| 16 | ||||
| 17 | #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" | |||
| 18 | #include "Plugins/ExpressionParser/Clang/ClangUtil.h" | |||
| 19 | #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" | |||
| 20 | #include "lldb/Core/Declaration.h" | |||
| 21 | #include "lldb/Core/Module.h" | |||
| 22 | #include "lldb/Symbol/SymbolFile.h" | |||
| 23 | #include "lldb/Symbol/TypeMap.h" | |||
| 24 | #include "lldb/Symbol/TypeSystem.h" | |||
| 25 | ||||
| 26 | #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" | |||
| 27 | #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" | |||
| 28 | #include "llvm/DebugInfo/PDB/PDBSymbol.h" | |||
| 29 | #include "llvm/DebugInfo/PDB/PDBSymbolData.h" | |||
| 30 | #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" | |||
| 31 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" | |||
| 32 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" | |||
| 33 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" | |||
| 34 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" | |||
| 35 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" | |||
| 36 | #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" | |||
| 37 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" | |||
| 38 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" | |||
| 39 | ||||
| 40 | #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" | |||
| 41 | ||||
| 42 | using namespace lldb; | |||
| 43 | using namespace lldb_private; | |||
| 44 | using namespace llvm::pdb; | |||
| 45 | ||||
| 46 | static int TranslateUdtKind(PDB_UdtType pdb_kind) { | |||
| 47 | switch (pdb_kind) { | |||
| 48 | case PDB_UdtType::Class: | |||
| 49 | return clang::TTK_Class; | |||
| 50 | case PDB_UdtType::Struct: | |||
| 51 | return clang::TTK_Struct; | |||
| 52 | case PDB_UdtType::Union: | |||
| 53 | return clang::TTK_Union; | |||
| 54 | case PDB_UdtType::Interface: | |||
| 55 | return clang::TTK_Interface; | |||
| 56 | } | |||
| 57 | llvm_unreachable("unsuported PDB UDT type")__builtin_unreachable(); | |||
| 58 | } | |||
| 59 | ||||
| 60 | static lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) { | |||
| 61 | switch (type) { | |||
| 62 | case PDB_BuiltinType::Float: | |||
| 63 | return lldb::eEncodingIEEE754; | |||
| 64 | case PDB_BuiltinType::Int: | |||
| 65 | case PDB_BuiltinType::Long: | |||
| 66 | case PDB_BuiltinType::Char: | |||
| 67 | return lldb::eEncodingSint; | |||
| 68 | case PDB_BuiltinType::Bool: | |||
| 69 | case PDB_BuiltinType::Char16: | |||
| 70 | case PDB_BuiltinType::Char32: | |||
| 71 | case PDB_BuiltinType::UInt: | |||
| 72 | case PDB_BuiltinType::ULong: | |||
| 73 | case PDB_BuiltinType::HResult: | |||
| 74 | case PDB_BuiltinType::WCharT: | |||
| 75 | return lldb::eEncodingUint; | |||
| 76 | default: | |||
| 77 | return lldb::eEncodingInvalid; | |||
| 78 | } | |||
| 79 | } | |||
| 80 | ||||
| 81 | static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) { | |||
| 82 | switch (type) { | |||
| 83 | case PDB_VariantType::Int8: | |||
| 84 | case PDB_VariantType::Int16: | |||
| 85 | case PDB_VariantType::Int32: | |||
| 86 | case PDB_VariantType::Int64: | |||
| 87 | return lldb::eEncodingSint; | |||
| 88 | ||||
| 89 | case PDB_VariantType::UInt8: | |||
| 90 | case PDB_VariantType::UInt16: | |||
| 91 | case PDB_VariantType::UInt32: | |||
| 92 | case PDB_VariantType::UInt64: | |||
| 93 | return lldb::eEncodingUint; | |||
| 94 | ||||
| 95 | default: | |||
| 96 | break; | |||
| 97 | } | |||
| 98 | ||||
| 99 | return lldb::eEncodingSint; | |||
| 100 | } | |||
| 101 | ||||
| 102 | static CompilerType | |||
| 103 | GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast, | |||
| 104 | const PDBSymbolTypeBuiltin &pdb_type, | |||
| 105 | Encoding encoding, uint32_t width) { | |||
| 106 | clang::ASTContext &ast = clang_ast.getASTContext(); | |||
| 107 | ||||
| 108 | switch (pdb_type.getBuiltinType()) { | |||
| 109 | default: | |||
| 110 | break; | |||
| 111 | case PDB_BuiltinType::None: | |||
| 112 | return CompilerType(); | |||
| 113 | case PDB_BuiltinType::Void: | |||
| 114 | return clang_ast.GetBasicType(eBasicTypeVoid); | |||
| 115 | case PDB_BuiltinType::Char: | |||
| 116 | return clang_ast.GetBasicType(eBasicTypeChar); | |||
| 117 | case PDB_BuiltinType::Bool: | |||
| 118 | return clang_ast.GetBasicType(eBasicTypeBool); | |||
| 119 | case PDB_BuiltinType::Long: | |||
| 120 | if (width == ast.getTypeSize(ast.LongTy)) | |||
| 121 | return CompilerType(&clang_ast, ast.LongTy.getAsOpaquePtr()); | |||
| 122 | if (width == ast.getTypeSize(ast.LongLongTy)) | |||
| 123 | return CompilerType(&clang_ast, ast.LongLongTy.getAsOpaquePtr()); | |||
| 124 | break; | |||
| 125 | case PDB_BuiltinType::ULong: | |||
| 126 | if (width == ast.getTypeSize(ast.UnsignedLongTy)) | |||
| 127 | return CompilerType(&clang_ast, ast.UnsignedLongTy.getAsOpaquePtr()); | |||
| 128 | if (width == ast.getTypeSize(ast.UnsignedLongLongTy)) | |||
| 129 | return CompilerType(&clang_ast, ast.UnsignedLongLongTy.getAsOpaquePtr()); | |||
| 130 | break; | |||
| 131 | case PDB_BuiltinType::WCharT: | |||
| 132 | if (width == ast.getTypeSize(ast.WCharTy)) | |||
| 133 | return CompilerType(&clang_ast, ast.WCharTy.getAsOpaquePtr()); | |||
| 134 | break; | |||
| 135 | case PDB_BuiltinType::Char16: | |||
| 136 | return CompilerType(&clang_ast, ast.Char16Ty.getAsOpaquePtr()); | |||
| 137 | case PDB_BuiltinType::Char32: | |||
| 138 | return CompilerType(&clang_ast, ast.Char32Ty.getAsOpaquePtr()); | |||
| 139 | case PDB_BuiltinType::Float: | |||
| 140 | // Note: types `long double` and `double` have same bit size in MSVC and | |||
| 141 | // there is no information in the PDB to distinguish them. So when falling | |||
| 142 | // back to default search, the compiler type of `long double` will be | |||
| 143 | // represented by the one generated for `double`. | |||
| 144 | break; | |||
| 145 | } | |||
| 146 | // If there is no match on PDB_BuiltinType, fall back to default search by | |||
| 147 | // encoding and width only | |||
| 148 | return clang_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, width); | |||
| 149 | } | |||
| 150 | ||||
| 151 | static ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type, | |||
| 152 | CompilerType &compiler_type) { | |||
| 153 | PDB_BuiltinType kind = pdb_type.getBuiltinType(); | |||
| 154 | switch (kind) { | |||
| 155 | default: | |||
| 156 | break; | |||
| 157 | case PDB_BuiltinType::Currency: | |||
| 158 | return ConstString("CURRENCY"); | |||
| 159 | case PDB_BuiltinType::Date: | |||
| 160 | return ConstString("DATE"); | |||
| 161 | case PDB_BuiltinType::Variant: | |||
| 162 | return ConstString("VARIANT"); | |||
| 163 | case PDB_BuiltinType::Complex: | |||
| 164 | return ConstString("complex"); | |||
| 165 | case PDB_BuiltinType::Bitfield: | |||
| 166 | return ConstString("bitfield"); | |||
| 167 | case PDB_BuiltinType::BSTR: | |||
| 168 | return ConstString("BSTR"); | |||
| 169 | case PDB_BuiltinType::HResult: | |||
| 170 | return ConstString("HRESULT"); | |||
| 171 | case PDB_BuiltinType::BCD: | |||
| 172 | return ConstString("BCD"); | |||
| 173 | case PDB_BuiltinType::Char16: | |||
| 174 | return ConstString("char16_t"); | |||
| 175 | case PDB_BuiltinType::Char32: | |||
| 176 | return ConstString("char32_t"); | |||
| 177 | case PDB_BuiltinType::None: | |||
| 178 | return ConstString("..."); | |||
| 179 | } | |||
| 180 | return compiler_type.GetTypeName(); | |||
| 181 | } | |||
| 182 | ||||
| 183 | static bool GetDeclarationForSymbol(const PDBSymbol &symbol, | |||
| 184 | Declaration &decl) { | |||
| 185 | auto &raw_sym = symbol.getRawSymbol(); | |||
| 186 | auto first_line_up = raw_sym.getSrcLineOnTypeDefn(); | |||
| 187 | ||||
| 188 | if (!first_line_up) { | |||
| 189 | auto lines_up = symbol.getSession().findLineNumbersByAddress( | |||
| 190 | raw_sym.getVirtualAddress(), raw_sym.getLength()); | |||
| 191 | if (!lines_up) | |||
| 192 | return false; | |||
| 193 | first_line_up = lines_up->getNext(); | |||
| 194 | if (!first_line_up) | |||
| 195 | return false; | |||
| 196 | } | |||
| 197 | uint32_t src_file_id = first_line_up->getSourceFileId(); | |||
| 198 | auto src_file_up = symbol.getSession().getSourceFileById(src_file_id); | |||
| 199 | if (!src_file_up) | |||
| 200 | return false; | |||
| 201 | ||||
| 202 | FileSpec spec(src_file_up->getFileName()); | |||
| 203 | decl.SetFile(spec); | |||
| 204 | decl.SetColumn(first_line_up->getColumnNumber()); | |||
| 205 | decl.SetLine(first_line_up->getLineNumber()); | |||
| 206 | return true; | |||
| 207 | } | |||
| 208 | ||||
| 209 | static AccessType TranslateMemberAccess(PDB_MemberAccess access) { | |||
| 210 | switch (access) { | |||
| 211 | case PDB_MemberAccess::Private: | |||
| 212 | return eAccessPrivate; | |||
| 213 | case PDB_MemberAccess::Protected: | |||
| 214 | return eAccessProtected; | |||
| 215 | case PDB_MemberAccess::Public: | |||
| 216 | return eAccessPublic; | |||
| 217 | } | |||
| 218 | return eAccessNone; | |||
| 219 | } | |||
| 220 | ||||
| 221 | static AccessType GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind) { | |||
| 222 | switch (udt_kind) { | |||
| 223 | case PDB_UdtType::Struct: | |||
| 224 | case PDB_UdtType::Union: | |||
| 225 | return eAccessPublic; | |||
| 226 | case PDB_UdtType::Class: | |||
| 227 | case PDB_UdtType::Interface: | |||
| 228 | return eAccessPrivate; | |||
| 229 | } | |||
| 230 | llvm_unreachable("unsupported PDB UDT type")__builtin_unreachable(); | |||
| 231 | } | |||
| 232 | ||||
| 233 | static AccessType GetAccessibilityForUdt(const PDBSymbolTypeUDT &udt) { | |||
| 234 | AccessType access = TranslateMemberAccess(udt.getAccess()); | |||
| 235 | if (access != lldb::eAccessNone || !udt.isNested()) | |||
| 236 | return access; | |||
| 237 | ||||
| 238 | auto parent = udt.getClassParent(); | |||
| 239 | if (!parent) | |||
| 240 | return lldb::eAccessNone; | |||
| 241 | ||||
| 242 | auto parent_udt = llvm::dyn_cast<PDBSymbolTypeUDT>(parent.get()); | |||
| 243 | if (!parent_udt) | |||
| 244 | return lldb::eAccessNone; | |||
| 245 | ||||
| 246 | return GetDefaultAccessibilityForUdtKind(parent_udt->getUdtKind()); | |||
| 247 | } | |||
| 248 | ||||
| 249 | static clang::MSInheritanceAttr::Spelling | |||
| 250 | GetMSInheritance(const PDBSymbolTypeUDT &udt) { | |||
| 251 | int base_count = 0; | |||
| 252 | bool has_virtual = false; | |||
| 253 | ||||
| 254 | auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>(); | |||
| 255 | if (bases_enum) { | |||
| 256 | while (auto base = bases_enum->getNext()) { | |||
| 257 | base_count++; | |||
| 258 | has_virtual |= base->isVirtualBaseClass(); | |||
| 259 | } | |||
| 260 | } | |||
| 261 | ||||
| 262 | if (has_virtual) | |||
| 263 | return clang::MSInheritanceAttr::Keyword_virtual_inheritance; | |||
| 264 | if (base_count > 1) | |||
| 265 | return clang::MSInheritanceAttr::Keyword_multiple_inheritance; | |||
| 266 | return clang::MSInheritanceAttr::Keyword_single_inheritance; | |||
| 267 | } | |||
| 268 | ||||
| 269 | static std::unique_ptr<llvm::pdb::PDBSymbol> | |||
| 270 | GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) { | |||
| 271 | const IPDBSession &session = symbol.getSession(); | |||
| 272 | const IPDBRawSymbol &raw = symbol.getRawSymbol(); | |||
| 273 | auto tag = symbol.getSymTag(); | |||
| 274 | ||||
| 275 | // For items that are nested inside of a class, return the class that it is | |||
| 276 | // nested inside of. | |||
| 277 | // Note that only certain items can be nested inside of classes. | |||
| 278 | switch (tag) { | |||
| 279 | case PDB_SymType::Function: | |||
| 280 | case PDB_SymType::Data: | |||
| 281 | case PDB_SymType::UDT: | |||
| 282 | case PDB_SymType::Enum: | |||
| 283 | case PDB_SymType::FunctionSig: | |||
| 284 | case PDB_SymType::Typedef: | |||
| 285 | case PDB_SymType::BaseClass: | |||
| 286 | case PDB_SymType::VTable: { | |||
| 287 | auto class_parent_id = raw.getClassParentId(); | |||
| 288 | if (auto class_parent = session.getSymbolById(class_parent_id)) | |||
| 289 | return class_parent; | |||
| 290 | break; | |||
| 291 | } | |||
| 292 | default: | |||
| 293 | break; | |||
| 294 | } | |||
| 295 | ||||
| 296 | // Otherwise, if it is nested inside of a function, return the function. | |||
| 297 | // Note that only certain items can be nested inside of functions. | |||
| 298 | switch (tag) { | |||
| 299 | case PDB_SymType::Block: | |||
| 300 | case PDB_SymType::Data: { | |||
| 301 | auto lexical_parent_id = raw.getLexicalParentId(); | |||
| 302 | auto lexical_parent = session.getSymbolById(lexical_parent_id); | |||
| 303 | if (!lexical_parent) | |||
| 304 | return nullptr; | |||
| 305 | ||||
| 306 | auto lexical_parent_tag = lexical_parent->getSymTag(); | |||
| 307 | if (lexical_parent_tag == PDB_SymType::Function) | |||
| 308 | return lexical_parent; | |||
| 309 | if (lexical_parent_tag == PDB_SymType::Exe) | |||
| 310 | return nullptr; | |||
| 311 | ||||
| 312 | return GetClassOrFunctionParent(*lexical_parent); | |||
| 313 | } | |||
| 314 | default: | |||
| 315 | return nullptr; | |||
| 316 | } | |||
| 317 | } | |||
| 318 | ||||
| 319 | static clang::NamedDecl * | |||
| 320 | GetDeclFromContextByName(const clang::ASTContext &ast, | |||
| 321 | const clang::DeclContext &decl_context, | |||
| 322 | llvm::StringRef name) { | |||
| 323 | clang::IdentifierInfo &ident = ast.Idents.get(name); | |||
| 324 | clang::DeclarationName decl_name = ast.DeclarationNames.getIdentifier(&ident); | |||
| 325 | clang::DeclContext::lookup_result result = decl_context.lookup(decl_name); | |||
| 326 | if (result.empty()) | |||
| 327 | return nullptr; | |||
| 328 | ||||
| 329 | return *result.begin(); | |||
| 330 | } | |||
| 331 | ||||
| 332 | static bool IsAnonymousNamespaceName(llvm::StringRef name) { | |||
| 333 | return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; | |||
| 334 | } | |||
| 335 | ||||
| 336 | static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) { | |||
| 337 | switch (pdb_cc) { | |||
| 338 | case llvm::codeview::CallingConvention::NearC: | |||
| 339 | return clang::CC_C; | |||
| 340 | case llvm::codeview::CallingConvention::NearStdCall: | |||
| 341 | return clang::CC_X86StdCall; | |||
| 342 | case llvm::codeview::CallingConvention::NearFast: | |||
| 343 | return clang::CC_X86FastCall; | |||
| 344 | case llvm::codeview::CallingConvention::ThisCall: | |||
| 345 | return clang::CC_X86ThisCall; | |||
| 346 | case llvm::codeview::CallingConvention::NearVector: | |||
| 347 | return clang::CC_X86VectorCall; | |||
| 348 | case llvm::codeview::CallingConvention::NearPascal: | |||
| 349 | return clang::CC_X86Pascal; | |||
| 350 | default: | |||
| 351 | assert(false && "Unknown calling convention")((void)0); | |||
| 352 | return clang::CC_C; | |||
| 353 | } | |||
| 354 | } | |||
| 355 | ||||
| 356 | PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {} | |||
| 357 | ||||
| 358 | PDBASTParser::~PDBASTParser() = default; | |||
| 359 | ||||
| 360 | // DebugInfoASTParser interface | |||
| 361 | ||||
| 362 | lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { | |||
| 363 | Declaration decl; | |||
| 364 | switch (type.getSymTag()) { | |||
| ||||
| 365 | case PDB_SymType::BaseClass: { | |||
| 366 | auto symbol_file = m_ast.GetSymbolFile(); | |||
| 367 | if (!symbol_file) | |||
| 368 | return nullptr; | |||
| 369 | ||||
| 370 | auto ty = symbol_file->ResolveTypeUID(type.getRawSymbol().getTypeId()); | |||
| 371 | return ty ? ty->shared_from_this() : nullptr; | |||
| 372 | } break; | |||
| 373 | case PDB_SymType::UDT: { | |||
| 374 | auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type); | |||
| 375 | assert(udt)((void)0); | |||
| 376 | ||||
| 377 | // Note that, unnamed UDT being typedef-ed is generated as a UDT symbol | |||
| 378 | // other than a Typedef symbol in PDB. For example, | |||
| 379 | // typedef union { short Row; short Col; } Union; | |||
| 380 | // is generated as a named UDT in PDB: | |||
| 381 | // union Union { short Row; short Col; } | |||
| 382 | // Such symbols will be handled here. | |||
| 383 | ||||
| 384 | // Some UDT with trival ctor has zero length. Just ignore. | |||
| 385 | if (udt->getLength() == 0) | |||
| 386 | return nullptr; | |||
| 387 | ||||
| 388 | // Ignore unnamed-tag UDTs. | |||
| 389 | std::string name = | |||
| 390 | std::string(MSVCUndecoratedNameParser::DropScope(udt->getName())); | |||
| 391 | if (name.empty()) | |||
| 392 | return nullptr; | |||
| 393 | ||||
| 394 | auto decl_context = GetDeclContextContainingSymbol(type); | |||
| 395 | ||||
| 396 | // Check if such an UDT already exists in the current context. | |||
| 397 | // This may occur with const or volatile types. There are separate type | |||
| 398 | // symbols in PDB for types with const or volatile modifiers, but we need | |||
| 399 | // to create only one declaration for them all. | |||
| 400 | Type::ResolveState type_resolve_state; | |||
| 401 | CompilerType clang_type = m_ast.GetTypeForIdentifier<clang::CXXRecordDecl>( | |||
| 402 | ConstString(name), decl_context); | |||
| 403 | if (!clang_type.IsValid()) { | |||
| 404 | auto access = GetAccessibilityForUdt(*udt); | |||
| 405 | ||||
| 406 | auto tag_type_kind = TranslateUdtKind(udt->getUdtKind()); | |||
| 407 | ||||
| 408 | ClangASTMetadata metadata; | |||
| 409 | metadata.SetUserID(type.getSymIndexId()); | |||
| 410 | metadata.SetIsDynamicCXXType(false); | |||
| 411 | ||||
| 412 | clang_type = m_ast.CreateRecordType( | |||
| 413 | decl_context, OptionalClangModuleID(), access, name, tag_type_kind, | |||
| 414 | lldb::eLanguageTypeC_plus_plus, &metadata); | |||
| 415 | assert(clang_type.IsValid())((void)0); | |||
| 416 | ||||
| 417 | auto record_decl = | |||
| 418 | m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()); | |||
| 419 | assert(record_decl)((void)0); | |||
| 420 | m_uid_to_decl[type.getSymIndexId()] = record_decl; | |||
| 421 | ||||
| 422 | auto inheritance_attr = clang::MSInheritanceAttr::CreateImplicit( | |||
| 423 | m_ast.getASTContext(), GetMSInheritance(*udt)); | |||
| 424 | record_decl->addAttr(inheritance_attr); | |||
| 425 | ||||
| 426 | TypeSystemClang::StartTagDeclarationDefinition(clang_type); | |||
| 427 | ||||
| 428 | auto children = udt->findAllChildren(); | |||
| 429 | if (!children || children->getChildCount() == 0) { | |||
| 430 | // PDB does not have symbol of forwarder. We assume we get an udt w/o | |||
| 431 | // any fields. Just complete it at this point. | |||
| 432 | TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); | |||
| 433 | ||||
| 434 | TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(), | |||
| 435 | false); | |||
| 436 | ||||
| 437 | type_resolve_state = Type::ResolveState::Full; | |||
| 438 | } else { | |||
| 439 | // Add the type to the forward declarations. It will help us to avoid | |||
| 440 | // an endless recursion in CompleteTypeFromUdt function. | |||
| 441 | m_forward_decl_to_uid[record_decl] = type.getSymIndexId(); | |||
| 442 | ||||
| 443 | TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(), | |||
| 444 | true); | |||
| 445 | ||||
| 446 | type_resolve_state = Type::ResolveState::Forward; | |||
| 447 | } | |||
| 448 | } else | |||
| 449 | type_resolve_state = Type::ResolveState::Forward; | |||
| 450 | ||||
| 451 | if (udt->isConstType()) | |||
| 452 | clang_type = clang_type.AddConstModifier(); | |||
| 453 | ||||
| 454 | if (udt->isVolatileType()) | |||
| 455 | clang_type = clang_type.AddVolatileModifier(); | |||
| 456 | ||||
| 457 | GetDeclarationForSymbol(type, decl); | |||
| 458 | return std::make_shared<lldb_private::Type>( | |||
| 459 | type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), | |||
| 460 | udt->getLength(), nullptr, LLDB_INVALID_UID0xffffffffffffffffULL, | |||
| 461 | lldb_private::Type::eEncodingIsUID, decl, clang_type, | |||
| 462 | type_resolve_state); | |||
| 463 | } break; | |||
| 464 | case PDB_SymType::Enum: { | |||
| 465 | auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type); | |||
| 466 | assert(enum_type)((void)0); | |||
| 467 | ||||
| 468 | std::string name = | |||
| 469 | std::string(MSVCUndecoratedNameParser::DropScope(enum_type->getName())); | |||
| ||||
| 470 | auto decl_context = GetDeclContextContainingSymbol(type); | |||
| 471 | uint64_t bytes = enum_type->getLength(); | |||
| 472 | ||||
| 473 | // Check if such an enum already exists in the current context | |||
| 474 | CompilerType ast_enum = m_ast.GetTypeForIdentifier<clang::EnumDecl>( | |||
| 475 | ConstString(name), decl_context); | |||
| 476 | if (!ast_enum.IsValid()) { | |||
| 477 | auto underlying_type_up = enum_type->getUnderlyingType(); | |||
| 478 | if (!underlying_type_up) | |||
| 479 | return nullptr; | |||
| 480 | ||||
| 481 | lldb::Encoding encoding = | |||
| 482 | TranslateBuiltinEncoding(underlying_type_up->getBuiltinType()); | |||
| 483 | // FIXME: Type of underlying builtin is always `Int`. We correct it with | |||
| 484 | // the very first enumerator's encoding if any. | |||
| 485 | auto first_child = enum_type->findOneChild<PDBSymbolData>(); | |||
| 486 | if (first_child) | |||
| 487 | encoding = TranslateEnumEncoding(first_child->getValue().Type); | |||
| 488 | ||||
| 489 | CompilerType builtin_type; | |||
| 490 | if (bytes > 0) | |||
| 491 | builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize( | |||
| 492 | m_ast, *underlying_type_up, encoding, bytes * 8); | |||
| 493 | else | |||
| 494 | builtin_type = m_ast.GetBasicType(eBasicTypeInt); | |||
| 495 | ||||
| 496 | // FIXME: PDB does not have information about scoped enumeration (Enum | |||
| 497 | // Class). Set it false for now. | |||
| 498 | bool isScoped = false; | |||
| 499 | ||||
| 500 | ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, | |||
| 501 | OptionalClangModuleID(), decl, | |||
| 502 | builtin_type, isScoped); | |||
| 503 | ||||
| 504 | auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum); | |||
| 505 | assert(enum_decl)((void)0); | |||
| 506 | m_uid_to_decl[type.getSymIndexId()] = enum_decl; | |||
| 507 | ||||
| 508 | auto enum_values = enum_type->findAllChildren<PDBSymbolData>(); | |||
| 509 | if (enum_values) { | |||
| 510 | while (auto enum_value = enum_values->getNext()) { | |||
| 511 | if (enum_value->getDataKind() != PDB_DataKind::Constant) | |||
| 512 | continue; | |||
| 513 | AddEnumValue(ast_enum, *enum_value); | |||
| 514 | } | |||
| 515 | } | |||
| 516 | ||||
| 517 | if (TypeSystemClang::StartTagDeclarationDefinition(ast_enum)) | |||
| 518 | TypeSystemClang::CompleteTagDeclarationDefinition(ast_enum); | |||
| 519 | } | |||
| 520 | ||||
| 521 | if (enum_type->isConstType()) | |||
| 522 | ast_enum = ast_enum.AddConstModifier(); | |||
| 523 | ||||
| 524 | if (enum_type->isVolatileType()) | |||
| 525 | ast_enum = ast_enum.AddVolatileModifier(); | |||
| 526 | ||||
| 527 | GetDeclarationForSymbol(type, decl); | |||
| 528 | return std::make_shared<lldb_private::Type>( | |||
| 529 | type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes, | |||
| 530 | nullptr, LLDB_INVALID_UID0xffffffffffffffffULL, lldb_private::Type::eEncodingIsUID, decl, | |||
| 531 | ast_enum, lldb_private::Type::ResolveState::Full); | |||
| 532 | } break; | |||
| 533 | case PDB_SymType::Typedef: { | |||
| 534 | auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type); | |||
| 535 | assert(type_def)((void)0); | |||
| 536 | ||||
| 537 | SymbolFile *symbol_file = m_ast.GetSymbolFile(); | |||
| 538 | if (!symbol_file) | |||
| 539 | return nullptr; | |||
| 540 | ||||
| 541 | lldb_private::Type *target_type = | |||
| 542 | symbol_file->ResolveTypeUID(type_def->getTypeId()); | |||
| 543 | if (!target_type) | |||
| 544 | return nullptr; | |||
| 545 | ||||
| 546 | std::string name = | |||
| 547 | std::string(MSVCUndecoratedNameParser::DropScope(type_def->getName())); | |||
| 548 | auto decl_ctx = GetDeclContextContainingSymbol(type); | |||
| 549 | ||||
| 550 | // Check if such a typedef already exists in the current context | |||
| 551 | CompilerType ast_typedef = | |||
| 552 | m_ast.GetTypeForIdentifier<clang::TypedefNameDecl>(ConstString(name), | |||
| 553 | decl_ctx); | |||
| 554 | if (!ast_typedef.IsValid()) { | |||
| 555 | CompilerType target_ast_type = target_type->GetFullCompilerType(); | |||
| 556 | ||||
| 557 | ast_typedef = target_ast_type.CreateTypedef( | |||
| 558 | name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0); | |||
| 559 | if (!ast_typedef) | |||
| 560 | return nullptr; | |||
| 561 | ||||
| 562 | auto typedef_decl = TypeSystemClang::GetAsTypedefDecl(ast_typedef); | |||
| 563 | assert(typedef_decl)((void)0); | |||
| 564 | m_uid_to_decl[type.getSymIndexId()] = typedef_decl; | |||
| 565 | } | |||
| 566 | ||||
| 567 | if (type_def->isConstType()) | |||
| 568 | ast_typedef = ast_typedef.AddConstModifier(); | |||
| 569 | ||||
| 570 | if (type_def->isVolatileType()) | |||
| 571 | ast_typedef = ast_typedef.AddVolatileModifier(); | |||
| 572 | ||||
| 573 | GetDeclarationForSymbol(type, decl); | |||
| 574 | llvm::Optional<uint64_t> size; | |||
| 575 | if (type_def->getLength()) | |||
| 576 | size = type_def->getLength(); | |||
| 577 | return std::make_shared<lldb_private::Type>( | |||
| 578 | type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), | |||
| 579 | size, nullptr, target_type->GetID(), | |||
| 580 | lldb_private::Type::eEncodingIsTypedefUID, decl, ast_typedef, | |||
| 581 | lldb_private::Type::ResolveState::Full); | |||
| 582 | } break; | |||
| 583 | case PDB_SymType::Function: | |||
| 584 | case PDB_SymType::FunctionSig: { | |||
| 585 | std::string name; | |||
| 586 | PDBSymbolTypeFunctionSig *func_sig = nullptr; | |||
| 587 | if (auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(&type)) { | |||
| 588 | if (pdb_func->isCompilerGenerated()) | |||
| 589 | return nullptr; | |||
| 590 | ||||
| 591 | auto sig = pdb_func->getSignature(); | |||
| 592 | if (!sig) | |||
| 593 | return nullptr; | |||
| 594 | func_sig = sig.release(); | |||
| 595 | // Function type is named. | |||
| 596 | name = std::string( | |||
| 597 | MSVCUndecoratedNameParser::DropScope(pdb_func->getName())); | |||
| 598 | } else if (auto pdb_func_sig = | |||
| 599 | llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) { | |||
| 600 | func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig); | |||
| 601 | } else | |||
| 602 | llvm_unreachable("Unexpected PDB symbol!")__builtin_unreachable(); | |||
| 603 | ||||
| 604 | auto arg_enum = func_sig->getArguments(); | |||
| 605 | uint32_t num_args = arg_enum->getChildCount(); | |||
| 606 | std::vector<CompilerType> arg_list; | |||
| 607 | ||||
| 608 | bool is_variadic = func_sig->isCVarArgs(); | |||
| 609 | // Drop last variadic argument. | |||
| 610 | if (is_variadic) | |||
| 611 | --num_args; | |||
| 612 | for (uint32_t arg_idx = 0; arg_idx < num_args; arg_idx++) { | |||
| 613 | auto arg = arg_enum->getChildAtIndex(arg_idx); | |||
| 614 | if (!arg) | |||
| 615 | break; | |||
| 616 | ||||
| 617 | SymbolFile *symbol_file = m_ast.GetSymbolFile(); | |||
| 618 | if (!symbol_file) | |||
| 619 | return nullptr; | |||
| 620 | ||||
| 621 | lldb_private::Type *arg_type = | |||
| 622 | symbol_file->ResolveTypeUID(arg->getSymIndexId()); | |||
| 623 | // If there's some error looking up one of the dependent types of this | |||
| 624 | // function signature, bail. | |||
| 625 | if (!arg_type) | |||
| 626 | return nullptr; | |||
| 627 | CompilerType arg_ast_type = arg_type->GetFullCompilerType(); | |||
| 628 | arg_list.push_back(arg_ast_type); | |||
| 629 | } | |||
| 630 | lldbassert(arg_list.size() <= num_args)lldb_private::lldb_assert(static_cast<bool>(arg_list.size () <= num_args), "arg_list.size() <= num_args", __FUNCTION__ , "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 630); | |||
| 631 | ||||
| 632 | auto pdb_return_type = func_sig->getReturnType(); | |||
| 633 | SymbolFile *symbol_file = m_ast.GetSymbolFile(); | |||
| 634 | if (!symbol_file) | |||
| 635 | return nullptr; | |||
| 636 | ||||
| 637 | lldb_private::Type *return_type = | |||
| 638 | symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId()); | |||
| 639 | // If there's some error looking up one of the dependent types of this | |||
| 640 | // function signature, bail. | |||
| 641 | if (!return_type) | |||
| 642 | return nullptr; | |||
| 643 | CompilerType return_ast_type = return_type->GetFullCompilerType(); | |||
| 644 | uint32_t type_quals = 0; | |||
| 645 | if (func_sig->isConstType()) | |||
| 646 | type_quals |= clang::Qualifiers::Const; | |||
| 647 | if (func_sig->isVolatileType()) | |||
| 648 | type_quals |= clang::Qualifiers::Volatile; | |||
| 649 | auto cc = TranslateCallingConvention(func_sig->getCallingConvention()); | |||
| 650 | CompilerType func_sig_ast_type = | |||
| 651 | m_ast.CreateFunctionType(return_ast_type, arg_list.data(), | |||
| 652 | arg_list.size(), is_variadic, type_quals, cc); | |||
| 653 | ||||
| 654 | GetDeclarationForSymbol(type, decl); | |||
| 655 | return std::make_shared<lldb_private::Type>( | |||
| 656 | type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), | |||
| 657 | llvm::None, nullptr, LLDB_INVALID_UID0xffffffffffffffffULL, | |||
| 658 | lldb_private::Type::eEncodingIsUID, decl, func_sig_ast_type, | |||
| 659 | lldb_private::Type::ResolveState::Full); | |||
| 660 | } break; | |||
| 661 | case PDB_SymType::ArrayType: { | |||
| 662 | auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type); | |||
| 663 | assert(array_type)((void)0); | |||
| 664 | uint32_t num_elements = array_type->getCount(); | |||
| 665 | uint32_t element_uid = array_type->getElementTypeId(); | |||
| 666 | llvm::Optional<uint64_t> bytes; | |||
| 667 | if (uint64_t size = array_type->getLength()) | |||
| 668 | bytes = size; | |||
| 669 | ||||
| 670 | SymbolFile *symbol_file = m_ast.GetSymbolFile(); | |||
| 671 | if (!symbol_file) | |||
| 672 | return nullptr; | |||
| 673 | ||||
| 674 | // If array rank > 0, PDB gives the element type at N=0. So element type | |||
| 675 | // will parsed in the order N=0, N=1,..., N=rank sequentially. | |||
| 676 | lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid); | |||
| 677 | if (!element_type) | |||
| 678 | return nullptr; | |||
| 679 | ||||
| 680 | CompilerType element_ast_type = element_type->GetForwardCompilerType(); | |||
| 681 | // If element type is UDT, it needs to be complete. | |||
| 682 | if (TypeSystemClang::IsCXXClassType(element_ast_type) && | |||
| 683 | !element_ast_type.GetCompleteType()) { | |||
| 684 | if (TypeSystemClang::StartTagDeclarationDefinition(element_ast_type)) { | |||
| 685 | TypeSystemClang::CompleteTagDeclarationDefinition(element_ast_type); | |||
| 686 | } else { | |||
| 687 | // We are not able to start defintion. | |||
| 688 | return nullptr; | |||
| 689 | } | |||
| 690 | } | |||
| 691 | CompilerType array_ast_type = m_ast.CreateArrayType( | |||
| 692 | element_ast_type, num_elements, /*is_gnu_vector*/ false); | |||
| 693 | TypeSP type_sp = std::make_shared<lldb_private::Type>( | |||
| 694 | array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), | |||
| 695 | bytes, nullptr, LLDB_INVALID_UID0xffffffffffffffffULL, lldb_private::Type::eEncodingIsUID, | |||
| 696 | decl, array_ast_type, lldb_private::Type::ResolveState::Full); | |||
| 697 | type_sp->SetEncodingType(element_type); | |||
| 698 | return type_sp; | |||
| 699 | } break; | |||
| 700 | case PDB_SymType::BuiltinType: { | |||
| 701 | auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type); | |||
| 702 | assert(builtin_type)((void)0); | |||
| 703 | PDB_BuiltinType builtin_kind = builtin_type->getBuiltinType(); | |||
| 704 | if (builtin_kind == PDB_BuiltinType::None) | |||
| 705 | return nullptr; | |||
| 706 | ||||
| 707 | llvm::Optional<uint64_t> bytes; | |||
| 708 | if (uint64_t size = builtin_type->getLength()) | |||
| 709 | bytes = size; | |||
| 710 | Encoding encoding = TranslateBuiltinEncoding(builtin_kind); | |||
| 711 | CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize( | |||
| 712 | m_ast, *builtin_type, encoding, bytes.getValueOr(0) * 8); | |||
| 713 | ||||
| 714 | if (builtin_type->isConstType()) | |||
| 715 | builtin_ast_type = builtin_ast_type.AddConstModifier(); | |||
| 716 | ||||
| 717 | if (builtin_type->isVolatileType()) | |||
| 718 | builtin_ast_type = builtin_ast_type.AddVolatileModifier(); | |||
| 719 | ||||
| 720 | auto type_name = GetPDBBuiltinTypeName(*builtin_type, builtin_ast_type); | |||
| 721 | ||||
| 722 | return std::make_shared<lldb_private::Type>( | |||
| 723 | builtin_type->getSymIndexId(), m_ast.GetSymbolFile(), type_name, bytes, | |||
| 724 | nullptr, LLDB_INVALID_UID0xffffffffffffffffULL, lldb_private::Type::eEncodingIsUID, decl, | |||
| 725 | builtin_ast_type, lldb_private::Type::ResolveState::Full); | |||
| 726 | } break; | |||
| 727 | case PDB_SymType::PointerType: { | |||
| 728 | auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type); | |||
| 729 | assert(pointer_type)((void)0); | |||
| 730 | ||||
| 731 | SymbolFile *symbol_file = m_ast.GetSymbolFile(); | |||
| 732 | if (!symbol_file) | |||
| 733 | return nullptr; | |||
| 734 | ||||
| 735 | Type *pointee_type = symbol_file->ResolveTypeUID( | |||
| 736 | pointer_type->getPointeeType()->getSymIndexId()); | |||
| 737 | if (!pointee_type) | |||
| 738 | return nullptr; | |||
| 739 | ||||
| 740 | if (pointer_type->isPointerToDataMember() || | |||
| 741 | pointer_type->isPointerToMemberFunction()) { | |||
| 742 | auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId(); | |||
| 743 | auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid); | |||
| 744 | assert(class_parent_type)((void)0); | |||
| 745 | ||||
| 746 | CompilerType pointer_ast_type; | |||
| 747 | pointer_ast_type = TypeSystemClang::CreateMemberPointerType( | |||
| 748 | class_parent_type->GetLayoutCompilerType(), | |||
| 749 | pointee_type->GetForwardCompilerType()); | |||
| 750 | assert(pointer_ast_type)((void)0); | |||
| 751 | ||||
| 752 | return std::make_shared<lldb_private::Type>( | |||
| 753 | pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), | |||
| 754 | pointer_type->getLength(), nullptr, LLDB_INVALID_UID0xffffffffffffffffULL, | |||
| 755 | lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type, | |||
| 756 | lldb_private::Type::ResolveState::Forward); | |||
| 757 | } | |||
| 758 | ||||
| 759 | CompilerType pointer_ast_type; | |||
| 760 | pointer_ast_type = pointee_type->GetFullCompilerType(); | |||
| 761 | if (pointer_type->isReference()) | |||
| 762 | pointer_ast_type = pointer_ast_type.GetLValueReferenceType(); | |||
| 763 | else if (pointer_type->isRValueReference()) | |||
| 764 | pointer_ast_type = pointer_ast_type.GetRValueReferenceType(); | |||
| 765 | else | |||
| 766 | pointer_ast_type = pointer_ast_type.GetPointerType(); | |||
| 767 | ||||
| 768 | if (pointer_type->isConstType()) | |||
| 769 | pointer_ast_type = pointer_ast_type.AddConstModifier(); | |||
| 770 | ||||
| 771 | if (pointer_type->isVolatileType()) | |||
| 772 | pointer_ast_type = pointer_ast_type.AddVolatileModifier(); | |||
| 773 | ||||
| 774 | if (pointer_type->isRestrictedType()) | |||
| 775 | pointer_ast_type = pointer_ast_type.AddRestrictModifier(); | |||
| 776 | ||||
| 777 | return std::make_shared<lldb_private::Type>( | |||
| 778 | pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), | |||
| 779 | pointer_type->getLength(), nullptr, LLDB_INVALID_UID0xffffffffffffffffULL, | |||
| 780 | lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type, | |||
| 781 | lldb_private::Type::ResolveState::Full); | |||
| 782 | } break; | |||
| 783 | default: | |||
| 784 | break; | |||
| 785 | } | |||
| 786 | return nullptr; | |||
| 787 | } | |||
| 788 | ||||
| 789 | bool PDBASTParser::CompleteTypeFromPDB( | |||
| 790 | lldb_private::CompilerType &compiler_type) { | |||
| 791 | if (GetClangASTImporter().CanImport(compiler_type)) | |||
| 792 | return GetClangASTImporter().CompleteType(compiler_type); | |||
| 793 | ||||
| 794 | // Remove the type from the forward declarations to avoid | |||
| 795 | // an endless recursion for types like a linked list. | |||
| 796 | clang::CXXRecordDecl *record_decl = | |||
| 797 | m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType()); | |||
| 798 | auto uid_it = m_forward_decl_to_uid.find(record_decl); | |||
| 799 | if (uid_it == m_forward_decl_to_uid.end()) | |||
| 800 | return true; | |||
| 801 | ||||
| 802 | auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); | |||
| 803 | if (!symbol_file) | |||
| 804 | return false; | |||
| 805 | ||||
| 806 | std::unique_ptr<PDBSymbol> symbol = | |||
| 807 | symbol_file->GetPDBSession().getSymbolById(uid_it->getSecond()); | |||
| 808 | if (!symbol) | |||
| 809 | return false; | |||
| 810 | ||||
| 811 | m_forward_decl_to_uid.erase(uid_it); | |||
| 812 | ||||
| 813 | TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), | |||
| 814 | false); | |||
| 815 | ||||
| 816 | switch (symbol->getSymTag()) { | |||
| 817 | case PDB_SymType::UDT: { | |||
| 818 | auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(symbol.get()); | |||
| 819 | if (!udt) | |||
| 820 | return false; | |||
| 821 | ||||
| 822 | return CompleteTypeFromUDT(*symbol_file, compiler_type, *udt); | |||
| 823 | } | |||
| 824 | default: | |||
| 825 | llvm_unreachable("not a forward clang type decl!")__builtin_unreachable(); | |||
| 826 | } | |||
| 827 | } | |||
| 828 | ||||
| 829 | clang::Decl * | |||
| 830 | PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { | |||
| 831 | uint32_t sym_id = symbol.getSymIndexId(); | |||
| 832 | auto it = m_uid_to_decl.find(sym_id); | |||
| 833 | if (it != m_uid_to_decl.end()) | |||
| 834 | return it->second; | |||
| 835 | ||||
| 836 | auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); | |||
| 837 | if (!symbol_file) | |||
| 838 | return nullptr; | |||
| 839 | ||||
| 840 | // First of all, check if the symbol is a member of a class. Resolve the full | |||
| 841 | // class type and return the declaration from the cache if so. | |||
| 842 | auto tag = symbol.getSymTag(); | |||
| 843 | if (tag == PDB_SymType::Data || tag == PDB_SymType::Function) { | |||
| 844 | const IPDBSession &session = symbol.getSession(); | |||
| 845 | const IPDBRawSymbol &raw = symbol.getRawSymbol(); | |||
| 846 | ||||
| 847 | auto class_parent_id = raw.getClassParentId(); | |||
| 848 | if (std::unique_ptr<PDBSymbol> class_parent = | |||
| 849 | session.getSymbolById(class_parent_id)) { | |||
| 850 | auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_id); | |||
| 851 | if (!class_parent_type) | |||
| 852 | return nullptr; | |||
| 853 | ||||
| 854 | CompilerType class_parent_ct = class_parent_type->GetFullCompilerType(); | |||
| 855 | ||||
| 856 | // Look a declaration up in the cache after completing the class | |||
| 857 | clang::Decl *decl = m_uid_to_decl.lookup(sym_id); | |||
| 858 | if (decl) | |||
| 859 | return decl; | |||
| 860 | ||||
| 861 | // A declaration was not found in the cache. It means that the symbol | |||
| 862 | // has the class parent, but the class doesn't have the symbol in its | |||
| 863 | // children list. | |||
| 864 | if (auto func = llvm::dyn_cast_or_null<PDBSymbolFunc>(&symbol)) { | |||
| 865 | // Try to find a class child method with the same RVA and use its | |||
| 866 | // declaration if found. | |||
| 867 | if (uint32_t rva = func->getRelativeVirtualAddress()) { | |||
| 868 | if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolFunc>> | |||
| 869 | methods_enum = | |||
| 870 | class_parent->findAllChildren<PDBSymbolFunc>()) { | |||
| 871 | while (std::unique_ptr<PDBSymbolFunc> method = | |||
| 872 | methods_enum->getNext()) { | |||
| 873 | if (method->getRelativeVirtualAddress() == rva) { | |||
| 874 | decl = m_uid_to_decl.lookup(method->getSymIndexId()); | |||
| 875 | if (decl) | |||
| 876 | break; | |||
| 877 | } | |||
| 878 | } | |||
| 879 | } | |||
| 880 | } | |||
| 881 | ||||
| 882 | // If no class methods with the same RVA were found, then create a new | |||
| 883 | // method. It is possible for template methods. | |||
| 884 | if (!decl) | |||
| 885 | decl = AddRecordMethod(*symbol_file, class_parent_ct, *func); | |||
| 886 | } | |||
| 887 | ||||
| 888 | if (decl) | |||
| 889 | m_uid_to_decl[sym_id] = decl; | |||
| 890 | ||||
| 891 | return decl; | |||
| 892 | } | |||
| 893 | } | |||
| 894 | ||||
| 895 | // If we are here, then the symbol is not belonging to a class and is not | |||
| 896 | // contained in the cache. So create a declaration for it. | |||
| 897 | switch (symbol.getSymTag()) { | |||
| 898 | case PDB_SymType::Data: { | |||
| 899 | auto data = llvm::dyn_cast<PDBSymbolData>(&symbol); | |||
| 900 | assert(data)((void)0); | |||
| 901 | ||||
| 902 | auto decl_context = GetDeclContextContainingSymbol(symbol); | |||
| 903 | assert(decl_context)((void)0); | |||
| 904 | ||||
| 905 | // May be the current context is a class really, but we haven't found | |||
| 906 | // any class parent. This happens e.g. in the case of class static | |||
| 907 | // variables - they has two symbols, one is a child of the class when | |||
| 908 | // another is a child of the exe. So always complete the parent and use | |||
| 909 | // an existing declaration if possible. | |||
| 910 | if (auto parent_decl = llvm::dyn_cast_or_null<clang::TagDecl>(decl_context)) | |||
| 911 | m_ast.GetCompleteDecl(parent_decl); | |||
| 912 | ||||
| 913 | std::string name = | |||
| 914 | std::string(MSVCUndecoratedNameParser::DropScope(data->getName())); | |||
| 915 | ||||
| 916 | // Check if the current context already contains the symbol with the name. | |||
| 917 | clang::Decl *decl = | |||
| 918 | GetDeclFromContextByName(m_ast.getASTContext(), *decl_context, name); | |||
| 919 | if (!decl) { | |||
| 920 | auto type = symbol_file->ResolveTypeUID(data->getTypeId()); | |||
| 921 | if (!type) | |||
| 922 | return nullptr; | |||
| 923 | ||||
| 924 | decl = m_ast.CreateVariableDeclaration( | |||
| 925 | decl_context, OptionalClangModuleID(), name.c_str(), | |||
| 926 | ClangUtil::GetQualType(type->GetLayoutCompilerType())); | |||
| 927 | } | |||
| 928 | ||||
| 929 | m_uid_to_decl[sym_id] = decl; | |||
| 930 | ||||
| 931 | return decl; | |||
| 932 | } | |||
| 933 | case PDB_SymType::Function: { | |||
| 934 | auto func = llvm::dyn_cast<PDBSymbolFunc>(&symbol); | |||
| 935 | assert(func)((void)0); | |||
| 936 | ||||
| 937 | auto decl_context = GetDeclContextContainingSymbol(symbol); | |||
| 938 | assert(decl_context)((void)0); | |||
| 939 | ||||
| 940 | std::string name = | |||
| 941 | std::string(MSVCUndecoratedNameParser::DropScope(func->getName())); | |||
| 942 | ||||
| 943 | Type *type = symbol_file->ResolveTypeUID(sym_id); | |||
| 944 | if (!type) | |||
| 945 | return nullptr; | |||
| 946 | ||||
| 947 | auto storage = func->isStatic() ? clang::StorageClass::SC_Static | |||
| 948 | : clang::StorageClass::SC_None; | |||
| 949 | ||||
| 950 | auto decl = m_ast.CreateFunctionDeclaration( | |||
| 951 | decl_context, OptionalClangModuleID(), name, | |||
| 952 | type->GetForwardCompilerType(), storage, func->hasInlineAttribute()); | |||
| 953 | ||||
| 954 | std::vector<clang::ParmVarDecl *> params; | |||
| 955 | if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) { | |||
| 956 | if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg>> | |||
| 957 | arg_enum = sig->findAllChildren<PDBSymbolTypeFunctionArg>()) { | |||
| 958 | while (std::unique_ptr<PDBSymbolTypeFunctionArg> arg = | |||
| 959 | arg_enum->getNext()) { | |||
| 960 | Type *arg_type = symbol_file->ResolveTypeUID(arg->getTypeId()); | |||
| 961 | if (!arg_type) | |||
| 962 | continue; | |||
| 963 | ||||
| 964 | clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration( | |||
| 965 | decl, OptionalClangModuleID(), nullptr, | |||
| 966 | arg_type->GetForwardCompilerType(), clang::SC_None, true); | |||
| 967 | if (param) | |||
| 968 | params.push_back(param); | |||
| 969 | } | |||
| 970 | } | |||
| 971 | } | |||
| 972 | if (params.size()) | |||
| 973 | m_ast.SetFunctionParameters(decl, params); | |||
| 974 | ||||
| 975 | m_uid_to_decl[sym_id] = decl; | |||
| 976 | ||||
| 977 | return decl; | |||
| 978 | } | |||
| 979 | default: { | |||
| 980 | // It's not a variable and not a function, check if it's a type | |||
| 981 | Type *type = symbol_file->ResolveTypeUID(sym_id); | |||
| 982 | if (!type) | |||
| 983 | return nullptr; | |||
| 984 | ||||
| 985 | return m_uid_to_decl.lookup(sym_id); | |||
| 986 | } | |||
| 987 | } | |||
| 988 | } | |||
| 989 | ||||
| 990 | clang::DeclContext * | |||
| 991 | PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) { | |||
| 992 | if (symbol.getSymTag() == PDB_SymType::Function) { | |||
| 993 | clang::DeclContext *result = | |||
| 994 | llvm::dyn_cast_or_null<clang::FunctionDecl>(GetDeclForSymbol(symbol)); | |||
| 995 | ||||
| 996 | if (result) | |||
| 997 | m_decl_context_to_uid[result] = symbol.getSymIndexId(); | |||
| 998 | ||||
| 999 | return result; | |||
| 1000 | } | |||
| 1001 | ||||
| 1002 | auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); | |||
| 1003 | if (!symbol_file) | |||
| 1004 | return nullptr; | |||
| 1005 | ||||
| 1006 | auto type = symbol_file->ResolveTypeUID(symbol.getSymIndexId()); | |||
| 1007 | if (!type) | |||
| 1008 | return nullptr; | |||
| 1009 | ||||
| 1010 | clang::DeclContext *result = | |||
| 1011 | m_ast.GetDeclContextForType(type->GetForwardCompilerType()); | |||
| 1012 | ||||
| 1013 | if (result) | |||
| 1014 | m_decl_context_to_uid[result] = symbol.getSymIndexId(); | |||
| 1015 | ||||
| 1016 | return result; | |||
| 1017 | } | |||
| 1018 | ||||
| 1019 | clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol( | |||
| 1020 | const llvm::pdb::PDBSymbol &symbol) { | |||
| 1021 | auto parent = GetClassOrFunctionParent(symbol); | |||
| 1022 | while (parent) { | |||
| 1023 | if (auto parent_context = GetDeclContextForSymbol(*parent)) | |||
| 1024 | return parent_context; | |||
| 1025 | ||||
| 1026 | parent = GetClassOrFunctionParent(*parent); | |||
| 1027 | } | |||
| 1028 | ||||
| 1029 | // We can't find any class or function parent of the symbol. So analyze | |||
| 1030 | // the full symbol name. The symbol may be belonging to a namespace | |||
| 1031 | // or function (or even to a class if it's e.g. a static variable symbol). | |||
| 1032 | ||||
| 1033 | // TODO: Make clang to emit full names for variables in namespaces | |||
| 1034 | // (as MSVC does) | |||
| 1035 | ||||
| 1036 | std::string name(symbol.getRawSymbol().getName()); | |||
| 1037 | MSVCUndecoratedNameParser parser(name); | |||
| 1038 | llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); | |||
| 1039 | if (specs.empty()) | |||
| 1040 | return m_ast.GetTranslationUnitDecl(); | |||
| 1041 | ||||
| 1042 | auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); | |||
| 1043 | if (!symbol_file) | |||
| 1044 | return m_ast.GetTranslationUnitDecl(); | |||
| 1045 | ||||
| 1046 | auto global = symbol_file->GetPDBSession().getGlobalScope(); | |||
| 1047 | if (!global) | |||
| 1048 | return m_ast.GetTranslationUnitDecl(); | |||
| 1049 | ||||
| 1050 | bool has_type_or_function_parent = false; | |||
| 1051 | clang::DeclContext *curr_context = m_ast.GetTranslationUnitDecl(); | |||
| 1052 | for (std::size_t i = 0; i < specs.size() - 1; i++) { | |||
| 1053 | // Check if there is a function or a type with the current context's name. | |||
| 1054 | if (std::unique_ptr<IPDBEnumSymbols> children_enum = global->findChildren( | |||
| 1055 | PDB_SymType::None, specs[i].GetFullName(), NS_CaseSensitive)) { | |||
| 1056 | while (IPDBEnumChildren<PDBSymbol>::ChildTypePtr child = | |||
| 1057 | children_enum->getNext()) { | |||
| 1058 | if (clang::DeclContext *child_context = | |||
| 1059 | GetDeclContextForSymbol(*child)) { | |||
| 1060 | // Note that `GetDeclContextForSymbol' retrieves | |||
| 1061 | // a declaration context for functions and types only, | |||
| 1062 | // so if we are here then `child_context' is guaranteed | |||
| 1063 | // a function or a type declaration context. | |||
| 1064 | has_type_or_function_parent = true; | |||
| 1065 | curr_context = child_context; | |||
| 1066 | } | |||
| 1067 | } | |||
| 1068 | } | |||
| 1069 | ||||
| 1070 | // If there were no functions or types above then retrieve a namespace with | |||
| 1071 | // the current context's name. There can be no namespaces inside a function | |||
| 1072 | // or a type. We check it to avoid fake namespaces such as `__l2': | |||
| 1073 | // `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct' | |||
| 1074 | if (!has_type_or_function_parent) { | |||
| 1075 | std::string namespace_name = std::string(specs[i].GetBaseName()); | |||
| 1076 | const char *namespace_name_c_str = | |||
| 1077 | IsAnonymousNamespaceName(namespace_name) ? nullptr | |||
| 1078 | : namespace_name.data(); | |||
| 1079 | clang::NamespaceDecl *namespace_decl = | |||
| 1080 | m_ast.GetUniqueNamespaceDeclaration( | |||
| 1081 | namespace_name_c_str, curr_context, OptionalClangModuleID()); | |||
| 1082 | ||||
| 1083 | m_parent_to_namespaces[curr_context].insert(namespace_decl); | |||
| 1084 | m_namespaces.insert(namespace_decl); | |||
| 1085 | ||||
| 1086 | curr_context = namespace_decl; | |||
| 1087 | } | |||
| 1088 | } | |||
| 1089 | ||||
| 1090 | return curr_context; | |||
| 1091 | } | |||
| 1092 | ||||
| 1093 | void PDBASTParser::ParseDeclsForDeclContext( | |||
| 1094 | const clang::DeclContext *decl_context) { | |||
| 1095 | auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); | |||
| 1096 | if (!symbol_file) | |||
| 1097 | return; | |||
| 1098 | ||||
| 1099 | IPDBSession &session = symbol_file->GetPDBSession(); | |||
| 1100 | auto symbol_up = | |||
| 1101 | session.getSymbolById(m_decl_context_to_uid.lookup(decl_context)); | |||
| 1102 | auto global_up = session.getGlobalScope(); | |||
| 1103 | ||||
| 1104 | PDBSymbol *symbol; | |||
| 1105 | if (symbol_up) | |||
| 1106 | symbol = symbol_up.get(); | |||
| 1107 | else if (global_up) | |||
| 1108 | symbol = global_up.get(); | |||
| 1109 | else | |||
| 1110 | return; | |||
| 1111 | ||||
| 1112 | if (auto children = symbol->findAllChildren()) | |||
| 1113 | while (auto child = children->getNext()) | |||
| 1114 | GetDeclForSymbol(*child); | |||
| 1115 | } | |||
| 1116 | ||||
| 1117 | clang::NamespaceDecl * | |||
| 1118 | PDBASTParser::FindNamespaceDecl(const clang::DeclContext *parent, | |||
| 1119 | llvm::StringRef name) { | |||
| 1120 | NamespacesSet *set; | |||
| 1121 | if (parent) { | |||
| 1122 | auto pit = m_parent_to_namespaces.find(parent); | |||
| 1123 | if (pit == m_parent_to_namespaces.end()) | |||
| 1124 | return nullptr; | |||
| 1125 | ||||
| 1126 | set = &pit->second; | |||
| 1127 | } else { | |||
| 1128 | set = &m_namespaces; | |||
| 1129 | } | |||
| 1130 | assert(set)((void)0); | |||
| 1131 | ||||
| 1132 | for (clang::NamespaceDecl *namespace_decl : *set) | |||
| 1133 | if (namespace_decl->getName().equals(name)) | |||
| 1134 | return namespace_decl; | |||
| 1135 | ||||
| 1136 | for (clang::NamespaceDecl *namespace_decl : *set) | |||
| 1137 | if (namespace_decl->isAnonymousNamespace()) | |||
| 1138 | return FindNamespaceDecl(namespace_decl, name); | |||
| 1139 | ||||
| 1140 | return nullptr; | |||
| 1141 | } | |||
| 1142 | ||||
| 1143 | bool PDBASTParser::AddEnumValue(CompilerType enum_type, | |||
| 1144 | const PDBSymbolData &enum_value) { | |||
| 1145 | Declaration decl; | |||
| 1146 | Variant v = enum_value.getValue(); | |||
| 1147 | std::string name = | |||
| 1148 | std::string(MSVCUndecoratedNameParser::DropScope(enum_value.getName())); | |||
| 1149 | int64_t raw_value; | |||
| 1150 | switch (v.Type) { | |||
| 1151 | case PDB_VariantType::Int8: | |||
| 1152 | raw_value = v.Value.Int8; | |||
| 1153 | break; | |||
| 1154 | case PDB_VariantType::Int16: | |||
| 1155 | raw_value = v.Value.Int16; | |||
| 1156 | break; | |||
| 1157 | case PDB_VariantType::Int32: | |||
| 1158 | raw_value = v.Value.Int32; | |||
| 1159 | break; | |||
| 1160 | case PDB_VariantType::Int64: | |||
| 1161 | raw_value = v.Value.Int64; | |||
| 1162 | break; | |||
| 1163 | case PDB_VariantType::UInt8: | |||
| 1164 | raw_value = v.Value.UInt8; | |||
| 1165 | break; | |||
| 1166 | case PDB_VariantType::UInt16: | |||
| 1167 | raw_value = v.Value.UInt16; | |||
| 1168 | break; | |||
| 1169 | case PDB_VariantType::UInt32: | |||
| 1170 | raw_value = v.Value.UInt32; | |||
| 1171 | break; | |||
| 1172 | case PDB_VariantType::UInt64: | |||
| 1173 | raw_value = v.Value.UInt64; | |||
| 1174 | break; | |||
| 1175 | default: | |||
| 1176 | return false; | |||
| 1177 | } | |||
| 1178 | CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type); | |||
| 1179 | uint32_t byte_size = m_ast.getASTContext().getTypeSize( | |||
| 1180 | ClangUtil::GetQualType(underlying_type)); | |||
| 1181 | auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType( | |||
| 1182 | enum_type, decl, name.c_str(), raw_value, byte_size * 8); | |||
| 1183 | if (!enum_constant_decl) | |||
| 1184 | return false; | |||
| 1185 | ||||
| 1186 | m_uid_to_decl[enum_value.getSymIndexId()] = enum_constant_decl; | |||
| 1187 | ||||
| 1188 | return true; | |||
| 1189 | } | |||
| 1190 | ||||
| 1191 | bool PDBASTParser::CompleteTypeFromUDT( | |||
| 1192 | lldb_private::SymbolFile &symbol_file, | |||
| 1193 | lldb_private::CompilerType &compiler_type, | |||
| 1194 | llvm::pdb::PDBSymbolTypeUDT &udt) { | |||
| 1195 | ClangASTImporter::LayoutInfo layout_info; | |||
| 1196 | layout_info.bit_size = udt.getLength() * 8; | |||
| 1197 | ||||
| 1198 | auto nested_enums = udt.findAllChildren<PDBSymbolTypeUDT>(); | |||
| 1199 | if (nested_enums) | |||
| 1200 | while (auto nested = nested_enums->getNext()) | |||
| 1201 | symbol_file.ResolveTypeUID(nested->getSymIndexId()); | |||
| 1202 | ||||
| 1203 | auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>(); | |||
| 1204 | if (bases_enum) | |||
| 1205 | AddRecordBases(symbol_file, compiler_type, | |||
| 1206 | TranslateUdtKind(udt.getUdtKind()), *bases_enum, | |||
| 1207 | layout_info); | |||
| 1208 | ||||
| 1209 | auto members_enum = udt.findAllChildren<PDBSymbolData>(); | |||
| 1210 | if (members_enum) | |||
| 1211 | AddRecordMembers(symbol_file, compiler_type, *members_enum, layout_info); | |||
| 1212 | ||||
| 1213 | auto methods_enum = udt.findAllChildren<PDBSymbolFunc>(); | |||
| 1214 | if (methods_enum) | |||
| 1215 | AddRecordMethods(symbol_file, compiler_type, *methods_enum); | |||
| 1216 | ||||
| 1217 | m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType()); | |||
| 1218 | TypeSystemClang::BuildIndirectFields(compiler_type); | |||
| 1219 | TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); | |||
| 1220 | ||||
| 1221 | clang::CXXRecordDecl *record_decl = | |||
| 1222 | m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType()); | |||
| 1223 | if (!record_decl) | |||
| 1224 | return static_cast<bool>(compiler_type); | |||
| 1225 | ||||
| 1226 | GetClangASTImporter().SetRecordLayout(record_decl, layout_info); | |||
| 1227 | ||||
| 1228 | return static_cast<bool>(compiler_type); | |||
| 1229 | } | |||
| 1230 | ||||
| 1231 | void PDBASTParser::AddRecordMembers( | |||
| 1232 | lldb_private::SymbolFile &symbol_file, | |||
| 1233 | lldb_private::CompilerType &record_type, | |||
| 1234 | PDBDataSymbolEnumerator &members_enum, | |||
| 1235 | lldb_private::ClangASTImporter::LayoutInfo &layout_info) { | |||
| 1236 | while (auto member = members_enum.getNext()) { | |||
| 1237 | if (member->isCompilerGenerated()) | |||
| 1238 | continue; | |||
| 1239 | ||||
| 1240 | auto member_name = member->getName(); | |||
| 1241 | ||||
| 1242 | auto member_type = symbol_file.ResolveTypeUID(member->getTypeId()); | |||
| 1243 | if (!member_type) | |||
| 1244 | continue; | |||
| 1245 | ||||
| 1246 | auto member_comp_type = member_type->GetLayoutCompilerType(); | |||
| 1247 | if (!member_comp_type.GetCompleteType()) { | |||
| 1248 | symbol_file.GetObjectFile()->GetModule()->ReportError( | |||
| 1249 | ":: Class '%s' has a member '%s' of type '%s' " | |||
| 1250 | "which does not have a complete definition.", | |||
| 1251 | record_type.GetTypeName().GetCString(), member_name.c_str(), | |||
| 1252 | member_comp_type.GetTypeName().GetCString()); | |||
| 1253 | if (TypeSystemClang::StartTagDeclarationDefinition(member_comp_type)) | |||
| 1254 | TypeSystemClang::CompleteTagDeclarationDefinition(member_comp_type); | |||
| 1255 | } | |||
| 1256 | ||||
| 1257 | auto access = TranslateMemberAccess(member->getAccess()); | |||
| 1258 | ||||
| 1259 | switch (member->getDataKind()) { | |||
| 1260 | case PDB_DataKind::Member: { | |||
| 1261 | auto location_type = member->getLocationType(); | |||
| 1262 | ||||
| 1263 | auto bit_size = member->getLength(); | |||
| 1264 | if (location_type == PDB_LocType::ThisRel) | |||
| 1265 | bit_size *= 8; | |||
| 1266 | ||||
| 1267 | auto decl = TypeSystemClang::AddFieldToRecordType( | |||
| 1268 | record_type, member_name.c_str(), member_comp_type, access, bit_size); | |||
| 1269 | if (!decl) | |||
| 1270 | continue; | |||
| 1271 | ||||
| 1272 | m_uid_to_decl[member->getSymIndexId()] = decl; | |||
| 1273 | ||||
| 1274 | auto offset = member->getOffset() * 8; | |||
| 1275 | if (location_type == PDB_LocType::BitField) | |||
| 1276 | offset += member->getBitPosition(); | |||
| 1277 | ||||
| 1278 | layout_info.field_offsets.insert(std::make_pair(decl, offset)); | |||
| 1279 | ||||
| 1280 | break; | |||
| 1281 | } | |||
| 1282 | case PDB_DataKind::StaticMember: { | |||
| 1283 | auto decl = TypeSystemClang::AddVariableToRecordType( | |||
| 1284 | record_type, member_name.c_str(), member_comp_type, access); | |||
| 1285 | if (!decl) | |||
| 1286 | continue; | |||
| 1287 | ||||
| 1288 | // Static constant members may be a const[expr] declaration. | |||
| 1289 | // Query the symbol's value as the variable initializer if valid. | |||
| 1290 | if (member_comp_type.IsConst()) { | |||
| 1291 | auto value = member->getValue(); | |||
| 1292 | clang::QualType qual_type = decl->getType(); | |||
| 1293 | unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type); | |||
| 1294 | unsigned constant_width = value.getBitWidth(); | |||
| 1295 | ||||
| 1296 | if (qual_type->isIntegralOrEnumerationType()) { | |||
| 1297 | if (type_width >= constant_width) { | |||
| 1298 | TypeSystemClang::SetIntegerInitializerForVariable( | |||
| 1299 | decl, value.toAPSInt().extOrTrunc(type_width)); | |||
| 1300 | } else { | |||
| 1301 | LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST),do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1302 | "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1303 | "which resolves to a wider constant value ({4} bits). "do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1304 | "Ignoring constant.",do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1305 | record_type.GetTypeName(), member_name,do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1306 | member_comp_type.GetTypeName(), type_width,do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1307 | constant_width)do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0); | |||
| 1308 | } | |||
| 1309 | } else { | |||
| 1310 | switch (member_comp_type.GetBasicTypeEnumeration()) { | |||
| 1311 | case lldb::eBasicTypeFloat: | |||
| 1312 | case lldb::eBasicTypeDouble: | |||
| 1313 | case lldb::eBasicTypeLongDouble: | |||
| 1314 | if (type_width == constant_width) { | |||
| 1315 | TypeSystemClang::SetFloatingInitializerForVariable( | |||
| 1316 | decl, value.toAPFloat()); | |||
| 1317 | decl->setConstexpr(true); | |||
| 1318 | } else { | |||
| 1319 | LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST),do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} " "bits) which resolves to a constant value of mismatched " "width ({4} bits). Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1320 | "Class '{0}' has a member '{1}' of type '{2}' ({3} "do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} " "bits) which resolves to a constant value of mismatched " "width ({4} bits). Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1321 | "bits) which resolves to a constant value of mismatched "do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} " "bits) which resolves to a constant value of mismatched " "width ({4} bits). Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1322 | "width ({4} bits). Ignoring constant.",do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} " "bits) which resolves to a constant value of mismatched " "width ({4} bits). Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1323 | record_type.GetTypeName(), member_name,do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} " "bits) which resolves to a constant value of mismatched " "width ({4} bits). Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1324 | member_comp_type.GetTypeName(), type_width,do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} " "bits) which resolves to a constant value of mismatched " "width ({4} bits). Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0) | |||
| 1325 | constant_width)do { ::lldb_private::Log *log_private = (GetLogIfAllCategoriesSet ((1u << 31))); if (log_private) log_private->Format( "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , __func__, "Class '{0}' has a member '{1}' of type '{2}' ({3} " "bits) which resolves to a constant value of mismatched " "width ({4} bits). Ignoring constant." , record_type.GetTypeName(), member_name, member_comp_type.GetTypeName (), type_width, constant_width); } while (0); | |||
| 1326 | } | |||
| 1327 | break; | |||
| 1328 | default: | |||
| 1329 | break; | |||
| 1330 | } | |||
| 1331 | } | |||
| 1332 | } | |||
| 1333 | ||||
| 1334 | m_uid_to_decl[member->getSymIndexId()] = decl; | |||
| 1335 | ||||
| 1336 | break; | |||
| 1337 | } | |||
| 1338 | default: | |||
| 1339 | llvm_unreachable("unsupported PDB data kind")__builtin_unreachable(); | |||
| 1340 | } | |||
| 1341 | } | |||
| 1342 | } | |||
| 1343 | ||||
| 1344 | void PDBASTParser::AddRecordBases( | |||
| 1345 | lldb_private::SymbolFile &symbol_file, | |||
| 1346 | lldb_private::CompilerType &record_type, int record_kind, | |||
| 1347 | PDBBaseClassSymbolEnumerator &bases_enum, | |||
| 1348 | lldb_private::ClangASTImporter::LayoutInfo &layout_info) const { | |||
| 1349 | std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> base_classes; | |||
| 1350 | ||||
| 1351 | while (auto base = bases_enum.getNext()) { | |||
| 1352 | auto base_type = symbol_file.ResolveTypeUID(base->getTypeId()); | |||
| 1353 | if (!base_type) | |||
| 1354 | continue; | |||
| 1355 | ||||
| 1356 | auto base_comp_type = base_type->GetFullCompilerType(); | |||
| 1357 | if (!base_comp_type.GetCompleteType()) { | |||
| 1358 | symbol_file.GetObjectFile()->GetModule()->ReportError( | |||
| 1359 | ":: Class '%s' has a base class '%s' " | |||
| 1360 | "which does not have a complete definition.", | |||
| 1361 | record_type.GetTypeName().GetCString(), | |||
| 1362 | base_comp_type.GetTypeName().GetCString()); | |||
| 1363 | if (TypeSystemClang::StartTagDeclarationDefinition(base_comp_type)) | |||
| 1364 | TypeSystemClang::CompleteTagDeclarationDefinition(base_comp_type); | |||
| 1365 | } | |||
| 1366 | ||||
| 1367 | auto access = TranslateMemberAccess(base->getAccess()); | |||
| 1368 | ||||
| 1369 | auto is_virtual = base->isVirtualBaseClass(); | |||
| 1370 | ||||
| 1371 | std::unique_ptr<clang::CXXBaseSpecifier> base_spec = | |||
| 1372 | m_ast.CreateBaseClassSpecifier(base_comp_type.GetOpaqueQualType(), | |||
| 1373 | access, is_virtual, | |||
| 1374 | record_kind == clang::TTK_Class); | |||
| 1375 | lldbassert(base_spec)lldb_private::lldb_assert(static_cast<bool>(base_spec), "base_spec", __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 1375); | |||
| 1376 | ||||
| 1377 | base_classes.push_back(std::move(base_spec)); | |||
| 1378 | ||||
| 1379 | if (is_virtual) | |||
| 1380 | continue; | |||
| 1381 | ||||
| 1382 | auto decl = m_ast.GetAsCXXRecordDecl(base_comp_type.GetOpaqueQualType()); | |||
| 1383 | if (!decl) | |||
| 1384 | continue; | |||
| 1385 | ||||
| 1386 | auto offset = clang::CharUnits::fromQuantity(base->getOffset()); | |||
| 1387 | layout_info.base_offsets.insert(std::make_pair(decl, offset)); | |||
| 1388 | } | |||
| 1389 | ||||
| 1390 | m_ast.TransferBaseClasses(record_type.GetOpaqueQualType(), | |||
| 1391 | std::move(base_classes)); | |||
| 1392 | } | |||
| 1393 | ||||
| 1394 | void PDBASTParser::AddRecordMethods(lldb_private::SymbolFile &symbol_file, | |||
| 1395 | lldb_private::CompilerType &record_type, | |||
| 1396 | PDBFuncSymbolEnumerator &methods_enum) { | |||
| 1397 | while (std::unique_ptr<PDBSymbolFunc> method = methods_enum.getNext()) | |||
| 1398 | if (clang::CXXMethodDecl *decl = | |||
| 1399 | AddRecordMethod(symbol_file, record_type, *method)) | |||
| 1400 | m_uid_to_decl[method->getSymIndexId()] = decl; | |||
| 1401 | } | |||
| 1402 | ||||
| 1403 | clang::CXXMethodDecl * | |||
| 1404 | PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file, | |||
| 1405 | lldb_private::CompilerType &record_type, | |||
| 1406 | const llvm::pdb::PDBSymbolFunc &method) const { | |||
| 1407 | std::string name = | |||
| 1408 | std::string(MSVCUndecoratedNameParser::DropScope(method.getName())); | |||
| 1409 | ||||
| 1410 | Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId()); | |||
| 1411 | // MSVC specific __vecDelDtor. | |||
| 1412 | if (!method_type) | |||
| 1413 | return nullptr; | |||
| 1414 | ||||
| 1415 | CompilerType method_comp_type = method_type->GetFullCompilerType(); | |||
| 1416 | if (!method_comp_type.GetCompleteType()) { | |||
| 1417 | symbol_file.GetObjectFile()->GetModule()->ReportError( | |||
| 1418 | ":: Class '%s' has a method '%s' whose type cannot be completed.", | |||
| 1419 | record_type.GetTypeName().GetCString(), | |||
| 1420 | method_comp_type.GetTypeName().GetCString()); | |||
| 1421 | if (TypeSystemClang::StartTagDeclarationDefinition(method_comp_type)) | |||
| 1422 | TypeSystemClang::CompleteTagDeclarationDefinition(method_comp_type); | |||
| 1423 | } | |||
| 1424 | ||||
| 1425 | AccessType access = TranslateMemberAccess(method.getAccess()); | |||
| 1426 | if (access == eAccessNone) | |||
| 1427 | access = eAccessPublic; | |||
| 1428 | ||||
| 1429 | // TODO: get mangled name for the method. | |||
| 1430 | return m_ast.AddMethodToCXXRecordType( | |||
| 1431 | record_type.GetOpaqueQualType(), name.c_str(), | |||
| 1432 | /*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(), | |||
| 1433 | method.isStatic(), method.hasInlineAttribute(), | |||
| 1434 | /*is_explicit*/ false, // FIXME: Need this field in CodeView. | |||
| 1435 | /*is_attr_used*/ false, | |||
| 1436 | /*is_artificial*/ method.isCompilerGenerated()); | |||
| 1437 | } |