| 1 | //===-- TypeSystemClang.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_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H |
| 10 | #define LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H |
| 11 | |
| 12 | #include <cstdint> |
| 13 | |
| 14 | #include <functional> |
| 15 | #include <initializer_list> |
| 16 | #include <memory> |
| 17 | #include <optional> |
| 18 | #include <set> |
| 19 | #include <string> |
| 20 | #include <utility> |
| 21 | #include <vector> |
| 22 | |
| 23 | #include "clang/AST/ASTContext.h" |
| 24 | #include "clang/AST/ASTFwd.h" |
| 25 | #include "clang/AST/Attr.h" |
| 26 | #include "clang/AST/Decl.h" |
| 27 | #include "clang/AST/TemplateBase.h" |
| 28 | #include "clang/AST/Type.h" |
| 29 | #include "clang/Basic/TargetInfo.h" |
| 30 | #include "llvm/ADT/APSInt.h" |
| 31 | #include "llvm/ADT/SmallVector.h" |
| 32 | |
| 33 | #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" |
| 34 | #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" |
| 35 | #include "lldb/Expression/ExpressionVariable.h" |
| 36 | #include "lldb/Symbol/CompilerType.h" |
| 37 | #include "lldb/Symbol/TypeSystem.h" |
| 38 | #include "lldb/Target/Target.h" |
| 39 | #include "lldb/Utility/ConstString.h" |
| 40 | #include "lldb/Utility/Flags.h" |
| 41 | #include "lldb/Utility/Log.h" |
| 42 | #include "lldb/lldb-enumerations.h" |
| 43 | |
| 44 | class DWARFASTParserClang; |
| 45 | class PDBASTParser; |
| 46 | |
| 47 | namespace clang { |
| 48 | class FileManager; |
| 49 | class ; |
| 50 | class ; |
| 51 | class ModuleMap; |
| 52 | } // namespace clang |
| 53 | |
| 54 | namespace lldb_private { |
| 55 | |
| 56 | class ClangASTSource; |
| 57 | class Declaration; |
| 58 | |
| 59 | /// A Clang module ID. |
| 60 | class OptionalClangModuleID { |
| 61 | unsigned m_id = 0; |
| 62 | |
| 63 | public: |
| 64 | OptionalClangModuleID() = default; |
| 65 | explicit OptionalClangModuleID(unsigned id) : m_id(id) {} |
| 66 | bool HasValue() const { return m_id != 0; } |
| 67 | unsigned GetValue() const { return m_id; } |
| 68 | }; |
| 69 | |
| 70 | /// The implementation of lldb::Type's m_payload field for TypeSystemClang. |
| 71 | class TypePayloadClang { |
| 72 | /// The payload is used for typedefs and ptrauth types. |
| 73 | /// For typedefs, the Layout is as follows: |
| 74 | /// \verbatim |
| 75 | /// bit 0..30 ... Owning Module ID. |
| 76 | /// bit 31 ...... IsCompleteObjCClass. |
| 77 | /// \endverbatim |
| 78 | /// For ptrauth types, we store the PointerAuthQualifier as an opaque value. |
| 79 | Type::Payload m_payload = 0; |
| 80 | |
| 81 | public: |
| 82 | TypePayloadClang() = default; |
| 83 | explicit TypePayloadClang(OptionalClangModuleID owning_module, |
| 84 | bool is_complete_objc_class = false); |
| 85 | explicit TypePayloadClang(uint32_t opaque_payload) : m_payload(opaque_payload) {} |
| 86 | operator Type::Payload() { return m_payload; } |
| 87 | |
| 88 | static constexpr unsigned ObjCClassBit = 1 << 31; |
| 89 | bool IsCompleteObjCClass() { return Flags(m_payload).Test(bit: ObjCClassBit); } |
| 90 | void SetIsCompleteObjCClass(bool is_complete_objc_class) { |
| 91 | m_payload = is_complete_objc_class ? Flags(m_payload).Set(ObjCClassBit) |
| 92 | : Flags(m_payload).Clear(mask: ObjCClassBit); |
| 93 | } |
| 94 | OptionalClangModuleID GetOwningModule() { |
| 95 | return OptionalClangModuleID(Flags(m_payload).Clear(mask: ObjCClassBit)); |
| 96 | } |
| 97 | void SetOwningModule(OptionalClangModuleID id); |
| 98 | /// \} |
| 99 | }; |
| 100 | |
| 101 | /// A TypeSystem implementation based on Clang. |
| 102 | /// |
| 103 | /// This class uses a single clang::ASTContext as the backend for storing |
| 104 | /// its types and declarations. Every clang::ASTContext should also just have |
| 105 | /// a single associated TypeSystemClang instance that manages it. |
| 106 | /// |
| 107 | /// The clang::ASTContext instance can either be created by TypeSystemClang |
| 108 | /// itself or it can adopt an existing clang::ASTContext (for example, when |
| 109 | /// it is necessary to provide a TypeSystem interface for an existing |
| 110 | /// clang::ASTContext that was created by clang::CompilerInstance). |
| 111 | class TypeSystemClang : public TypeSystem { |
| 112 | // LLVM RTTI support |
| 113 | static char ID; |
| 114 | |
| 115 | public: |
| 116 | typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); |
| 117 | typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, |
| 118 | clang::ObjCInterfaceDecl *); |
| 119 | |
| 120 | // llvm casting support |
| 121 | bool isA(const void *ClassID) const override { return ClassID == &ID; } |
| 122 | static bool classof(const TypeSystem *ts) { return ts->isA(ClassID: &ID); } |
| 123 | |
| 124 | /// Constructs a TypeSystemClang with an ASTContext using the given triple. |
| 125 | /// |
| 126 | /// \param name The name for the TypeSystemClang (for logging purposes) |
| 127 | /// \param triple The llvm::Triple used for the ASTContext. The triple defines |
| 128 | /// certain characteristics of the ASTContext and its types |
| 129 | /// (e.g., whether certain primitive types exist or what their |
| 130 | /// signedness is). |
| 131 | explicit TypeSystemClang(llvm::StringRef name, llvm::Triple triple); |
| 132 | |
| 133 | /// Constructs a TypeSystemClang that uses an existing ASTContext internally. |
| 134 | /// Useful when having an existing ASTContext created by Clang. |
| 135 | /// |
| 136 | /// \param name The name for the TypeSystemClang (for logging purposes) |
| 137 | /// \param existing_ctxt An existing ASTContext. |
| 138 | explicit TypeSystemClang(llvm::StringRef name, |
| 139 | clang::ASTContext &existing_ctxt); |
| 140 | |
| 141 | ~TypeSystemClang() override; |
| 142 | |
| 143 | void Finalize() override; |
| 144 | |
| 145 | // PluginInterface functions |
| 146 | llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } |
| 147 | |
| 148 | static llvm::StringRef GetPluginNameStatic() { return "clang" ; } |
| 149 | |
| 150 | static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, |
| 151 | Module *module, Target *target); |
| 152 | |
| 153 | static LanguageSet GetSupportedLanguagesForTypes(); |
| 154 | static LanguageSet GetSupportedLanguagesForExpressions(); |
| 155 | |
| 156 | static void Initialize(); |
| 157 | |
| 158 | static void Terminate(); |
| 159 | |
| 160 | static TypeSystemClang *GetASTContext(clang::ASTContext *ast_ctx); |
| 161 | |
| 162 | /// Returns the display name of this TypeSystemClang that indicates what |
| 163 | /// purpose it serves in LLDB. Used for example in logs. |
| 164 | llvm::StringRef getDisplayName() const { return m_display_name; } |
| 165 | |
| 166 | /// Returns the clang::ASTContext instance managed by this TypeSystemClang. |
| 167 | clang::ASTContext &getASTContext() const; |
| 168 | |
| 169 | clang::MangleContext *getMangleContext(); |
| 170 | |
| 171 | std::shared_ptr<clang::TargetOptions> &getTargetOptions(); |
| 172 | |
| 173 | clang::TargetInfo *getTargetInfo(); |
| 174 | |
| 175 | void setSema(clang::Sema *s); |
| 176 | clang::Sema *getSema() { return m_sema; } |
| 177 | |
| 178 | const char *GetTargetTriple(); |
| 179 | |
| 180 | void SetExternalSource( |
| 181 | llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> &ast_source_up); |
| 182 | |
| 183 | bool GetCompleteDecl(clang::Decl *decl) { |
| 184 | return TypeSystemClang::GetCompleteDecl(ast: &getASTContext(), decl); |
| 185 | } |
| 186 | |
| 187 | static void DumpDeclHiearchy(clang::Decl *decl); |
| 188 | |
| 189 | static void DumpDeclContextHiearchy(clang::DeclContext *decl_ctx); |
| 190 | |
| 191 | static bool GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl); |
| 192 | |
| 193 | void SetMetadataAsUserID(const clang::Decl *decl, lldb::user_id_t user_id); |
| 194 | void SetMetadataAsUserID(const clang::Type *type, lldb::user_id_t user_id); |
| 195 | |
| 196 | void SetMetadata(const clang::Decl *object, ClangASTMetadata meta_data); |
| 197 | |
| 198 | void SetMetadata(const clang::Type *object, ClangASTMetadata meta_data); |
| 199 | std::optional<ClangASTMetadata> GetMetadata(const clang::Decl *object); |
| 200 | std::optional<ClangASTMetadata> GetMetadata(const clang::Type *object); |
| 201 | |
| 202 | void SetCXXRecordDeclAccess(const clang::CXXRecordDecl *object, |
| 203 | clang::AccessSpecifier access); |
| 204 | clang::AccessSpecifier |
| 205 | GetCXXRecordDeclAccess(const clang::CXXRecordDecl *object); |
| 206 | |
| 207 | // Basic Types |
| 208 | CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, |
| 209 | size_t bit_size) override; |
| 210 | |
| 211 | CompilerType GetBasicType(lldb::BasicType type); |
| 212 | |
| 213 | static lldb::BasicType GetBasicTypeEnumeration(llvm::StringRef name); |
| 214 | |
| 215 | CompilerType |
| 216 | GetBuiltinTypeForDWARFEncodingAndBitSize(llvm::StringRef type_name, |
| 217 | uint32_t dw_ate, uint32_t bit_size); |
| 218 | |
| 219 | CompilerType GetCStringType(bool is_const); |
| 220 | |
| 221 | static clang::DeclContext *GetDeclContextForType(clang::QualType type); |
| 222 | |
| 223 | static clang::DeclContext *GetDeclContextForType(const CompilerType &type); |
| 224 | |
| 225 | CompilerDeclContext |
| 226 | GetCompilerDeclContextForType(const CompilerType &type) override; |
| 227 | |
| 228 | uint32_t GetPointerByteSize() override; |
| 229 | |
| 230 | clang::TranslationUnitDecl *GetTranslationUnitDecl() { |
| 231 | return getASTContext().getTranslationUnitDecl(); |
| 232 | } |
| 233 | |
| 234 | static bool AreTypesSame(CompilerType type1, CompilerType type2, |
| 235 | bool ignore_qualifiers = false); |
| 236 | |
| 237 | /// Creates a CompilerType from the given QualType with the current |
| 238 | /// TypeSystemClang instance as the CompilerType's typesystem. |
| 239 | /// \param qt The QualType for a type that belongs to the ASTContext of this |
| 240 | /// TypeSystemClang. |
| 241 | /// \return The CompilerType representing the given QualType. If the |
| 242 | /// QualType's type pointer is a nullptr then the function returns an |
| 243 | /// invalid CompilerType. |
| 244 | CompilerType GetType(clang::QualType qt) { |
| 245 | if (qt.getTypePtrOrNull() == nullptr) |
| 246 | return CompilerType(); |
| 247 | // Check that the type actually belongs to this TypeSystemClang. |
| 248 | assert(qt->getAsTagDecl() == nullptr || |
| 249 | &qt->getAsTagDecl()->getASTContext() == &getASTContext()); |
| 250 | return CompilerType(weak_from_this(), qt.getAsOpaquePtr()); |
| 251 | } |
| 252 | |
| 253 | CompilerType GetTypeForDecl(clang::NamedDecl *decl); |
| 254 | |
| 255 | CompilerType GetTypeForDecl(clang::TagDecl *decl); |
| 256 | |
| 257 | CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl); |
| 258 | |
| 259 | CompilerType GetTypeForDecl(clang::ValueDecl *value_decl); |
| 260 | |
| 261 | template <typename RecordDeclType> |
| 262 | CompilerType |
| 263 | GetTypeForIdentifier(llvm::StringRef type_name, |
| 264 | clang::DeclContext *decl_context = nullptr) { |
| 265 | CompilerType compiler_type; |
| 266 | if (type_name.empty()) |
| 267 | return compiler_type; |
| 268 | |
| 269 | clang::ASTContext &ast = getASTContext(); |
| 270 | if (!decl_context) |
| 271 | decl_context = ast.getTranslationUnitDecl(); |
| 272 | |
| 273 | clang::IdentifierInfo &myIdent = ast.Idents.get(Name: type_name); |
| 274 | clang::DeclarationName myName = |
| 275 | ast.DeclarationNames.getIdentifier(ID: &myIdent); |
| 276 | clang::DeclContext::lookup_result result = decl_context->lookup(Name: myName); |
| 277 | if (result.empty()) |
| 278 | return compiler_type; |
| 279 | |
| 280 | clang::NamedDecl *named_decl = *result.begin(); |
| 281 | if (const RecordDeclType *record_decl = |
| 282 | llvm::dyn_cast<RecordDeclType>(named_decl)) |
| 283 | compiler_type = CompilerType( |
| 284 | weak_from_this(), |
| 285 | clang::QualType(record_decl->getTypeForDecl(), 0).getAsOpaquePtr()); |
| 286 | |
| 287 | return compiler_type; |
| 288 | } |
| 289 | |
| 290 | CompilerType CreateStructForIdentifier( |
| 291 | llvm::StringRef type_name, |
| 292 | const std::initializer_list<std::pair<const char *, CompilerType>> |
| 293 | &type_fields, |
| 294 | bool packed = false); |
| 295 | |
| 296 | CompilerType GetOrCreateStructForIdentifier( |
| 297 | llvm::StringRef type_name, |
| 298 | const std::initializer_list<std::pair<const char *, CompilerType>> |
| 299 | &type_fields, |
| 300 | bool packed = false); |
| 301 | |
| 302 | static bool IsOperator(llvm::StringRef name, |
| 303 | clang::OverloadedOperatorKind &op_kind); |
| 304 | |
| 305 | // Structure, Unions, Classes |
| 306 | |
| 307 | static clang::AccessSpecifier |
| 308 | ConvertAccessTypeToAccessSpecifier(lldb::AccessType access); |
| 309 | |
| 310 | static clang::AccessSpecifier |
| 311 | UnifyAccessSpecifiers(clang::AccessSpecifier lhs, clang::AccessSpecifier rhs); |
| 312 | |
| 313 | uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl, |
| 314 | bool omit_empty_base_classes); |
| 315 | |
| 316 | uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl, |
| 317 | clang::NamedDecl *canonical_decl, |
| 318 | bool omit_empty_base_classes); |
| 319 | |
| 320 | uint32_t GetIndexForRecordBase(const clang::RecordDecl *record_decl, |
| 321 | const clang::CXXBaseSpecifier *base_spec, |
| 322 | bool omit_empty_base_classes); |
| 323 | |
| 324 | /// Synthesize a clang::Module and return its ID or a default-constructed ID. |
| 325 | OptionalClangModuleID GetOrCreateClangModule(llvm::StringRef name, |
| 326 | OptionalClangModuleID parent, |
| 327 | bool is_framework = false, |
| 328 | bool is_explicit = false); |
| 329 | |
| 330 | CompilerType |
| 331 | CreateRecordType(clang::DeclContext *decl_ctx, |
| 332 | OptionalClangModuleID owning_module, |
| 333 | lldb::AccessType access_type, llvm::StringRef name, int kind, |
| 334 | lldb::LanguageType language, |
| 335 | std::optional<ClangASTMetadata> metadata = std::nullopt, |
| 336 | bool exports_symbols = false); |
| 337 | |
| 338 | class TemplateParameterInfos { |
| 339 | public: |
| 340 | TemplateParameterInfos() = default; |
| 341 | TemplateParameterInfos(llvm::ArrayRef<const char *> names_in, |
| 342 | llvm::ArrayRef<clang::TemplateArgument> args_in) |
| 343 | : names(names_in), args(args_in) { |
| 344 | assert(names.size() == args_in.size()); |
| 345 | } |
| 346 | |
| 347 | TemplateParameterInfos(TemplateParameterInfos const &) = delete; |
| 348 | TemplateParameterInfos(TemplateParameterInfos &&) = delete; |
| 349 | |
| 350 | TemplateParameterInfos &operator=(TemplateParameterInfos const &) = delete; |
| 351 | TemplateParameterInfos &operator=(TemplateParameterInfos &&) = delete; |
| 352 | |
| 353 | ~TemplateParameterInfos() = default; |
| 354 | |
| 355 | bool IsValid() const { |
| 356 | // Having a pack name but no packed args doesn't make sense, so mark |
| 357 | // these template parameters as invalid. |
| 358 | if (pack_name && !packed_args) |
| 359 | return false; |
| 360 | return args.size() == names.size() && |
| 361 | (!packed_args || !packed_args->packed_args); |
| 362 | } |
| 363 | |
| 364 | bool IsEmpty() const { return args.empty(); } |
| 365 | size_t Size() const { return args.size(); } |
| 366 | |
| 367 | llvm::ArrayRef<clang::TemplateArgument> GetArgs() const { return args; } |
| 368 | llvm::ArrayRef<const char *> GetNames() const { return names; } |
| 369 | |
| 370 | clang::TemplateArgument const &Front() const { |
| 371 | assert(!args.empty()); |
| 372 | return args.front(); |
| 373 | } |
| 374 | |
| 375 | void InsertArg(char const *name, clang::TemplateArgument arg) { |
| 376 | args.emplace_back(Args: std::move(arg)); |
| 377 | names.push_back(Elt: name); |
| 378 | } |
| 379 | |
| 380 | // Parameter pack related |
| 381 | |
| 382 | bool hasParameterPack() const { return static_cast<bool>(packed_args); } |
| 383 | |
| 384 | TemplateParameterInfos const &GetParameterPack() const { |
| 385 | assert(packed_args != nullptr); |
| 386 | return *packed_args; |
| 387 | } |
| 388 | |
| 389 | TemplateParameterInfos &GetParameterPack() { |
| 390 | assert(packed_args != nullptr); |
| 391 | return *packed_args; |
| 392 | } |
| 393 | |
| 394 | llvm::ArrayRef<clang::TemplateArgument> GetParameterPackArgs() const { |
| 395 | assert(packed_args != nullptr); |
| 396 | return packed_args->GetArgs(); |
| 397 | } |
| 398 | |
| 399 | bool HasPackName() const { return pack_name && pack_name[0]; } |
| 400 | |
| 401 | llvm::StringRef GetPackName() const { |
| 402 | assert(HasPackName()); |
| 403 | return pack_name; |
| 404 | } |
| 405 | |
| 406 | void SetPackName(char const *name) { pack_name = name; } |
| 407 | |
| 408 | void SetParameterPack(std::unique_ptr<TemplateParameterInfos> args) { |
| 409 | packed_args = std::move(args); |
| 410 | } |
| 411 | |
| 412 | private: |
| 413 | /// Element 'names[i]' holds the template argument name |
| 414 | /// of 'args[i]' |
| 415 | llvm::SmallVector<const char *, 2> names; |
| 416 | llvm::SmallVector<clang::TemplateArgument, 2> args; |
| 417 | |
| 418 | const char * pack_name = nullptr; |
| 419 | std::unique_ptr<TemplateParameterInfos> packed_args; |
| 420 | }; |
| 421 | |
| 422 | clang::FunctionTemplateDecl *CreateFunctionTemplateDecl( |
| 423 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, |
| 424 | clang::FunctionDecl *func_decl, const TemplateParameterInfos &infos); |
| 425 | |
| 426 | void CreateFunctionTemplateSpecializationInfo( |
| 427 | clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template, |
| 428 | const TemplateParameterInfos &infos); |
| 429 | |
| 430 | clang::ClassTemplateDecl *CreateClassTemplateDecl( |
| 431 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, |
| 432 | lldb::AccessType access_type, llvm::StringRef class_name, int kind, |
| 433 | const TemplateParameterInfos &infos); |
| 434 | |
| 435 | clang::TemplateTemplateParmDecl * |
| 436 | CreateTemplateTemplateParmDecl(const char *template_name); |
| 437 | |
| 438 | clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl( |
| 439 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, |
| 440 | clang::ClassTemplateDecl *class_template_decl, int kind, |
| 441 | const TemplateParameterInfos &infos); |
| 442 | |
| 443 | CompilerType |
| 444 | CreateClassTemplateSpecializationType(clang::ClassTemplateSpecializationDecl * |
| 445 | class_template_specialization_decl); |
| 446 | |
| 447 | static clang::DeclContext * |
| 448 | GetAsDeclContext(clang::FunctionDecl *function_decl); |
| 449 | |
| 450 | static bool CheckOverloadedOperatorKindParameterCount( |
| 451 | bool is_method, clang::OverloadedOperatorKind op_kind, |
| 452 | uint32_t num_params); |
| 453 | |
| 454 | bool FieldIsBitfield(clang::FieldDecl *field, uint32_t &bitfield_bit_size); |
| 455 | |
| 456 | bool RecordHasFields(const clang::RecordDecl *record_decl); |
| 457 | |
| 458 | bool BaseSpecifierIsEmpty(const clang::CXXBaseSpecifier *b); |
| 459 | |
| 460 | CompilerType |
| 461 | CreateObjCClass(llvm::StringRef name, clang::DeclContext *decl_ctx, |
| 462 | OptionalClangModuleID owning_module, bool isInternal, |
| 463 | std::optional<ClangASTMetadata> metadata = std::nullopt); |
| 464 | |
| 465 | // Returns a mask containing bits from the TypeSystemClang::eTypeXXX |
| 466 | // enumerations |
| 467 | |
| 468 | // Namespace Declarations |
| 469 | |
| 470 | clang::NamespaceDecl * |
| 471 | GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx, |
| 472 | OptionalClangModuleID owning_module, |
| 473 | bool is_inline = false); |
| 474 | |
| 475 | // Function Types |
| 476 | |
| 477 | clang::FunctionDecl *CreateFunctionDeclaration( |
| 478 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, |
| 479 | llvm::StringRef name, const CompilerType &function_Type, |
| 480 | clang::StorageClass storage, bool is_inline); |
| 481 | |
| 482 | CompilerType |
| 483 | CreateFunctionType(const CompilerType &result_type, |
| 484 | llvm::ArrayRef<CompilerType> args, bool is_variadic, |
| 485 | unsigned type_quals, clang::CallingConv cc = clang::CC_C, |
| 486 | clang::RefQualifierKind ref_qual = clang::RQ_None); |
| 487 | |
| 488 | clang::ParmVarDecl * |
| 489 | CreateParameterDeclaration(clang::DeclContext *decl_ctx, |
| 490 | OptionalClangModuleID owning_module, |
| 491 | const char *name, const CompilerType ¶m_type, |
| 492 | int storage, bool add_decl = false); |
| 493 | |
| 494 | CompilerType CreateBlockPointerType(const CompilerType &function_type); |
| 495 | |
| 496 | // Array Types |
| 497 | |
| 498 | CompilerType CreateArrayType(const CompilerType &element_type, |
| 499 | std::optional<size_t> element_count, |
| 500 | bool is_vector); |
| 501 | |
| 502 | // Enumeration Types |
| 503 | CompilerType CreateEnumerationType( |
| 504 | llvm::StringRef name, clang::DeclContext *decl_ctx, |
| 505 | OptionalClangModuleID owning_module, const Declaration &decl, |
| 506 | const CompilerType &integer_qual_type, bool is_scoped, |
| 507 | std::optional<clang::EnumExtensibilityAttr::Kind> enum_kind = |
| 508 | std::nullopt); |
| 509 | |
| 510 | // Integer type functions |
| 511 | |
| 512 | CompilerType GetIntTypeFromBitSize(size_t bit_size, bool is_signed); |
| 513 | |
| 514 | CompilerType GetPointerSizedIntType(bool is_signed); |
| 515 | |
| 516 | // Floating point functions |
| 517 | |
| 518 | static CompilerType GetFloatTypeFromBitSize(clang::ASTContext *ast, |
| 519 | size_t bit_size); |
| 520 | |
| 521 | // TypeSystem methods |
| 522 | plugin::dwarf::DWARFASTParser *GetDWARFParser() override; |
| 523 | PDBASTParser *GetPDBParser() override; |
| 524 | npdb::PdbAstBuilder *GetNativePDBParser() override; |
| 525 | |
| 526 | // TypeSystemClang callbacks for external source lookups. |
| 527 | void CompleteTagDecl(clang::TagDecl *); |
| 528 | |
| 529 | void CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *); |
| 530 | |
| 531 | bool LayoutRecordType( |
| 532 | const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, |
| 533 | llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, |
| 534 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> |
| 535 | &base_offsets, |
| 536 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> |
| 537 | &vbase_offsets); |
| 538 | |
| 539 | /// Creates a CompilerDecl from the given Decl with the current |
| 540 | /// TypeSystemClang instance as its typesystem. |
| 541 | /// The Decl has to come from the ASTContext of this |
| 542 | /// TypeSystemClang. |
| 543 | CompilerDecl GetCompilerDecl(clang::Decl *decl) { |
| 544 | assert(&decl->getASTContext() == &getASTContext() && |
| 545 | "CreateCompilerDecl for Decl from wrong ASTContext?" ); |
| 546 | return CompilerDecl(this, decl); |
| 547 | } |
| 548 | |
| 549 | // CompilerDecl override functions |
| 550 | ConstString DeclGetName(void *opaque_decl) override; |
| 551 | |
| 552 | ConstString DeclGetMangledName(void *opaque_decl) override; |
| 553 | |
| 554 | CompilerDeclContext DeclGetDeclContext(void *opaque_decl) override; |
| 555 | |
| 556 | CompilerType DeclGetFunctionReturnType(void *opaque_decl) override; |
| 557 | |
| 558 | size_t DeclGetFunctionNumArguments(void *opaque_decl) override; |
| 559 | |
| 560 | CompilerType DeclGetFunctionArgumentType(void *opaque_decl, |
| 561 | size_t arg_idx) override; |
| 562 | |
| 563 | std::vector<lldb_private::CompilerContext> |
| 564 | DeclGetCompilerContext(void *opaque_decl) override; |
| 565 | |
| 566 | Scalar DeclGetConstantValue(void *opaque_decl) override; |
| 567 | |
| 568 | CompilerType GetTypeForDecl(void *opaque_decl) override; |
| 569 | |
| 570 | // CompilerDeclContext override functions |
| 571 | |
| 572 | /// Creates a CompilerDeclContext from the given DeclContext |
| 573 | /// with the current TypeSystemClang instance as its typesystem. |
| 574 | /// The DeclContext has to come from the ASTContext of this |
| 575 | /// TypeSystemClang. |
| 576 | CompilerDeclContext CreateDeclContext(clang::DeclContext *ctx); |
| 577 | |
| 578 | /// Set the owning module for \p decl. |
| 579 | static void SetOwningModule(clang::Decl *decl, |
| 580 | OptionalClangModuleID owning_module); |
| 581 | |
| 582 | std::vector<CompilerDecl> |
| 583 | DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, |
| 584 | const bool ignore_using_decls) override; |
| 585 | |
| 586 | ConstString DeclContextGetName(void *opaque_decl_ctx) override; |
| 587 | |
| 588 | ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override; |
| 589 | |
| 590 | bool DeclContextIsClassMethod(void *opaque_decl_ctx) override; |
| 591 | |
| 592 | bool DeclContextIsContainedInLookup(void *opaque_decl_ctx, |
| 593 | void *other_opaque_decl_ctx) override; |
| 594 | |
| 595 | lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) override; |
| 596 | |
| 597 | std::vector<lldb_private::CompilerContext> |
| 598 | DeclContextGetCompilerContext(void *opaque_decl_ctx) override; |
| 599 | |
| 600 | // Clang specific clang::DeclContext functions |
| 601 | |
| 602 | static clang::DeclContext * |
| 603 | DeclContextGetAsDeclContext(const CompilerDeclContext &dc); |
| 604 | |
| 605 | static clang::ObjCMethodDecl * |
| 606 | DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc); |
| 607 | |
| 608 | static clang::CXXMethodDecl * |
| 609 | DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc); |
| 610 | |
| 611 | static clang::FunctionDecl * |
| 612 | DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc); |
| 613 | |
| 614 | static clang::NamespaceDecl * |
| 615 | DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc); |
| 616 | |
| 617 | static std::optional<ClangASTMetadata> |
| 618 | DeclContextGetMetaData(const CompilerDeclContext &dc, |
| 619 | const clang::Decl *object); |
| 620 | |
| 621 | static clang::ASTContext * |
| 622 | DeclContextGetTypeSystemClang(const CompilerDeclContext &dc); |
| 623 | |
| 624 | // Tests |
| 625 | |
| 626 | #ifndef NDEBUG |
| 627 | bool Verify(lldb::opaque_compiler_type_t type) override; |
| 628 | #endif |
| 629 | |
| 630 | bool IsArrayType(lldb::opaque_compiler_type_t type, |
| 631 | CompilerType *element_type, uint64_t *size, |
| 632 | bool *is_incomplete) override; |
| 633 | |
| 634 | bool IsVectorType(lldb::opaque_compiler_type_t type, |
| 635 | CompilerType *element_type, uint64_t *size) override; |
| 636 | |
| 637 | bool IsAggregateType(lldb::opaque_compiler_type_t type) override; |
| 638 | |
| 639 | bool IsAnonymousType(lldb::opaque_compiler_type_t type) override; |
| 640 | |
| 641 | bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; |
| 642 | |
| 643 | bool IsCharType(lldb::opaque_compiler_type_t type) override; |
| 644 | |
| 645 | bool IsCompleteType(lldb::opaque_compiler_type_t type) override; |
| 646 | |
| 647 | bool IsConst(lldb::opaque_compiler_type_t type) override; |
| 648 | |
| 649 | bool IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length); |
| 650 | |
| 651 | static bool IsCXXClassType(const CompilerType &type); |
| 652 | |
| 653 | bool IsDefined(lldb::opaque_compiler_type_t type) override; |
| 654 | |
| 655 | bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, |
| 656 | bool &is_complex) override; |
| 657 | |
| 658 | unsigned GetPtrAuthKey(lldb::opaque_compiler_type_t type) override; |
| 659 | unsigned GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) override; |
| 660 | bool GetPtrAuthAddressDiversity(lldb::opaque_compiler_type_t type) override; |
| 661 | |
| 662 | bool IsFunctionType(lldb::opaque_compiler_type_t type) override; |
| 663 | |
| 664 | uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, |
| 665 | CompilerType *base_type_ptr) override; |
| 666 | |
| 667 | size_t |
| 668 | GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; |
| 669 | |
| 670 | CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, |
| 671 | const size_t index) override; |
| 672 | |
| 673 | bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; |
| 674 | |
| 675 | bool IsMemberFunctionPointerType(lldb::opaque_compiler_type_t type) override; |
| 676 | |
| 677 | bool IsBlockPointerType(lldb::opaque_compiler_type_t type, |
| 678 | CompilerType *function_pointer_type_ptr) override; |
| 679 | |
| 680 | bool IsIntegerType(lldb::opaque_compiler_type_t type, |
| 681 | bool &is_signed) override; |
| 682 | |
| 683 | bool IsEnumerationType(lldb::opaque_compiler_type_t type, |
| 684 | bool &is_signed) override; |
| 685 | |
| 686 | bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) override; |
| 687 | |
| 688 | static bool IsObjCClassType(const CompilerType &type); |
| 689 | |
| 690 | static bool IsObjCObjectOrInterfaceType(const CompilerType &type); |
| 691 | |
| 692 | static bool IsObjCObjectPointerType(const CompilerType &type, |
| 693 | CompilerType *target_type = nullptr); |
| 694 | |
| 695 | bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; |
| 696 | |
| 697 | static bool IsClassType(lldb::opaque_compiler_type_t type); |
| 698 | |
| 699 | static bool IsEnumType(lldb::opaque_compiler_type_t type); |
| 700 | |
| 701 | bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, |
| 702 | CompilerType *target_type, // Can pass nullptr |
| 703 | bool check_cplusplus, bool check_objc) override; |
| 704 | |
| 705 | bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; |
| 706 | |
| 707 | bool IsPointerType(lldb::opaque_compiler_type_t type, |
| 708 | CompilerType *pointee_type) override; |
| 709 | |
| 710 | bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, |
| 711 | CompilerType *pointee_type) override; |
| 712 | |
| 713 | bool IsReferenceType(lldb::opaque_compiler_type_t type, |
| 714 | CompilerType *pointee_type, bool *is_rvalue) override; |
| 715 | |
| 716 | bool IsScalarType(lldb::opaque_compiler_type_t type) override; |
| 717 | |
| 718 | bool IsTypedefType(lldb::opaque_compiler_type_t type) override; |
| 719 | |
| 720 | bool IsVoidType(lldb::opaque_compiler_type_t type) override; |
| 721 | |
| 722 | bool CanPassInRegisters(const CompilerType &type) override; |
| 723 | |
| 724 | bool SupportsLanguage(lldb::LanguageType language) override; |
| 725 | |
| 726 | static std::optional<std::string> GetCXXClassName(const CompilerType &type); |
| 727 | |
| 728 | // Type Completion |
| 729 | |
| 730 | bool GetCompleteType(lldb::opaque_compiler_type_t type) override; |
| 731 | |
| 732 | bool IsForcefullyCompleted(lldb::opaque_compiler_type_t type) override; |
| 733 | |
| 734 | // Accessors |
| 735 | |
| 736 | ConstString GetTypeName(lldb::opaque_compiler_type_t type, |
| 737 | bool base_only) override; |
| 738 | |
| 739 | ConstString GetDisplayTypeName(lldb::opaque_compiler_type_t type) override; |
| 740 | |
| 741 | uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type, |
| 742 | CompilerType *pointee_or_element_compiler_type) override; |
| 743 | |
| 744 | lldb::LanguageType |
| 745 | GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; |
| 746 | |
| 747 | lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; |
| 748 | |
| 749 | unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; |
| 750 | |
| 751 | // Creating related types |
| 752 | |
| 753 | CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, |
| 754 | ExecutionContextScope *exe_scope) override; |
| 755 | |
| 756 | CompilerType GetArrayType(lldb::opaque_compiler_type_t type, |
| 757 | uint64_t size) override; |
| 758 | |
| 759 | CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; |
| 760 | |
| 761 | CompilerType |
| 762 | GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; |
| 763 | |
| 764 | CompilerType |
| 765 | GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) override; |
| 766 | |
| 767 | // Returns -1 if this isn't a function of if the function doesn't have a |
| 768 | // prototype Returns a value >= 0 if there is a prototype. |
| 769 | int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; |
| 770 | |
| 771 | CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, |
| 772 | size_t idx) override; |
| 773 | |
| 774 | CompilerType |
| 775 | GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; |
| 776 | |
| 777 | size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; |
| 778 | |
| 779 | TypeMemberFunctionImpl |
| 780 | GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, |
| 781 | size_t idx) override; |
| 782 | |
| 783 | CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; |
| 784 | |
| 785 | CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; |
| 786 | |
| 787 | CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; |
| 788 | |
| 789 | CompilerType |
| 790 | GetLValueReferenceType(lldb::opaque_compiler_type_t type) override; |
| 791 | |
| 792 | CompilerType |
| 793 | GetRValueReferenceType(lldb::opaque_compiler_type_t type) override; |
| 794 | |
| 795 | CompilerType GetAtomicType(lldb::opaque_compiler_type_t type) override; |
| 796 | |
| 797 | CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override; |
| 798 | |
| 799 | CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type, |
| 800 | uint32_t payload) override; |
| 801 | |
| 802 | CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override; |
| 803 | |
| 804 | CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override; |
| 805 | |
| 806 | /// Using the current type, create a new typedef to that type using |
| 807 | /// "typedef_name" as the name and "decl_ctx" as the decl context. |
| 808 | /// \param opaque_payload is an opaque TypePayloadClang. |
| 809 | CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, |
| 810 | const char *name, |
| 811 | const CompilerDeclContext &decl_ctx, |
| 812 | uint32_t opaque_payload) override; |
| 813 | |
| 814 | // If the current object represents a typedef type, get the underlying type |
| 815 | CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; |
| 816 | |
| 817 | // Create related types using the current type's AST |
| 818 | CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; |
| 819 | |
| 820 | // Create a generic function prototype that can be used in ValuObject types |
| 821 | // to correctly display a function pointer with the right value and summary. |
| 822 | CompilerType CreateGenericFunctionPrototype() override; |
| 823 | |
| 824 | // Exploring the type |
| 825 | |
| 826 | const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) override; |
| 827 | |
| 828 | llvm::Expected<uint64_t> GetByteSize(lldb::opaque_compiler_type_t type, |
| 829 | ExecutionContextScope *exe_scope) { |
| 830 | auto bit_size_or_err = GetBitSize(type, exe_scope); |
| 831 | if (!bit_size_or_err) |
| 832 | return bit_size_or_err.takeError(); |
| 833 | return (*bit_size_or_err + 7) / 8; |
| 834 | } |
| 835 | |
| 836 | llvm::Expected<uint64_t> |
| 837 | GetBitSize(lldb::opaque_compiler_type_t type, |
| 838 | ExecutionContextScope *exe_scope) override; |
| 839 | |
| 840 | lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, |
| 841 | uint64_t &count) override; |
| 842 | |
| 843 | lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; |
| 844 | |
| 845 | std::optional<size_t> |
| 846 | GetTypeBitAlign(lldb::opaque_compiler_type_t type, |
| 847 | ExecutionContextScope *exe_scope) override; |
| 848 | |
| 849 | llvm::Expected<uint32_t> |
| 850 | GetNumChildren(lldb::opaque_compiler_type_t type, |
| 851 | bool omit_empty_base_classes, |
| 852 | const ExecutionContext *exe_ctx) override; |
| 853 | |
| 854 | CompilerType GetBuiltinTypeByName(ConstString name) override; |
| 855 | |
| 856 | lldb::BasicType |
| 857 | GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; |
| 858 | |
| 859 | void ForEachEnumerator( |
| 860 | lldb::opaque_compiler_type_t type, |
| 861 | std::function<bool(const CompilerType &integer_type, |
| 862 | ConstString name, |
| 863 | const llvm::APSInt &value)> const &callback) override; |
| 864 | |
| 865 | uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; |
| 866 | |
| 867 | CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, |
| 868 | std::string &name, uint64_t *bit_offset_ptr, |
| 869 | uint32_t *bitfield_bit_size_ptr, |
| 870 | bool *is_bitfield_ptr) override; |
| 871 | |
| 872 | uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override; |
| 873 | |
| 874 | uint32_t GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override; |
| 875 | |
| 876 | CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, |
| 877 | size_t idx, |
| 878 | uint32_t *bit_offset_ptr) override; |
| 879 | |
| 880 | CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, |
| 881 | size_t idx, |
| 882 | uint32_t *bit_offset_ptr) override; |
| 883 | |
| 884 | CompilerDecl GetStaticFieldWithName(lldb::opaque_compiler_type_t type, |
| 885 | llvm::StringRef name) override; |
| 886 | |
| 887 | static uint32_t GetNumPointeeChildren(clang::QualType type); |
| 888 | |
| 889 | llvm::Expected<CompilerType> |
| 890 | GetDereferencedType(lldb::opaque_compiler_type_t type, |
| 891 | ExecutionContext *exe_ctx, std::string &deref_name, |
| 892 | uint32_t &deref_byte_size, int32_t &deref_byte_offset, |
| 893 | ValueObject *valobj, uint64_t &language_flags) override; |
| 894 | |
| 895 | llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( |
| 896 | lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, |
| 897 | bool transparent_pointers, bool omit_empty_base_classes, |
| 898 | bool ignore_array_bounds, std::string &child_name, |
| 899 | uint32_t &child_byte_size, int32_t &child_byte_offset, |
| 900 | uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, |
| 901 | bool &child_is_base_class, bool &child_is_deref_of_parent, |
| 902 | ValueObject *valobj, uint64_t &language_flags) override; |
| 903 | |
| 904 | // Lookup a child given a name. This function will match base class names and |
| 905 | // member member names in "clang_type" only, not descendants. |
| 906 | llvm::Expected<uint32_t> |
| 907 | GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, |
| 908 | llvm::StringRef name, |
| 909 | bool omit_empty_base_classes) override; |
| 910 | |
| 911 | // Lookup a child member given a name. This function will match member names |
| 912 | // only and will descend into "clang_type" children in search for the first |
| 913 | // member in this class, or any base class that matches "name". |
| 914 | // TODO: Return all matches for a given name by returning a |
| 915 | // vector<vector<uint32_t>> |
| 916 | // so we catch all names that match a given child name, not just the first. |
| 917 | size_t |
| 918 | GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, |
| 919 | llvm::StringRef name, |
| 920 | bool omit_empty_base_classes, |
| 921 | std::vector<uint32_t> &child_indexes) override; |
| 922 | |
| 923 | CompilerType GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type, |
| 924 | llvm::StringRef name) override; |
| 925 | |
| 926 | bool IsTemplateType(lldb::opaque_compiler_type_t type) override; |
| 927 | |
| 928 | size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type, |
| 929 | bool expand_pack) override; |
| 930 | |
| 931 | lldb::TemplateArgumentKind |
| 932 | GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx, |
| 933 | bool expand_pack) override; |
| 934 | CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, |
| 935 | size_t idx, bool expand_pack) override; |
| 936 | std::optional<CompilerType::IntegralTemplateArgument> |
| 937 | GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, |
| 938 | bool expand_pack) override; |
| 939 | |
| 940 | CompilerType GetTypeForFormatters(void *type) override; |
| 941 | |
| 942 | #define LLDB_INVALID_DECL_LEVEL UINT32_MAX |
| 943 | // LLDB_INVALID_DECL_LEVEL is returned by CountDeclLevels if child_decl_ctx |
| 944 | // could not be found in decl_ctx. |
| 945 | uint32_t CountDeclLevels(clang::DeclContext *frame_decl_ctx, |
| 946 | clang::DeclContext *child_decl_ctx, |
| 947 | ConstString *child_name = nullptr, |
| 948 | CompilerType *child_type = nullptr); |
| 949 | |
| 950 | // Modifying RecordType |
| 951 | static clang::FieldDecl *AddFieldToRecordType(const CompilerType &type, |
| 952 | llvm::StringRef name, |
| 953 | const CompilerType &field_type, |
| 954 | lldb::AccessType access, |
| 955 | uint32_t bitfield_bit_size); |
| 956 | |
| 957 | static void BuildIndirectFields(const CompilerType &type); |
| 958 | |
| 959 | static void SetIsPacked(const CompilerType &type); |
| 960 | |
| 961 | static clang::VarDecl *AddVariableToRecordType(const CompilerType &type, |
| 962 | llvm::StringRef name, |
| 963 | const CompilerType &var_type, |
| 964 | lldb::AccessType access); |
| 965 | |
| 966 | /// Initializes a variable with an integer value. |
| 967 | /// \param var The variable to initialize. Must not already have an |
| 968 | /// initializer and must have an integer or enum type. |
| 969 | /// \param init_value The integer value that the variable should be |
| 970 | /// initialized to. Has to match the bit width of the |
| 971 | /// variable type. |
| 972 | static void SetIntegerInitializerForVariable(clang::VarDecl *var, |
| 973 | const llvm::APInt &init_value); |
| 974 | |
| 975 | /// Initializes a variable with a floating point value. |
| 976 | /// \param var The variable to initialize. Must not already have an |
| 977 | /// initializer and must have a floating point type. |
| 978 | /// \param init_value The float value that the variable should be |
| 979 | /// initialized to. |
| 980 | static void |
| 981 | SetFloatingInitializerForVariable(clang::VarDecl *var, |
| 982 | const llvm::APFloat &init_value); |
| 983 | |
| 984 | /// For each parameter type of \c prototype, creates a \c clang::ParmVarDecl |
| 985 | /// whose \c clang::DeclContext is \c context. |
| 986 | /// |
| 987 | /// \param[in] context Non-null \c clang::FunctionDecl which will be the \c |
| 988 | /// clang::DeclContext of each parameter created/returned by this function. |
| 989 | /// \param[in] prototype The \c clang::FunctionProtoType of \c context. |
| 990 | /// \param[in] param_names The ith element of this vector contains the name |
| 991 | /// of the ith parameter. This parameter may be unnamed, in which case the |
| 992 | /// ith entry in \c param_names is an empty string. This vector is either |
| 993 | /// empty, or will have an entry for *each* parameter of the prototype |
| 994 | /// regardless of whether a parameter is unnamed or not. |
| 995 | /// |
| 996 | /// \returns A list of newly created of non-null \c clang::ParmVarDecl (one |
| 997 | /// for each parameter of \c prototype). |
| 998 | llvm::SmallVector<clang::ParmVarDecl *> CreateParameterDeclarations( |
| 999 | clang::FunctionDecl *context, const clang::FunctionProtoType &prototype, |
| 1000 | const llvm::SmallVector<llvm::StringRef> ¶m_names); |
| 1001 | |
| 1002 | clang::CXXMethodDecl *AddMethodToCXXRecordType( |
| 1003 | lldb::opaque_compiler_type_t type, llvm::StringRef name, |
| 1004 | const char *mangled_name, const CompilerType &method_type, |
| 1005 | lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline, |
| 1006 | bool is_explicit, bool is_attr_used, bool is_artificial); |
| 1007 | |
| 1008 | void AddMethodOverridesForCXXRecordType(lldb::opaque_compiler_type_t type); |
| 1009 | |
| 1010 | // C++ Base Classes |
| 1011 | std::unique_ptr<clang::CXXBaseSpecifier> |
| 1012 | CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, |
| 1013 | lldb::AccessType access, bool is_virtual, |
| 1014 | bool base_of_class); |
| 1015 | |
| 1016 | bool TransferBaseClasses( |
| 1017 | lldb::opaque_compiler_type_t type, |
| 1018 | std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases); |
| 1019 | |
| 1020 | static bool SetObjCSuperClass(const CompilerType &type, |
| 1021 | const CompilerType &superclass_compiler_type); |
| 1022 | |
| 1023 | static bool AddObjCClassProperty(const CompilerType &type, |
| 1024 | const char *property_name, |
| 1025 | const CompilerType &property_compiler_type, |
| 1026 | clang::ObjCIvarDecl *ivar_decl, |
| 1027 | const char *property_setter_name, |
| 1028 | const char *property_getter_name, |
| 1029 | uint32_t property_attributes, |
| 1030 | ClangASTMetadata metadata); |
| 1031 | |
| 1032 | static clang::ObjCMethodDecl *AddMethodToObjCObjectType( |
| 1033 | const CompilerType &type, |
| 1034 | const char *name, // the full symbol name as seen in the symbol table |
| 1035 | // (lldb::opaque_compiler_type_t type, "-[NString |
| 1036 | // stringWithCString:]") |
| 1037 | const CompilerType &method_compiler_type, bool is_artificial, |
| 1038 | bool is_variadic, bool is_objc_direct_call); |
| 1039 | |
| 1040 | static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type, |
| 1041 | bool has_extern); |
| 1042 | |
| 1043 | // Tag Declarations |
| 1044 | static bool StartTagDeclarationDefinition(const CompilerType &type); |
| 1045 | |
| 1046 | static bool CompleteTagDeclarationDefinition(const CompilerType &type); |
| 1047 | |
| 1048 | // Modifying Enumeration types |
| 1049 | clang::EnumConstantDecl *AddEnumerationValueToEnumerationType( |
| 1050 | const CompilerType &enum_type, const Declaration &decl, const char *name, |
| 1051 | uint64_t enum_value, uint32_t enum_value_bit_size); |
| 1052 | clang::EnumConstantDecl *AddEnumerationValueToEnumerationType( |
| 1053 | const CompilerType &enum_type, const Declaration &decl, const char *name, |
| 1054 | const llvm::APSInt &value); |
| 1055 | |
| 1056 | /// Returns the underlying integer type for an enum type. If the given type |
| 1057 | /// is invalid or not an enum-type, the function returns an invalid |
| 1058 | /// CompilerType. |
| 1059 | CompilerType GetEnumerationIntegerType(CompilerType type); |
| 1060 | |
| 1061 | // Pointers & References |
| 1062 | |
| 1063 | // Call this function using the class type when you want to make a member |
| 1064 | // pointer type to pointee_type. |
| 1065 | static CompilerType CreateMemberPointerType(const CompilerType &type, |
| 1066 | const CompilerType &pointee_type); |
| 1067 | |
| 1068 | // Dumping types |
| 1069 | #ifndef NDEBUG |
| 1070 | /// Convenience LLVM-style dump method for use in the debugger only. |
| 1071 | /// In contrast to the other \p Dump() methods this directly invokes |
| 1072 | /// \p clang::QualType::dump(). |
| 1073 | LLVM_DUMP_METHOD void dump(lldb::opaque_compiler_type_t type) const override; |
| 1074 | #endif |
| 1075 | |
| 1076 | /// \see lldb_private::TypeSystem::Dump |
| 1077 | void Dump(llvm::raw_ostream &output, llvm::StringRef filter) override; |
| 1078 | |
| 1079 | /// Dump clang AST types from the symbol file. |
| 1080 | /// |
| 1081 | /// \param[in] s |
| 1082 | /// A stream to send the dumped AST node(s) to |
| 1083 | /// \param[in] symbol_name |
| 1084 | /// The name of the symbol to dump, if it is empty dump all the symbols |
| 1085 | void DumpFromSymbolFile(Stream &s, llvm::StringRef symbol_name); |
| 1086 | |
| 1087 | bool (lldb::opaque_compiler_type_t type, Stream &s, |
| 1088 | lldb::Format format, const DataExtractor &data, |
| 1089 | lldb::offset_t data_offset, size_t data_byte_size, |
| 1090 | uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, |
| 1091 | ExecutionContextScope *exe_scope) override; |
| 1092 | |
| 1093 | void DumpTypeDescription( |
| 1094 | lldb::opaque_compiler_type_t type, |
| 1095 | lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override; |
| 1096 | |
| 1097 | void DumpTypeDescription( |
| 1098 | lldb::opaque_compiler_type_t type, Stream &s, |
| 1099 | lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override; |
| 1100 | |
| 1101 | static void DumpTypeName(const CompilerType &type); |
| 1102 | |
| 1103 | static clang::EnumDecl *GetAsEnumDecl(const CompilerType &type); |
| 1104 | |
| 1105 | static clang::RecordDecl *GetAsRecordDecl(const CompilerType &type); |
| 1106 | |
| 1107 | static clang::TagDecl *GetAsTagDecl(const CompilerType &type); |
| 1108 | |
| 1109 | static clang::TypedefNameDecl *GetAsTypedefDecl(const CompilerType &type); |
| 1110 | |
| 1111 | static clang::CXXRecordDecl * |
| 1112 | GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type); |
| 1113 | |
| 1114 | static clang::ObjCInterfaceDecl * |
| 1115 | GetAsObjCInterfaceDecl(const CompilerType &type); |
| 1116 | |
| 1117 | clang::ClassTemplateDecl *ParseClassTemplateDecl( |
| 1118 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, |
| 1119 | lldb::AccessType access_type, const char *parent_name, int tag_decl_kind, |
| 1120 | const TypeSystemClang::TemplateParameterInfos &template_param_infos); |
| 1121 | |
| 1122 | clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx, |
| 1123 | OptionalClangModuleID owning_module); |
| 1124 | |
| 1125 | clang::UsingDirectiveDecl * |
| 1126 | CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx, |
| 1127 | OptionalClangModuleID owning_module, |
| 1128 | clang::NamespaceDecl *ns_decl); |
| 1129 | |
| 1130 | clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, |
| 1131 | OptionalClangModuleID owning_module, |
| 1132 | clang::NamedDecl *target); |
| 1133 | |
| 1134 | clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context, |
| 1135 | OptionalClangModuleID owning_module, |
| 1136 | const char *name, |
| 1137 | clang::QualType type); |
| 1138 | |
| 1139 | static lldb::opaque_compiler_type_t |
| 1140 | GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type); |
| 1141 | |
| 1142 | static clang::QualType GetQualType(lldb::opaque_compiler_type_t type) { |
| 1143 | if (type) |
| 1144 | return clang::QualType::getFromOpaquePtr(Ptr: type); |
| 1145 | return clang::QualType(); |
| 1146 | } |
| 1147 | |
| 1148 | static clang::QualType |
| 1149 | GetCanonicalQualType(lldb::opaque_compiler_type_t type) { |
| 1150 | if (type) |
| 1151 | return clang::QualType::getFromOpaquePtr(Ptr: type).getCanonicalType(); |
| 1152 | return clang::QualType(); |
| 1153 | } |
| 1154 | |
| 1155 | clang::DeclarationName |
| 1156 | GetDeclarationName(llvm::StringRef name, |
| 1157 | const CompilerType &function_clang_type); |
| 1158 | |
| 1159 | clang::LangOptions *GetLangOpts() const { |
| 1160 | return m_language_options_up.get(); |
| 1161 | } |
| 1162 | clang::SourceManager *GetSourceMgr() const { |
| 1163 | return m_source_manager_up.get(); |
| 1164 | } |
| 1165 | |
| 1166 | /// Complete a type from debug info, or mark it as forcefully completed if |
| 1167 | /// there is no definition of the type in the current Module. Call this |
| 1168 | /// function in contexts where the usual C++ rules require a type to be |
| 1169 | /// complete (base class, member, etc.). |
| 1170 | static void RequireCompleteType(CompilerType type); |
| 1171 | |
| 1172 | bool SetDeclIsForcefullyCompleted(const clang::TagDecl *td); |
| 1173 | |
| 1174 | private: |
| 1175 | /// Returns the PrintingPolicy used when generating the internal type names. |
| 1176 | /// These type names are mostly used for the formatter selection. |
| 1177 | clang::PrintingPolicy GetTypePrintingPolicy(); |
| 1178 | /// Returns the internal type name for the given NamedDecl using the |
| 1179 | /// type printing policy. |
| 1180 | std::string GetTypeNameForDecl(const clang::NamedDecl *named_decl, |
| 1181 | bool qualified = true); |
| 1182 | |
| 1183 | const clang::ClassTemplateSpecializationDecl * |
| 1184 | GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type); |
| 1185 | |
| 1186 | bool IsTypeImpl(lldb::opaque_compiler_type_t type, |
| 1187 | llvm::function_ref<bool(clang::QualType)> predicate) const; |
| 1188 | |
| 1189 | /// Emits information about this TypeSystem into the expression log. |
| 1190 | /// |
| 1191 | /// Helper method that is used in \ref TypeSystemClang::TypeSystemClang |
| 1192 | /// on creation of a new instance. |
| 1193 | void LogCreation() const; |
| 1194 | |
| 1195 | llvm::Expected<uint64_t> GetObjCBitSize(clang::QualType qual_type, |
| 1196 | ExecutionContextScope *exe_scope); |
| 1197 | |
| 1198 | // Classes that inherit from TypeSystemClang can see and modify these |
| 1199 | std::string m_target_triple; |
| 1200 | std::unique_ptr<clang::ASTContext> m_ast_up; |
| 1201 | std::unique_ptr<clang::LangOptions> m_language_options_up; |
| 1202 | std::unique_ptr<clang::FileManager> m_file_manager_up; |
| 1203 | std::unique_ptr<clang::SourceManager> m_source_manager_up; |
| 1204 | std::unique_ptr<clang::DiagnosticOptions> m_diagnostic_options_up; |
| 1205 | std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_up; |
| 1206 | std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_up; |
| 1207 | std::shared_ptr<clang::TargetOptions> m_target_options_rp; |
| 1208 | std::unique_ptr<clang::TargetInfo> m_target_info_up; |
| 1209 | std::unique_ptr<clang::IdentifierTable> m_identifier_table_up; |
| 1210 | std::unique_ptr<clang::SelectorTable> m_selector_table_up; |
| 1211 | std::unique_ptr<clang::Builtin::Context> m_builtins_up; |
| 1212 | std::unique_ptr<clang::HeaderSearchOptions> ; |
| 1213 | std::unique_ptr<clang::HeaderSearch> ; |
| 1214 | std::unique_ptr<clang::ModuleMap> m_module_map_up; |
| 1215 | std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_up; |
| 1216 | std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up; |
| 1217 | std::unique_ptr<npdb::PdbAstBuilder> m_native_pdb_ast_parser_up; |
| 1218 | std::unique_ptr<clang::MangleContext> m_mangle_ctx_up; |
| 1219 | uint32_t m_pointer_byte_size = 0; |
| 1220 | bool m_ast_owned = false; |
| 1221 | /// A string describing what this TypeSystemClang represents (e.g., |
| 1222 | /// AST for debug information, an expression, some other utility ClangAST). |
| 1223 | /// Useful for logging and debugging. |
| 1224 | std::string m_display_name; |
| 1225 | |
| 1226 | typedef llvm::DenseMap<const clang::Decl *, ClangASTMetadata> DeclMetadataMap; |
| 1227 | /// Maps Decls to their associated ClangASTMetadata. |
| 1228 | DeclMetadataMap m_decl_metadata; |
| 1229 | |
| 1230 | typedef llvm::DenseMap<const clang::Type *, ClangASTMetadata> TypeMetadataMap; |
| 1231 | /// Maps Types to their associated ClangASTMetadata. |
| 1232 | TypeMetadataMap m_type_metadata; |
| 1233 | |
| 1234 | typedef llvm::DenseMap<const clang::CXXRecordDecl *, clang::AccessSpecifier> |
| 1235 | CXXRecordDeclAccessMap; |
| 1236 | /// Maps CXXRecordDecl to their most recent added method/field's |
| 1237 | /// AccessSpecifier. |
| 1238 | CXXRecordDeclAccessMap m_cxx_record_decl_access; |
| 1239 | |
| 1240 | /// The sema associated that is currently used to build this ASTContext. |
| 1241 | /// May be null if we are already done parsing this ASTContext or the |
| 1242 | /// ASTContext wasn't created by parsing source code. |
| 1243 | clang::Sema *m_sema = nullptr; |
| 1244 | |
| 1245 | // For TypeSystemClang only |
| 1246 | TypeSystemClang(const TypeSystemClang &); |
| 1247 | const TypeSystemClang &operator=(const TypeSystemClang &); |
| 1248 | /// Creates the internal ASTContext. |
| 1249 | void CreateASTContext(); |
| 1250 | void SetTargetTriple(llvm::StringRef target_triple); |
| 1251 | }; |
| 1252 | |
| 1253 | /// The TypeSystemClang instance used for the scratch ASTContext in a |
| 1254 | /// lldb::Target. |
| 1255 | class ScratchTypeSystemClang : public TypeSystemClang { |
| 1256 | /// LLVM RTTI support |
| 1257 | static char ID; |
| 1258 | |
| 1259 | public: |
| 1260 | ScratchTypeSystemClang(Target &target, llvm::Triple triple); |
| 1261 | |
| 1262 | ~ScratchTypeSystemClang() override = default; |
| 1263 | |
| 1264 | void Finalize() override; |
| 1265 | |
| 1266 | /// The different kinds of isolated ASTs within the scratch TypeSystem. |
| 1267 | /// |
| 1268 | /// These ASTs are isolated from the main scratch AST and are each |
| 1269 | /// dedicated to a special language option/feature that makes the contained |
| 1270 | /// AST nodes incompatible with other AST nodes. |
| 1271 | enum IsolatedASTKind { |
| 1272 | /// The isolated AST for declarations/types from expressions that imported |
| 1273 | /// type information from a C++ module. The templates from a C++ module |
| 1274 | /// often conflict with the templates we generate from debug information, |
| 1275 | /// so we put these types in their own AST. |
| 1276 | CppModules |
| 1277 | }; |
| 1278 | |
| 1279 | /// Alias for requesting the default scratch TypeSystemClang in GetForTarget. |
| 1280 | // This isn't constexpr as gtest/std::optional comparison logic is trying |
| 1281 | // to get the address of this for pretty-printing. |
| 1282 | static const std::nullopt_t DefaultAST; |
| 1283 | |
| 1284 | /// Infers the appropriate sub-AST from Clang's LangOptions. |
| 1285 | static std::optional<IsolatedASTKind> |
| 1286 | InferIsolatedASTKindFromLangOpts(const clang::LangOptions &l) { |
| 1287 | // If modules are activated we want the dedicated C++ module AST. |
| 1288 | // See IsolatedASTKind::CppModules for more info. |
| 1289 | if (l.Modules) |
| 1290 | return IsolatedASTKind::CppModules; |
| 1291 | return DefaultAST; |
| 1292 | } |
| 1293 | |
| 1294 | /// Returns the scratch TypeSystemClang for the given target. |
| 1295 | /// \param target The Target which scratch TypeSystemClang should be returned. |
| 1296 | /// \param ast_kind Allows requesting a specific sub-AST instead of the |
| 1297 | /// default scratch AST. See also `IsolatedASTKind`. |
| 1298 | /// \param create_on_demand If the scratch TypeSystemClang instance can be |
| 1299 | /// created by this call if it doesn't exist yet. If it doesn't exist yet and |
| 1300 | /// this parameter is false, this function returns a nullptr. |
| 1301 | /// \return The scratch type system of the target or a nullptr in case an |
| 1302 | /// error occurred. |
| 1303 | static lldb::TypeSystemClangSP |
| 1304 | GetForTarget(Target &target, |
| 1305 | std::optional<IsolatedASTKind> ast_kind = DefaultAST, |
| 1306 | bool create_on_demand = true); |
| 1307 | |
| 1308 | /// Returns the scratch TypeSystemClang for the given target. The returned |
| 1309 | /// TypeSystemClang will be the scratch AST or a sub-AST, depending on which |
| 1310 | /// fits best to the passed LangOptions. |
| 1311 | /// \param target The Target which scratch TypeSystemClang should be returned. |
| 1312 | /// \param lang_opts The LangOptions of a clang ASTContext that the caller |
| 1313 | /// wants to export type information from. This is used to |
| 1314 | /// find the best matching sub-AST that will be returned. |
| 1315 | static lldb::TypeSystemClangSP |
| 1316 | GetForTarget(Target &target, const clang::LangOptions &lang_opts) { |
| 1317 | return GetForTarget(target, ast_kind: InferIsolatedASTKindFromLangOpts(l: lang_opts)); |
| 1318 | } |
| 1319 | |
| 1320 | /// \see lldb_private::TypeSystem::Dump |
| 1321 | void Dump(llvm::raw_ostream &output, llvm::StringRef filter) override; |
| 1322 | |
| 1323 | UserExpression *GetUserExpression(llvm::StringRef expr, |
| 1324 | llvm::StringRef prefix, |
| 1325 | SourceLanguage language, |
| 1326 | Expression::ResultType desired_type, |
| 1327 | const EvaluateExpressionOptions &options, |
| 1328 | ValueObject *ctx_obj) override; |
| 1329 | |
| 1330 | FunctionCaller *GetFunctionCaller(const CompilerType &return_type, |
| 1331 | const Address &function_address, |
| 1332 | const ValueList &arg_value_list, |
| 1333 | const char *name) override; |
| 1334 | |
| 1335 | std::unique_ptr<UtilityFunction> |
| 1336 | CreateUtilityFunction(std::string text, std::string name) override; |
| 1337 | |
| 1338 | PersistentExpressionState *GetPersistentExpressionState() override; |
| 1339 | |
| 1340 | /// Unregisters the given ASTContext as a source from the scratch AST (and |
| 1341 | /// all sub-ASTs). |
| 1342 | /// \see ClangASTImporter::ForgetSource |
| 1343 | void ForgetSource(clang::ASTContext *src_ctx, ClangASTImporter &importer); |
| 1344 | |
| 1345 | // llvm casting support |
| 1346 | bool isA(const void *ClassID) const override { |
| 1347 | return ClassID == &ID || TypeSystemClang::isA(ClassID); |
| 1348 | } |
| 1349 | static bool classof(const TypeSystem *ts) { return ts->isA(ClassID: &ID); } |
| 1350 | |
| 1351 | private: |
| 1352 | std::unique_ptr<ClangASTSource> CreateASTSource(); |
| 1353 | /// Returns the requested sub-AST. |
| 1354 | /// Will lazily create the sub-AST if it hasn't been created before. |
| 1355 | TypeSystemClang &GetIsolatedAST(IsolatedASTKind feature); |
| 1356 | |
| 1357 | /// The target triple. |
| 1358 | /// This was potentially adjusted and might not be identical to the triple |
| 1359 | /// of `m_target_wp`. |
| 1360 | llvm::Triple m_triple; |
| 1361 | lldb::TargetWP m_target_wp; |
| 1362 | /// The persistent variables associated with this process for the expression |
| 1363 | /// parser. |
| 1364 | std::unique_ptr<ClangPersistentVariables> m_persistent_variables; |
| 1365 | /// The ExternalASTSource that performs lookups and completes minimally |
| 1366 | /// imported types. |
| 1367 | std::unique_ptr<ClangASTSource> m_scratch_ast_source_up; |
| 1368 | |
| 1369 | // FIXME: GCC 5.x doesn't support enum as map keys. |
| 1370 | typedef int IsolatedASTKey; |
| 1371 | |
| 1372 | /// Map from IsolatedASTKind to their actual TypeSystemClang instance. |
| 1373 | /// This map is lazily filled with sub-ASTs and should be accessed via |
| 1374 | /// `GetSubAST` (which lazily fills this map). |
| 1375 | llvm::DenseMap<IsolatedASTKey, std::shared_ptr<TypeSystemClang>> |
| 1376 | m_isolated_asts; |
| 1377 | }; |
| 1378 | |
| 1379 | } // namespace lldb_private |
| 1380 | |
| 1381 | #endif // LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H |
| 1382 | |