//===-- ClangASTContext.h ---------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef liblldb_ClangASTContext_h_ #define liblldb_ClangASTContext_h_ // C Includes #include // C++ Includes #include #include #include #include #include #include #include #include // Other libraries and framework includes #include "clang/AST/ASTContext.h" #include "clang/AST/TemplateBase.h" #include "llvm/ADT/SmallVector.h" // Project includes #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" #include "lldb/Core/ClangForward.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Utility/ConstString.h" #include "lldb/lldb-enumerations.h" class DWARFASTParserClang; //class PDBASTParser; namespace lldb_private { class Declaration; class ClangASTContext : public TypeSystem { public: typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *); //------------------------------------------------------------------ // llvm casting support //------------------------------------------------------------------ static bool classof(const TypeSystem *ts) { return ts->getKind() == TypeSystem::eKindClang; } //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ ClangASTContext(const char *triple = nullptr); ~ClangASTContext() override; void Finalize() override; //------------------------------------------------------------------ // PluginInterface functions //------------------------------------------------------------------ ConstString GetPluginName() override; uint32_t GetPluginVersion() override; static ConstString GetPluginNameStatic(); static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, Module *module, Target *target); static void EnumerateSupportedLanguages( std::set &languages_for_types, std::set &languages_for_expressions); static void Initialize(); static void Terminate(); static ClangASTContext *GetASTContext(clang::ASTContext *ast_ctx); clang::ASTContext *getASTContext(); void setASTContext(clang::ASTContext *ast_ctx); clang::Builtin::Context *getBuiltinContext(); clang::IdentifierTable *getIdentifierTable(); clang::LangOptions *getLanguageOptions(); clang::SelectorTable *getSelectorTable(); clang::FileManager *getFileManager(); clang::SourceManager *getSourceManager(); clang::DiagnosticsEngine *getDiagnosticsEngine(); clang::DiagnosticConsumer *getDiagnosticConsumer(); clang::MangleContext *getMangleContext(); std::shared_ptr &getTargetOptions(); clang::TargetInfo *getTargetInfo(); void Clear(); const char *GetTargetTriple(); void SetTargetTriple(const char *target_triple); void SetArchitecture(const ArchSpec &arch); bool HasExternalSource(); void SetExternalSource( llvm::IntrusiveRefCntPtr &ast_source_ap); void RemoveExternalSource(); bool GetCompleteDecl(clang::Decl *decl) { return ClangASTContext::GetCompleteDecl(getASTContext(), decl); } static void DumpDeclHiearchy(clang::Decl *decl); static void DumpDeclContextHiearchy(clang::DeclContext *decl_ctx); static bool DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl); static bool GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl); void SetMetadataAsUserID(const void *object, lldb::user_id_t user_id); void SetMetadata(const void *object, ClangASTMetadata &meta_data) { SetMetadata(getASTContext(), object, meta_data); } static void SetMetadata(clang::ASTContext *ast, const void *object, ClangASTMetadata &meta_data); ClangASTMetadata *GetMetadata(const void *object) { return GetMetadata(getASTContext(), object); } static ClangASTMetadata *GetMetadata(clang::ASTContext *ast, const void *object); //------------------------------------------------------------------ // Basic Types //------------------------------------------------------------------ CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size) override; static CompilerType GetBuiltinTypeForEncodingAndBitSize( clang::ASTContext *ast, lldb::Encoding encoding, uint32_t bit_size); CompilerType GetBasicType(lldb::BasicType type); static CompilerType GetBasicType(clang::ASTContext *ast, lldb::BasicType type); static CompilerType GetBasicType(clang::ASTContext *ast, const ConstString &name); static lldb::BasicType GetBasicTypeEnumeration(const ConstString &name); CompilerType GetBuiltinTypeForDWARFEncodingAndBitSize(const char *type_name, uint32_t dw_ate, uint32_t bit_size); CompilerType GetCStringType(bool is_const); static CompilerType GetUnknownAnyType(clang::ASTContext *ast); CompilerType GetUnknownAnyType() { return ClangASTContext::GetUnknownAnyType(getASTContext()); } static clang::DeclContext *GetDeclContextForType(clang::QualType type); static clang::DeclContext *GetDeclContextForType(const CompilerType &type); uint32_t GetPointerByteSize() override; static clang::DeclContext *GetTranslationUnitDecl(clang::ASTContext *ast); clang::DeclContext *GetTranslationUnitDecl() { return GetTranslationUnitDecl(getASTContext()); } static clang::Decl *CopyDecl(clang::ASTContext *dest_context, clang::ASTContext *source_context, clang::Decl *source_decl); static bool AreTypesSame(CompilerType type1, CompilerType type2, bool ignore_qualifiers = false); static CompilerType GetTypeForDecl(clang::NamedDecl *decl); static CompilerType GetTypeForDecl(clang::TagDecl *decl); static CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl); template CompilerType GetTypeForIdentifier(const ConstString &type_name) { CompilerType compiler_type; if (type_name.GetLength()) { clang::ASTContext *ast = getASTContext(); if (ast) { clang::IdentifierInfo &myIdent = ast->Idents.get(type_name.GetCString()); clang::DeclarationName myName = ast->DeclarationNames.getIdentifier(&myIdent); clang::DeclContext::lookup_result result = ast->getTranslationUnitDecl()->lookup(myName); if (!result.empty()) { clang::NamedDecl *named_decl = result[0]; if (const RecordDeclType *record_decl = llvm::dyn_cast(named_decl)) compiler_type.SetCompilerType( ast, clang::QualType(record_decl->getTypeForDecl(), 0)); } } } return compiler_type; } CompilerType CreateStructForIdentifier( const ConstString &type_name, const std::initializer_list> &type_fields, bool packed = false); CompilerType GetOrCreateStructForIdentifier( const ConstString &type_name, const std::initializer_list> &type_fields, bool packed = false); //------------------------------------------------------------------ // Structure, Unions, Classes //------------------------------------------------------------------ static clang::AccessSpecifier ConvertAccessTypeToAccessSpecifier(lldb::AccessType access); static clang::AccessSpecifier UnifyAccessSpecifiers(clang::AccessSpecifier lhs, clang::AccessSpecifier rhs); static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes); CompilerType CreateRecordType(clang::DeclContext *decl_ctx, lldb::AccessType access_type, const char *name, int kind, lldb::LanguageType language, ClangASTMetadata *metadata = nullptr); class TemplateParameterInfos { public: bool IsValid() const { if (args.empty()) return false; return args.size() == names.size(); } size_t GetSize() const { if (IsValid()) return args.size(); return 0; } llvm::SmallVector names; llvm::SmallVector args; }; clang::FunctionTemplateDecl * CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl, const char *name, const TemplateParameterInfos &infos); void CreateFunctionTemplateSpecializationInfo( clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template, const TemplateParameterInfos &infos); clang::ClassTemplateDecl * CreateClassTemplateDecl(clang::DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name, int kind, const TemplateParameterInfos &infos); clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl( clang::DeclContext *decl_ctx, clang::ClassTemplateDecl *class_template_decl, int kind, const TemplateParameterInfos &infos); CompilerType CreateClassTemplateSpecializationType(clang::ClassTemplateSpecializationDecl * class_template_specialization_decl); static clang::DeclContext * GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl); static clang::DeclContext * GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl); static bool CheckOverloadedOperatorKindParameterCount( bool is_method, clang::OverloadedOperatorKind op_kind, uint32_t num_params); bool FieldIsBitfield(clang::FieldDecl *field, uint32_t &bitfield_bit_size); static bool FieldIsBitfield(clang::ASTContext *ast, clang::FieldDecl *field, uint32_t &bitfield_bit_size); static bool RecordHasFields(const clang::RecordDecl *record_decl); CompilerType CreateObjCClass(const char *name, clang::DeclContext *decl_ctx, bool isForwardDecl, bool isInternal, ClangASTMetadata *metadata = nullptr); bool SetTagTypeKind(clang::QualType type, int kind) const; bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities); // Returns a mask containing bits from the ClangASTContext::eTypeXXX // enumerations //------------------------------------------------------------------ // Namespace Declarations //------------------------------------------------------------------ clang::NamespaceDecl * GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx); static clang::NamespaceDecl * GetUniqueNamespaceDeclaration(clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx); //------------------------------------------------------------------ // Function Types //------------------------------------------------------------------ clang::FunctionDecl * CreateFunctionDeclaration(clang::DeclContext *decl_ctx, const char *name, const CompilerType &function_Type, int storage, bool is_inline); static CompilerType CreateFunctionType(clang::ASTContext *ast, const CompilerType &result_type, const CompilerType *args, unsigned num_args, bool is_variadic, unsigned type_quals); CompilerType CreateFunctionType(const CompilerType &result_type, const CompilerType *args, unsigned num_args, bool is_variadic, unsigned type_quals) { return ClangASTContext::CreateFunctionType( getASTContext(), result_type, args, num_args, is_variadic, type_quals); } clang::ParmVarDecl *CreateParameterDeclaration(const char *name, const CompilerType ¶m_type, int storage); void SetFunctionParameters(clang::FunctionDecl *function_decl, clang::ParmVarDecl **params, unsigned num_params); CompilerType CreateBlockPointerType(const CompilerType &function_type); //------------------------------------------------------------------ // Array Types //------------------------------------------------------------------ CompilerType CreateArrayType(const CompilerType &element_type, size_t element_count, bool is_vector); //------------------------------------------------------------------ // Enumeration Types //------------------------------------------------------------------ CompilerType CreateEnumerationType(const char *name, clang::DeclContext *decl_ctx, const Declaration &decl, const CompilerType &integer_qual_type); //------------------------------------------------------------------ // Integer type functions //------------------------------------------------------------------ static CompilerType GetIntTypeFromBitSize(clang::ASTContext *ast, size_t bit_size, bool is_signed); CompilerType GetPointerSizedIntType(bool is_signed) { return GetPointerSizedIntType(getASTContext(), is_signed); } static CompilerType GetPointerSizedIntType(clang::ASTContext *ast, bool is_signed); //------------------------------------------------------------------ // Floating point functions //------------------------------------------------------------------ static CompilerType GetFloatTypeFromBitSize(clang::ASTContext *ast, size_t bit_size); //------------------------------------------------------------------ // TypeSystem methods //------------------------------------------------------------------ DWARFASTParser *GetDWARFParser() override; //PDBASTParser *GetPDBParser(); //------------------------------------------------------------------ // ClangASTContext callbacks for external source lookups. //------------------------------------------------------------------ static void CompleteTagDecl(void *baton, clang::TagDecl *); static void CompleteObjCInterfaceDecl(void *baton, clang::ObjCInterfaceDecl *); static bool LayoutRecordType( void *baton, const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, llvm::DenseMap &field_offsets, llvm::DenseMap &base_offsets, llvm::DenseMap &vbase_offsets); //---------------------------------------------------------------------- // CompilerDecl override functions //---------------------------------------------------------------------- ConstString DeclGetName(void *opaque_decl) override; ConstString DeclGetMangledName(void *opaque_decl) override; CompilerDeclContext DeclGetDeclContext(void *opaque_decl) override; CompilerType DeclGetFunctionReturnType(void *opaque_decl) override; size_t DeclGetFunctionNumArguments(void *opaque_decl) override; CompilerType DeclGetFunctionArgumentType(void *opaque_decl, size_t arg_idx) override; //---------------------------------------------------------------------- // CompilerDeclContext override functions //---------------------------------------------------------------------- std::vector DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) override; bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override; ConstString DeclContextGetName(void *opaque_decl_ctx) override; ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override; bool DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr, bool *is_instance_method_ptr, ConstString *language_object_name_ptr) override; //---------------------------------------------------------------------- // Clang specific clang::DeclContext functions //---------------------------------------------------------------------- static clang::DeclContext * DeclContextGetAsDeclContext(const CompilerDeclContext &dc); static clang::ObjCMethodDecl * DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc); static clang::CXXMethodDecl * DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc); static clang::FunctionDecl * DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc); static clang::NamespaceDecl * DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc); static ClangASTMetadata *DeclContextGetMetaData(const CompilerDeclContext &dc, const void *object); static clang::ASTContext * DeclContextGetClangASTContext(const CompilerDeclContext &dc); //---------------------------------------------------------------------- // Tests //---------------------------------------------------------------------- bool IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size, bool *is_incomplete) override; bool IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size) override; bool IsAggregateType(lldb::opaque_compiler_type_t type) override; bool IsAnonymousType(lldb::opaque_compiler_type_t type) override; bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; bool IsCharType(lldb::opaque_compiler_type_t type) override; bool IsCompleteType(lldb::opaque_compiler_type_t type) override; bool IsConst(lldb::opaque_compiler_type_t type) override; bool IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length) override; static bool IsCXXClassType(const CompilerType &type); bool IsDefined(lldb::opaque_compiler_type_t type) override; bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) override; bool IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr) override; uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr) override; size_t GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index) override; bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; bool IsBlockPointerType(lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override; bool IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override; bool IsEnumerationType(lldb::opaque_compiler_type_t type, bool &is_signed) override; static bool IsObjCClassType(const CompilerType &type); static bool IsObjCClassTypeAndHasIVars(const CompilerType &type, bool check_superclass); static bool IsObjCObjectOrInterfaceType(const CompilerType &type); static bool IsObjCObjectPointerType(const CompilerType &type, CompilerType *target_type = nullptr); bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; static bool IsClassType(lldb::opaque_compiler_type_t type); static bool IsEnumType(lldb::opaque_compiler_type_t type); bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type, // Can pass nullptr bool check_cplusplus, bool check_objc) override; bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; bool IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type) override; bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type) override; bool IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue) override; bool IsScalarType(lldb::opaque_compiler_type_t type) override; bool IsTypedefType(lldb::opaque_compiler_type_t type) override; bool IsVoidType(lldb::opaque_compiler_type_t type) override; bool SupportsLanguage(lldb::LanguageType language) override; static bool GetCXXClassName(const CompilerType &type, std::string &class_name); static bool GetObjCClassName(const CompilerType &type, std::string &class_name); //---------------------------------------------------------------------- // Type Completion //---------------------------------------------------------------------- bool GetCompleteType(lldb::opaque_compiler_type_t type) override; //---------------------------------------------------------------------- // Accessors //---------------------------------------------------------------------- ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type) override; lldb::LanguageType GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; //---------------------------------------------------------------------- // Creating related types //---------------------------------------------------------------------- // Using the current type, create a new typedef to that type using // "typedef_name" // as the name and "decl_ctx" as the decl context. static CompilerType CreateTypedefType(const CompilerType &type, const char *typedef_name, const CompilerDeclContext &compiler_decl_ctx); CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride) override; CompilerType GetArrayType(lldb::opaque_compiler_type_t type, uint64_t size) override; CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; CompilerType GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; // Returns -1 if this isn't a function of if the function doesn't have a // prototype // Returns a value >= 0 if there is a prototype. int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override; CompilerType GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; TypeMemberFunctionImpl GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override; CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; CompilerType GetLValueReferenceType(lldb::opaque_compiler_type_t type) override; CompilerType GetRValueReferenceType(lldb::opaque_compiler_type_t type) override; CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override; CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override; CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override; CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, const CompilerDeclContext &decl_ctx) override; // If the current object represents a typedef type, get the underlying type CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; //---------------------------------------------------------------------- // Create related types using the current type's AST //---------------------------------------------------------------------- CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; //---------------------------------------------------------------------- // Exploring the type //---------------------------------------------------------------------- uint64_t GetByteSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) { return (GetBitSize(type, exe_scope) + 7) / 8; } uint64_t GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) override; lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override; lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes) override; CompilerType GetBuiltinTypeByName(const ConstString &name) override; lldb::BasicType GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; static lldb::BasicType GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type, const ConstString &name); void ForEachEnumerator( lldb::opaque_compiler_type_t type, std::function const &callback) override; uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, std::string &name, uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) override; uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override; uint32_t GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override; CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override; CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override; static uint32_t GetNumPointeeChildren(clang::QualType type); CompilerType GetChildCompilerTypeAtIndex( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, bool ignore_array_bounds, std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj, uint64_t &language_flags) override; // Lookup a child given a name. This function will match base class names // and member member names in "clang_type" only, not descendants. uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes) override; // Lookup a child member given a name. This function will match member names // only and will descend into "clang_type" children in search for the first // member in this class, or any base class that matches "name". // TODO: Return all matches for a given name by returning a // vector> // so we catch all names that match a given child name, not just the first. size_t GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes, std::vector &child_indexes) override; size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, lldb::TemplateArgumentKind &kind) override; CompilerType GetTypeForFormatters(void *type) override; #define LLDB_INVALID_DECL_LEVEL UINT32_MAX // LLDB_INVALID_DECL_LEVEL is returned by CountDeclLevels if // child_decl_ctx could not be found in decl_ctx. uint32_t CountDeclLevels(clang::DeclContext *frame_decl_ctx, clang::DeclContext *child_decl_ctx, ConstString *child_name = nullptr, CompilerType *child_type = nullptr); //---------------------------------------------------------------------- // Modifying RecordType //---------------------------------------------------------------------- static clang::FieldDecl *AddFieldToRecordType(const CompilerType &type, const char *name, const CompilerType &field_type, lldb::AccessType access, uint32_t bitfield_bit_size); static void BuildIndirectFields(const CompilerType &type); static void SetIsPacked(const CompilerType &type); static clang::VarDecl *AddVariableToRecordType(const CompilerType &type, const char *name, const CompilerType &var_type, lldb::AccessType access); clang::CXXMethodDecl * AddMethodToCXXRecordType(lldb::opaque_compiler_type_t type, const char *name, const CompilerType &method_type, lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline, bool is_explicit, bool is_attr_used, bool is_artificial); // C++ Base Classes clang::CXXBaseSpecifier * CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, lldb::AccessType access, bool is_virtual, bool base_of_class); static void DeleteBaseClassSpecifiers(clang::CXXBaseSpecifier **base_classes, unsigned num_base_classes); bool SetBaseClassesForClassType(lldb::opaque_compiler_type_t type, clang::CXXBaseSpecifier const *const *base_classes, unsigned num_base_classes); static bool SetObjCSuperClass(const CompilerType &type, const CompilerType &superclass_compiler_type); static bool AddObjCClassProperty(const CompilerType &type, const char *property_name, const CompilerType &property_compiler_type, clang::ObjCIvarDecl *ivar_decl, const char *property_setter_name, const char *property_getter_name, uint32_t property_attributes, ClangASTMetadata *metadata); static clang::ObjCMethodDecl *AddMethodToObjCObjectType( const CompilerType &type, const char *name, // the full symbol name as seen in the symbol table // (lldb::opaque_compiler_type_t type, "-[NString // stringWithCString:]") const CompilerType &method_compiler_type, lldb::AccessType access, bool is_artificial, bool is_variadic); static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type, bool has_extern); static bool GetHasExternalStorage(const CompilerType &type); //------------------------------------------------------------------ // Tag Declarations //------------------------------------------------------------------ static bool StartTagDeclarationDefinition(const CompilerType &type); static bool CompleteTagDeclarationDefinition(const CompilerType &type); //---------------------------------------------------------------------- // Modifying Enumeration types //---------------------------------------------------------------------- bool AddEnumerationValueToEnumerationType( lldb::opaque_compiler_type_t type, const CompilerType &enumerator_qual_type, const Declaration &decl, const char *name, int64_t enum_value, uint32_t enum_value_bit_size); CompilerType GetEnumerationIntegerType(lldb::opaque_compiler_type_t type); //------------------------------------------------------------------ // Pointers & References //------------------------------------------------------------------ // Call this function using the class type when you want to make a // member pointer type to pointee_type. static CompilerType CreateMemberPointerType(const CompilerType &type, const CompilerType &pointee_type); // Converts "s" to a floating point value and place resulting floating // point bytes in the "dst" buffer. size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, size_t dst_size) override; //---------------------------------------------------------------------- // Dumping types //---------------------------------------------------------------------- void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary, bool verbose, uint32_t depth) override; bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) override; void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size) override; void DumpTypeDescription( lldb::opaque_compiler_type_t type) override; // Dump to stdout void DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s) override; static void DumpTypeName(const CompilerType &type); static clang::EnumDecl *GetAsEnumDecl(const CompilerType &type); static clang::RecordDecl *GetAsRecordDecl(const CompilerType &type); static clang::TagDecl *GetAsTagDecl(const CompilerType &type); clang::CXXRecordDecl *GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type); static clang::ObjCInterfaceDecl * GetAsObjCInterfaceDecl(const CompilerType &type); clang::ClassTemplateDecl *ParseClassTemplateDecl( clang::DeclContext *decl_ctx, lldb::AccessType access_type, const char *parent_name, int tag_decl_kind, const ClangASTContext::TemplateParameterInfos &template_param_infos); clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx); clang::UsingDirectiveDecl * CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl); clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, clang::NamedDecl *target); clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context, const char *name, clang::QualType type); static lldb::opaque_compiler_type_t GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type); static clang::QualType GetQualType(lldb::opaque_compiler_type_t type) { if (type) return clang::QualType::getFromOpaquePtr(type); return clang::QualType(); } static clang::QualType GetCanonicalQualType(lldb::opaque_compiler_type_t type) { if (type) return clang::QualType::getFromOpaquePtr(type).getCanonicalType(); return clang::QualType(); } clang::DeclarationName GetDeclarationName(const char *name, const CompilerType &function_clang_type); protected: //------------------------------------------------------------------ // Classes that inherit from ClangASTContext can see and modify these //------------------------------------------------------------------ // clang-format off std::string m_target_triple; std::unique_ptr m_ast_ap; std::unique_ptr m_language_options_ap; std::unique_ptr m_file_manager_ap; std::unique_ptr m_file_system_options_ap; std::unique_ptr m_source_manager_ap; std::unique_ptr m_diagnostics_engine_ap; std::unique_ptr m_diagnostic_consumer_ap; std::shared_ptr m_target_options_rp; std::unique_ptr m_target_info_ap; std::unique_ptr m_identifier_table_ap; std::unique_ptr m_selector_table_ap; std::unique_ptr m_builtins_ap; std::unique_ptr m_dwarf_ast_parser_ap; // std::unique_ptr m_pdb_ast_parser_ap; std::unique_ptr m_scratch_ast_source_ap; std::unique_ptr m_mangle_ctx_ap; CompleteTagDeclCallback m_callback_tag_decl; CompleteObjCInterfaceDeclCallback m_callback_objc_decl; void * m_callback_baton; uint32_t m_pointer_byte_size; bool m_ast_owned; bool m_can_evaluate_expressions; // clang-format on private: //------------------------------------------------------------------ // For ClangASTContext only //------------------------------------------------------------------ ClangASTContext(const ClangASTContext &); const ClangASTContext &operator=(const ClangASTContext &); }; class ClangASTContextForExpressions : public ClangASTContext { public: ClangASTContextForExpressions(Target &target); ~ClangASTContextForExpressions() override = default; UserExpression * GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, Expression::ResultType desired_type, const EvaluateExpressionOptions &options) override; FunctionCaller *GetFunctionCaller(const CompilerType &return_type, const Address &function_address, const ValueList &arg_value_list, const char *name) override; UtilityFunction *GetUtilityFunction(const char *text, const char *name) override; PersistentExpressionState *GetPersistentExpressionState() override; private: lldb::TargetWP m_target_wp; lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the ///persistent ///variables ///associated with ///this process for ///the expression ///parser. }; } // namespace lldb_private #endif // liblldb_ClangASTContext_h_