diff options
104 files changed, 8243 insertions, 10333 deletions
diff --git a/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h index e08c1aeeaed..3729b2f84b9 100644 --- a/lldb/include/lldb/API/SBType.h +++ b/lldb/include/lldb/API/SBType.h @@ -164,10 +164,6 @@ public: bool IsTypeComplete (); - // DEPRECATED: but needed for Xcode right now - static bool - IsPointerType (void * clang_type); - bool GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level); diff --git a/lldb/include/lldb/Core/DataBufferHeap.h b/lldb/include/lldb/Core/DataBufferHeap.h index dfd5d7e18ab..dac9a28befb 100644 --- a/lldb/include/lldb/Core/DataBufferHeap.h +++ b/lldb/include/lldb/Core/DataBufferHeap.h @@ -121,6 +121,9 @@ public: void CopyData (const void *src, lldb::offset_t src_len); + void + Clear(); + private: //------------------------------------------------------------------ // This object uses a std::vector<uint8_t> to store its data. This diff --git a/lldb/include/lldb/Core/Value.h b/lldb/include/lldb/Core/Value.h index 3ca7301a5df..5461ca73d08 100644 --- a/lldb/include/lldb/Core/Value.h +++ b/lldb/include/lldb/Core/Value.h @@ -21,6 +21,7 @@ #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Error.h" #include "lldb/Core/Scalar.h" +#include "lldb/Symbol/ClangASTType.h" namespace lldb_private { @@ -46,7 +47,6 @@ public: // m_context contains... // ==================== eContextTypeInvalid, // undefined - eContextTypeClangType, // void * (an opaque clang::QualType * that can be fed to "static QualType QualType::getFromOpaquePtr(void *)") eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector register) eContextTypeLLDBType, // lldb_private::Type * eContextTypeVariable // lldb_private::Variable * @@ -77,7 +77,13 @@ public: return *this; } - bool + void + Clear () + { + length = 0; + } + + bool SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order) { this->length = length; @@ -124,8 +130,11 @@ public: Value & operator=(const Value &rhs); - lldb::clang_type_t + const ClangASTType & GetClangType(); + + void + SetClangType (const ClangASTType &clang_type); ValueType GetValueType() const; @@ -173,7 +182,7 @@ public: GetType(); Scalar & - ResolveValue (ExecutionContext *exe_ctx, clang::ASTContext *ast_context); + ResolveValue (ExecutionContext *exe_ctx); const Scalar & GetScalar() const @@ -227,7 +236,7 @@ public: ResizeData(size_t len); bool - ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context); + ValueOf(ExecutionContext *exe_ctx); Variable * GetVariable(); @@ -239,11 +248,10 @@ public: GetValueDefaultFormat (); uint64_t - GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr); + GetValueByteSize (Error *error_ptr); Error GetValueAsData (ExecutionContext *exe_ctx, - clang::ASTContext *ast_context, DataExtractor &data, uint32_t data_offset, Module *module); // Can be NULL @@ -257,11 +265,15 @@ public: bool GetData (DataExtractor &data); + void + Clear(); + protected: Scalar m_value; Vector m_vector; - ValueType m_value_type; + ClangASTType m_clang_type; void * m_context; + ValueType m_value_type; ContextType m_context_type; DataBufferHeap m_data_buffer; }; diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index 26fa3aad61d..0d965d6ccc0 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -596,10 +596,7 @@ public: virtual ~ValueObject(); - clang::ASTContext * - GetClangAST (); - - lldb::clang_type_t + ClangASTType GetClangType (); //------------------------------------------------------------------ @@ -624,7 +621,7 @@ public: GetObjectRuntimeLanguage(); virtual uint32_t - GetTypeInfo (lldb::clang_type_t *pointee_or_element_clang_type = NULL); + GetTypeInfo (ClangASTType *pointee_or_element_clang_type = NULL); virtual bool IsPointerType (); @@ -718,12 +715,6 @@ public: return m_is_array_item_for_pointer; } - virtual bool - SetClangAST (clang::ASTContext *ast) - { - return false; - } - virtual const char * GetValueAsCString (); @@ -1337,10 +1328,7 @@ protected: // Sublasses must implement the functions below. //------------------------------------------------------------------ - virtual clang::ASTContext * - GetClangASTImpl () = 0; - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl () = 0; const char * diff --git a/lldb/include/lldb/Core/ValueObjectCast.h b/lldb/include/lldb/Core/ValueObjectCast.h index 2ddee7aaa1f..1538d7a5563 100644 --- a/lldb/include/lldb/Core/ValueObjectCast.h +++ b/lldb/include/lldb/Core/ValueObjectCast.h @@ -66,10 +66,7 @@ protected: virtual bool UpdateValue (); - virtual clang::ASTContext * - GetClangASTImpl (); - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl (); ClangASTType m_cast_type; diff --git a/lldb/include/lldb/Core/ValueObjectChild.h b/lldb/include/lldb/Core/ValueObjectChild.h index b071a0f3510..780529a4af1 100644 --- a/lldb/include/lldb/Core/ValueObjectChild.h +++ b/lldb/include/lldb/Core/ValueObjectChild.h @@ -81,20 +81,13 @@ protected: virtual bool UpdateValue (); - virtual clang::ASTContext * - GetClangASTImpl () - { - return m_clang_ast; - } - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl () { return m_clang_type; } - clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from - void *m_clang_type; // The type of the child in question within the parent (m_parent_sp) + ClangASTType m_clang_type; ConstString m_type_name; uint64_t m_byte_size; int32_t m_byte_offset; @@ -111,8 +104,7 @@ protected: friend class ValueObject; friend class ValueObjectConstResult; ValueObjectChild (ValueObject &parent, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, uint64_t byte_size, int32_t byte_offset, diff --git a/lldb/include/lldb/Core/ValueObjectConstResult.h b/lldb/include/lldb/Core/ValueObjectConstResult.h index bce25e59e77..4964d0589a0 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -34,16 +34,14 @@ public: static lldb::ValueObjectSP Create (ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, const DataExtractor &data, lldb::addr_t address = LLDB_INVALID_ADDRESS); static lldb::ValueObjectSP Create (ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, const lldb::DataBufferSP &result_data_sp, lldb::ByteOrder byte_order, @@ -52,8 +50,7 @@ public: static lldb::ValueObjectSP Create (ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, lldb::addr_t address, AddressType address_type, @@ -61,7 +58,6 @@ public: static lldb::ValueObjectSP Create (ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, Value &value, const ConstString &name); @@ -87,13 +83,6 @@ public: virtual bool IsInScope (); - virtual bool - SetClangAST (clang::ASTContext *ast) - { - m_clang_ast = ast; - return true; - } - void SetByteSize (size_t size); @@ -139,13 +128,9 @@ protected: virtual bool UpdateValue (); - virtual clang::ASTContext * - GetClangASTImpl (); - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl (); - clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from ConstString m_type_name; uint64_t m_byte_size; @@ -159,15 +144,13 @@ private: lldb::addr_t address); ValueObjectConstResult (ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, const DataExtractor &data, lldb::addr_t address); ValueObjectConstResult (ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, const lldb::DataBufferSP &result_data_sp, lldb::ByteOrder byte_order, @@ -175,15 +158,13 @@ private: lldb::addr_t address); ValueObjectConstResult (ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, lldb::addr_t address, AddressType address_type, uint32_t addr_byte_size); ValueObjectConstResult (ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, const Value &value, const ConstString &name); diff --git a/lldb/include/lldb/Core/ValueObjectConstResultChild.h b/lldb/include/lldb/Core/ValueObjectConstResultChild.h index fbc3e7c694d..9063276b019 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResultChild.h +++ b/lldb/include/lldb/Core/ValueObjectConstResultChild.h @@ -27,8 +27,7 @@ class ValueObjectConstResultChild : public ValueObjectChild public: ValueObjectConstResultChild (ValueObject &parent, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, uint32_t byte_size, int32_t byte_offset, @@ -45,7 +44,7 @@ public: virtual ValueObject * CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index); - virtual lldb::clang_type_t + virtual ClangASTType GetClangType () { return ValueObjectChild::GetClangType(); diff --git a/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/lldb/include/lldb/Core/ValueObjectDynamicValue.h index 12f75bdae93..c0f6baade3f 100644 --- a/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -109,10 +109,7 @@ protected: return true; } - virtual clang::ASTContext * - GetClangASTImpl (); - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl (); Address m_address; ///< The variable that this value object is based upon diff --git a/lldb/include/lldb/Core/ValueObjectMemory.h b/lldb/include/lldb/Core/ValueObjectMemory.h index 21bd75a678d..627d73eb4b2 100644 --- a/lldb/include/lldb/Core/ValueObjectMemory.h +++ b/lldb/include/lldb/Core/ValueObjectMemory.h @@ -63,10 +63,7 @@ protected: virtual bool UpdateValue (); - virtual clang::ASTContext * - GetClangASTImpl (); - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl (); Address m_address; ///< The variable that this value object is based upon diff --git a/lldb/include/lldb/Core/ValueObjectRegister.h b/lldb/include/lldb/Core/ValueObjectRegister.h index 73f6e583ad6..6820629f08e 100644 --- a/lldb/include/lldb/Core/ValueObjectRegister.h +++ b/lldb/include/lldb/Core/ValueObjectRegister.h @@ -56,10 +56,7 @@ protected: virtual bool UpdateValue (); - virtual clang::ASTContext * - GetClangASTImpl (); - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl (); lldb::RegisterContextSP m_reg_ctx_sp; @@ -113,10 +110,7 @@ protected: virtual bool UpdateValue (); - virtual clang::ASTContext * - GetClangASTImpl (); - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl (); lldb::RegisterContextSP m_reg_ctx_sp; @@ -173,17 +167,14 @@ protected: virtual bool UpdateValue (); - virtual clang::ASTContext * - GetClangASTImpl (); - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl (); lldb::RegisterContextSP m_reg_ctx_sp; RegisterInfo m_reg_info; RegisterValue m_reg_value; ConstString m_type_name; - void *m_clang_type; + ClangASTType m_clang_type; private: void diff --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index 75c57c12f77..f1d8c885c25 100644 --- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -140,10 +140,7 @@ protected: virtual bool UpdateValue (); - virtual clang::ASTContext * - GetClangASTImpl (); - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl (); virtual void diff --git a/lldb/include/lldb/Core/ValueObjectVariable.h b/lldb/include/lldb/Core/ValueObjectVariable.h index 897ce82d959..8a30b00f6bb 100644 --- a/lldb/include/lldb/Core/ValueObjectVariable.h +++ b/lldb/include/lldb/Core/ValueObjectVariable.h @@ -71,10 +71,7 @@ protected: virtual bool UpdateValue (); - virtual clang::ASTContext * - GetClangASTImpl (); - - virtual lldb::clang_type_t + virtual ClangASTType GetClangTypeImpl (); lldb::VariableSP m_variable_sp; ///< The variable that this value object is based upon diff --git a/lldb/include/lldb/DataFormatters/FormatNavigator.h b/lldb/include/lldb/DataFormatters/FormatNavigator.h index 0d3a833660b..a738cfd069e 100644 --- a/lldb/include/lldb/DataFormatters/FormatNavigator.h +++ b/lldb/include/lldb/DataFormatters/FormatNavigator.h @@ -288,8 +288,8 @@ public: uint32_t* why = NULL) { uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice; - clang::QualType type = clang::QualType::getFromOpaquePtr(valobj.GetClangType()); - bool ret = Get(valobj, type, entry, use_dynamic, value); + ClangASTType ast_type(valobj.GetClangType()); + bool ret = Get(valobj, ast_type, entry, use_dynamic, value); if (ret) entry = MapValueType(entry); else @@ -523,29 +523,23 @@ protected: bool Get_Impl (ValueObject& valobj, - clang::QualType type, + ClangASTType clang_type, MapValueType& entry, lldb::DynamicValueType use_dynamic, uint32_t& reason) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); - if (type.isNull()) + if (!clang_type.IsValid()) { if (log) - log->Printf("[Get_Impl] type is NULL, returning"); + log->Printf("[Get_Impl] type is invalid, returning"); return false; } - type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict(); - const clang::Type* typePtr = type.getTypePtrOrNull(); - if (!typePtr) - { - if (log) - log->Printf("[Get_Impl] type is NULL, returning"); - return false; - } - ConstString typeName(ClangASTType::GetTypeNameForQualType(valobj.GetClangAST(), type).c_str()); + clang_type = clang_type.RemoveFastQualifiers(); + + ConstString typeName(clang_type.GetConstTypeName()); if (valobj.GetBitfieldBitSize() > 0) { @@ -569,33 +563,30 @@ protected: log->Printf("[Get_Impl] no direct match"); // strip pointers and references and see if that helps - if (typePtr->isReferenceType()) + if (clang_type.IsReferenceType()) { if (log) log->Printf("[Get_Impl] stripping reference"); - if (Get_Impl(valobj,type.getNonReferenceType(),entry, use_dynamic, reason) && !entry->SkipsReferences()) + if (Get_Impl(valobj, clang_type.GetNonReferenceType(), entry, use_dynamic, reason) && !entry->SkipsReferences()) { reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference; return true; } } - else if (typePtr->isPointerType()) + else if (clang_type.IsPointerType()) { if (log) log->Printf("[Get_Impl] stripping pointer"); - clang::QualType pointee = typePtr->getPointeeType(); - if (Get_Impl(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers()) + if (Get_Impl(valobj, clang_type.GetPointeeType(), entry, use_dynamic, reason) && !entry->SkipsPointers()) { reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference; return true; } } - bool canBeObjCDynamic = ClangASTContext::IsPossibleDynamicType (valobj.GetClangAST(), - type.getAsOpaquePtr(), - NULL, - false, // no C++ - true); // yes ObjC + bool canBeObjCDynamic = valobj.GetClangType().IsPossibleDynamicType (NULL, + false, // no C++ + true); // yes ObjC if (canBeObjCDynamic) { @@ -611,8 +602,7 @@ protected: } if (log) log->Printf("[Get_Impl] dynamic disabled or failed - stripping ObjC pointer"); - clang::QualType pointee = typePtr->getPointeeType(); - if (Get_Impl(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers()) + if (Get_Impl(valobj, clang_type.GetPointeeType(), entry, use_dynamic, reason) && !entry->SkipsPointers()) { reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference; return true; @@ -620,12 +610,11 @@ protected: } // try to strip typedef chains - const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>(); - if (type_tdef) + if (clang_type.IsTypedefType()) { if (log) log->Printf("[Get_Impl] stripping typedef"); - if ((Get_Impl(valobj, type_tdef->getDecl()->getUnderlyingType(), entry, use_dynamic, reason)) && entry->Cascades()) + if ((Get_Impl(valobj, clang_type.GetTypedefedType(), entry, use_dynamic, reason)) && entry->Cascades()) { reason |= lldb_private::eFormatterChoiceCriterionNavigatedTypedefs; return true; @@ -639,40 +628,35 @@ protected: // we are separately passing in valobj and type because the valobj is fixed (and is used for ObjC discovery and bitfield size) // but the type can change (e.g. stripping pointers, ...) bool Get (ValueObject& valobj, - clang::QualType type, + ClangASTType clang_type, MapValueType& entry, lldb::DynamicValueType use_dynamic, uint32_t& reason) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); - if (Get_Impl (valobj,type,entry,use_dynamic,reason)) + if (Get_Impl (valobj, clang_type, entry, use_dynamic, reason)) return true; // try going to the unqualified type do { if (log) log->Printf("[Get] trying the unqualified type"); - lldb::clang_type_t opaque_type = type.getAsOpaquePtr(); - if (!opaque_type) - { - if (log) - log->Printf("[Get] could not get the opaque_type"); + if (!clang_type.IsValid()) break; - } - ClangASTType unqual_clang_ast_type = ClangASTType::GetFullyUnqualifiedType(valobj.GetClangAST(),opaque_type); + + ClangASTType unqual_clang_ast_type = clang_type.GetFullyUnqualifiedType(); if (!unqual_clang_ast_type.IsValid()) { if (log) log->Printf("[Get] could not get the unqual_clang_ast_type"); break; } - clang::QualType unqualified_qual_type = clang::QualType::getFromOpaquePtr(unqual_clang_ast_type.GetOpaqueQualType()); - if (unqualified_qual_type.getTypePtrOrNull() != type.getTypePtrOrNull()) + if (unqual_clang_ast_type.GetOpaqueQualType() != clang_type.GetOpaqueQualType()) { if (log) log->Printf("[Get] unqualified type is there and is not the same, let's try"); - if (Get_Impl (valobj,unqualified_qual_type,entry,use_dynamic,reason)) + if (Get_Impl (valobj, unqual_clang_ast_type,entry, use_dynamic, reason)) return true; } else if (log) @@ -689,7 +673,7 @@ protected: { if (log) log->Printf("[Get] has a static value - actually use it"); - if (Get(*static_value_sp.get(), clang::QualType::getFromOpaquePtr(static_value_sp->GetClangType()) , entry, use_dynamic, reason)) + if (Get(*static_value_sp.get(), static_value_sp->GetClangType(), entry, use_dynamic, reason)) { reason |= lldb_private::eFormatterChoiceCriterionWentToStaticValue; return true; diff --git a/lldb/include/lldb/Expression/ASTDumper.h b/lldb/include/lldb/Expression/ASTDumper.h index 5118eb38b42..47f7ea460b8 100644 --- a/lldb/include/lldb/Expression/ASTDumper.h +++ b/lldb/include/lldb/Expression/ASTDumper.h @@ -28,6 +28,7 @@ public: ASTDumper (const clang::Type *type); ASTDumper (clang::QualType type); ASTDumper (lldb::clang_type_t type); + ASTDumper (const ClangASTType &clang_type); const char *GetCString(); void ToSTDERR(); diff --git a/lldb/include/lldb/Expression/ClangASTSource.h b/lldb/include/lldb/Expression/ClangASTSource.h index 020a815d0da..3e41a9e69e9 100644 --- a/lldb/include/lldb/Expression/ClangASTSource.h +++ b/lldb/include/lldb/Expression/ClangASTSource.h @@ -404,10 +404,8 @@ protected: /// @return /// The imported type. //------------------------------------------------------------------ - void * - GuardedCopyType (clang::ASTContext *dest_context, - clang::ASTContext *source_context, - void *clang_type); + ClangASTType + GuardedCopyType (const ClangASTType &src_type); friend struct NameSearchContext; @@ -434,7 +432,7 @@ struct NameSearchContext { ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules const clang::DeclarationName &m_decl_name; ///< The name being looked for const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into - llvm::SmallSet <lldb::clang_type_t, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts + llvm::SmallSet <ClangASTType, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts struct { bool variable : 1; @@ -479,7 +477,7 @@ struct NameSearchContext { /// @param[in] type /// The opaque QualType for the VarDecl being registered. //------------------------------------------------------------------ - clang::NamedDecl *AddVarDecl(void *type); + clang::NamedDecl *AddVarDecl(const ClangASTType &type); //------------------------------------------------------------------ /// Create a FunDecl with the name being searched for and the provided @@ -488,7 +486,7 @@ struct NameSearchContext { /// @param[in] type /// The opaque QualType for the FunDecl being registered. //------------------------------------------------------------------ - clang::NamedDecl *AddFunDecl(void *type); + clang::NamedDecl *AddFunDecl(const ClangASTType &type); //------------------------------------------------------------------ /// Create a FunDecl with the name being searched for and generic @@ -504,7 +502,7 @@ struct NameSearchContext { /// @param[in] type /// The opaque QualType for the TypeDecl being registered. //------------------------------------------------------------------ - clang::NamedDecl *AddTypeDecl(void *type); + clang::NamedDecl *AddTypeDecl(const ClangASTType &clang_type); //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index b8be7f031e5..b2a43e0ac75 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -549,8 +549,8 @@ private: /// @param[in] var /// The variable to evaluate. /// - /// @param[in] parser_ast_context - /// The AST context of the parser, to store the found type in. + /// @param[out] var_location + /// The variable location value to fill in /// /// @param[out] found_type /// The type of the found value, as it was found in the user process. @@ -566,11 +566,11 @@ private: /// The Decl to be looked up. /// /// @return - /// The LLDB Value for the variable. + /// Return true if the value was successfully filled in. //------------------------------------------------------------------ - Value * + bool GetVariableValue (lldb::VariableSP &var, - clang::ASTContext *parser_ast_context, + lldb_private::Value &var_location, TypeFromUser *found_type = NULL, TypeFromParser *parser_type = NULL); diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h index 4f0ba6798b6..620e604fb18 100644 --- a/lldb/include/lldb/Expression/ClangExpressionVariable.h +++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h @@ -25,6 +25,7 @@ #include "lldb/lldb-public.h" #include "lldb/Core/ClangForward.h" #include "lldb/Core/ConstString.h" +#include "lldb/Core/Value.h" #include "lldb/Symbol/TaggedASTType.h" namespace llvm { @@ -98,7 +99,7 @@ public: m_parser_type(), m_named_decl (NULL), m_llvm_value (NULL), - m_lldb_value (NULL), + m_lldb_value (), m_lldb_var (), m_lldb_sym (NULL) { @@ -107,7 +108,7 @@ public: TypeFromParser m_parser_type; ///< The type of the variable according to the parser const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue - lldb_private::Value *m_lldb_value; ///< The value found in LLDB for this variable + lldb_private::Value m_lldb_value; ///< The value found in LLDB for this variable lldb::VariableSP m_lldb_var; ///< The original variable for this variable const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol }; @@ -215,17 +216,11 @@ public: void SetRegisterInfo (const RegisterInfo *reg_info); - lldb::clang_type_t + ClangASTType GetClangType (); void - SetClangType (lldb::clang_type_t); - - clang::ASTContext * - GetClangAST (); - - void - SetClangAST (clang::ASTContext *ast); + SetClangType (const ClangASTType &clang_type); TypeFromUser GetTypeFromUser (); @@ -420,8 +415,7 @@ public: { lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size)); var_sp->SetName (name); - var_sp->SetClangType (user_type.GetOpaqueQualType()); - var_sp->SetClangAST (user_type.GetASTContext()); + var_sp->SetClangType (user_type); m_variables.push_back(var_sp); return var_sp; } diff --git a/lldb/include/lldb/Expression/ClangFunction.h b/lldb/include/lldb/Expression/ClangFunction.h index ca7619f27d4..3f96f7bd311 100644 --- a/lldb/include/lldb/Expression/ClangFunction.h +++ b/lldb/include/lldb/Expression/ClangFunction.h @@ -112,8 +112,7 @@ public: /// be overridden using WriteFunctionArguments(). //------------------------------------------------------------------ ClangFunction (ExecutionContextScope &exe_scope, - ClangASTContext *ast_context, - void *return_qualtype, + const ClangASTType &return_type, const Address& function_address, const ValueList &arg_value_list); @@ -624,7 +623,7 @@ private: Function *m_function_ptr; ///< The function we're going to call. May be NULL if we don't have debug info for the function. Address m_function_addr; ///< If we don't have the FunctionSP, we at least need the address & return type. - lldb::clang_type_t m_function_return_qual_type; ///< The opaque clang qual type for the function return type. + ClangASTType m_function_return_type; ///< The opaque clang qual type for the function return type. ClangASTContext *m_clang_ast_context; ///< This is the clang_ast_context that we're getting types from the and value, and the function return the function pointer is NULL. std::string m_wrapper_function_name; ///< The name of the wrapper function. diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h index 35fa0a90e3d..2692831ecc8 100644 --- a/lldb/include/lldb/Expression/DWARFExpression.h +++ b/lldb/include/lldb/Expression/DWARFExpression.h @@ -250,7 +250,6 @@ public: //------------------------------------------------------------------ bool Evaluate (ExecutionContextScope *exe_scope, - clang::ASTContext *ast_context, ClangExpressionVariableList *expr_locals, ClangExpressionDeclMap *decl_map, lldb::addr_t loclist_base_load_addr, @@ -264,7 +263,6 @@ public: //------------------------------------------------------------------ bool Evaluate (ExecutionContext *exe_ctx, - clang::ASTContext *ast_context, ClangExpressionVariableList *expr_locals, ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx, @@ -281,9 +279,6 @@ public: /// expression. The location expression may access the target's /// memory, especially if it comes from the expression parser. /// - /// @param[in] ast_context - /// The context in which to interpret types. - /// /// @param[in] opcodes /// This is a static method so the opcodes need to be provided /// explicitly. @@ -334,7 +329,6 @@ public: //------------------------------------------------------------------ static bool Evaluate (ExecutionContext *exe_ctx, - clang::ASTContext *ast_context, ClangExpressionVariableList *expr_locals, ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx, diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index b3da283d610..75fc07b480e 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -35,31 +35,6 @@ class Declaration; class ClangASTContext { public: - enum { - eTypeHasChildren = (1u << 0), - eTypeHasValue = (1u << 1), - eTypeIsArray = (1u << 2), - eTypeIsBlock = (1u << 3), - eTypeIsBuiltIn = (1u << 4), - eTypeIsClass = (1u << 5), - eTypeIsCPlusPlus = (1u << 6), - eTypeIsEnumeration = (1u << 7), - eTypeIsFuncPrototype = (1u << 8), - eTypeIsMember = (1u << 9), - eTypeIsObjC = (1u << 10), - eTypeIsPointer = (1u << 11), - eTypeIsReference = (1u << 12), - eTypeIsStructUnion = (1u << 13), - eTypeIsTemplate = (1u << 14), - eTypeIsTypedef = (1u << 15), - eTypeIsVector = (1u << 16), - eTypeIsScalar = (1u << 17), - eTypeIsInteger = (1u << 18), - eTypeIsFloat = (1u << 19), - eTypeIsComplex = (1u << 20), - eTypeIsSigned = (1u << 21) - }; - typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *); @@ -123,20 +98,6 @@ public: void RemoveExternalSource (); - - bool - GetCompleteType (lldb::clang_type_t clang_type); - - static bool - GetCompleteType (clang::ASTContext *ast, - lldb::clang_type_t clang_type); - - bool - IsCompleteType (lldb::clang_type_t clang_type); - - static bool - IsCompleteType (clang::ASTContext *ast, - lldb::clang_type_t clang_type); bool GetCompleteDecl (clang::Decl *decl) @@ -175,70 +136,48 @@ public: //------------------------------------------------------------------ // Basic Types //------------------------------------------------------------------ - - lldb::clang_type_t + ClangASTType GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding, uint32_t bit_size); - - static lldb::clang_type_t + + static ClangASTType GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast, lldb::Encoding encoding, uint32_t bit_size); - lldb::clang_type_t - GetBuiltinTypeForDWARFEncodingAndBitSize ( - const char *type_name, - uint32_t dw_ate, - uint32_t bit_size); + ClangASTType + GetBasicType (lldb::BasicType type); - static lldb::clang_type_t - GetBuiltInType_void(clang::ASTContext *ast); + static ClangASTType + GetBasicType (clang::ASTContext *ast, lldb::BasicType type); - lldb::clang_type_t - GetBuiltInType_void() - { - return GetBuiltInType_void(getASTContext()); - } + static ClangASTType + GetBasicType (clang::ASTContext *ast, const ConstString &name); - lldb::clang_type_t - GetBuiltInType_bool(); + static lldb::BasicType + GetBasicTypeEnumeration (const ConstString &name); - lldb::clang_type_t - GetBuiltInType_objc_id(); - - static lldb::clang_type_t - GetBuiltInType_objc_id(clang::ASTContext *ast); + ClangASTType + GetBuiltinTypeForDWARFEncodingAndBitSize ( + const char *type_name, + uint32_t dw_ate, + uint32_t bit_size); - lldb::clang_type_t - GetBuiltInType_objc_Class(); + ClangASTType + GetCStringType(bool is_const); - static lldb::clang_type_t + static ClangASTType GetUnknownAnyType(clang::ASTContext *ast); - lldb::clang_type_t + ClangASTType GetUnknownAnyType() { return ClangASTContext::GetUnknownAnyType(getASTContext()); } - - lldb::clang_type_t - GetBuiltInType_objc_selector(); - - lldb::clang_type_t - GetCStringType(bool is_const); - - lldb::clang_type_t - GetVoidType(); - lldb::clang_type_t - GetVoidType(clang::ASTContext *ast); + uint32_t + GetPointerByteSize (); - lldb::clang_type_t - GetVoidPtrType(bool is_const); - - static lldb::clang_type_t - GetVoidPtrType(clang::ASTContext *ast, bool is_const); - static clang::DeclContext * GetTranslationUnitDecl (clang::ASTContext *ast); @@ -254,10 +193,9 @@ public: bool &is_instance_method, ConstString &language_object_name); - static lldb::clang_type_t + static ClangASTType CopyType(clang::ASTContext *dest_context, - clang::ASTContext *source_context, - lldb::clang_type_t clang_type); + ClangASTType source_type); static clang::Decl * CopyDecl (clang::ASTContext *dest_context, @@ -265,146 +203,42 @@ public: clang::Decl *source_decl); static bool - AreTypesSame(clang::ASTContext *ast, - lldb::clang_type_t type1, - lldb::clang_type_t type2, + AreTypesSame(ClangASTType type1, + ClangASTType type2, bool ignore_qualifiers = false); - bool - AreTypesSame(lldb::clang_type_t type1, - lldb::clang_type_t type2, - bool ignore_qualifiers = false) - { - return ClangASTContext::AreTypesSame(getASTContext(), type1, type2, ignore_qualifiers); - } - - - lldb::clang_type_t + ClangASTType GetTypeForDecl (clang::TagDecl *decl); - lldb::clang_type_t + ClangASTType GetTypeForDecl (clang::ObjCInterfaceDecl *objc_decl); - static lldb::BasicType - GetLLDBBasicTypeEnumeration (lldb::clang_type_t clang_type); - //------------------------------------------------------------------ - // CVR modifiers + // Structure, Unions, Classes //------------------------------------------------------------------ - static lldb::clang_type_t - AddConstModifier (lldb::clang_type_t clang_type); + static clang::AccessSpecifier + ConvertAccessTypeToAccessSpecifier (lldb::AccessType access); - static lldb::clang_type_t - AddRestrictModifier (lldb::clang_type_t clang_type); + static clang::AccessSpecifier + UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs); - static lldb::clang_type_t - AddVolatileModifier (lldb::clang_type_t clang_type); + static uint32_t + GetNumBaseClasses (const clang::CXXRecordDecl *cxx_record_decl, + bool omit_empty_base_classes); - //------------------------------------------------------------------ - // Structure, Unions, Classes - //------------------------------------------------------------------ + static uint32_t + GetIndexForRecordBase (const clang::RecordDecl *record_decl, + const clang::CXXBaseSpecifier *base_spec, + bool omit_empty_base_classes); - lldb::clang_type_t + ClangASTType CreateRecordType (clang::DeclContext *decl_ctx, lldb::AccessType access_type, const char *name, int kind, lldb::LanguageType language, ClangASTMetadata *metadata = NULL); - - static clang::FieldDecl * - AddFieldToRecordType (clang::ASTContext *ast, - lldb::clang_type_t record_qual_type, - const char *name, - lldb::clang_type_t field_type, - lldb::AccessType access, - uint32_t bitfield_bit_size); - - clang::FieldDecl * - AddFieldToRecordType (lldb::clang_type_t record_qual_type, - const char *name, - lldb::clang_type_t field_type, - lldb::AccessType access, - uint32_t bitfield_bit_size) - { - return ClangASTContext::AddFieldToRecordType (getASTContext(), - record_qual_type, - name, - field_type, - access, - bitfield_bit_size); - } - - clang::VarDecl * - AddVariableToRecordType (lldb::clang_type_t record_opaque_type, - const char *name, - lldb::clang_type_t var_opaque_type, - lldb::AccessType access) - { - return ClangASTContext::AddVariableToRecordType (getASTContext(), - record_opaque_type, - name, - var_opaque_type, - access); - } - - static clang::VarDecl * - AddVariableToRecordType (clang::ASTContext *ast, - lldb::clang_type_t record_opaque_type, - const char *name, - lldb::clang_type_t var_opaque_type, - lldb::AccessType access); - - static void - BuildIndirectFields (clang::ASTContext *ast, - lldb::clang_type_t record_qual_type); - - void - BuildIndirectFields (lldb::clang_type_t record_qual_type) - { - ClangASTContext::BuildIndirectFields(getASTContext(), - record_qual_type); - } - - static clang::CXXMethodDecl * - AddMethodToCXXRecordType (clang::ASTContext *ast, - lldb::clang_type_t record_opaque_type, - const char *name, - lldb::clang_type_t method_type, - lldb::AccessType access, - bool is_virtual, - bool is_static, - bool is_inline, - bool is_explicit, - bool is_attr_used, - bool is_artificial); - - clang::CXXMethodDecl * - AddMethodToCXXRecordType (lldb::clang_type_t record_opaque_type, - const char *name, - lldb::clang_type_t method_type, - lldb::AccessType access, - bool is_virtual, - bool is_static, - bool is_inline, - bool is_explicit, - bool is_attr_used, - bool is_artificial) - - { - return ClangASTContext::AddMethodToCXXRecordType (getASTContext(), - record_opaque_type, - name, - method_type, - access, - is_virtual, - is_static, - is_inline, - is_explicit, - is_attr_used, - is_artificial); - } class TemplateParameterInfos { @@ -453,7 +287,7 @@ public: int kind, const TemplateParameterInfos &infos); - lldb::clang_type_t + ClangASTType CreateClassTemplateSpecializationType (clang::ClassTemplateSpecializationDecl *class_template_specialization_decl); static clang::DeclContext * @@ -479,292 +313,16 @@ public: static bool RecordHasFields (const clang::RecordDecl *record_decl); - void - SetDefaultAccessForRecordFields (lldb::clang_type_t clang_type, - int default_accessibility, - int *assigned_accessibilities, - size_t num_assigned_accessibilities); - lldb::clang_type_t + ClangASTType CreateObjCClass (const char *name, clang::DeclContext *decl_ctx, bool isForwardDecl, bool isInternal, ClangASTMetadata *metadata = NULL); - - static clang::FieldDecl * - AddObjCClassIVar (clang::ASTContext *ast, - lldb::clang_type_t class_opaque_type, - const char *name, - lldb::clang_type_t ivar_opaque_type, - lldb::AccessType access, - uint32_t bitfield_bit_size, - bool isSynthesized); - - clang::FieldDecl * - AddObjCClassIVar (lldb::clang_type_t class_opaque_type, - const char *name, - lldb::clang_type_t ivar_opaque_type, - lldb::AccessType access, - uint32_t bitfield_bit_size, - bool isSynthesized) - { - return ClangASTContext::AddObjCClassIVar (getASTContext(), - class_opaque_type, - name, - ivar_opaque_type, - access, - bitfield_bit_size, - isSynthesized); - } - - static bool - AddObjCClassProperty - ( - clang::ASTContext *ast, - lldb::clang_type_t class_opaque_type, - const char *property_name, - lldb::clang_type_t property_opaque_type, // The property type is only required if you don't have an ivar decl - clang::ObjCIvarDecl *ivar_decl, - const char *property_setter_name, - const char *property_getter_name, - uint32_t property_attributes, - ClangASTMetadata *metadata = NULL - ); - - bool - AddObjCClassProperty - ( - lldb::clang_type_t class_opaque_type, - const char *property_name, - lldb::clang_type_t property_opaque_type, - clang::ObjCIvarDecl *ivar_decl, - const char *property_setter_name, - const char *property_getter_name, - uint32_t property_attributes, - ClangASTMetadata *metadata = NULL - ) - { - return ClangASTContext::AddObjCClassProperty (getASTContext(), - class_opaque_type, - property_name, - property_opaque_type, - ivar_decl, - property_setter_name, - property_getter_name, - property_attributes, - metadata); - } - - bool - SetObjCSuperClass (lldb::clang_type_t class_clang_type, - lldb::clang_type_t superclass_clang_type); - - static bool - ObjCTypeHasIVars (lldb::clang_type_t class_clang_type, bool check_superclass); - - static bool - ObjCDeclHasIVars (clang::ObjCInterfaceDecl *class_interface_decl, - bool check_superclass); - - - static clang::ObjCMethodDecl * - AddMethodToObjCObjectType (clang::ASTContext *ast, - lldb::clang_type_t class_opaque_type, - const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") - lldb::clang_type_t method_opaque_type, - lldb::AccessType access, - bool is_artificial); - - clang::ObjCMethodDecl * - AddMethodToObjCObjectType (lldb::clang_type_t class_opaque_type, - const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") - lldb::clang_type_t method_opaque_type, - lldb::AccessType access, - bool is_artificial) - { - return AddMethodToObjCObjectType (getASTContext(), - class_opaque_type, - name, - method_opaque_type, - access, is_artificial); - } - - static bool - SetHasExternalStorage (lldb::clang_type_t clang_type, bool has_extern); - - //------------------------------------------------------------------ - // Aggregate Types - //------------------------------------------------------------------ - static bool - IsAggregateType (lldb::clang_type_t clang_type); // Returns a mask containing bits from the ClangASTContext::eTypeXXX enumerations - static uint32_t - GetTypeInfo (lldb::clang_type_t clang_type, - clang::ASTContext *ast, // The AST for clang_type (can be NULL) - lldb::clang_type_t *pointee_or_element_type); // (can be NULL) - - static uint32_t - GetNumChildren (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - bool omit_empty_base_classes); - static uint32_t - GetNumDirectBaseClasses (clang::ASTContext *ast, - lldb::clang_type_t clang_type); - - static uint32_t - GetNumVirtualBaseClasses (clang::ASTContext *ast, - lldb::clang_type_t clang_type); - - static uint32_t - GetNumFields (clang::ASTContext *ast, - lldb::clang_type_t clang_type); - - static lldb::clang_type_t - GetDirectBaseClassAtIndex (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - size_t idx, - uint32_t *bit_offset_ptr); - - static lldb::clang_type_t - GetVirtualBaseClassAtIndex (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - size_t idx, - uint32_t *bit_offset_ptr); - - static lldb::clang_type_t - GetFieldAtIndex (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - size_t idx, - std::string& name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr); - - static size_t - GetIndexOfFieldWithName (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - const char* name, - lldb::clang_type_t* field_clang_type = NULL, - uint64_t *bit_offset_ptr = NULL, - uint32_t *bitfield_bit_size_ptr = NULL, - bool *is_bitfield_ptr = NULL); - - static uint32_t - GetNumPointeeChildren (lldb::clang_type_t clang_type); - - lldb::clang_type_t - GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, - const char *parent_name, - lldb::clang_type_t parent_clang_type, - 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); - - static lldb::clang_type_t - GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, - clang::ASTContext *ast, - const char *parent_name, - lldb::clang_type_t parent_clang_type, - 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); - - // Lookup a child given a name. This function will match base class names - // and member member names in "clang_type" only, not descendants. - static uint32_t - GetIndexOfChildWithName (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - const char *name, - bool omit_empty_base_classes); - - // 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<vector<uint32_t>> - // so we catch all names that match a given child name, not just the first. - static size_t - GetIndexOfChildMemberWithName (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - const char *name, - bool omit_empty_base_classes, - std::vector<uint32_t>& child_indexes); - - size_t - GetNumTemplateArguments (lldb::clang_type_t clang_type) - { - return GetNumTemplateArguments(getASTContext(), clang_type); - } - - lldb::clang_type_t - GetTemplateArgument (lldb::clang_type_t clang_type, - size_t idx, - lldb::TemplateArgumentKind &kind) - { - return GetTemplateArgument(getASTContext(), clang_type, idx, kind); - } - - static size_t - GetNumTemplateArguments (clang::ASTContext *ast, - lldb::clang_type_t clang_type); - - static lldb::clang_type_t - GetTemplateArgument (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - size_t idx, - lldb::TemplateArgumentKind &kind); - - //------------------------------------------------------------------ - // clang::TagType - //------------------------------------------------------------------ - - bool - SetTagTypeKind (lldb::clang_type_t tag_qual_type, - int kind); - - //------------------------------------------------------------------ - // C++ Base Classes - //------------------------------------------------------------------ - - clang::CXXBaseSpecifier * - CreateBaseClassSpecifier (lldb::clang_type_t base_class_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::clang_type_t class_clang_type, - clang::CXXBaseSpecifier const * const *base_classes, - unsigned num_base_classes); - - //------------------------------------------------------------------ - // DeclContext Functions - //------------------------------------------------------------------ - - static clang::DeclContext * - GetDeclContextForType (lldb::clang_type_t qual_type); //------------------------------------------------------------------ // Namespace Declarations @@ -781,21 +339,21 @@ public: clang::FunctionDecl * CreateFunctionDeclaration (clang::DeclContext *decl_ctx, const char *name, - lldb::clang_type_t function_Type, + const ClangASTType &function_Type, int storage, bool is_inline); - static lldb::clang_type_t + static ClangASTType CreateFunctionType (clang::ASTContext *ast, - lldb::clang_type_t result_type, - lldb::clang_type_t *args, + const ClangASTType &result_type, + const ClangASTType *args, unsigned num_args, bool is_variadic, unsigned type_quals); - lldb::clang_type_t - CreateFunctionType (lldb::clang_type_t result_type, - lldb::clang_type_t *args, + ClangASTType + CreateFunctionType (const ClangASTType &result_type, + const ClangASTType *args, unsigned num_args, bool is_variadic, unsigned type_quals) @@ -810,8 +368,8 @@ public: clang::ParmVarDecl * CreateParameterDeclaration (const char *name, - lldb::clang_type_t param_type, - int storage); + const ClangASTType ¶m_type, + int storage); void SetFunctionParameters (clang::FunctionDecl *function_decl, @@ -822,222 +380,54 @@ public: // Array Types //------------------------------------------------------------------ - lldb::clang_type_t - CreateArrayType (lldb::clang_type_t element_type, + ClangASTType + CreateArrayType (const ClangASTType &element_type, size_t element_count, bool is_vector); //------------------------------------------------------------------ - // Tag Declarations - //------------------------------------------------------------------ - bool - StartTagDeclarationDefinition (lldb::clang_type_t qual_type); - - bool - CompleteTagDeclarationDefinition (lldb::clang_type_t qual_type); - - //------------------------------------------------------------------ // Enumeration Types //------------------------------------------------------------------ - lldb::clang_type_t + ClangASTType CreateEnumerationType (const char *name, clang::DeclContext *decl_ctx, const Declaration &decl, - lldb::clang_type_t integer_qual_type); - - static lldb::clang_type_t - GetEnumerationIntegerType (lldb::clang_type_t enum_clang_type); - - bool - AddEnumerationValueToEnumerationType (lldb::clang_type_t enum_qual_type, - lldb::clang_type_t enumerator_qual_type, - const Declaration &decl, - const char *name, - int64_t enum_value, - uint32_t enum_value_bit_size); + const ClangASTType &integer_qual_type); //------------------------------------------------------------------ - // Pointers & References + // Floating point functions //------------------------------------------------------------------ - lldb::clang_type_t - CreatePointerType (lldb::clang_type_t clang_type); - - static lldb::clang_type_t - CreatePointerType (clang::ASTContext *ast, - lldb::clang_type_t clang_type); - - static lldb::clang_type_t - CreateLValueReferenceType (clang::ASTContext *ast_context, - lldb::clang_type_t clang_type); - - static lldb::clang_type_t - CreateRValueReferenceType (clang::ASTContext *ast_context, - lldb::clang_type_t clang_type); - - lldb::clang_type_t - CreateLValueReferenceType (lldb::clang_type_t clang_type) - { - return ClangASTContext::CreateLValueReferenceType(getASTContext(), clang_type); - } - - lldb::clang_type_t - CreateRValueReferenceType (lldb::clang_type_t clang_type) - { - return ClangASTContext::CreateRValueReferenceType(getASTContext(), clang_type); - } - - lldb::clang_type_t - CreateMemberPointerType (lldb::clang_type_t clang_pointee_type, - lldb::clang_type_t clang_class_type); - - uint64_t - GetPointerBitSize (); - - static bool - IsIntegerType (lldb::clang_type_t clang_type, bool &is_signed); - static bool - IsPointerType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL); - - static bool - IsReferenceType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL); - - static bool - IsPointerOrReferenceType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL); - - static bool - IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - lldb::clang_type_t *target_type = NULL); - - static bool - IsPossibleDynamicType (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - lldb::clang_type_t *dynamic_pointee_type, // Can pass NULL - bool check_cplusplus, - bool check_objc); - - static bool - IsCStringType (lldb::clang_type_t clang_type, uint32_t &length); - - static bool - IsFunctionPointerType (lldb::clang_type_t clang_type); - - static lldb::clang_type_t - GetAsArrayType (lldb::clang_type_t clang_type, - lldb::clang_type_t *member_type, - uint64_t *size, - bool *is_incomplete); - - static bool - IsArrayType (lldb::clang_type_t clang_type, - lldb::clang_type_t *member_type, - uint64_t *size, - bool *is_incomplete) - { - return GetAsArrayType(clang_type, member_type, size, is_incomplete) != 0; - } - - //------------------------------------------------------------------ - // Typedefs - //------------------------------------------------------------------ - lldb::clang_type_t - CreateTypedefType (const char *name, - lldb::clang_type_t clang_type, - clang::DeclContext *decl_ctx); - - //------------------------------------------------------------------ - // Type names - //------------------------------------------------------------------ - static bool - IsFloatingPointType (lldb::clang_type_t clang_type, uint32_t &count, bool &is_complex); - - // true iff this is one of the types that can "fit" - // in a Scalar object - static bool - IsScalarType (lldb::clang_type_t clang_type); - - static bool - IsPointerToScalarType (lldb::clang_type_t clang_type); - - static bool - IsArrayOfScalarType (lldb::clang_type_t clang_type); - - static bool - GetCXXClassName (lldb::clang_type_t clang_type, - std::string &class_name); - - static bool - IsCXXClassType (lldb::clang_type_t clang_type); - - static bool - IsBeingDefined (lldb::clang_type_t clang_type); - - static bool - IsObjCClassType (lldb::clang_type_t clang_type); - - static bool - IsObjCObjectPointerType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type); - - static bool - GetObjCClassName (lldb::clang_type_t clang_type, - std::string &class_name); - - static bool - IsCharType (lldb::clang_type_t clang_type); - - static size_t - GetArraySize (lldb::clang_type_t clang_type); - - //static bool - //ConvertFloatValueToString (clang::ASTContext *ast, - // lldb::clang_type_t clang_type, - // const uint8_t* bytes, - // size_t byte_size, - // int apint_byte_order, - // std::string &float_str); - - static size_t - ConvertStringToFloatValue (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - const char *s, - uint8_t *dst, - size_t dst_size); - - lldb::clang_type_t + ClangASTType GetFloatTypeFromBitSize (size_t bit_size) { return GetFloatTypeFromBitSize (getASTContext(), bit_size); } - static lldb::clang_type_t + static ClangASTType GetFloatTypeFromBitSize (clang::ASTContext *ast, size_t bit_size); - //------------------------------------------------------------------ - // Qualifiers - //------------------------------------------------------------------ - static unsigned - GetTypeQualifiers(lldb::clang_type_t clang_type); protected: //------------------------------------------------------------------ // Classes that inherit from ClangASTContext can see and modify these //------------------------------------------------------------------ std::string m_target_triple; - std::unique_ptr<clang::ASTContext> m_ast_ap; - std::unique_ptr<clang::LangOptions> m_language_options_ap; - std::unique_ptr<clang::FileManager> m_file_manager_ap; - std::unique_ptr<clang::FileSystemOptions> m_file_system_options_ap; - std::unique_ptr<clang::SourceManager> m_source_manager_ap; - std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_ap; - std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_ap; + std::unique_ptr<clang::ASTContext> m_ast_ap; + std::unique_ptr<clang::LangOptions> m_language_options_ap; + std::unique_ptr<clang::FileManager> m_file_manager_ap; + std::unique_ptr<clang::FileSystemOptions> m_file_system_options_ap; + std::unique_ptr<clang::SourceManager> m_source_manager_ap; + std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_ap; + std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_ap; llvm::IntrusiveRefCntPtr<clang::TargetOptions> m_target_options_rp; - std::unique_ptr<clang::TargetInfo> m_target_info_ap; - std::unique_ptr<clang::IdentifierTable> m_identifier_table_ap; - std::unique_ptr<clang::SelectorTable> m_selector_table_ap; - std::unique_ptr<clang::Builtin::Context> m_builtins_ap; + std::unique_ptr<clang::TargetInfo> m_target_info_ap; + std::unique_ptr<clang::IdentifierTable> m_identifier_table_ap; + std::unique_ptr<clang::SelectorTable> m_selector_table_ap; + std::unique_ptr<clang::Builtin::Context> m_builtins_ap; CompleteTagDeclCallback m_callback_tag_decl; CompleteObjCInterfaceDeclCallback m_callback_objc_decl; void * m_callback_baton; + uint32_t m_pointer_byte_size; private: //------------------------------------------------------------------ // For ClangASTContext only diff --git a/lldb/include/lldb/Symbol/ClangASTImporter.h b/lldb/include/lldb/Symbol/ClangASTImporter.h index bc23230fbd9..10df7da893a 100644 --- a/lldb/include/lldb/Symbol/ClangASTImporter.h +++ b/lldb/include/lldb/Symbol/ClangASTImporter.h @@ -14,7 +14,6 @@ #include <set> #include "lldb/lldb-types.h" - #include "clang/AST/ASTImporter.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" diff --git a/lldb/include/lldb/Symbol/ClangASTType.h b/lldb/include/lldb/Symbol/ClangASTType.h index 63a2e1e6f55..d9e754e8ceb 100644 --- a/lldb/include/lldb/Symbol/ClangASTType.h +++ b/lldb/include/lldb/Symbol/ClangASTType.h @@ -13,6 +13,7 @@ #include <string> #include "lldb/lldb-private.h" #include "lldb/Core/ClangForward.h" +#include "clang/AST/Type.h" namespace lldb_private { @@ -29,16 +30,46 @@ namespace lldb_private { class ClangASTType { public: - + enum { + eTypeHasChildren = (1u << 0), + eTypeHasValue = (1u << 1), + eTypeIsArray = (1u << 2), + eTypeIsBlock = (1u << 3), + eTypeIsBuiltIn = (1u << 4), + eTypeIsClass = (1u << 5), + eTypeIsCPlusPlus = (1u << 6), + eTypeIsEnumeration = (1u << 7), + eTypeIsFuncPrototype = (1u << 8), + eTypeIsMember = (1u << 9), + eTypeIsObjC = (1u << 10), + eTypeIsPointer = (1u << 11), + eTypeIsReference = (1u << 12), + eTypeIsStructUnion = (1u << 13), + eTypeIsTemplate = (1u << 14), + eTypeIsTypedef = (1u << 15), + eTypeIsVector = (1u << 16), + eTypeIsScalar = (1u << 17), + eTypeIsInteger = (1u << 18), + eTypeIsFloat = (1u << 19), + eTypeIsComplex = (1u << 20), + eTypeIsSigned = (1u << 21) + }; + + + //---------------------------------------------------------------------- + // Constructors and Destructors + //---------------------------------------------------------------------- ClangASTType (clang::ASTContext *ast_context, lldb::clang_type_t type) : m_type (type), m_ast (ast_context) { } - - ClangASTType (const ClangASTType &tw) : - m_type (tw.m_type), - m_ast (tw.m_ast) + + ClangASTType (clang::ASTContext *ast_context, clang::QualType qual_type); + + ClangASTType (const ClangASTType &rhs) : + m_type (rhs.m_type), + m_ast (rhs.m_ast) { } @@ -48,125 +79,500 @@ public: { } - virtual ~ClangASTType(); + ~ClangASTType(); + //---------------------------------------------------------------------- + // Operators + //---------------------------------------------------------------------- + const ClangASTType & - operator= (const ClangASTType &atb) + operator= (const ClangASTType &rhs) { - m_type = atb.m_type; - m_ast = atb.m_ast; + m_type = rhs.m_type; + m_ast = rhs.m_ast; return *this; } + + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- + + operator bool () const + { + return m_type != NULL && m_ast != NULL; + } + + bool + operator < (const ClangASTType &rhs) const + { + if (m_ast == rhs.m_ast) + return m_type < rhs.m_type; + return m_ast < rhs.m_ast; + } + bool IsValid () const { return m_type != NULL && m_ast != NULL; } + + bool + IsArrayType (ClangASTType *element_type, + uint64_t *size, + bool *is_incomplete) const; - lldb::clang_type_t - GetOpaqueQualType() const - { - return m_type; + bool + IsArrayOfScalarType () const; + + bool + IsAggregateType () const; + + bool + IsBeingDefined () const; + + bool + IsCharType () const; + + bool + IsCompleteType () const; + + bool + IsConst() const; + + bool + IsCStringType (uint32_t &length) const; + + bool + IsCXXClassType () const; + + bool + IsDefined() const; + + bool + IsFloatingPointType (uint32_t &count, bool &is_complex) const; + + bool + IsFunctionType (bool *is_variadic_ptr = NULL) const; + + bool + IsVariadicFunctionType () const; + + bool + IsFunctionPointerType () const; + + bool + IsIntegerType (bool &is_signed) const; + + bool + IsObjCClassType () const; + + bool + IsObjCClassTypeAndHasIVars (bool check_superclass) const; + + bool + IsObjCObjectOrInterfaceType () const; + + bool + IsObjCObjectPointerType (ClangASTType *target_type = NULL); + + bool + IsPolymorphicClass () const; + + bool + IsPossibleCPlusPlusDynamicType (ClangASTType *target_type = NULL) const + { + return IsPossibleDynamicType (target_type, true, false); } + bool + IsPossibleDynamicType (ClangASTType *target_type, // Can pass NULL + bool check_cplusplus, + bool check_objc) const; + + + bool + IsPointerToScalarType () const; + + bool + IsPointerType (ClangASTType *pointee_type = NULL) const; + + bool + IsPointerOrReferenceType (ClangASTType *pointee_type = NULL) const; + + bool + IsReferenceType (ClangASTType *pointee_type = NULL) const; + + bool + IsScalarType () const; + + bool + IsTypedefType () const; + + bool + IsVoidType () const; + + bool + GetCXXClassName (std::string &class_name) const; + + bool + GetObjCClassName (std::string &class_name); + + + //---------------------------------------------------------------------- + // Type Completion + //---------------------------------------------------------------------- + + bool + GetCompleteType () const; + + //---------------------------------------------------------------------- + // AST related queries + //---------------------------------------------------------------------- + + size_t + GetPointerByteSize () const; + + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- + clang::ASTContext * GetASTContext() const - { - return m_ast; + { + return m_ast; } + + ConstString + GetConstQualifiedTypeName () const; - static ClangASTType - GetCanonicalType (clang::ASTContext *ast, lldb::clang_type_t clang_type); + ConstString + GetConstTypeName () const; + + std::string + GetTypeName () const; - ClangASTType - GetCanonicalType () + uint32_t + GetTypeInfo (ClangASTType *pointee_or_element_clang_type = NULL) const; + + lldb::LanguageType + GetMinimumLanguage (); + + lldb::clang_type_t + GetOpaqueQualType() const { - return GetCanonicalType (GetASTContext(), GetOpaqueQualType()); + return m_type; } - ConstString - GetConstTypeName (); + lldb::TypeClass + GetTypeClass () const; - ConstString - GetConstQualifiedTypeName (); + void + SetClangType (clang::ASTContext *ast, lldb::clang_type_t type) + { + m_ast = ast; + m_type = type; + } - static lldb::BasicType - GetBasicTypeEnumeration (const ConstString &name); + void + SetClangType (clang::ASTContext *ast, clang::QualType qual_type); - static ClangASTType - GetBasicType (clang::ASTContext *ast, lldb::BasicType type); + unsigned + GetTypeQualifiers() const; + + //---------------------------------------------------------------------- + // Creating related types + //---------------------------------------------------------------------- - static ClangASTType - GetBasicType (clang::ASTContext *ast, const ConstString &name); + ClangASTType + AddConstModifier () const; - static ConstString - GetConstTypeName (clang::ASTContext *ast, - lldb::clang_type_t clang_type); + ClangASTType + AddRestrictModifier () const; + + ClangASTType + AddVolatileModifier () const; + + // Using the current type, create a new typedef to that type using "typedef_name" + // as the name and "decl_ctx" as the decl context. + ClangASTType + CreateTypedefType (const char *typedef_name, + clang::DeclContext *decl_ctx) const; + + ClangASTType + GetArrayElementType (uint64_t& stride) const; + + ClangASTType + GetCanonicalType () const; - static ConstString - GetConstQualifiedTypeName (clang::ASTContext *ast, - lldb::clang_type_t clang_type); + ClangASTType + GetFullyUnqualifiedType () const; + + // Returns -1 if this isn't a function of if the fucntion doesn't have a prototype + // Returns a value >= 0 if there is a prototype. + int + GetFunctionArgumentCount () const; + + ClangASTType + GetFunctionArgumentTypeAtIndex (size_t idx); - static std::string - GetTypeNameForQualType (clang::ASTContext *ast, - clang::QualType qual_type); + ClangASTType + GetFunctionReturnType () const; + + ClangASTType + GetLValueReferenceType () const; + + ClangASTType + GetNonReferenceType () const; - static std::string - GetTypeNameForOpaqueQualType (clang::ASTContext *ast, - lldb::clang_type_t opaque_qual_type); + ClangASTType + GetPointeeType () const; + + ClangASTType + GetPointerType () const; + + ClangASTType + GetRValueReferenceType () const; - uint64_t - GetClangTypeByteSize (); + // If the current object represents a typedef type, get the underlying type + ClangASTType + GetTypedefedType () const; - static uint64_t - GetClangTypeByteSize (clang::ASTContext *ast_context, - lldb::clang_type_t clang_type); + ClangASTType + RemoveFastQualifiers () const; + //---------------------------------------------------------------------- + // Create related types using the current type's AST + //---------------------------------------------------------------------- + ClangASTType + GetBasicTypeFromAST (lldb::BasicType basic_type) const; + + //---------------------------------------------------------------------- + // Exploring the type + //---------------------------------------------------------------------- + uint64_t - GetClangTypeBitWidth (); + GetByteSize () const; - static uint64_t - GetClangTypeBitWidth (clang::ASTContext *ast_context, lldb::clang_type_t opaque_clang_qual_type); + uint64_t + GetBitSize () const; + + lldb::Encoding + GetEncoding (uint64_t &count) const; + + lldb::Format + GetFormat () const; + + size_t + GetTypeBitAlign () const; + + uint32_t + GetNumChildren (bool omit_empty_base_classes) const; + + lldb::BasicType + GetBasicTypeEnumeration () const; + static lldb::BasicType + GetBasicTypeEnumeration (const ConstString &name); + + uint32_t + GetNumDirectBaseClasses () const; + + uint32_t + GetNumVirtualBaseClasses () const; + + uint32_t + GetNumFields () const; + + ClangASTType + GetDirectBaseClassAtIndex (size_t idx, + uint32_t *bit_offset_ptr) const; + + ClangASTType + GetVirtualBaseClassAtIndex (size_t idx, + uint32_t *bit_offset_ptr) const; + + ClangASTType + GetFieldAtIndex (size_t idx, + std::string& name, + uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) const; + + uint32_t + GetIndexOfFieldWithName (const char* name, + ClangASTType* field_clang_type = NULL, + uint64_t *bit_offset_ptr = NULL, + uint32_t *bitfield_bit_size_ptr = NULL, + bool *is_bitfield_ptr = NULL) const; + + uint32_t + GetNumPointeeChildren () const; + + ClangASTType + GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, + const char *parent_name, + 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) const; + + // 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 (const char *name, + bool omit_empty_base_classes) const; + + // 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<vector<uint32_t>> + // so we catch all names that match a given child name, not just the first. size_t - GetTypeBitAlign (); + GetIndexOfChildMemberWithName (const char *name, + bool omit_empty_base_classes, + std::vector<uint32_t>& child_indexes) const; - static size_t - GetTypeBitAlign (clang::ASTContext *ast_context, lldb::clang_type_t clang_type); + size_t + GetNumTemplateArguments () const; + + ClangASTType + GetTemplateArgument (size_t idx, + lldb::TemplateArgumentKind &kind) const; - lldb::LanguageType - GetMinimumLanguage (); - static lldb::LanguageType - GetMinimumLanguage (clang::ASTContext *ctx, - lldb::clang_type_t clang_type); + //---------------------------------------------------------------------- + // Modifying RecordType + //---------------------------------------------------------------------- + clang::FieldDecl * + AddFieldToRecordType (const char *name, + const ClangASTType &field_type, + lldb::AccessType access, + uint32_t bitfield_bit_size); + + void + BuildIndirectFields (); + + clang::VarDecl * + AddVariableToRecordType (const char *name, + const ClangASTType &var_type, + lldb::AccessType access); + + clang::CXXMethodDecl * + AddMethodToCXXRecordType (const char *name, + const ClangASTType &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::AccessType access, + bool is_virtual, + bool base_of_class); + + static void + DeleteBaseClassSpecifiers (clang::CXXBaseSpecifier **base_classes, + unsigned num_base_classes); + + bool + SetBaseClassesForClassType (clang::CXXBaseSpecifier const * const *base_classes, + unsigned num_base_classes); + + + bool + SetObjCSuperClass (const ClangASTType &superclass_clang_type); + + bool + AddObjCClassProperty (const char *property_name, + const ClangASTType &property_clang_type, + clang::ObjCIvarDecl *ivar_decl, + const char *property_setter_name, + const char *property_getter_name, + uint32_t property_attributes, + ClangASTMetadata *metadata); + + clang::ObjCMethodDecl * + AddMethodToObjCObjectType (const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") + const ClangASTType &method_clang_type, + lldb::AccessType access, + bool is_artificial); - static lldb::TypeClass - GetTypeClass (clang::ASTContext *ast_context, - lldb::clang_type_t clang_type); + clang::DeclContext * + GetDeclContextForType () const; - lldb::TypeClass - GetTypeClass () const - { - return GetTypeClass (GetASTContext(), GetOpaqueQualType()); - } bool - IsPolymorphicClass () - { - return IsPolymorphicClass(GetASTContext(), GetOpaqueQualType()); - } + SetDefaultAccessForRecordFields (int default_accessibility, + int *assigned_accessibilities, + size_t num_assigned_accessibilities); + + bool + SetHasExternalStorage (bool has_extern); + + + //------------------------------------------------------------------ + // clang::TagType + //------------------------------------------------------------------ + + bool + SetTagTypeKind (int kind) const; + + //------------------------------------------------------------------ + // Tag Declarations + //------------------------------------------------------------------ + bool + StartTagDeclarationDefinition (); + + bool + CompleteTagDeclarationDefinition (); - static bool - IsPolymorphicClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type); + //---------------------------------------------------------------------- + // Modifying Enumeration types + //---------------------------------------------------------------------- + bool + AddEnumerationValueToEnumerationType (const ClangASTType &enumerator_qual_type, + const Declaration &decl, + const char *name, + int64_t enum_value, + uint32_t enum_value_bit_size); + + ClangASTType - GetFullyUnqualifiedType (); + GetEnumerationIntegerType () const; + + + //------------------------------------------------------------------ + // Pointers & References + //------------------------------------------------------------------ + + // Call this function using the class type when you want to make a + // member pointer type to pointee_type. + ClangASTType + CreateMemberPointerType (const ClangASTType &pointee_type) const; - static ClangASTType - GetFullyUnqualifiedType (clang::ASTContext *ast_context, lldb::clang_type_t clang_type); + // Converts "s" to a floating point value and place resulting floating + // point bytes in the "dst" buffer. + size_t + ConvertStringToFloatValue (const char *s, + uint8_t *dst, + size_t dst_size) const; + //---------------------------------------------------------------------- + // Dumping types + //---------------------------------------------------------------------- void DumpValue (ExecutionContext *exe_ctx, Stream *s, @@ -181,22 +587,6 @@ public: bool verbose, uint32_t depth); - static void - DumpValue (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_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); - bool DumpTypeValue (Stream *s, lldb::Format format, @@ -207,164 +597,50 @@ public: uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope); - - static bool - DumpTypeValue (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_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); - void DumpSummary (ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size); - - - static void - DumpSummary (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_type, - ExecutionContext *exe_ctx, - Stream *s, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size); - - void - DumpTypeDescription (); // Dump to stdout void - DumpTypeDescription (Stream *s); - - static void - DumpTypeDescription (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_type, - Stream *s); - - lldb::Encoding - GetEncoding (uint64_t &count); - - static lldb::Encoding - GetEncoding (lldb::clang_type_t opaque_clang_qual_type, uint64_t &count); + DumpTypeDescription () const; // Dump to stdout - lldb::Format - GetFormat (); - - static lldb::Format - GetFormat (lldb::clang_type_t opaque_clang_qual_type); - - uint64_t - GetTypeByteSize() const; + void + DumpTypeDescription (Stream *s) const; - static uint64_t - GetTypeByteSize(clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_type); - bool GetValueAsScalar (const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, - Scalar &value); - - static bool - GetValueAsScalar (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_type, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size, - Scalar &value); - - - bool - IsDefined(); - - static bool - IsDefined (lldb::clang_type_t opaque_clang_qual_type); + Scalar &value) const; bool - IsConst(); - - static bool - IsConst (lldb::clang_type_t opaque_clang_qual_type); - - bool SetValueFromScalar (const Scalar &value, Stream &strm); - static bool - SetValueFromScalar (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_type, - const Scalar &value, - Stream &strm); - - void - SetClangType (clang::ASTContext *ast, lldb::clang_type_t type) - { - m_type = type; - m_ast = ast; - } - bool ReadFromMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data); - static bool - ReadFromMemory (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_type, - ExecutionContext *exe_ctx, - lldb::addr_t addr, - AddressType address_type, - DataExtractor &data); - bool WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, StreamString &new_value); - static bool - WriteToMemory (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_type, - ExecutionContext *exe_ctx, - lldb::addr_t addr, - AddressType address_type, - StreamString &new_value); - - lldb::clang_type_t - GetPointeeType () const; - - static lldb::clang_type_t - GetPointeeType (lldb::clang_type_t opaque_clang_qual_type); - - lldb::clang_type_t - GetArrayElementType (uint64_t& stride); - static lldb::clang_type_t - GetArrayElementType (clang::ASTContext* ast, - lldb::clang_type_t opaque_clang_qual_type, - uint64_t& stride); + clang::RecordDecl * + GetAsRecordDecl () const; - lldb::clang_type_t - GetPointerType () const; + clang::CXXRecordDecl * + GetAsCXXRecordDecl () const; - static lldb::clang_type_t - GetPointerType (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_type); - - static lldb::clang_type_t - RemoveFastQualifiers (lldb::clang_type_t); - - static clang::CXXRecordDecl * - GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type); + clang::ObjCInterfaceDecl * + GetAsObjCInterfaceDecl () const; void Clear() @@ -373,9 +649,25 @@ public: m_ast = NULL; } + clang::QualType + GetQualType () const + { + if (m_type) + return clang::QualType::getFromOpaquePtr(m_type); + return clang::QualType(); + } + clang::QualType + GetCanonicalQualType () const + { + if (m_type) + return clang::QualType::getFromOpaquePtr(m_type).getCanonicalType(); + return clang::QualType(); + } + private: lldb::clang_type_t m_type; clang::ASTContext *m_ast; + }; bool operator == (const ClangASTType &lhs, const ClangASTType &rhs); diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h index 55cc819496c..787f81c5ad2 100644 --- a/lldb/include/lldb/Symbol/Function.h +++ b/lldb/include/lldb/Symbol/Function.h @@ -564,19 +564,9 @@ public: //------------------------------------------------------------------ const Type* GetType() const; - - lldb::clang_type_t - GetReturnClangType (); - - // The Number of arguments, or -1 for an unprototyped function. - int - GetArgumentCount (); - - lldb::clang_type_t - GetArgumentTypeAtIndex (size_t idx); - - bool - IsVariadic (); + + ClangASTType + GetClangType (); uint32_t GetPrologueByteSize (); diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index ef433d33684..5b774e3a7d1 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -128,7 +128,7 @@ public: virtual size_t ParseTypes (const SymbolContext& sc) = 0; virtual size_t ParseVariablesForContext (const SymbolContext& sc) = 0; virtual Type* ResolveTypeUID (lldb::user_id_t type_uid) = 0; - virtual lldb::clang_type_t ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) = 0; + virtual bool ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) = 0; virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) { return NULL; } virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) { return NULL; } virtual uint32_t ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) = 0; diff --git a/lldb/include/lldb/Symbol/TaggedASTType.h b/lldb/include/lldb/Symbol/TaggedASTType.h index fbd18972281..c44a5356f86 100644 --- a/lldb/include/lldb/Symbol/TaggedASTType.h +++ b/lldb/include/lldb/Symbol/TaggedASTType.h @@ -20,16 +20,30 @@ namespace lldb_private template <unsigned int C> class TaggedASTType : public ClangASTType { public: + TaggedASTType (const ClangASTType &clang_type) : + ClangASTType(clang_type) + { + } + TaggedASTType (lldb::clang_type_t type, clang::ASTContext *ast_context) : - ClangASTType(ast_context, type) { } + ClangASTType(ast_context, type) + { + } TaggedASTType (const TaggedASTType<C> &tw) : - ClangASTType(tw) { } + ClangASTType(tw) + { + } TaggedASTType () : - ClangASTType() { } + ClangASTType() + { + } - virtual ~TaggedASTType() { } + virtual + ~TaggedASTType() + { + } TaggedASTType<C> &operator= (const TaggedASTType<C> &tw) { diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index e95441b5e30..50b22fe96b9 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -16,6 +16,7 @@ #include "lldb/Core/UserID.h" #include "lldb/Symbol/ClangASTType.h" #include "lldb/Symbol/Declaration.h" + #include <set> namespace lldb_private { @@ -84,7 +85,7 @@ public: lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type, const Declaration& decl, - lldb::clang_type_t clang_qual_type, + const ClangASTType &clang_qual_type, ResolveState clang_type_resolve_state); // This makes an invalid type. Used for functions that return a Type when they @@ -226,23 +227,20 @@ public: // Get the clang type, and resolve definitions for any // class/struct/union/enum types completely. - lldb::clang_type_t + ClangASTType GetClangFullType (); // Get the clang type, and resolve definitions enough so that the type could // have layout performed. This allows ptrs and refs to class/struct/union/enum // types remain forward declarations. - lldb::clang_type_t + ClangASTType GetClangLayoutType (); // Get the clang type and leave class/struct/union/enum types as forward // declarations if they haven't already been fully defined. - lldb::clang_type_t + ClangASTType GetClangForwardType (); - clang::ASTContext * - GetClangAST (); - ClangASTContext & GetClangASTContext (); @@ -264,21 +262,10 @@ public: uint32_t GetEncodingMask (); - - void * - CreateClangPointerType (Type *type); - - void * + + ClangASTType CreateClangTypedefType (Type *typedef_type, Type *base_type); - // For C++98 references (&) - void * - CreateClangLValueReferenceType (Type *type); - - // For C++0x references (&&) - void * - CreateClangRValueReferenceType (Type *type); - bool IsRealObjCClass(); @@ -303,7 +290,7 @@ protected: EncodingDataType m_encoding_uid_type; uint64_t m_byte_size; Declaration m_decl; - lldb::clang_type_t m_clang_type; + ClangASTType m_clang_type; struct Flags { ResolveState clang_type_resolve_state : 2; diff --git a/lldb/include/lldb/Symbol/TypeHierarchyNavigator.h b/lldb/include/lldb/Symbol/TypeHierarchyNavigator.h deleted file mode 100644 index d1657c02686..00000000000 --- a/lldb/include/lldb/Symbol/TypeHierarchyNavigator.h +++ /dev/null @@ -1,75 +0,0 @@ -//===-- TypeHierarchyNavigator.h ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef lldb_TypeHierarchyNavigator_h_ -#define lldb_TypeHierarchyNavigator_h_ - -// C Includes -// C++ Includes - -// Other libraries and framework includes -#include "clang/AST/DeclCXX.h" -#include "clang/AST/Type.h" -#include "clang/AST/DeclObjC.h" - -// Project includes -#include "lldb/lldb-public.h" -#include "lldb/lldb-enumerations.h" - -namespace lldb_private { - -class TypeHierarchyNavigator { - -public: - - enum RelationshipToCurrentType - { - eRootType, - eCXXBaseClass, - eCXXVBaseClass, - eObjCBaseClass, - eStrippedPointer, - eStrippedReference, - eStrippedTypedef - }; - - typedef bool (*TypeHierarchyNavigatorCallback)(const clang::QualType& qual_type, - RelationshipToCurrentType reason_why_here, - void* callback_baton); - - TypeHierarchyNavigator(const clang::QualType& qual_type, - ValueObject& val_obj, - void* callback_baton = NULL) : - m_root_type(qual_type), - m_value_object(val_obj), - m_default_callback_baton(callback_baton) - { - } - - bool - LoopThrough(TypeHierarchyNavigatorCallback callback, - void* callback_baton = NULL); - -private: - - bool - LoopThrough(const clang::QualType& qual_type, - TypeHierarchyNavigatorCallback callback, - RelationshipToCurrentType reason_why_here, - void* callback_baton); - - const clang::QualType& m_root_type; - ValueObject& m_value_object; - void* m_default_callback_baton; - -}; - -} // namespace lldb_private - -#endif // lldb_TypeHierarchyNavigator_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepOut.h b/lldb/include/lldb/Target/ThreadPlanStepOut.h index 9097eff26e2..918c023885a 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepOut.h +++ b/lldb/include/lldb/Target/ThreadPlanStepOut.h @@ -63,7 +63,7 @@ private: bool m_stop_others; lldb::ThreadPlanSP m_step_through_inline_plan_sp; lldb::ThreadPlanSP m_step_out_plan_sp; - Function *m_immediate_step_from_function; + Function *m_immediate_step_from_function; lldb::ValueObjectSP m_return_valobj_sp; friend ThreadPlan * diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index e7c5938406e..96162c7ddc2 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -539,7 +539,6 @@ 9461569C14E358A6003A195C /* SBTypeSummary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568C14E35621003A195C /* SBTypeSummary.cpp */; }; 9461569D14E358A6003A195C /* SBTypeSynthetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568D14E35621003A195C /* SBTypeSynthetic.cpp */; }; 9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */; }; - 9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */; }; 9475C18814E5E9FA001BFC6D /* SBTypeCategory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9475C18714E5E9FA001BFC6D /* SBTypeCategory.cpp */; }; 9475C18914E5EA08001BFC6D /* SBTypeCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 9475C18514E5E9C5001BFC6D /* SBTypeCategory.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9475C18E14E5F834001BFC6D /* SBTypeNameSpecifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9475C18D14E5F834001BFC6D /* SBTypeNameSpecifier.cpp */; }; @@ -1584,8 +1583,6 @@ 9461569514E3567F003A195C /* SBTypeSynthetic.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBTypeSynthetic.i; sourceTree = "<group>"; }; 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = CommandObjectType.cpp; path = source/Commands/CommandObjectType.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 9463D4CE13B179A500C230D4 /* CommandObjectType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CommandObjectType.h; path = source/Commands/CommandObjectType.h; sourceTree = "<group>"; }; - 9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeHierarchyNavigator.cpp; path = source/Symbol/TypeHierarchyNavigator.cpp; sourceTree = "<group>"; }; - 9467E65413C3D98900B3B6F3 /* TypeHierarchyNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeHierarchyNavigator.h; path = include/lldb/Symbol/TypeHierarchyNavigator.h; sourceTree = "<group>"; }; 9475C18514E5E9C5001BFC6D /* SBTypeCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeCategory.h; path = include/lldb/API/SBTypeCategory.h; sourceTree = "<group>"; }; 9475C18714E5E9FA001BFC6D /* SBTypeCategory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBTypeCategory.cpp; path = source/API/SBTypeCategory.cpp; sourceTree = "<group>"; }; 9475C18A14E5EA1C001BFC6D /* SBTypeCategory.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBTypeCategory.i; sourceTree = "<group>"; }; @@ -2753,8 +2750,6 @@ 49BB309511F79450001A4197 /* TaggedASTType.h */, 26BC7C6510F1B6E900F91463 /* Type.h */, 26BC7F2010F1B8EC00F91463 /* Type.cpp */, - 9467E65413C3D98900B3B6F3 /* TypeHierarchyNavigator.h */, - 9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */, 26BC7C6610F1B6E900F91463 /* TypeList.h */, 26BC7F2110F1B8EC00F91463 /* TypeList.cpp */, 49B01A2D15F67B1700666829 /* TypeVendor.h */, @@ -3536,6 +3531,7 @@ 26FFC19E14FC072100087D58 /* DynamicLoaderPOSIXDYLD.h in Headers */, AF254E32170CCC33007AE5C9 /* PlatformDarwinKernel.h in Headers */, 2694E99E14FC0BB30076DE67 /* PlatformFreeBSD.h in Headers */, + 2635878C17822E20004C30BA /* SymbolVendorELF.h in Headers */, 2694E9A514FC0BBD0076DE67 /* PlatformLinux.h in Headers */, 2663E379152BD1890091EC22 /* ReadWriteLock.h in Headers */, 26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */, @@ -4228,7 +4224,6 @@ 4CCA645813B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */, 9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */, 49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */, - 9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */, 26ED3D6D13C563810017D45E /* OptionGroupVariable.cpp in Sources */, 94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */, 94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */, diff --git a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme index 4bc97ecb822..494df2d726a 100644 --- a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme +++ b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme @@ -79,15 +79,16 @@ isEnabled = "YES"> </CommandLineArgument> <CommandLineArgument - argument = "-f" - isEnabled = "YES"> - </CommandLineArgument> - <CommandLineArgument - argument = "ConditionalBreakTestCase.test_with_dwarf_command" + argument = "functionalities/breakpoint/breakpoint_conditions" isEnabled = "YES"> </CommandLineArgument> </CommandLineArguments> <AdditionalOptions> + <AdditionalOption + key = "DYLD_INSERT_LIBRARIES" + value = "/usr/lib/libgmalloc.dylib" + isEnabled = "YES"> + </AdditionalOption> </AdditionalOptions> </LaunchAction> <ProfileAction diff --git a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme index bd7c34c49d2..39343d6ff83 100644 --- a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme +++ b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme @@ -100,6 +100,12 @@ ReferencedContainer = "container:lldb.xcodeproj"> </BuildableReference> </BuildableProductRunnable> + <CommandLineArguments> + <CommandLineArgument + argument = "/private/tmp/a.out" + isEnabled = "YES"> + </CommandLineArgument> + </CommandLineArguments> <EnvironmentVariables> <EnvironmentVariable key = "LLDB_LAUNCH_FLAG_DISABLE_ASLR" diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp index 390ca64e6c1..5f5fc9292cd 100644 --- a/lldb/source/API/SBModule.cpp +++ b/lldb/source/API/SBModule.cpp @@ -506,7 +506,7 @@ SBModule::FindFirstType (const char *name_cstr) sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match)); if (!sb_type.IsValid()) - sb_type = SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name)); + sb_type = SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name)); } return sb_type; } @@ -516,7 +516,7 @@ SBModule::GetBasicType(lldb::BasicType type) { ModuleSP module_sp (GetSP ()); if (module_sp) - return SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type)); + return SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type)); return SBType(); } @@ -549,7 +549,7 @@ SBModule::FindTypes (const char *type) } else { - SBType sb_type(ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name)); + SBType sb_type(ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name)); if (sb_type.IsValid()) retval.Append(sb_type); } diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 7e47fbf0187..f37c8f8a614 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -2153,7 +2153,7 @@ SBTarget::FindFirstType (const char* typename_cstr) // No matches, search for basic typename matches ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); if (clang_ast) - return SBType (ClangASTType::GetBasicType (clang_ast->getASTContext(), const_typename)); + return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename)); } return SBType(); } @@ -2166,7 +2166,7 @@ SBTarget::GetBasicType(lldb::BasicType type) { ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); if (clang_ast) - return SBType (ClangASTType::GetBasicType (clang_ast->getASTContext(), type)); + return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), type)); } return SBType(); } @@ -2233,7 +2233,7 @@ SBTarget::FindTypes (const char* typename_cstr) // No matches, search for basic typename matches ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); if (clang_ast) - sb_type_list.Append (SBType (ClangASTType::GetBasicType (clang_ast->getASTContext(), const_typename))); + sb_type_list.Append (SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename))); } } return sb_type_list; diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp index f6d2fc5568a..372d073acf1 100644 --- a/lldb/source/API/SBType.cpp +++ b/lldb/source/API/SBType.cpp @@ -142,7 +142,7 @@ SBType::GetByteSize() if (!IsValid()) return 0; - return ClangASTType::GetTypeByteSize(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return m_opaque_sp->GetClangASTType().GetByteSize(); } @@ -151,13 +151,7 @@ SBType::IsPointerType() { if (!IsValid()) return false; - - QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); - const clang::Type* typePtr = qt.getTypePtrOrNull(); - - if (typePtr) - return typePtr->isAnyPointerType(); - return false; + return m_opaque_sp->GetClangASTType().IsPointerType(); } bool @@ -165,13 +159,7 @@ SBType::IsReferenceType() { if (!IsValid()) return false; - - QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); - const clang::Type* typePtr = qt.getTypePtrOrNull(); - - if (typePtr) - return typePtr->isReferenceType(); - return false; + return m_opaque_sp->GetClangASTType().IsReferenceType(); } SBType @@ -180,8 +168,7 @@ SBType::GetPointerType() if (!IsValid()) return SBType(); - return SBType(ClangASTType(m_opaque_sp->GetASTContext(), - ClangASTContext::CreatePointerType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()))); + return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointerType())); } SBType @@ -189,13 +176,7 @@ SBType::GetPointeeType() { if (!IsValid()) return SBType(); - - QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); - const clang::Type* typePtr = qt.getTypePtrOrNull(); - - if (typePtr) - return SBType(ClangASTType(m_opaque_sp->GetASTContext(),typePtr->getPointeeType().getAsOpaquePtr())); - return SBType(); + return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointeeType())); } SBType @@ -203,9 +184,7 @@ SBType::GetReferenceType() { if (!IsValid()) return SBType(); - - return SBType(ClangASTType(m_opaque_sp->GetASTContext(), - ClangASTContext::CreateLValueReferenceType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()))); + return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetLValueReferenceType())); } SBType @@ -213,32 +192,23 @@ SBType::GetDereferencedType() { if (!IsValid()) return SBType(); - - QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); - - return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getNonReferenceType().getAsOpaquePtr())); + return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetNonReferenceType())); } bool SBType::IsFunctionType () { - if (IsValid()) - { - QualType qual_type(QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType())); - const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr()); - return func != NULL; - } - return false; + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType().IsFunctionType(); } bool SBType::IsPolymorphicClass () { - if (IsValid()) - { - return ClangASTType::IsPolymorphicClass (m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); - } - return false; + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType().IsPolymorphicClass(); } @@ -248,12 +218,9 @@ SBType::GetFunctionReturnType () { if (IsValid()) { - QualType qual_type(QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType())); - const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr()); - - if (func) - return SBType(ClangASTType(m_opaque_sp->GetASTContext(), - func->getResultType().getAsOpaquePtr())); + ClangASTType return_clang_type (m_opaque_sp->GetClangASTType().GetFunctionReturnType()); + if (return_clang_type.IsValid()) + return SBType(return_clang_type); } return lldb::SBType(); } @@ -281,19 +248,14 @@ SBType::GetUnqualifiedType() { if (!IsValid()) return SBType(); - - QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType())); - return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getUnqualifiedType().getAsOpaquePtr())); + return SBType(m_opaque_sp->GetClangASTType().GetFullyUnqualifiedType()); } lldb::SBType SBType::GetCanonicalType() { if (IsValid()) - { - QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType())); - return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getCanonicalType().getAsOpaquePtr())); - } + return SBType(m_opaque_sp->GetClangASTType().GetCanonicalType()); return SBType(); } @@ -302,15 +264,15 @@ lldb::BasicType SBType::GetBasicType() { if (IsValid()) - return ClangASTContext::GetLLDBBasicTypeEnumeration (m_opaque_sp->GetOpaqueQualType()); + return m_opaque_sp->GetClangASTType().GetBasicTypeEnumeration (); return eBasicTypeInvalid; } SBType -SBType::GetBasicType(lldb::BasicType type) +SBType::GetBasicType(lldb::BasicType basic_type) { if (IsValid()) - return SBType (ClangASTType::GetBasicType (m_opaque_sp->GetASTContext(), type)); + return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetASTContext(), basic_type)); return SBType(); } @@ -318,7 +280,7 @@ uint32_t SBType::GetNumberOfDirectBaseClasses () { if (IsValid()) - return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return m_opaque_sp->GetClangASTType().GetNumDirectBaseClasses(); return 0; } @@ -326,7 +288,7 @@ uint32_t SBType::GetNumberOfVirtualBaseClasses () { if (IsValid()) - return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return m_opaque_sp->GetClangASTType().GetNumVirtualBaseClasses(); return 0; } @@ -334,7 +296,7 @@ uint32_t SBType::GetNumberOfFields () { if (IsValid()) - return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return m_opaque_sp->GetClangASTType().GetNumFields(); return 0; } @@ -361,13 +323,15 @@ SBType::GetDirectBaseClassAtIndex (uint32_t idx) SBTypeMember sb_type_member; if (IsValid()) { - clang::ASTContext* ast = m_opaque_sp->GetASTContext(); - uint32_t bit_offset = 0; - clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); - if (clang_type) + ClangASTType this_type (m_opaque_sp->GetClangASTType ()); + if (this_type.IsValid()) { - TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); - sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); + uint32_t bit_offset = 0; + ClangASTType base_class_type (this_type.GetDirectBaseClassAtIndex(idx, &bit_offset)); + if (base_class_type.IsValid()) + { + sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); + } } } return sb_type_member; @@ -380,14 +344,16 @@ SBType::GetVirtualBaseClassAtIndex (uint32_t idx) SBTypeMember sb_type_member; if (IsValid()) { - uint32_t bit_offset = 0; - clang::ASTContext* ast = m_opaque_sp->GetASTContext(); - clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); - if (clang_type) + ClangASTType this_type (m_opaque_sp->GetClangASTType ()); + if (this_type.IsValid()) { - TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); - sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); - } + uint32_t bit_offset = 0; + ClangASTType base_class_type (this_type.GetVirtualBaseClassAtIndex(idx, &bit_offset)); + if (base_class_type.IsValid()) + { + sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); + } + } } return sb_type_member; } @@ -398,20 +364,30 @@ SBType::GetFieldAtIndex (uint32_t idx) SBTypeMember sb_type_member; if (IsValid()) { - uint64_t bit_offset = 0; - uint32_t bitfield_bit_size = 0; - bool is_bitfield = false; - clang::ASTContext* ast = m_opaque_sp->GetASTContext(); - std::string name_sstr; - clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield); - if (clang_type) + ClangASTType this_type (m_opaque_sp->GetClangASTType ()); + if (this_type.IsValid()) { - ConstString name; - if (!name_sstr.empty()) - name.SetCString(name_sstr.c_str()); - TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); - sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name, bitfield_bit_size, is_bitfield)); - } + uint64_t bit_offset = 0; + uint32_t bitfield_bit_size = 0; + bool is_bitfield = false; + std::string name_sstr; + ClangASTType field_type (this_type.GetFieldAtIndex (idx, + name_sstr, + &bit_offset, + &bitfield_bit_size, + &is_bitfield)); + if (field_type.IsValid()) + { + ConstString name; + if (!name_sstr.empty()) + name.SetCString(name_sstr.c_str()); + sb_type_member.reset (new TypeMemberImpl (TypeImplSP (new TypeImpl(field_type)), + bit_offset, + name, + bitfield_bit_size, + is_bitfield)); + } + } } return sb_type_member; } @@ -420,9 +396,8 @@ bool SBType::IsTypeComplete() { if (!IsValid()) - return false; - - return ClangASTContext::IsCompleteType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return false; + return m_opaque_sp->GetClangASTType().IsCompleteType(); } const char* @@ -430,17 +405,14 @@ SBType::GetName() { if (!IsValid()) return ""; - - return ClangASTType::GetConstTypeName(m_opaque_sp->GetASTContext(), - m_opaque_sp->GetOpaqueQualType()).GetCString(); + return m_opaque_sp->GetClangASTType().GetConstTypeName().GetCString(); } lldb::TypeClass SBType::GetTypeClass () { if (IsValid()) - return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(), - m_opaque_sp->GetOpaqueQualType()); + return m_opaque_sp->GetClangASTType().GetTypeClass(); return lldb::eTypeClassInvalid; } @@ -448,10 +420,7 @@ uint32_t SBType::GetNumberOfTemplateArguments () { if (IsValid()) - { - return ClangASTContext::GetNumTemplateArguments (m_opaque_sp->GetASTContext(), - m_opaque_sp->GetOpaqueQualType()); - } + return m_opaque_sp->GetClangASTType().GetNumTemplateArguments(); return 0; } @@ -461,11 +430,9 @@ SBType::GetTemplateArgumentType (uint32_t idx) if (IsValid()) { TemplateArgumentKind kind = eTemplateArgumentKindNull; - return SBType(ClangASTType(m_opaque_sp->GetASTContext(), - ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), - m_opaque_sp->GetOpaqueQualType(), - idx, - kind))); + ClangASTType template_arg_type = m_opaque_sp->GetClangASTType().GetTemplateArgument (idx, kind); + if (template_arg_type.IsValid()) + return SBType(template_arg_type); } return SBType(); } @@ -476,18 +443,11 @@ SBType::GetTemplateArgumentKind (uint32_t idx) { TemplateArgumentKind kind = eTemplateArgumentKindNull; if (IsValid()) - { - ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), - m_opaque_sp->GetOpaqueQualType(), - idx, - kind); - } + m_opaque_sp->GetClangASTType().GetTemplateArgument (idx, kind); return kind; } - - SBTypeList::SBTypeList() : m_opaque_ap(new TypeListImpl()) { @@ -543,20 +503,6 @@ SBTypeList::~SBTypeList() { } -bool -SBType::IsPointerType (void *opaque_type) -{ - Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - - bool ret_value = ClangASTContext::IsPointerType (opaque_type); - - if (log) - log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false")); - - return ret_value; -} - - SBTypeMember::SBTypeMember() : m_opaque_ap() { diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 33608f3ebeb..aa9b23ac7c6 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -473,7 +473,7 @@ SBValue::GetType() TypeImplSP type_sp; if (value_sp) { - type_sp.reset (new TypeImpl(ClangASTType (value_sp->GetClangAST(), value_sp->GetClangType()))); + type_sp.reset (new TypeImpl(value_sp->GetClangType())); sb_type.SetSP(type_sp); } if (log) @@ -761,17 +761,14 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType s lldb::TypeImplSP type_impl_sp (sb_type.GetSP()); if (value_sp && type_impl_sp) { - ClangASTType pointee_ast_type(type_impl_sp->GetASTContext(), type_impl_sp->GetClangASTType().GetPointerType ()); - lldb::TypeImplSP pointee_type_impl_sp (new TypeImpl(pointee_ast_type)); - if (pointee_type_impl_sp) + ClangASTType pointee_ast_type(type_impl_sp->GetClangASTType().GetPointerType ()); + if (pointee_ast_type) { - lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - pointee_type_impl_sp->GetASTContext(), - pointee_type_impl_sp->GetOpaqueQualType(), + pointee_ast_type, ConstString(name), buffer, lldb::endian::InlHostByteOrder(), @@ -811,8 +808,7 @@ SBValue::CreateValueFromData (const char* name, SBData data, SBType type) ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - type.m_opaque_sp->GetASTContext() , - type.m_opaque_sp->GetOpaqueQualType(), + type.m_opaque_sp->GetClangASTType(), ConstString(name), *data.m_opaque_sp, LLDB_INVALID_ADDRESS); @@ -1187,7 +1183,7 @@ SBValue::GetOpaqueType() ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) - return value_sp->GetClangType(); + return value_sp->GetClangType().GetOpaqueQualType(); return NULL; } @@ -1665,7 +1661,7 @@ SBValue::Watch (bool resolve_location, bool read, bool write, SBError &error) watch_type |= LLDB_WATCH_TYPE_WRITE; Error rc; - ClangASTType type (value_sp->GetClangAST(), value_sp->GetClangType()); + ClangASTType type (value_sp->GetClangType()); WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc); error.SetError(rc); diff --git a/lldb/source/Breakpoint/Watchpoint.cpp b/lldb/source/Breakpoint/Watchpoint.cpp index f18722a9901..45559b1901a 100644 --- a/lldb/source/Breakpoint/Watchpoint.cpp +++ b/lldb/source/Breakpoint/Watchpoint.cpp @@ -54,8 +54,7 @@ Watchpoint::Watchpoint (Target& target, lldb::addr_t addr, uint32_t size, const { // If we don't have a known type, then we force it to unsigned int of the right size. ClangASTContext *ast_context = target.GetScratchClangASTContext(); - clang_type_t clang_type = ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8 * size); - m_type.SetClangType(ast_context->getASTContext(), clang_type); + m_type = ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8 * size); } // Set the initial value of the watched variable: diff --git a/lldb/source/Commands/CommandObjectArgs.cpp b/lldb/source/Commands/CommandObjectArgs.cpp index b2b4cdff13c..05fd53bbe89 100644 --- a/lldb/source/Commands/CommandObjectArgs.cpp +++ b/lldb/source/Commands/CommandObjectArgs.cpp @@ -164,7 +164,7 @@ CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result) const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index); Value value; value.SetValueType(Value::eValueTypeScalar); - void *type; + ClangASTType clang_type; char *int_pos; if ((int_pos = strstr (const_cast<char*>(arg_type_cstr), "int"))) @@ -207,9 +207,9 @@ CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result) return false; } - type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width); + clang_type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width); - if (!type) + if (!clang_type.IsValid()) { result.AppendErrorWithFormat ("Couldn't get Clang type for format %s (%s integer, width %d).\n", arg_type_cstr, @@ -223,9 +223,9 @@ CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result) else if (strchr (arg_type_cstr, '*')) { if (!strcmp (arg_type_cstr, "void*")) - type = ast_context.CreatePointerType (ast_context.GetBuiltInType_void ()); + clang_type = ast_context.GetBasicType(eBasicTypeVoid).GetPointerType(); else if (!strcmp (arg_type_cstr, "char*")) - type = ast_context.GetCStringType (false); + clang_type = ast_context.GetCStringType (false); else { result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr); @@ -240,8 +240,7 @@ CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result) return false; } - value.SetContext (Value::eContextTypeClangType, type); - + value.SetClangType (clang_type); value_list.PushValue(value); } diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp index 97ab957ff73..eea0cf5001f 100644 --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -543,15 +543,15 @@ protected: else { TypeSP type_sp (type_list.GetTypeAtIndex(0)); - clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType()); + clang_ast_type = type_sp->GetClangFullType(); } } while (pointer_count > 0) { - clang_type_t pointer_type = ClangASTContext::CreatePointerType (clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()); - if (pointer_type) - clang_ast_type.SetClangType (clang_ast_type.GetASTContext(), pointer_type); + ClangASTType pointer_type = clang_ast_type.GetPointerType(); + if (pointer_type.IsValid()) + clang_ast_type = pointer_type; else { result.AppendError ("unable make a pointer type\n"); @@ -561,7 +561,7 @@ protected: --pointer_count; } - m_format_options.GetByteSizeValue() = clang_ast_type.GetClangTypeByteSize(); + m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize(); if (m_format_options.GetByteSizeValue() == 0) { @@ -675,7 +675,7 @@ protected: if (m_format_options.GetFormatValue().OptionWasSet() == false) m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault); - bytes_read = clang_ast_type.GetTypeByteSize() * m_format_options.GetCountValue().GetCurrentValue(); + bytes_read = clang_ast_type.GetByteSize() * m_format_options.GetCountValue().GetCurrentValue(); } else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString) { diff --git a/lldb/source/Commands/CommandObjectVersion.cpp b/lldb/source/Commands/CommandObjectVersion.cpp index ea1930e0ffd..2d950a89c9b 100644 --- a/lldb/source/Commands/CommandObjectVersion.cpp +++ b/lldb/source/Commands/CommandObjectVersion.cpp @@ -38,8 +38,16 @@ CommandObjectVersion::~CommandObjectVersion () bool CommandObjectVersion::DoExecute (Args& args, CommandReturnObject &result) { - result.AppendMessageWithFormat ("%s\n", lldb_private::GetVersion()); - result.SetStatus (eReturnStatusSuccessFinishResult); + if (args.GetArgumentCount() == 0) + { + result.AppendMessageWithFormat ("%s\n", lldb_private::GetVersion()); + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendError("the version command takes no arguments."); + result.SetStatus (eReturnStatusFailed); + } return true; } diff --git a/lldb/source/Commands/CommandObjectVersion.h b/lldb/source/Commands/CommandObjectVersion.h index 035c65e6674..1fdbed60c65 100644 --- a/lldb/source/Commands/CommandObjectVersion.h +++ b/lldb/source/Commands/CommandObjectVersion.h @@ -34,7 +34,7 @@ public: protected: virtual bool DoExecute (Args& args, - CommandReturnObject &result); + CommandReturnObject &result); }; diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp index 7a6a47e60d0..c1f0c41e34f 100644 --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -1050,7 +1050,7 @@ protected: valobj_sp = valobj_list.GetValueObjectAtIndex(0); } - ClangASTType type; + ClangASTType clang_type; if (valobj_sp) { @@ -1063,7 +1063,7 @@ protected: size = m_option_watchpoint.watch_size == 0 ? valobj_sp->GetByteSize() : m_option_watchpoint.watch_size; } - type.SetClangType(valobj_sp->GetClangAST(), valobj_sp->GetClangType()); + clang_type = valobj_sp->GetClangType(); } else { @@ -1080,7 +1080,7 @@ protected: uint32_t watch_type = m_option_watchpoint.watch_type; error.Clear(); - Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get(); + Watchpoint *wp = target->CreateWatchpoint(addr, size, &clang_type, watch_type, error).get(); if (wp) { wp->SetWatchSpec(command.GetArgumentAtIndex(0)); @@ -1292,12 +1292,10 @@ protected: // Fetch the type from the value object, the type of the watched object is the pointee type /// of the expression, so convert to that if we found a valid type. - ClangASTType type(valobj_sp->GetClangAST(), valobj_sp->GetClangType()); - if (type.IsValid()) - type.SetClangType(type.GetASTContext(), type.GetPointeeType()); + ClangASTType clang_type(valobj_sp->GetClangType()); Error error; - Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get(); + Watchpoint *wp = target->CreateWatchpoint(addr, size, &clang_type, watch_type, error).get(); if (wp) { Stream &output_stream = result.GetOutputStream(); diff --git a/lldb/source/Core/DataBufferHeap.cpp b/lldb/source/Core/DataBufferHeap.cpp index 3692aa90a5b..74893767d14 100644 --- a/lldb/source/Core/DataBufferHeap.cpp +++ b/lldb/source/Core/DataBufferHeap.cpp @@ -101,5 +101,9 @@ DataBufferHeap::CopyData (const void *src, uint64_t src_len) m_data.clear(); } - - +void +DataBufferHeap::Clear() +{ + buffer_t empty; + m_data.swap(empty); +} diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 4a6477f280a..01e5ae3a4bf 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -1632,9 +1632,10 @@ FormatPromptRecurse } // TODO use flags for these - bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL); - bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType()); - bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType()); + const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL); + bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0; + bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0; + bool is_aggregate = target->GetClangType().IsAggregateType(); if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions { diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp index 9c696081a04..3fe75d3d4ce 100644 --- a/lldb/source/Core/Value.cpp +++ b/lldb/source/Core/Value.cpp @@ -33,8 +33,10 @@ using namespace lldb_private; Value::Value() : m_value (), - m_value_type (eValueTypeScalar), + m_vector (), + m_clang_type (), m_context (NULL), + m_value_type (eValueTypeScalar), m_context_type (eContextTypeInvalid), m_data_buffer () { @@ -42,8 +44,10 @@ Value::Value() : Value::Value(const Scalar& scalar) : m_value (scalar), - m_value_type (eValueTypeScalar), + m_vector (), + m_clang_type (), m_context (NULL), + m_value_type (eValueTypeScalar), m_context_type (eContextTypeInvalid), m_data_buffer () { @@ -52,8 +56,10 @@ Value::Value(const Scalar& scalar) : Value::Value(const uint8_t *bytes, int len) : m_value (), - m_value_type (eValueTypeHostAddress), + m_vector (), + m_clang_type (), m_context (NULL), + m_value_type (eValueTypeHostAddress), m_context_type (eContextTypeInvalid), m_data_buffer () { @@ -62,10 +68,13 @@ Value::Value(const uint8_t *bytes, int len) : } Value::Value(const Value &v) : - m_value(v.m_value), - m_value_type(v.m_value_type), - m_context(v.m_context), - m_context_type(v.m_context_type) + m_value (v.m_value), + m_vector (v.m_vector), + m_clang_type (v.m_clang_type), + m_context (v.m_context), + m_value_type (v.m_value_type), + m_context_type (v.m_context_type), + m_data_buffer () { if ((uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)v.m_data_buffer.GetBytes()) { @@ -82,8 +91,10 @@ Value::operator=(const Value &rhs) if (this != &rhs) { m_value = rhs.m_value; - m_value_type = rhs.m_value_type; + m_vector = rhs.m_vector; + m_clang_type = rhs.m_clang_type; m_context = rhs.m_context; + m_value_type = rhs.m_value_type; m_context_type = rhs.m_context_type; if ((uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)rhs.m_data_buffer.GetBytes()) { @@ -152,72 +163,42 @@ Value::ResizeData(size_t len) } bool -Value::ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context) +Value::ValueOf(ExecutionContext *exe_ctx) { switch (m_context_type) { case eContextTypeInvalid: - case eContextTypeClangType: // clang::Type * case eContextTypeRegisterInfo: // RegisterInfo * case eContextTypeLLDBType: // Type * break; case eContextTypeVariable: // Variable * - ResolveValue(exe_ctx, ast_context); + ResolveValue(exe_ctx); return true; } return false; } uint64_t -Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr) +Value::GetValueByteSize (Error *error_ptr) { uint64_t byte_size = 0; switch (m_context_type) { - case eContextTypeInvalid: - // If we have no context, there is no way to know how much memory to read - if (error_ptr) - error_ptr->SetErrorString ("Invalid context type, there is no way to know how much memory to read."); - break; - - case eContextTypeClangType: - if (ast_context == NULL) - { - if (error_ptr) - error_ptr->SetErrorString ("Can't determine size of opaque clang type with NULL ASTContext *."); - } - else - { - byte_size = ClangASTType(ast_context, m_context).GetClangTypeByteSize(); - } - break; - case eContextTypeRegisterInfo: // RegisterInfo * if (GetRegisterInfo()) byte_size = GetRegisterInfo()->byte_size; - else if (error_ptr) - error_ptr->SetErrorString ("Can't determine byte size with NULL RegisterInfo *."); - break; - - case eContextTypeLLDBType: // Type * - if (GetType()) - byte_size = GetType()->GetByteSize(); - else if (error_ptr) - error_ptr->SetErrorString ("Can't determine byte size with NULL Type *."); break; + case eContextTypeInvalid: + case eContextTypeLLDBType: // Type * case eContextTypeVariable: // Variable * - if (GetVariable()) - { - if (GetVariable()->GetType()) - byte_size = GetVariable()->GetType()->GetByteSize(); - else if (error_ptr) - error_ptr->SetErrorString ("Can't determine byte size with NULL Type *."); + { + const ClangASTType &ast_type = GetClangType(); + if (ast_type.IsValid()) + byte_size = ast_type.GetByteSize(); } - else if (error_ptr) - error_ptr->SetErrorString ("Can't determine byte size with NULL Variable *."); break; } @@ -236,32 +217,48 @@ Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr) return byte_size; } -clang_type_t +const ClangASTType & Value::GetClangType () { - switch (m_context_type) + if (!m_clang_type.IsValid()) { - case eContextTypeInvalid: - break; - - case eContextTypeClangType: - return m_context; + switch (m_context_type) + { + case eContextTypeInvalid: + break; - case eContextTypeRegisterInfo: - break; // TODO: Eventually convert into a clang type? + case eContextTypeRegisterInfo: + break; // TODO: Eventually convert into a clang type? - case eContextTypeLLDBType: - if (GetType()) - return GetType()->GetClangForwardType(); - break; + case eContextTypeLLDBType: + { + Type *lldb_type = GetType(); + if (lldb_type) + m_clang_type = lldb_type->GetClangForwardType(); + } + break; - case eContextTypeVariable: - if (GetVariable()) - return GetVariable()->GetType()->GetClangForwardType(); - break; + case eContextTypeVariable: + { + Variable *variable = GetVariable(); + if (variable) + { + Type *variable_type = variable->GetType(); + if (variable_type) + m_clang_type = variable_type->GetClangForwardType(); + } + } + break; + } } - return NULL; + return m_clang_type; +} + +void +Value::SetClangType (const ClangASTType &clang_type) +{ + m_clang_type = clang_type; } lldb::Format @@ -269,25 +266,19 @@ Value::GetValueDefaultFormat () { switch (m_context_type) { - case eContextTypeInvalid: - break; - - case eContextTypeClangType: - return ClangASTType::GetFormat (m_context); - case eContextTypeRegisterInfo: if (GetRegisterInfo()) return GetRegisterInfo()->format; break; + case eContextTypeInvalid: case eContextTypeLLDBType: - if (GetType()) - return GetType()->GetFormat(); - break; - case eContextTypeVariable: - if (GetVariable()) - return GetVariable()->GetType()->GetFormat(); + { + const ClangASTType &ast_type = GetClangType(); + if (ast_type.IsValid()) + return ast_type.GetFormat(); + } break; } @@ -326,8 +317,7 @@ Value::GetData (DataExtractor &data) Error Value::GetValueAsData (ExecutionContext *exe_ctx, - clang::ASTContext *ast_context, - DataExtractor &data, + DataExtractor &data, uint32_t data_offset, Module *module) { @@ -337,15 +327,12 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, lldb::addr_t address = LLDB_INVALID_ADDRESS; AddressType address_type = eAddressTypeFile; Address file_so_addr; + const ClangASTType &ast_type = GetClangType(); switch (m_value_type) { case eValueTypeVector: - if (m_context_type == eContextTypeClangType && ast_context) - { - ClangASTType ptr_type (ast_context, ClangASTContext::GetVoidPtrType(ast_context, false)); - uint64_t ptr_byte_size = ptr_type.GetClangTypeByteSize(); - data.SetAddressByteSize (ptr_byte_size); - } + if (ast_type.IsValid()) + data.SetAddressByteSize (ast_type.GetPointerByteSize()); else data.SetAddressByteSize(sizeof(void *)); data.SetData(m_vector.bytes, m_vector.length, m_vector.byte_order); @@ -353,12 +340,8 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, case eValueTypeScalar: data.SetByteOrder (lldb::endian::InlHostByteOrder()); - if (m_context_type == eContextTypeClangType && ast_context) - { - ClangASTType ptr_type (ast_context, ClangASTContext::GetVoidPtrType(ast_context, false)); - uint64_t ptr_byte_size = ptr_type.GetClangTypeByteSize(); - data.SetAddressByteSize (ptr_byte_size); - } + if (ast_type.IsValid()) + data.SetAddressByteSize (ast_type.GetPointerByteSize()); else data.SetAddressByteSize(sizeof(void *)); if (m_value.GetData (data)) @@ -562,7 +545,7 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, } // If we got here, we need to read the value from memory - size_t byte_size = GetValueByteSize (ast_context, &error); + size_t byte_size = GetValueByteSize (&error); // Bail if we encountered any errors getting the byte size if (error.Fail()) @@ -637,10 +620,10 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, } Scalar & -Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context) -{ - void *opaque_clang_qual_type = GetClangType(); - if (opaque_clang_qual_type) +Value::ResolveValue(ExecutionContext *exe_ctx) +{ + const ClangASTType &clang_type = GetClangType(); + if (clang_type.IsValid()) { switch (m_value_type) { @@ -654,11 +637,11 @@ Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context) { DataExtractor data; lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS); - Error error (GetValueAsData (exe_ctx, ast_context, data, 0, NULL)); + Error error (GetValueAsData (exe_ctx, data, 0, NULL)); if (error.Success()) { Scalar scalar; - if (ClangASTType::GetValueAsScalar (ast_context, opaque_clang_qual_type, data, 0, data.GetByteSize(), scalar)) + if (clang_type.GetValueAsScalar (data, 0, data.GetByteSize(), scalar)) { m_value = scalar; m_value_type = eValueTypeScalar; @@ -695,6 +678,19 @@ Value::GetVariable() return NULL; } +void +Value::Clear() +{ + m_value.Clear(); + m_vector.Clear(); + m_clang_type.Clear(); + m_value_type = eValueTypeScalar; + m_context = NULL; + m_context_type = eContextTypeInvalid; + m_data_buffer.Clear(); +} + + const char * Value::GetValueTypeAsCString (ValueType value_type) { @@ -715,7 +711,6 @@ Value::GetContextTypeAsCString (ContextType context_type) switch (context_type) { case eContextTypeInvalid: return "invalid"; - case eContextTypeClangType: return "clang::Type *"; case eContextTypeRegisterInfo: return "RegisterInfo *"; case eContextTypeLLDBType: return "Type *"; case eContextTypeVariable: return "Variable *"; @@ -763,3 +758,4 @@ ValueList::Clear () { m_values.clear(); } + diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index e2a87d4270b..a30cc1306c6 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -283,101 +283,80 @@ ValueObject::ClearDynamicTypeInformation () ClangASTType ValueObject::MaybeCalculateCompleteType () { - ClangASTType ret(GetClangASTImpl(), GetClangTypeImpl()); + ClangASTType clang_type(GetClangTypeImpl()); if (m_did_calculate_complete_objc_class_type) { if (m_override_type.IsValid()) return m_override_type; else - return ret; + return clang_type; } - clang_type_t ast_type(GetClangTypeImpl()); - clang_type_t class_type; - bool is_pointer_type; + ClangASTType class_type; + bool is_pointer_type = false; - if (ClangASTContext::IsObjCObjectPointerType(ast_type, &class_type)) + if (clang_type.IsObjCObjectPointerType(&class_type)) { is_pointer_type = true; } - else if (ClangASTContext::IsObjCClassType(ast_type)) + else if (clang_type.IsObjCObjectOrInterfaceType()) { - is_pointer_type = false; - class_type = ast_type; + class_type = clang_type; } else { - return ret; + return clang_type; } m_did_calculate_complete_objc_class_type = true; - if (!class_type) - return ret; - - std::string class_name; - - if (!ClangASTContext::GetObjCClassName(class_type, class_name)) - return ret; - - ProcessSP process_sp(GetUpdatePoint().GetExecutionContextRef().GetProcessSP()); - - if (!process_sp) - return ret; - - ObjCLanguageRuntime *objc_language_runtime(process_sp->GetObjCLanguageRuntime()); - - if (!objc_language_runtime) - return ret; - - ConstString class_name_cs(class_name.c_str()); - - TypeSP complete_objc_class_type_sp = objc_language_runtime->LookupInCompleteClassCache(class_name_cs); - - if (!complete_objc_class_type_sp) - return ret; - - ClangASTType complete_class(complete_objc_class_type_sp->GetClangAST(), - complete_objc_class_type_sp->GetClangFullType()); - - if (!ClangASTContext::GetCompleteType(complete_class.GetASTContext(), - complete_class.GetOpaqueQualType())) - return ret; - - if (is_pointer_type) + if (class_type) { - clang_type_t pointer_type = ClangASTContext::CreatePointerType(complete_class.GetASTContext(), - complete_class.GetOpaqueQualType()); + ConstString class_name (class_type.GetConstTypeName()); - m_override_type = ClangASTType(complete_class.GetASTContext(), - pointer_type); - } - else - { - m_override_type = complete_class; + if (class_name) + { + ProcessSP process_sp(GetUpdatePoint().GetExecutionContextRef().GetProcessSP()); + + if (process_sp) + { + ObjCLanguageRuntime *objc_language_runtime(process_sp->GetObjCLanguageRuntime()); + + if (objc_language_runtime) + { + TypeSP complete_objc_class_type_sp = objc_language_runtime->LookupInCompleteClassCache(class_name); + + if (complete_objc_class_type_sp) + { + ClangASTType complete_class(complete_objc_class_type_sp->GetClangFullType()); + + if (complete_class.GetCompleteType()) + { + if (is_pointer_type) + { + m_override_type = complete_class.GetPointerType(); + } + else + { + m_override_type = complete_class; + } + + if (m_override_type.IsValid()) + return m_override_type; + } + } + } + } + } } - - if (m_override_type.IsValid()) - return m_override_type; - else - return ret; -} - -clang::ASTContext * -ValueObject::GetClangAST () -{ - ClangASTType type = MaybeCalculateCompleteType(); - - return type.GetASTContext(); + return clang_type; } -lldb::clang_type_t +ClangASTType ValueObject::GetClangType () { - ClangASTType type = MaybeCalculateCompleteType(); - - return type.GetOpaqueQualType(); + return MaybeCalculateCompleteType(); } DataExtractor & @@ -474,7 +453,7 @@ ValueObject::ResolveValue (Scalar &scalar) { ExecutionContext exe_ctx (GetExecutionContextRef()); Value tmp_value(m_value); - scalar = tmp_value.ResolveValue(&exe_ctx, GetClangAST ()); + scalar = tmp_value.ResolveValue(&exe_ctx); if (scalar.IsValid()) { const uint32_t bitfield_bit_size = GetBitfieldBitSize(); @@ -620,10 +599,7 @@ size_t ValueObject::GetIndexOfChildWithName (const ConstString &name) { bool omit_empty_base_classes = true; - return ClangASTContext::GetIndexOfChildWithName (GetClangAST(), - GetClangType(), - name.GetCString(), - omit_empty_base_classes); + return GetClangType().GetIndexOfChildWithName (name.GetCString(), omit_empty_base_classes); } ValueObjectSP @@ -639,14 +615,10 @@ ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create) UpdateValueIfNeeded(false); std::vector<uint32_t> child_indexes; - clang::ASTContext *clang_ast = GetClangAST(); - void *clang_type = GetClangType(); bool omit_empty_base_classes = true; - const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast, - clang_type, - name.GetCString(), - omit_empty_base_classes, - child_indexes); + const size_t num_child_indexes = GetClangType().GetIndexOfChildMemberWithName (name.GetCString(), + omit_empty_base_classes, + child_indexes); if (num_child_indexes > 0) { std::vector<uint32_t>::const_iterator pos = child_indexes.begin (); @@ -689,9 +661,9 @@ ValueObject::MightHaveChildren() const uint32_t type_info = GetTypeInfo(); if (type_info) { - if (type_info & (ClangASTContext::eTypeHasChildren | - ClangASTContext::eTypeIsPointer | - ClangASTContext::eTypeIsReference)) + if (type_info & (ClangASTType::eTypeHasChildren | + ClangASTType::eTypeIsPointer | + ClangASTType::eTypeIsReference)) has_children = true; } else @@ -731,27 +703,23 @@ ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_ bool child_is_deref_of_parent = false; const bool transparent_pointers = synthetic_array_member == false; - clang::ASTContext *clang_ast = GetClangAST(); - clang_type_t clang_type = GetClangType(); - clang_type_t child_clang_type; + ClangASTType child_clang_type; ExecutionContext exe_ctx (GetExecutionContextRef()); - child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, - clang_ast, - GetName().GetCString(), - clang_type, - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name_str, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); + child_clang_type = GetClangType().GetChildClangTypeAtIndex (&exe_ctx, + GetName().GetCString(), + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name_str, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); if (child_clang_type) { if (synthetic_index) @@ -762,7 +730,6 @@ ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_ child_name.SetCString (child_name_str.c_str()); valobj = new ValueObjectChild (*this, - clang_ast, child_clang_type, child_name, child_byte_size, @@ -809,19 +776,14 @@ ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr, } else { - clang_type_t clang_type = GetClangType(); + ClangASTType clang_type = GetClangType(); // Do some default printout for function pointers if (clang_type) { - StreamString sstr; - clang_type_t elem_or_pointee_clang_type; - const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, - GetClangAST(), - &elem_or_pointee_clang_type)); - - if (ClangASTContext::IsFunctionPointerType (clang_type)) + if (clang_type.IsFunctionPointerType ()) { + StreamString sstr; AddressType func_ptr_address_type = eAddressTypeInvalid; addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type); if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) @@ -885,15 +847,15 @@ ValueObject::GetSummaryAsCString () bool ValueObject::IsCStringContainer(bool check_pointer) { - clang_type_t elem_or_pointee_clang_type; - const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type)); - bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) && - ClangASTContext::IsCharType (elem_or_pointee_clang_type)); + ClangASTType pointee_or_element_clang_type; + const Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type)); + bool is_char_arr_ptr (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) && + pointee_or_element_clang_type.IsCharType ()); if (!is_char_arr_ptr) return false; if (!check_pointer) return true; - if (type_flags.Test(ClangASTContext::eTypeIsArray)) + if (type_flags.Test(ClangASTType::eTypeIsArray)) return true; addr_t cstr_address = LLDB_INVALID_ADDRESS; AddressType cstr_address_type = eAddressTypeInvalid; @@ -906,23 +868,18 @@ ValueObject::GetPointeeData (DataExtractor& data, uint32_t item_idx, uint32_t item_count) { - clang_type_t pointee_or_element_clang_type; + ClangASTType pointee_or_element_clang_type; const uint32_t type_info = GetTypeInfo (&pointee_or_element_clang_type); - const bool is_pointer_type = type_info & ClangASTContext::eTypeIsPointer; - const bool is_array_type = type_info & ClangASTContext::eTypeIsArray; + const bool is_pointer_type = type_info & ClangASTType::eTypeIsPointer; + const bool is_array_type = type_info & ClangASTType::eTypeIsArray; if (!(is_pointer_type || is_array_type)) return 0; if (item_count == 0) return 0; - clang::ASTContext *ast = GetClangAST(); - ClangASTType pointee_or_element_type(ast, pointee_or_element_clang_type); - - const uint64_t item_type_size = pointee_or_element_type.GetClangTypeByteSize(); - + const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize(); const uint64_t bytes = item_count * item_type_size; - const uint64_t offset = item_idx * item_type_size; if (item_idx == 0 && item_count == 1) // simply a deref @@ -996,8 +953,7 @@ ValueObject::GetPointeeData (DataExtractor& data, break; case eAddressTypeHost: { - ClangASTType valobj_type(ast, GetClangType()); - uint64_t max_bytes = valobj_type.GetClangTypeByteSize(); + const uint64_t max_bytes = GetClangType().GetByteSize(); if (max_bytes > offset) { size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes); @@ -1019,7 +975,7 @@ ValueObject::GetData (DataExtractor& data) { UpdateValueIfNeeded(false); ExecutionContext exe_ctx (GetExecutionContextRef()); - Error error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), data, 0, GetModule().get()); + Error error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get()); if (error.Fail()) { if (m_data.GetByteSize()) @@ -1050,7 +1006,7 @@ ValueObject::SetData (DataExtractor &data, Error &error) } uint64_t count = 0; - Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count); + const Encoding encoding = GetClangType().GetEncoding(count); const size_t byte_size = GetByteSize(); @@ -1163,25 +1119,29 @@ ValueObject::ReadPointedString (Stream& s, size_t bytes_read = 0; size_t total_bytes_read = 0; - clang_type_t clang_type = GetClangType(); - clang_type_t elem_or_pointee_clang_type; + ClangASTType clang_type = GetClangType(); + ClangASTType elem_or_pointee_clang_type; const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type)); - if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) && - ClangASTContext::IsCharType (elem_or_pointee_clang_type)) + if (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) && + elem_or_pointee_clang_type.IsCharType ()) { addr_t cstr_address = LLDB_INVALID_ADDRESS; AddressType cstr_address_type = eAddressTypeInvalid; size_t cstr_len = 0; bool capped_data = false; - if (type_flags.Test (ClangASTContext::eTypeIsArray)) + if (type_flags.Test (ClangASTType::eTypeIsArray)) { // We have an array - cstr_len = ClangASTContext::GetArraySize (clang_type); - if (cstr_len > max_length) + uint64_t array_size = 0; + if (clang_type.IsArrayType(NULL, &array_size, NULL)) { - capped_data = true; - cstr_len = max_length; + cstr_len = array_size; + if (cstr_len > max_length) + { + capped_data = true; + cstr_len = max_length; + } } cstr_address = GetAddressOf (true, &cstr_address_type); } @@ -1318,12 +1278,11 @@ ValueObject::GetObjectDescription () if (runtime == NULL) { // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway... - clang_type_t opaque_qual_type = GetClangType(); - if (opaque_qual_type != NULL) + ClangASTType clang_type = GetClangType(); + if (clang_type) { bool is_signed; - if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed) - || ClangASTContext::IsPointerType (opaque_qual_type)) + if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType ()) { runtime = process->GetLanguageRuntime(eLanguageTypeObjC); } @@ -1345,94 +1304,79 @@ bool ValueObject::GetValueAsCString (lldb::Format format, std::string& destination) { - if (ClangASTContext::IsAggregateType (GetClangType()) == false && - UpdateValueIfNeeded(false)) + if (GetClangType().IsAggregateType () == false && UpdateValueIfNeeded(false)) { const Value::ContextType context_type = m_value.GetContextType(); - switch (context_type) + if (context_type == Value::eContextTypeRegisterInfo) { - case Value::eContextTypeClangType: - case Value::eContextTypeLLDBType: - case Value::eContextTypeVariable: + const RegisterInfo *reg_info = m_value.GetRegisterInfo(); + if (reg_info) { - clang_type_t clang_type = GetClangType (); - if (clang_type) + ExecutionContext exe_ctx (GetExecutionContextRef()); + + StreamString reg_sstr; + m_data.Dump (®_sstr, + 0, + format, + reg_info->byte_size, + 1, + UINT32_MAX, + LLDB_INVALID_ADDRESS, + 0, + 0, + exe_ctx.GetBestExecutionContextScope()); + destination.swap(reg_sstr.GetString()); + } + } + else + { + ClangASTType clang_type = GetClangType (); + if (clang_type) + { + // put custom bytes to display in this DataExtractor to override the default value logic + lldb_private::DataExtractor special_format_data; + if (format == eFormatCString) { - // put custom bytes to display in this DataExtractor to override the default value logic - lldb_private::DataExtractor special_format_data; - clang::ASTContext* ast = GetClangAST(); - if (format == eFormatCString) + Flags type_flags(clang_type.GetTypeInfo(NULL)); + if (type_flags.Test(ClangASTType::eTypeIsPointer) && !type_flags.Test(ClangASTType::eTypeIsObjC)) { - Flags type_flags(ClangASTContext::GetTypeInfo(clang_type, ast, NULL)); - if (type_flags.Test(ClangASTContext::eTypeIsPointer) && !type_flags.Test(ClangASTContext::eTypeIsObjC)) + // if we are dumping a pointer as a c-string, get the pointee data as a string + TargetSP target_sp(GetTargetSP()); + if (target_sp) { - // if we are dumping a pointer as a c-string, get the pointee data as a string - TargetSP target_sp(GetTargetSP()); - if (target_sp) - { - size_t max_len = target_sp->GetMaximumSizeOfStringSummary(); - Error error; - DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0)); - Address address(GetPointerValue()); - if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success()) - special_format_data.SetData(buffer_sp); - } + size_t max_len = target_sp->GetMaximumSizeOfStringSummary(); + Error error; + DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0)); + Address address(GetPointerValue()); + if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success()) + special_format_data.SetData(buffer_sp); } } - - StreamString sstr; - ExecutionContext exe_ctx (GetExecutionContextRef()); - ClangASTType::DumpTypeValue (ast, // The clang AST - clang_type, // The clang type to display - &sstr, // The stream to use for display - format, // Format to display this type with - special_format_data.GetByteSize() ? - special_format_data: m_data, // Data to extract from - 0, // Byte offset into "m_data" - GetByteSize(), // Byte size of item in "m_data" - GetBitfieldBitSize(), // Bitfield bit size - GetBitfieldBitOffset(), // Bitfield bit offset - exe_ctx.GetBestExecutionContextScope()); - // Don't set the m_error to anything here otherwise - // we won't be able to re-format as anything else. The - // code for ClangASTType::DumpTypeValue() should always - // return something, even if that something contains - // an error messsage. "m_error" is used to detect errors - // when reading the valid object, not for formatting errors. - if (sstr.GetString().empty()) - destination.clear(); - else - destination.swap(sstr.GetString()); } - } - break; - case Value::eContextTypeRegisterInfo: - { - const RegisterInfo *reg_info = m_value.GetRegisterInfo(); - if (reg_info) - { - ExecutionContext exe_ctx (GetExecutionContextRef()); - - StreamString reg_sstr; - m_data.Dump (®_sstr, - 0, - format, - reg_info->byte_size, - 1, - UINT32_MAX, - LLDB_INVALID_ADDRESS, - 0, - 0, - exe_ctx.GetBestExecutionContextScope()); - destination.swap(reg_sstr.GetString()); - } + StreamString sstr; + ExecutionContext exe_ctx (GetExecutionContextRef()); + clang_type.DumpTypeValue (&sstr, // The stream to use for display + format, // Format to display this type with + special_format_data.GetByteSize() ? + special_format_data: m_data, // Data to extract from + 0, // Byte offset into "m_data" + GetByteSize(), // Byte size of item in "m_data" + GetBitfieldBitSize(), // Bitfield bit size + GetBitfieldBitOffset(), // Bitfield bit offset + exe_ctx.GetBestExecutionContextScope()); + // Don't set the m_error to anything here otherwise + // we won't be able to re-format as anything else. The + // code for ClangASTType::DumpTypeValue() should always + // return something, even if that something contains + // an error messsage. "m_error" is used to detect errors + // when reading the valid object, not for formatting errors. + if (sstr.GetString().empty()) + destination.clear(); + else + destination.swap(sstr.GetString()); } - break; - - default: - break; } return !destination.empty(); } @@ -1464,8 +1408,7 @@ ValueObject::GetValueAsCString () } else { - clang_type_t clang_type = GetClangType (); - my_format = ClangASTType::GetFormat(clang_type); + my_format = GetClangType().GetFormat(); } } } @@ -1495,7 +1438,7 @@ uint64_t ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success) { // If our byte size is zero this is an aggregate type that has children - if (ClangASTContext::IsAggregateType (GetClangType()) == false) + if (!GetClangType().IsAggregateType()) { Scalar scalar; if (ResolveValue (scalar)) @@ -1519,10 +1462,8 @@ bool ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display, Format custom_format) { - clang_type_t elem_or_pointee_type; - Flags flags(GetTypeInfo(&elem_or_pointee_type)); - - if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) + Flags flags(GetTypeInfo()); + if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) { if (IsCStringContainer(true) && @@ -1532,7 +1473,7 @@ ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle va custom_format == eFormatVectorOfChar)) return true; - if (flags.Test(ClangASTContext::eTypeIsArray)) + if (flags.Test(ClangASTType::eTypeIsArray)) { if ((custom_format == eFormatBytes) || (custom_format == eFormatBytesWithASCII)) @@ -1563,15 +1504,14 @@ ValueObject::DumpPrintableRepresentation(Stream& s, PrintableRepresentationSpecialCases special) { - clang_type_t elem_or_pointee_type; - Flags flags(GetTypeInfo(&elem_or_pointee_type)); + Flags flags(GetTypeInfo()); bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow); bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly); if (allow_special) { - if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) + if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) { // when being asked to get a printable display an array or pointer type directly, @@ -1597,7 +1537,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s, // this only works for arrays, because I have no way to know when // the pointed memory ends, and no special \0 end of data marker - if (flags.Test(ClangASTContext::eTypeIsArray)) + if (flags.Test(ClangASTType::eTypeIsArray)) { if ((custom_format == eFormatBytes) || (custom_format == eFormatBytesWithASCII)) @@ -1745,7 +1685,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s, cstr = GetSummaryAsCString(); else if (val_obj_display == eValueObjectRepresentationStyleSummary) { - if (ClangASTContext::IsAggregateType (GetClangType()) == true) + if (GetClangType().IsAggregateType()) { strm.Printf("%s @ %s", GetTypeName().AsCString(), GetLocationAsCString()); cstr = strm.GetString().c_str(); @@ -1862,7 +1802,7 @@ ValueObject::SetValueFromCString (const char *value_str, Error& error) } uint64_t count = 0; - Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count); + const Encoding encoding = GetClangType().GetEncoding (count); const size_t byte_size = GetByteSize(); @@ -1960,21 +1900,20 @@ ValueObject::GetDeclaration (Declaration &decl) ConstString ValueObject::GetTypeName() { - return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType()); + return GetClangType().GetConstTypeName(); } ConstString ValueObject::GetQualifiedTypeName() { - return ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType()); + return GetClangType().GetConstQualifiedTypeName(); } LanguageType ValueObject::GetObjectRuntimeLanguage () { - return ClangASTType::GetMinimumLanguage (GetClangAST(), - GetClangType()); + return GetClangType().GetMinimumLanguage (); } void @@ -1994,39 +1933,39 @@ ValueObject::GetSyntheticChild (const ConstString &key) const } uint32_t -ValueObject::GetTypeInfo (clang_type_t *pointee_or_element_clang_type) +ValueObject::GetTypeInfo (ClangASTType *pointee_or_element_clang_type) { - return ClangASTContext::GetTypeInfo (GetClangType(), GetClangAST(), pointee_or_element_clang_type); + return GetClangType().GetTypeInfo (pointee_or_element_clang_type); } bool ValueObject::IsPointerType () { - return ClangASTContext::IsPointerType (GetClangType()); + return GetClangType().IsPointerType(); } bool ValueObject::IsArrayType () { - return ClangASTContext::IsArrayType (GetClangType(), NULL, NULL, NULL); + return GetClangType().IsArrayType (NULL, NULL, NULL); } bool ValueObject::IsScalarType () { - return ClangASTContext::IsScalarType (GetClangType()); + return GetClangType().IsScalarType (); } bool ValueObject::IsIntegerType (bool &is_signed) { - return ClangASTContext::IsIntegerType (GetClangType(), is_signed); + return GetClangType().IsIntegerType (is_signed); } bool ValueObject::IsPointerOrReferenceType () { - return ClangASTContext::IsPointerOrReferenceType (GetClangType()); + return GetClangType().IsPointerOrReferenceType (); } bool @@ -2037,14 +1976,14 @@ ValueObject::IsPossibleDynamicType () if (process) return process->IsPossibleDynamicValue(*this); else - return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType(), NULL, true, true); + return GetClangType().IsPossibleDynamicType (NULL, true, true); } bool ValueObject::IsObjCNil () { - const uint32_t mask = ClangASTContext::eTypeIsObjC | ClangASTContext::eTypeIsPointer; - bool isObjCpointer = ( ((ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), NULL)) & mask) == mask); + const uint32_t mask = ClangASTType::eTypeIsObjC | ClangASTType::eTypeIsPointer; + bool isObjCpointer = (((GetClangType().GetTypeInfo(NULL)) & mask) == mask); if (!isObjCpointer) return false; bool canReadValue = true; @@ -2056,10 +1995,10 @@ ValueObjectSP ValueObject::GetSyntheticArrayMember (size_t index, bool can_create) { const uint32_t type_info = GetTypeInfo (); - if (type_info & ClangASTContext::eTypeIsArray) + if (type_info & ClangASTType::eTypeIsArray) return GetSyntheticArrayMemberFromArray(index, can_create); - if (type_info & ClangASTContext::eTypeIsPointer) + if (type_info & ClangASTType::eTypeIsPointer) return GetSyntheticArrayMemberFromPointer(index, can_create); return ValueObjectSP(); @@ -2155,20 +2094,18 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre synthetic_child_sp = GetSyntheticChild (index_const_str); if (!synthetic_child_sp) { - ValueObjectChild *synthetic_child; // We haven't made a synthetic array member for INDEX yet, so // lets make one and cache it for any future reference. - synthetic_child = new ValueObjectChild(*this, - GetClangAST(), - GetClangType(), - index_const_str, - GetByteSize(), - 0, - to-from+1, - from, - false, - false, - eAddressTypeInvalid); + ValueObjectChild *synthetic_child = new ValueObjectChild (*this, + GetClangType(), + index_const_str, + GetByteSize(), + 0, + to-from+1, + from, + false, + false, + eAddressTypeInvalid); // Cache the value if we got one back... if (synthetic_child) @@ -2204,10 +2141,9 @@ ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type return ValueObjectSP(); ValueObjectChild *synthetic_child = new ValueObjectChild(*this, - type.GetASTContext(), - type.GetOpaqueQualType(), + type, name_const_str, - type.GetTypeByteSize(), + type.GetByteSize(), offset, 0, 0, @@ -2377,9 +2313,9 @@ ValueObject::GetBaseClassPath (Stream &s) if (IsBaseClass()) { bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s); - clang_type_t clang_type = GetClangType(); + ClangASTType clang_type = GetClangType(); std::string cxx_class_name; - bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name); + bool this_had_base_class = clang_type.GetCXXClassName (cxx_class_name); if (this_had_base_class) { if (parent_had_base_class) @@ -2436,23 +2372,23 @@ ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExp ValueObject *non_base_class_parent = GetNonBaseClassParent(); if (non_base_class_parent) { - clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType(); + ClangASTType non_base_class_parent_clang_type = non_base_class_parent->GetClangType(); if (non_base_class_parent_clang_type) { - const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL); - if (parent && parent->IsDereferenceOfParent() && epformat == eGetExpressionPathFormatHonorPointers) { s.PutCString("->"); } else { - if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer) + const uint32_t non_base_class_parent_type_info = non_base_class_parent_clang_type.GetTypeInfo(); + + if (non_base_class_parent_type_info & ClangASTType::eTypeIsPointer) { s.PutCString("->"); } - else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) && - !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray)) + else if ((non_base_class_parent_type_info & ClangASTType::eTypeHasChildren) && + !(non_base_class_parent_type_info & ClangASTType::eTypeIsArray)) { s.PutChar('.'); } @@ -2657,13 +2593,13 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr - clang_type_t root_clang_type = root->GetClangType(); - clang_type_t pointee_clang_type; - Flags root_clang_type_info,pointee_clang_type_info; + ClangASTType root_clang_type = root->GetClangType(); + ClangASTType pointee_clang_type; + Flags pointee_clang_type_info; - root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type)); + Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type)); if (pointee_clang_type) - pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL)); + pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo()); if (!expression_cstr || *expression_cstr == '\0') { @@ -2676,15 +2612,15 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, case '-': { if (options.m_check_dot_vs_arrow_syntax && - root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error + root_clang_type_info.Test(ClangASTType::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot; *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; return ValueObjectSP(); } - if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden - root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && + if (root_clang_type_info.Test(ClangASTType::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden + root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && options.m_no_fragile_ivar) { *first_unparsed = expression_cstr; @@ -2704,7 +2640,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, case '.': // or fallthrough from -> { if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' && - root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error + root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow; @@ -2805,9 +2741,9 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } case '[': { - if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && !root_clang_type_info.Test(ClangASTContext::eTypeIsVector)) // if this is not a T[] nor a T* + if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && !root_clang_type_info.Test(ClangASTType::eTypeIsVector)) // if this is not a T[] nor a T* { - if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar... + if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar... { if (options.m_no_synthetic_children) // ...only chance left is synthetic { @@ -2827,7 +2763,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays { - if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) + if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray)) { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed; @@ -2864,7 +2800,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays { - if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) + if (root_clang_type_info.Test(ClangASTType::eTypeIsArray)) { *first_unparsed = expression_cstr+2; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet; @@ -2880,7 +2816,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } } // from here on we do have a valid index - if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) + if (root_clang_type_info.Test(ClangASTType::eTypeIsArray)) { ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true); if (!child_valobj_sp) @@ -2903,10 +2839,10 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, return ValueObjectSP(); } } - else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) + else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) { if (*what_next == ValueObject::eExpressionPathAftermathDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield - pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) + pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar)) { Error error; root = root->Dereference(error); @@ -2925,9 +2861,8 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } else { - if (ClangASTType::GetMinimumLanguage(root->GetClangAST(), - root->GetClangType()) == eLanguageTypeObjC - && pointee_clang_type_info.AllClear(ClangASTContext::eTypeIsPointer) + if (root->GetClangType().GetMinimumLanguage() == eLanguageTypeObjC + && pointee_clang_type_info.AllClear(ClangASTType::eTypeIsPointer) && root->HasSyntheticValue() && options.m_no_synthetic_children == false) { @@ -2950,7 +2885,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } } } - else if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) + else if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) { root = root->GetSyntheticBitFieldChild(index, index, true); if (!root.get()) @@ -2968,7 +2903,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, return root; } } - else if (root_clang_type_info.Test(ClangASTContext::eTypeIsVector)) + else if (root_clang_type_info.Test(ClangASTType::eTypeIsVector)) { root = root->GetChildAtIndex(index, true); if (!root.get()) @@ -3053,7 +2988,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, index_lower = index_higher; index_higher = temp; } - if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars + if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars { root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); if (!root.get()) @@ -3071,9 +3006,9 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, return root; } } - else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield + else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield *what_next == ValueObject::eExpressionPathAftermathDereference && - pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) + pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar)) { Error error; root = root->Dereference(error); @@ -3132,13 +3067,12 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr - clang_type_t root_clang_type = root->GetClangType(); - clang_type_t pointee_clang_type; - Flags root_clang_type_info,pointee_clang_type_info; - - root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type)); + ClangASTType root_clang_type = root->GetClangType(); + ClangASTType pointee_clang_type; + Flags pointee_clang_type_info; + Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type)); if (pointee_clang_type) - pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL)); + pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo()); if (!expression_cstr || *expression_cstr == '\0') { @@ -3151,9 +3085,9 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, { case '[': { - if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T* + if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if this is not a T[] nor a T* { - if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong! + if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong! { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid; @@ -3170,7 +3104,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, } if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays { - if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) + if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray)) { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed; @@ -3214,7 +3148,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, } if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays { - if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) + if (root_clang_type_info.Test(ClangASTType::eTypeIsArray)) { const size_t max_index = root->GetNumChildren() - 1; for (size_t index = 0; index < max_index; index++) @@ -3237,7 +3171,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, } } // from here on we do have a valid index - if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) + if (root_clang_type_info.Test(ClangASTType::eTypeIsArray)) { root = root->GetChildAtIndex(index, true); if (!root.get()) @@ -3256,10 +3190,10 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, return 1; } } - else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) + else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) { if (*what_next == ValueObject::eExpressionPathAftermathDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield - pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) + pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar)) { Error error; root = root->Dereference(error); @@ -3341,7 +3275,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, index_lower = index_higher; index_higher = temp; } - if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars + if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars { root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); if (!root.get()) @@ -3360,9 +3294,9 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, return 1; } } - else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield + else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield *what_next == ValueObject::eExpressionPathAftermathDereference && - pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) + pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar)) { Error error; root = root->Dereference(error); @@ -3431,12 +3365,11 @@ DumpValueObject_Impl (Stream &s, valobj = dynamic_value; } - clang_type_t clang_type = valobj->GetClangType(); - - const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL)); + ClangASTType clang_type = valobj->GetClangType(); + const Flags type_flags (clang_type.GetTypeInfo ()); const char *err_cstr = NULL; - const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren); - const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue); + const bool has_children = type_flags.Test (ClangASTType::eTypeHasChildren); + const bool has_value = type_flags.Test (ClangASTType::eTypeHasValue); const bool print_valobj = options.m_flat_output == false || has_value; @@ -3521,7 +3454,7 @@ DumpValueObject_Impl (Stream &s, } else { - const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference); + const bool is_ref = type_flags.Test (ClangASTType::eTypeIsReference); if (print_valobj) { if (is_nil) @@ -3573,7 +3506,7 @@ DumpValueObject_Impl (Stream &s, // current pointer depth below... uint32_t curr_ptr_depth = ptr_depth; - const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer); + const bool is_ptr = type_flags.Test (ClangASTType::eTypeIsPointer); if (is_ptr || is_ref) { // We have a pointer or reference whose value is an address. @@ -3742,7 +3675,6 @@ ValueObject::CreateConstantValue (const ConstString &name) if (UpdateValueIfNeeded(false) && m_error.Success()) { ExecutionContext exe_ctx (GetExecutionContextRef()); - clang::ASTContext *ast = GetClangAST (); DataExtractor data; data.SetByteOrder (m_data.GetByteOrder()); @@ -3751,13 +3683,12 @@ ValueObject::CreateConstantValue (const ConstString &name) if (IsBitfield()) { Value v(Scalar(GetValueAsUnsigned(UINT64_MAX))); - m_error = v.GetValueAsData (&exe_ctx, ast, data, 0, GetModule().get()); + m_error = v.GetValueAsData (&exe_ctx, data, 0, GetModule().get()); } else - m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule().get()); + m_error = m_value.GetValueAsData (&exe_ctx, data, 0, GetModule().get()); valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - ast, GetClangType(), name, data, @@ -3791,27 +3722,24 @@ ValueObject::Dereference (Error &error) bool child_is_base_class = false; bool child_is_deref_of_parent = false; const bool transparent_pointers = false; - clang::ASTContext *clang_ast = GetClangAST(); - clang_type_t clang_type = GetClangType(); - clang_type_t child_clang_type; + ClangASTType clang_type = GetClangType(); + ClangASTType child_clang_type; ExecutionContext exe_ctx (GetExecutionContextRef()); - child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, - clang_ast, - GetName().GetCString(), - clang_type, - 0, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name_str, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); + child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx, + GetName().GetCString(), + 0, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name_str, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); if (child_clang_type && child_byte_size) { ConstString child_name; @@ -3819,7 +3747,6 @@ ValueObject::Dereference (Error &error) child_name.SetCString (child_name_str.c_str()); m_deref_valobj = new ValueObjectChild (*this, - clang_ast, child_clang_type, child_name, child_byte_size, @@ -3876,16 +3803,14 @@ ValueObject::AddressOf (Error &error) case eAddressTypeLoad: case eAddressTypeHost: { - clang::ASTContext *ast = GetClangAST(); - clang_type_t clang_type = GetClangType(); - if (ast && clang_type) + ClangASTType clang_type = GetClangType(); + if (clang_type) { std::string name (1, '&'); name.append (m_name.AsCString("")); ExecutionContext exe_ctx (GetExecutionContextRef()); m_addr_of_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - ast, - ClangASTContext::CreatePointerType (ast, clang_type), + clang_type.GetPointerType(), ConstString (name.c_str()), addr, eAddressTypeInvalid, @@ -4104,103 +4029,6 @@ ValueObject::EvaluationPoint::SetUpdated () } -//bool -//ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope) -//{ -// if (!IsValid()) -// return false; -// -// bool needs_update = false; -// -// // The target has to be non-null, and the -// Target *target = exe_scope->CalculateTarget(); -// if (target != NULL) -// { -// Target *old_target = m_target_sp.get(); -// assert (target == old_target); -// Process *process = exe_scope->CalculateProcess(); -// if (process != NULL) -// { -// // FOR NOW - assume you can't update variable objects across process boundaries. -// Process *old_process = m_process_sp.get(); -// assert (process == old_process); -// ProcessModID current_mod_id = process->GetModID(); -// if (m_mod_id != current_mod_id) -// { -// needs_update = true; -// m_mod_id = current_mod_id; -// } -// // See if we're switching the thread or stack context. If no thread is given, this is -// // being evaluated in a global context. -// Thread *thread = exe_scope->CalculateThread(); -// if (thread != NULL) -// { -// user_id_t new_thread_index = thread->GetIndexID(); -// if (new_thread_index != m_thread_id) -// { -// needs_update = true; -// m_thread_id = new_thread_index; -// m_stack_id.Clear(); -// } -// -// StackFrame *new_frame = exe_scope->CalculateStackFrame(); -// if (new_frame != NULL) -// { -// if (new_frame->GetStackID() != m_stack_id) -// { -// needs_update = true; -// m_stack_id = new_frame->GetStackID(); -// } -// } -// else -// { -// m_stack_id.Clear(); -// needs_update = true; -// } -// } -// else -// { -// // If this had been given a thread, and now there is none, we should update. -// // Otherwise we don't have to do anything. -// if (m_thread_id != LLDB_INVALID_UID) -// { -// m_thread_id = LLDB_INVALID_UID; -// m_stack_id.Clear(); -// needs_update = true; -// } -// } -// } -// else -// { -// // If there is no process, then we don't need to update anything. -// // But if we're switching from having a process to not, we should try to update. -// if (m_process_sp.get() != NULL) -// { -// needs_update = true; -// m_process_sp.reset(); -// m_thread_id = LLDB_INVALID_UID; -// m_stack_id.Clear(); -// } -// } -// } -// else -// { -// // If there's no target, nothing can change so we don't need to update anything. -// // But if we're switching from having a target to not, we should try to update. -// if (m_target_sp.get() != NULL) -// { -// needs_update = true; -// m_target_sp.reset(); -// m_process_sp.reset(); -// m_thread_id = LLDB_INVALID_UID; -// m_stack_id.Clear(); -// } -// } -// if (!m_needs_update) -// m_needs_update = needs_update; -// -// return needs_update; -//} void ValueObject::ClearUserVisibleData(uint32_t clear_mask) @@ -4262,24 +4090,30 @@ ValueObject::CreateValueObjectFromAddress (const char* name, const ExecutionContext& exe_ctx, ClangASTType type) { - ClangASTType pointer_type(type.GetASTContext(),type.GetPointerType()); - lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); - lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - pointer_type.GetASTContext(), - pointer_type.GetOpaqueQualType(), - ConstString(name), - buffer, - lldb::endian::InlHostByteOrder(), - exe_ctx.GetAddressByteSize())); - if (ptr_result_valobj_sp) + if (type) { - ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); - Error err; - ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err); - if (ptr_result_valobj_sp && name && *name) - ptr_result_valobj_sp->SetName(ConstString(name)); + ClangASTType pointer_type(type.GetPointerType()); + if (pointer_type) + { + lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); + lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), + pointer_type, + ConstString(name), + buffer, + lldb::endian::InlHostByteOrder(), + exe_ctx.GetAddressByteSize())); + if (ptr_result_valobj_sp) + { + ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); + Error err; + ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err); + if (ptr_result_valobj_sp && name && *name) + ptr_result_valobj_sp->SetName(ConstString(name)); + } + return ptr_result_valobj_sp; + } } - return ptr_result_valobj_sp; + return lldb::ValueObjectSP(); } lldb::ValueObjectSP @@ -4290,8 +4124,7 @@ ValueObject::CreateValueObjectFromData (const char* name, { lldb::ValueObjectSP new_value_sp; new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - type.GetASTContext() , - type.GetOpaqueQualType(), + type, ConstString(name), data, LLDB_INVALID_ADDRESS); diff --git a/lldb/source/Core/ValueObjectCast.cpp b/lldb/source/Core/ValueObjectCast.cpp index e1c94cc5fa4..4f4f8cc681d 100644 --- a/lldb/source/Core/ValueObjectCast.cpp +++ b/lldb/source/Core/ValueObjectCast.cpp @@ -54,35 +54,30 @@ ValueObjectCast::ValueObjectCast m_cast_type (cast_type) { SetName (name); - m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType()); + //m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType()); + m_value.SetClangType (cast_type); } ValueObjectCast::~ValueObjectCast() { } -lldb::clang_type_t +ClangASTType ValueObjectCast::GetClangTypeImpl () { - return m_cast_type.GetOpaqueQualType(); + return m_cast_type; } size_t ValueObjectCast::CalculateNumChildren() { - return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true); -} - -clang::ASTContext * -ValueObjectCast::GetClangASTImpl () -{ - return m_cast_type.GetASTContext(); + return GetClangType().GetNumChildren (true); } uint64_t ValueObjectCast::GetByteSize() { - return m_value.GetValueByteSize(GetClangAST(), NULL); + return m_value.GetValueByteSize(NULL); } lldb::ValueType @@ -103,9 +98,11 @@ ValueObjectCast::UpdateValue () Value old_value(m_value); m_update_point.SetUpdated(); m_value = m_parent->GetValue(); - m_value.SetContext (Value::eContextTypeClangType, GetClangType()); + ClangASTType clang_type (GetClangType()); + //m_value.SetContext (Value::eContextTypeClangType, clang_type); + m_value.SetClangType (clang_type); SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren()); - if (ClangASTContext::IsAggregateType (GetClangType())) + if (clang_type.IsAggregateType ()) { // this value object represents an aggregate type whose // children have values, but this object does not. So we @@ -113,7 +110,7 @@ ValueObjectCast::UpdateValue () SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); } ExecutionContext exe_ctx (GetExecutionContextRef()); - m_error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); + m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); SetValueDidChange (m_parent->GetValueDidChange()); return true; } diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp index cf69ea5da68..23add1ccf0e 100644 --- a/lldb/source/Core/ValueObjectChild.cpp +++ b/lldb/source/Core/ValueObjectChild.cpp @@ -27,8 +27,7 @@ using namespace lldb_private; ValueObjectChild::ValueObjectChild ( ValueObject &parent, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, uint64_t byte_size, int32_t byte_offset, @@ -39,7 +38,6 @@ ValueObjectChild::ValueObjectChild AddressType child_ptr_or_ref_addr_type ) : ValueObject (parent), - m_clang_ast (clang_ast), m_clang_type (clang_type), m_byte_size (byte_size), m_byte_offset (byte_offset), @@ -65,7 +63,7 @@ ValueObjectChild::GetValueType() const size_t ValueObjectChild::CalculateNumChildren() { - return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true); + return GetClangType().GetNumChildren (true); } ConstString @@ -73,7 +71,7 @@ ValueObjectChild::GetTypeName() { if (m_type_name.IsEmpty()) { - m_type_name = ClangASTType::GetConstTypeName (GetClangAST(), GetClangType()); + m_type_name = GetClangType().GetConstTypeName (); if (m_type_name) { if (m_bitfield_bit_size > 0) @@ -94,7 +92,7 @@ ValueObjectChild::GetTypeName() ConstString ValueObjectChild::GetQualifiedTypeName() { - ConstString qualified_name = ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType()); + ConstString qualified_name = GetClangType().GetConstTypeName(); if (qualified_name) { if (m_bitfield_bit_size > 0) @@ -121,14 +119,14 @@ ValueObjectChild::UpdateValue () { if (parent->UpdateValueIfNeeded(false)) { - m_value.SetContext(Value::eContextTypeClangType, GetClangType()); + m_value.SetClangType(GetClangType()); // Copy the parent scalar value and the scalar value type m_value.GetScalar() = parent->GetValue().GetScalar(); Value::ValueType value_type = parent->GetValue().GetValueType(); m_value.SetValueType (value_type); - if (ClangASTContext::IsPointerOrReferenceType (parent->GetClangType())) + if (parent->GetClangType().IsPointerOrReferenceType ()) { lldb::addr_t addr = parent->GetPointerValue (); m_value.GetScalar() = addr; @@ -209,7 +207,7 @@ ValueObjectChild::UpdateValue () if (m_error.Success()) { ExecutionContext exe_ctx (GetExecutionContextRef().Lock()); - m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0, GetModule().get()); + m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); } } else diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp index b78e4ec3476..d6d86381358 100644 --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -30,13 +30,10 @@ using namespace lldb; using namespace lldb_private; ValueObjectSP -ValueObjectConstResult::Create -( - ExecutionContextScope *exe_scope, - ByteOrder byte_order, - uint32_t addr_byte_size, - lldb::addr_t address -) +ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, + ByteOrder byte_order, + uint32_t addr_byte_size, + lldb::addr_t address) { return (new ValueObjectConstResult (exe_scope, byte_order, @@ -44,15 +41,11 @@ ValueObjectConstResult::Create address))->GetSP(); } -ValueObjectConstResult::ValueObjectConstResult -( - ExecutionContextScope *exe_scope, - ByteOrder byte_order, - uint32_t addr_byte_size, - lldb::addr_t address -) : +ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, + ByteOrder byte_order, + uint32_t addr_byte_size, + lldb::addr_t address) : ValueObject (exe_scope), - m_clang_ast (NULL), m_type_name (), m_byte_size (0), m_impl(this, address) @@ -68,32 +61,25 @@ ValueObjectSP ValueObjectConstResult::Create ( ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, const DataExtractor &data, lldb::addr_t address ) { return (new ValueObjectConstResult (exe_scope, - clang_ast, clang_type, name, data, address))->GetSP(); } -ValueObjectConstResult::ValueObjectConstResult -( - ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, - const ConstString &name, - const DataExtractor &data, - lldb::addr_t address -) : +ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, + const ClangASTType &clang_type, + const ConstString &name, + const DataExtractor &data, + lldb::addr_t address) : ValueObject (exe_scope), - m_clang_ast (clang_ast), m_type_name (), m_byte_size (0), m_impl(this, address) @@ -108,7 +94,7 @@ ValueObjectConstResult::ValueObjectConstResult m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); m_value.SetValueType(Value::eValueTypeHostAddress); - m_value.SetContext(Value::eContextTypeClangType, clang_type); + m_value.SetClangType(clang_type); m_name = name; SetIsConstant (); SetValueIsValid(true); @@ -116,20 +102,15 @@ ValueObjectConstResult::ValueObjectConstResult } ValueObjectSP -ValueObjectConstResult::Create -( - ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, - const ConstString &name, - const lldb::DataBufferSP &data_sp, - lldb::ByteOrder data_byte_order, - uint32_t data_addr_size, - lldb::addr_t address -) +ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, + const ClangASTType &clang_type, + const ConstString &name, + const lldb::DataBufferSP &data_sp, + lldb::ByteOrder data_byte_order, + uint32_t data_addr_size, + lldb::addr_t address) { return (new ValueObjectConstResult (exe_scope, - clang_ast, clang_type, name, data_sp, @@ -140,26 +121,20 @@ ValueObjectConstResult::Create ValueObjectSP ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - Value &value, - const ConstString &name) + Value &value, + const ConstString &name) { - return (new ValueObjectConstResult (exe_scope, clang_ast, value, name))->GetSP(); + return (new ValueObjectConstResult (exe_scope, value, name))->GetSP(); } -ValueObjectConstResult::ValueObjectConstResult -( - ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, - const ConstString &name, - const lldb::DataBufferSP &data_sp, - lldb::ByteOrder data_byte_order, - uint32_t data_addr_size, - lldb::addr_t address -) : +ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, + const ClangASTType &clang_type, + const ConstString &name, + const lldb::DataBufferSP &data_sp, + lldb::ByteOrder data_byte_order, + uint32_t data_addr_size, + lldb::addr_t address) : ValueObject (exe_scope), - m_clang_ast (clang_ast), m_type_name (), m_byte_size (0), m_impl(this, address) @@ -169,7 +144,8 @@ ValueObjectConstResult::ValueObjectConstResult m_data.SetData(data_sp); m_value.GetScalar() = (uintptr_t)data_sp->GetBytes(); m_value.SetValueType(Value::eValueTypeHostAddress); - m_value.SetContext(Value::eContextTypeClangType, clang_type); + //m_value.SetContext(Value::eContextTypeClangType, clang_type); + m_value.SetClangType (clang_type); m_name = name; SetIsConstant (); SetValueIsValid(true); @@ -177,19 +153,14 @@ ValueObjectConstResult::ValueObjectConstResult } ValueObjectSP -ValueObjectConstResult::Create -( - ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, - const ConstString &name, - lldb::addr_t address, - AddressType address_type, - uint32_t addr_byte_size -) +ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, + const ClangASTType &clang_type, + const ConstString &name, + lldb::addr_t address, + AddressType address_type, + uint32_t addr_byte_size) { return (new ValueObjectConstResult (exe_scope, - clang_ast, clang_type, name, address, @@ -197,18 +168,13 @@ ValueObjectConstResult::Create addr_byte_size))->GetSP(); } -ValueObjectConstResult::ValueObjectConstResult -( - ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - void *clang_type, - const ConstString &name, - lldb::addr_t address, - AddressType address_type, - uint32_t addr_byte_size -) : +ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, + const ClangASTType &clang_type, + const ConstString &name, + lldb::addr_t address, + AddressType address_type, + uint32_t addr_byte_size) : ValueObject (exe_scope), - m_clang_ast (clang_ast), m_type_name (), m_byte_size (0), m_impl(this, address) @@ -224,7 +190,8 @@ ValueObjectConstResult::ValueObjectConstResult case eAddressTypeLoad: m_value.SetValueType(Value::eValueTypeLoadAddress); break; case eAddressTypeHost: m_value.SetValueType(Value::eValueTypeHostAddress); break; } - m_value.SetContext(Value::eContextTypeClangType, clang_type); +// m_value.SetContext(Value::eContextTypeClangType, clang_type); + m_value.SetClangType (clang_type); m_name = name; SetIsConstant (); SetValueIsValid(true); @@ -242,11 +209,9 @@ ValueObjectConstResult::Create error))->GetSP(); } -ValueObjectConstResult::ValueObjectConstResult ( - ExecutionContextScope *exe_scope, - const Error& error) : +ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, + const Error& error) : ValueObject (exe_scope), - m_clang_ast (NULL), m_type_name (), m_byte_size (0), m_impl(this) @@ -255,13 +220,10 @@ ValueObjectConstResult::ValueObjectConstResult ( SetIsConstant (); } -ValueObjectConstResult::ValueObjectConstResult ( - ExecutionContextScope *exe_scope, - clang::ASTContext *clang_ast, - const Value &value, - const ConstString &name) : +ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, + const Value &value, + const ConstString &name) : ValueObject (exe_scope), - m_clang_ast (clang_ast), m_type_name (), m_byte_size (0), m_impl(this) @@ -274,7 +236,7 @@ ValueObjectConstResult::~ValueObjectConstResult() { } -lldb::clang_type_t +ClangASTType ValueObjectConstResult::GetClangTypeImpl() { return m_value.GetClangType(); @@ -290,7 +252,7 @@ uint64_t ValueObjectConstResult::GetByteSize() { if (m_byte_size == 0) - m_byte_size = ClangASTType::GetTypeByteSize(GetClangAST(), GetClangType()); + m_byte_size = GetClangType().GetByteSize(); return m_byte_size; } @@ -303,20 +265,14 @@ ValueObjectConstResult::SetByteSize (size_t size) size_t ValueObjectConstResult::CalculateNumChildren() { - return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true); -} - -clang::ASTContext * -ValueObjectConstResult::GetClangASTImpl () -{ - return m_clang_ast; + return GetClangType().GetNumChildren (true); } ConstString ValueObjectConstResult::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = ClangASTType::GetConstTypeName (GetClangAST(), GetClangType()); + m_type_name = GetClangType().GetConstTypeName (); return m_type_name; } diff --git a/lldb/source/Core/ValueObjectConstResultChild.cpp b/lldb/source/Core/ValueObjectConstResultChild.cpp index 4f40381eb54..64425ea5096 100644 --- a/lldb/source/Core/ValueObjectConstResultChild.cpp +++ b/lldb/source/Core/ValueObjectConstResultChild.cpp @@ -19,8 +19,7 @@ using namespace lldb_private; ValueObjectConstResultChild::ValueObjectConstResultChild ( ValueObject &parent, - clang::ASTContext *clang_ast, - void *clang_type, + const ClangASTType &clang_type, const ConstString &name, uint32_t byte_size, int32_t byte_offset, @@ -30,7 +29,6 @@ ValueObjectConstResultChild::ValueObjectConstResultChild bool is_deref_of_parent ) : ValueObjectChild (parent, - clang_ast, clang_type, name, byte_size, diff --git a/lldb/source/Core/ValueObjectConstResultImpl.cpp b/lldb/source/Core/ValueObjectConstResultImpl.cpp index 3d86b9109f8..e0757f60cdb 100644 --- a/lldb/source/Core/ValueObjectConstResultImpl.cpp +++ b/lldb/source/Core/ValueObjectConstResultImpl.cpp @@ -55,7 +55,6 @@ ValueObjectConstResultImpl::DerefOnTarget() lldb::addr_t tgt_address = m_impl_backend->GetPointerValue(); ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); m_load_addr_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - m_impl_backend->GetClangAST(), m_impl_backend->GetClangType(), m_impl_backend->GetName(), tgt_address, @@ -104,27 +103,24 @@ ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array bool child_is_deref_of_parent = false; const bool transparent_pointers = synthetic_array_member == false; - clang::ASTContext *clang_ast = m_impl_backend->GetClangAST(); - lldb::clang_type_t clang_type = m_impl_backend->GetClangType(); - lldb::clang_type_t child_clang_type; + ClangASTType clang_type = m_impl_backend->GetClangType(); + ClangASTType child_clang_type; ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); - child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, - clang_ast, - m_impl_backend->GetName().GetCString(), - clang_type, - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name_str, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); + child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx, + m_impl_backend->GetName().GetCString(), + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name_str, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); if (child_clang_type && child_byte_size) { if (synthetic_index) @@ -135,7 +131,6 @@ ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array child_name.SetCString (child_name_str.c_str()); valobj = new ValueObjectConstResultChild (*m_impl_backend, - clang_ast, child_clang_type, child_name, child_byte_size, @@ -178,7 +173,7 @@ ValueObjectConstResultImpl::AddressOf (Error &error) return lldb::ValueObjectSP(); if (m_live_address != LLDB_INVALID_ADDRESS) { - ClangASTType type(m_impl_backend->GetClangAST(), m_impl_backend->GetClangType()); + ClangASTType clang_type(m_impl_backend->GetClangType()); lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t))); @@ -186,8 +181,7 @@ ValueObjectConstResultImpl::AddressOf (Error &error) new_name.append(m_impl_backend->GetName().AsCString("")); ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - type.GetASTContext(), - type.GetPointerType(), + clang_type.GetPointerType(), ConstString(new_name.c_str()), buffer, lldb::endian::InlHostByteOrder(), diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp index 95108f386fa..977cc4cd313 100644 --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -49,7 +49,7 @@ ValueObjectDynamicValue::~ValueObjectDynamicValue() m_owning_valobj_sp.reset(); } -lldb::clang_type_t +ClangASTType ValueObjectDynamicValue::GetClangTypeImpl () { if (m_dynamic_type_info.HasTypeSP()) @@ -65,7 +65,7 @@ ValueObjectDynamicValue::GetTypeName() if (success) { if (m_dynamic_type_info.HasTypeSP()) - return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType()); + return GetClangType().GetConstTypeName(); if (m_dynamic_type_info.HasName()) return m_dynamic_type_info.GetName(); } @@ -79,7 +79,7 @@ ValueObjectDynamicValue::GetQualifiedTypeName() if (success) { if (m_dynamic_type_info.HasTypeSP()) - return ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType()); + return GetClangType().GetConstQualifiedTypeName (); if (m_dynamic_type_info.HasName()) return m_dynamic_type_info.GetName(); } @@ -91,27 +91,17 @@ ValueObjectDynamicValue::CalculateNumChildren() { const bool success = UpdateValueIfNeeded(false); if (success && m_dynamic_type_info.HasTypeSP()) - return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true); + return GetClangType().GetNumChildren (true); else return m_parent->GetNumChildren(); } -clang::ASTContext * -ValueObjectDynamicValue::GetClangASTImpl () -{ - const bool success = UpdateValueIfNeeded(false); - if (success && m_dynamic_type_info.HasTypeSP()) - return m_dynamic_type_info.GetTypeSP()->GetClangAST(); - else - return m_parent->GetClangAST (); -} - uint64_t ValueObjectDynamicValue::GetByteSize() { const bool success = UpdateValueIfNeeded(false); if (success && m_dynamic_type_info.HasTypeSP()) - return m_value.GetValueByteSize(GetClangAST(), NULL); + return m_value.GetValueByteSize(NULL); else return m_parent->GetByteSize(); } @@ -196,7 +186,7 @@ ValueObjectDynamicValue::UpdateValue () ClearDynamicTypeInformation(); m_dynamic_type_info.Clear(); m_value = m_parent->GetValue(); - m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); + m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); return m_error.Success(); } @@ -234,21 +224,18 @@ ValueObjectDynamicValue::UpdateValue () m_value.GetScalar() = load_address; } - lldb::clang_type_t corrected_type; + ClangASTType corrected_type; if (m_dynamic_type_info.HasTypeSP()) { // The type will always be the type of the dynamic object. If our parent's type was a pointer, // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type // should be okay... - lldb::clang_type_t orig_type; - clang::ASTContext* ast; - orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType(); - ast = m_dynamic_type_info.GetTypeSP()->GetClangAST(); + ClangASTType orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType(); corrected_type = orig_type; if (m_parent->IsPointerType()) - corrected_type = ClangASTContext::CreatePointerType (ast, orig_type); + corrected_type = orig_type.GetPointerType (); else if (m_parent->IsPointerOrReferenceType()) - corrected_type = ClangASTContext::CreateLValueReferenceType (ast, orig_type); + corrected_type = orig_type.GetLValueReferenceType (); } else /*if (m_dynamic_type_info.HasName())*/ { @@ -262,7 +249,8 @@ ValueObjectDynamicValue::UpdateValue () m_dynamic_type_info.SetName(type_name_buf.c_str()); } - m_value.SetContext (Value::eContextTypeClangType, corrected_type); + //m_value.SetContext (Value::eContextTypeClangType, corrected_type); + m_value.SetClangType (corrected_type); // Our address is the location of the dynamic type stored in memory. It isn't a load address, // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us... @@ -278,10 +266,10 @@ ValueObjectDynamicValue::UpdateValue () { // The variable value is in the Scalar value inside the m_value. // We can point our m_data right to it. - m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); + m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); if (m_error.Success()) { - if (ClangASTContext::IsAggregateType (GetClangType())) + if (GetClangType().IsAggregateType ()) { // this value object represents an aggregate type whose // children have values, but this object does not. So we diff --git a/lldb/source/Core/ValueObjectMemory.cpp b/lldb/source/Core/ValueObjectMemory.cpp index 2bdf44f9c2d..42fd0e8fffb 100644 --- a/lldb/source/Core/ValueObjectMemory.cpp +++ b/lldb/source/Core/ValueObjectMemory.cpp @@ -103,7 +103,8 @@ ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, TargetSP target_sp (GetTargetSP()); SetName (ConstString(name)); - m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); +// m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); + m_value.SetClangType(m_clang_type); lldb::addr_t load_address = m_address.GetLoadAddress (target_sp.get()); if (load_address != LLDB_INVALID_ADDRESS) { @@ -130,12 +131,12 @@ ValueObjectMemory::~ValueObjectMemory() { } -lldb::clang_type_t +ClangASTType ValueObjectMemory::GetClangTypeImpl () { if (m_type_sp) return m_type_sp->GetClangForwardType(); - return m_clang_type.GetOpaqueQualType(); + return m_clang_type; } ConstString @@ -143,7 +144,7 @@ ValueObjectMemory::GetTypeName() { if (m_type_sp) return m_type_sp->GetName(); - return ClangASTType::GetConstTypeName (GetClangAST(), m_clang_type.GetOpaqueQualType()); + return m_clang_type.GetConstTypeName(); } size_t @@ -152,17 +153,7 @@ ValueObjectMemory::CalculateNumChildren() if (m_type_sp) return m_type_sp->GetNumChildren(true); const bool omit_empty_base_classes = true; - return ClangASTContext::GetNumChildren (m_clang_type.GetASTContext(), - m_clang_type.GetOpaqueQualType(), - omit_empty_base_classes); -} - -clang::ASTContext * -ValueObjectMemory::GetClangASTImpl () -{ - if (m_type_sp) - return m_type_sp->GetClangAST(); - return m_clang_type.GetASTContext(); + return m_clang_type.GetNumChildren (omit_empty_base_classes); } uint64_t @@ -170,7 +161,7 @@ ValueObjectMemory::GetByteSize() { if (m_type_sp) return m_type_sp->GetByteSize(); - return m_clang_type.GetClangTypeByteSize (); + return m_clang_type.GetByteSize (); } lldb::ValueType @@ -209,7 +200,7 @@ ValueObjectMemory::UpdateValue () case Value::eValueTypeScalar: // The variable value is in the Scalar value inside the m_value. // We can point our m_data right to it. - m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); + m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); break; case Value::eValueTypeFileAddress: @@ -234,7 +225,7 @@ ValueObjectMemory::UpdateValue () } } - if (ClangASTContext::IsAggregateType (GetClangType())) + if (GetClangType().IsAggregateType()) { // this value object represents an aggregate type whose // children have values, but this object does not. So we @@ -249,9 +240,12 @@ ValueObjectMemory::UpdateValue () if (m_type_sp) value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); else - value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); + { + //value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); + value.SetClangType(m_clang_type); + } - m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); + m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); } break; } diff --git a/lldb/source/Core/ValueObjectRegister.cpp b/lldb/source/Core/ValueObjectRegister.cpp index 8b0271338ad..4f21457519e 100644 --- a/lldb/source/Core/ValueObjectRegister.cpp +++ b/lldb/source/Core/ValueObjectRegister.cpp @@ -42,10 +42,10 @@ ValueObjectRegisterContext::~ValueObjectRegisterContext() { } -lldb::clang_type_t +ClangASTType ValueObjectRegisterContext::GetClangTypeImpl () { - return NULL; + return ClangASTType(); } ConstString @@ -66,12 +66,6 @@ ValueObjectRegisterContext::CalculateNumChildren() return m_reg_ctx_sp->GetRegisterSetCount(); } -clang::ASTContext * -ValueObjectRegisterContext::GetClangASTImpl () -{ - return NULL; -} - uint64_t ValueObjectRegisterContext::GetByteSize() { @@ -144,10 +138,10 @@ ValueObjectRegisterSet::~ValueObjectRegisterSet() { } -lldb::clang_type_t +ClangASTType ValueObjectRegisterSet::GetClangTypeImpl () { - return NULL; + return ClangASTType(); } ConstString @@ -171,12 +165,6 @@ ValueObjectRegisterSet::CalculateNumChildren() return 0; } -clang::ASTContext * -ValueObjectRegisterSet::GetClangASTImpl () -{ - return NULL; -} - uint64_t ValueObjectRegisterSet::GetByteSize() { @@ -285,7 +273,7 @@ ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterCon m_reg_info (), m_reg_value (), m_type_name (), - m_clang_type (NULL) + m_clang_type () { assert (reg_ctx_sp.get()); ConstructObject(reg_num); @@ -303,7 +291,7 @@ ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb m_reg_info (), m_reg_value (), m_type_name (), - m_clang_type (NULL) + m_clang_type () { assert (reg_ctx); ConstructObject(reg_num); @@ -313,10 +301,10 @@ ValueObjectRegister::~ValueObjectRegister() { } -lldb::clang_type_t +ClangASTType ValueObjectRegister::GetClangTypeImpl () { - if (m_clang_type == NULL) + if (!m_clang_type.IsValid()) { ExecutionContext exe_ctx (GetExecutionContextRef()); Target *target = exe_ctx.GetTargetPtr(); @@ -337,28 +325,14 @@ ConstString ValueObjectRegister::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = ClangASTType::GetConstTypeName (GetClangAST(), GetClangType()); + m_type_name = GetClangType().GetConstTypeName (); return m_type_name; } size_t ValueObjectRegister::CalculateNumChildren() { - return ClangASTContext::GetNumChildren(GetClangAST(), GetClangType(), true); -} - -clang::ASTContext * -ValueObjectRegister::GetClangASTImpl () -{ - ExecutionContext exe_ctx (GetExecutionContextRef()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) - { - Module *exe_module = target->GetExecutableModulePointer(); - if (exe_module) - return exe_module->GetClangASTContext().getASTContext(); - } - return NULL; + return GetClangType().GetNumChildren(true); } uint64_t diff --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp index ab5d1f524da..522ca082a69 100644 --- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -83,7 +83,7 @@ ValueObjectSynthetic::~ValueObjectSynthetic() { } -lldb::clang_type_t +ClangASTType ValueObjectSynthetic::GetClangTypeImpl () { return m_parent->GetClangType(); @@ -128,13 +128,6 @@ ValueObjectSynthetic::MightHaveChildren() return (m_might_have_children == eLazyBoolNo ? false : true); } - -clang::ASTContext * -ValueObjectSynthetic::GetClangASTImpl () -{ - return m_parent->GetClangAST (); -} - uint64_t ValueObjectSynthetic::GetByteSize() { @@ -273,5 +266,5 @@ ValueObjectSynthetic::CopyParentData () { m_value = m_parent->GetValue(); ExecutionContext exe_ctx (GetExecutionContextRef()); - m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); + m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); } diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp index 09e2f1f2476..38c0d91324a 100644 --- a/lldb/source/Core/ValueObjectVariable.cpp +++ b/lldb/source/Core/ValueObjectVariable.cpp @@ -54,13 +54,13 @@ ValueObjectVariable::~ValueObjectVariable() { } -lldb::clang_type_t +ClangASTType ValueObjectVariable::GetClangTypeImpl () { Type *var_type = m_variable_sp->GetType(); if (var_type) return var_type->GetClangForwardType(); - return NULL; + return ClangASTType(); } ConstString @@ -84,34 +84,24 @@ ValueObjectVariable::GetQualifiedTypeName() size_t ValueObjectVariable::CalculateNumChildren() { - ClangASTType type(GetClangAST(), - GetClangType()); + ClangASTType type(GetClangType()); if (!type.IsValid()) return 0; const bool omit_empty_base_classes = true; - return ClangASTContext::GetNumChildren(type.GetASTContext(), type.GetOpaqueQualType(), omit_empty_base_classes); -} - -clang::ASTContext * -ValueObjectVariable::GetClangASTImpl () -{ - Type *var_type = m_variable_sp->GetType(); - if (var_type) - return var_type->GetClangAST(); - return 0; + return type.GetNumChildren(omit_empty_base_classes); } uint64_t ValueObjectVariable::GetByteSize() { - ClangASTType type(GetClangAST(), GetClangType()); + ClangASTType type(GetClangType()); if (!type.IsValid()) return 0; - return type.GetClangTypeByteSize(); + return type.GetByteSize(); } lldb::ValueType @@ -162,7 +152,7 @@ ValueObjectVariable::UpdateValue () loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target); } Value old_value(m_value); - if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error)) + if (expr.Evaluate (&exe_ctx, NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error)) { m_resolved_value = m_value; m_value.SetContext(Value::eContextTypeVariable, variable); @@ -191,7 +181,7 @@ ValueObjectVariable::UpdateValue () case Value::eValueTypeScalar: // The variable value is in the Scalar value inside the m_value. // We can point our m_data right to it. - m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); + m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); break; case Value::eValueTypeFileAddress: @@ -231,7 +221,7 @@ ValueObjectVariable::UpdateValue () } } - if (ClangASTContext::IsAggregateType (GetClangType())) + if (GetClangType().IsAggregateType()) { // this value object represents an aggregate type whose // children have values, but this object does not. So we @@ -244,7 +234,7 @@ ValueObjectVariable::UpdateValue () // so it can extract read its value into m_data appropriately Value value(m_value); value.SetContext(Value::eContextTypeVariable, variable); - m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); + m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); } break; } diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp index 3432700cc72..fba92170d83 100644 --- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp +++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp @@ -518,12 +518,13 @@ lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Strea if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS) return false; - clang::ASTContext* ast = valobj.GetClangAST(); - + clang::ASTContext* ast = valobj.GetClangType().GetASTContext(); + if (!ast) return false; - uint32_t wchar_size = ClangASTType::GetClangTypeBitWidth(ast, ClangASTType::GetBasicType(ast, lldb::eBasicTypeWChar).GetOpaqueQualType()); + ClangASTType wchar_clang_type = ClangASTContext::GetBasicType(ast, lldb::eBasicTypeWChar); + const uint32_t wchar_size = wchar_clang_type.GetBitSize(); switch (wchar_size) { @@ -605,15 +606,15 @@ lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& str DataExtractor data; valobj.GetData(data); - clang::ASTContext* ast = valobj.GetClangAST(); + clang::ASTContext* ast = valobj.GetClangType().GetASTContext(); if (!ast) return false; + ClangASTType wchar_clang_type = ClangASTContext::GetBasicType(ast, lldb::eBasicTypeWChar); + const uint32_t wchar_size = wchar_clang_type.GetBitSize(); std::string value; - uint32_t wchar_size = ClangASTType::GetClangTypeBitWidth(ast, ClangASTType::GetBasicType(ast, lldb::eBasicTypeWChar).GetOpaqueQualType()); - switch (wchar_size) { case 8: @@ -1133,13 +1134,13 @@ lldb_private::formatters::NSAttributedStringSummaryProvider (ValueObject& valobj if (!target_sp) return false; uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize(); - uint64_t pointee = valobj.GetValueAsUnsigned(0); - if (!pointee) + uint64_t pointer_value = valobj.GetValueAsUnsigned(0); + if (!pointer_value) return false; - pointee += addr_size; - ClangASTType type(valobj.GetClangAST(),valobj.GetClangType()); + pointer_value += addr_size; + ClangASTType type(valobj.GetClangType()); ExecutionContext exe_ctx(target_sp,false); - ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointee, exe_ctx, type)); + ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointer_value, exe_ctx, type)); if (!child_ptr_sp) return false; DataExtractor data; @@ -1167,20 +1168,18 @@ lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider (ValueObject bool lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream) { - const uint32_t type_info = ClangASTContext::GetTypeInfo(valobj.GetClangType(), - valobj.GetClangAST(), - NULL); + const uint32_t type_info = valobj.GetClangType().GetTypeInfo(); ValueObjectSP real_guy_sp = valobj.GetSP(); - if (type_info & ClangASTContext::eTypeIsPointer) + if (type_info & ClangASTType::eTypeIsPointer) { Error err; real_guy_sp = valobj.Dereference(err); if (err.Fail() || !real_guy_sp) return false; } - else if (type_info & ClangASTContext::eTypeIsReference) + else if (type_info & ClangASTType::eTypeIsReference) { real_guy_sp = valobj.GetChildAtIndex(0, true); if (!real_guy_sp) @@ -1202,12 +1201,10 @@ lldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& s { lldb::ValueObjectSP valobj_sp; - if (!valobj.GetClangAST()) - return false; - void* char_opaque_type = valobj.GetClangAST()->CharTy.getAsOpaquePtr(); - if (!char_opaque_type) + ClangASTType charstar (valobj.GetClangType().GetBasicTypeFromAST(eBasicTypeChar).GetPointerType()); + + if (!charstar) return false; - ClangASTType charstar(valobj.GetClangAST(),ClangASTType::GetPointerType(valobj.GetClangAST(), char_opaque_type)); ExecutionContext exe_ctx(valobj.GetExecutionContextRef()); @@ -1303,7 +1300,7 @@ lldb_private::formatters::VectorIteratorSyntheticFrontEnd::Update() return false; Error err; m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); - m_item_sp = ValueObject::CreateValueObjectFromAddress("item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, ClangASTType(item_ptr->GetClangAST(),ClangASTType::GetPointeeType(item_ptr->GetClangType()))); + m_item_sp = ValueObject::CreateValueObjectFromAddress("item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, item_ptr->GetClangType().GetPointeeType()); if (err.Fail()) m_item_sp.reset(); return false; diff --git a/lldb/source/DataFormatters/Cocoa.cpp b/lldb/source/DataFormatters/Cocoa.cpp index 2a1e9099eba..555954db0bb 100644 --- a/lldb/source/DataFormatters/Cocoa.cpp +++ b/lldb/source/DataFormatters/Cocoa.cpp @@ -57,8 +57,7 @@ lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& if (!strcmp(class_name,"NSBundle")) { uint64_t offset = 5 * ptr_size; - ClangASTType type(valobj.GetClangAST(),ClangASTContext::GetBuiltInType_objc_id(valobj.GetClangAST())); - ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true)); + ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetClangType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID), true)); StreamString summary_stream; bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream); @@ -105,8 +104,7 @@ lldb_private::formatters::NSTimeZoneSummaryProvider (ValueObject& valobj, Stream if (!strcmp(class_name,"__NSTimeZone")) { uint64_t offset = ptr_size; - ClangASTType type(valobj.GetClangAST(),valobj.GetClangType()); - ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true)); + ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetClangType(), true)); StreamString summary_stream; bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream); if (was_nsstring_ok && summary_stream.GetSize() > 0) @@ -150,8 +148,7 @@ lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, St if (!strcmp(class_name,"NSConcreteNotification")) { uint64_t offset = ptr_size; - ClangASTType type(valobj.GetClangAST(),valobj.GetClangType()); - ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true)); + ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetClangType(), true)); StreamString summary_stream; bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream); if (was_nsstring_ok && summary_stream.GetSize() > 0) @@ -450,7 +447,7 @@ lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& str { uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit) uint64_t offset_base = offset_text + ptr_size; - ClangASTType type(valobj.GetClangAST(),valobj.GetClangType()); + ClangASTType type(valobj.GetClangType()); ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true)); ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true)); if (!text) diff --git a/lldb/source/DataFormatters/LibCxx.cpp b/lldb/source/DataFormatters/LibCxx.cpp index f7c2589dfa0..cdc57f6bd93 100644 --- a/lldb/source/DataFormatters/LibCxx.cpp +++ b/lldb/source/DataFormatters/LibCxx.cpp @@ -330,7 +330,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex (siz return lldb::ValueObjectSP(); uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0); DataExtractor data(&count, 8, m_byte_order, m_ptr_size); - m_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), ClangASTType(shared_owners_sp->GetClangAST(), shared_owners_sp->GetClangType())); + m_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_owners_sp->GetClangType()); } return m_count_sp; } @@ -343,7 +343,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex (siz return lldb::ValueObjectSP(); uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0); DataExtractor data(&count, 8, m_byte_order, m_ptr_size); - m_weak_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), ClangASTType(shared_weak_owners_sp->GetClangAST(), shared_weak_owners_sp->GetClangType())); + m_weak_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_weak_owners_sp->GetClangType()); } return m_weak_count_sp; } @@ -464,9 +464,8 @@ lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true); if (!data_type_finder_sp) return false; - m_element_type = ClangASTType(data_type_finder_sp->GetClangAST(),data_type_finder_sp->GetClangType()); - m_element_type.SetClangType(m_element_type.GetASTContext(), m_element_type.GetPointeeType()); - m_element_size = m_element_type.GetTypeByteSize(); + m_element_type = data_type_finder_sp->GetClangType().GetPointeeType(); + m_element_size = m_element_type.GetByteSize(); if (m_element_size > 0) { diff --git a/lldb/source/DataFormatters/LibCxxList.cpp b/lldb/source/DataFormatters/LibCxxList.cpp index d2669ea4d5d..de2ca1b2045 100644 --- a/lldb/source/DataFormatters/LibCxxList.cpp +++ b/lldb/source/DataFormatters/LibCxxList.cpp @@ -272,16 +272,14 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() ValueObjectSP impl_sp(m_backend.GetChildMemberWithName(ConstString("__end_"),true)); if (!impl_sp) return false; - auto list_type = m_backend.GetClangType(); - if (ClangASTContext::IsReferenceType(list_type)) - { - clang::QualType qt = clang::QualType::getFromOpaquePtr(list_type); - list_type = qt.getNonReferenceType().getAsOpaquePtr(); - } - if (ClangASTContext::GetNumTemplateArguments(m_backend.GetClangAST(), list_type) == 0) + ClangASTType list_type = m_backend.GetClangType(); + if (list_type.IsReferenceType()) + list_type = list_type.GetNonReferenceType(); + + if (list_type.GetNumTemplateArguments() == 0) return false; lldb::TemplateArgumentKind kind; - m_element_type = ClangASTType(m_backend.GetClangAST(), ClangASTContext::GetTemplateArgument(m_backend.GetClangAST(), list_type, 0, kind)); + m_element_type = list_type.GetTemplateArgument(0, kind); m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get(); return false; diff --git a/lldb/source/DataFormatters/LibCxxMap.cpp b/lldb/source/DataFormatters/LibCxxMap.cpp index 0b0b8f78fb7..5daa40f15f3 100644 --- a/lldb/source/DataFormatters/LibCxxMap.cpp +++ b/lldb/source/DataFormatters/LibCxxMap.cpp @@ -281,7 +281,7 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() deref = deref->GetChildMemberWithName(ConstString("__value_"), true); if (!deref) return false; - m_element_type.SetClangType(deref->GetClangAST(), deref->GetClangType()); + m_element_type = deref->GetClangType(); return true; } @@ -292,9 +292,9 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset (const l return; if (!node) return; - ClangASTType node_type(node->GetClangAST(),node->GetClangType()); + ClangASTType node_type(node->GetClangType()); uint64_t bit_offset; - if (ClangASTContext::GetIndexOfFieldWithName(node->GetClangAST(),node->GetClangType(),"__value_",NULL,&bit_offset) == UINT32_MAX) + if (node_type.GetIndexOfFieldWithName("__value_", NULL, &bit_offset) == UINT32_MAX) return; m_skip_size = bit_offset / 8u; } diff --git a/lldb/source/DataFormatters/LibStdcpp.cpp b/lldb/source/DataFormatters/LibStdcpp.cpp index a013051fa64..e0f23cc35e3 100644 --- a/lldb/source/DataFormatters/LibStdcpp.cpp +++ b/lldb/source/DataFormatters/LibStdcpp.cpp @@ -206,12 +206,12 @@ lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEndCreator (CXXSynthe */ lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -SyntheticChildrenFrontEnd(*valobj_sp.get()), -m_exe_ctx_ref(), -m_pair_address(0), -m_pair_type(), -m_options(), -m_pair_sp() + SyntheticChildrenFrontEnd(*valobj_sp.get()), + m_exe_ctx_ref(), + m_pair_address(0), + m_pair_type(), + m_options(), + m_pair_sp() { if (valobj_sp) Update(); @@ -249,14 +249,14 @@ lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::Update() m_pair_address += (is_64bit ? 32 : 16); - ClangASTType my_type(valobj_sp->GetClangAST(),valobj_sp->GetClangType()); - if (ClangASTContext::GetNumTemplateArguments(valobj_sp->GetClangAST(),valobj_sp->GetClangType()) >= 1) + ClangASTType my_type(valobj_sp->GetClangType()); + if (my_type.GetNumTemplateArguments() >= 1) { TemplateArgumentKind kind; - clang_type_t pair_type = ClangASTContext::GetTemplateArgument(valobj_sp->GetClangAST(),valobj_sp->GetClangType(), 0, kind); + ClangASTType pair_type = my_type.GetTemplateArgument(0, kind); if (kind != eTemplateArgumentKindType && kind != eTemplateArgumentKindTemplate && kind != eTemplateArgumentKindTemplateExpansion) return false; - m_pair_type = ClangASTType(valobj_sp->GetClangAST(),pair_type); + m_pair_type = pair_type; } else return false; @@ -273,15 +273,13 @@ lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChi lldb::ValueObjectSP lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx) { - if (m_pair_address == 0) - return lldb::ValueObjectSP(); - if (m_pair_type.GetASTContext() == NULL || - m_pair_type.GetOpaqueQualType() == NULL) - return lldb::ValueObjectSP(); - if (!m_pair_sp) - m_pair_sp = ValueObject::CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type); - if (m_pair_sp) - return m_pair_sp->GetChildAtIndex(idx, true); + if (m_pair_address != 0 && m_pair_type) + { + if (!m_pair_sp) + m_pair_sp = ValueObject::CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type); + if (m_pair_sp) + return m_pair_sp->GetChildAtIndex(idx, true); + } return lldb::ValueObjectSP(); } diff --git a/lldb/source/DataFormatters/NSArray.cpp b/lldb/source/DataFormatters/NSArray.cpp index cef087d1e9e..d8ee9bfa8a4 100644 --- a/lldb/source/DataFormatters/NSArray.cpp +++ b/lldb/source/DataFormatters/NSArray.cpp @@ -90,14 +90,18 @@ lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& s } lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -SyntheticChildrenFrontEnd(*valobj_sp.get()), -m_exe_ctx_ref(), -m_ptr_size(8), -m_data_32(NULL), -m_data_64(NULL) + SyntheticChildrenFrontEnd(*valobj_sp.get()), + m_exe_ctx_ref(), + m_ptr_size(8), + m_data_32(NULL), + m_data_64(NULL) { if (valobj_sp) - m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr()); + { + clang::ASTContext *ast = valobj_sp->GetClangType().GetASTContext(); + if (ast) + m_id_type = ClangASTType(ast, ast->ObjCBuiltinIdTy); + } } size_t @@ -195,14 +199,18 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::~NSArrayMSyntheticFrontEnd } lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -SyntheticChildrenFrontEnd(*valobj_sp.get()), -m_exe_ctx_ref(), -m_ptr_size(8), -m_items(0), -m_data_ptr(0) + SyntheticChildrenFrontEnd (*valobj_sp.get()), + m_exe_ctx_ref (), + m_ptr_size (8), + m_items (0), + m_data_ptr (0) { if (valobj_sp) - m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr()); + { + clang::ASTContext *ast = valobj_sp->GetClangType().GetASTContext(); + if (ast) + m_id_type = ClangASTType(ast, ast->ObjCBuiltinIdTy); + } } lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd () diff --git a/lldb/source/DataFormatters/NSDictionary.cpp b/lldb/source/DataFormatters/NSDictionary.cpp index c9fef4288c0..05a5dda39e5 100644 --- a/lldb/source/DataFormatters/NSDictionary.cpp +++ b/lldb/source/DataFormatters/NSDictionary.cpp @@ -30,52 +30,52 @@ using namespace lldb_private::formatters; static ClangASTType GetLLDBNSPairType (TargetSP target_sp) { - ClangASTType clang_type = ClangASTType(); + ClangASTType clang_type; ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext(); - if (!target_ast_context) - return clang_type; - - const char* type_name = "__lldb_autogen_nspair"; - - clang::IdentifierInfo &myIdent = target_ast_context->getASTContext()->Idents.get(type_name); - clang::DeclarationName myName = target_ast_context->getASTContext()->DeclarationNames.getIdentifier(&myIdent); - - clang::DeclContext::lookup_const_result result = target_ast_context->getASTContext()->getTranslationUnitDecl()->lookup(myName); - - clang_type_t opaque_type = NULL; - - for (clang::NamedDecl *named_decl : result) + if (target_ast_context) { - if (const clang::CXXRecordDecl *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(named_decl)) - { - opaque_type = clang::QualType(record_decl->getTypeForDecl(), 0).getAsOpaquePtr(); - break; - } - else + clang::ASTContext *ast = target_ast_context->getASTContext(); + + if (ast) { - // somebody else (the user?) has defined a type with the magic name already - fail!!! - return clang_type; + const char* type_name = "__lldb_autogen_nspair"; + + clang::IdentifierInfo &myIdent = ast->Idents.get(type_name); + clang::DeclarationName myName = ast->DeclarationNames.getIdentifier(&myIdent); + + clang::DeclContext::lookup_const_result result = ast->getTranslationUnitDecl()->lookup(myName); + + for (clang::NamedDecl *named_decl : result) + { + if (const clang::CXXRecordDecl *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(named_decl)) + { + clang_type.SetClangType(ast, clang::QualType(record_decl->getTypeForDecl(), 0)); + break; + } + else + { + // somebody else (the user?) has defined a type with the magic name already - fail!!! + return clang_type; + } + } + + if (!clang_type) + { + clang_type = target_ast_context->CreateRecordType(NULL, lldb::eAccessPublic, type_name, clang::TTK_Struct, lldb::eLanguageTypeC); + + if (clang_type) + { + clang_type.StartTagDeclarationDefinition(); + ClangASTType id_clang_type = target_ast_context->GetBasicType (eBasicTypeObjCID); + clang_type.AddFieldToRecordType("key", id_clang_type, lldb::eAccessPublic, 0); + clang_type.AddFieldToRecordType("value", id_clang_type, lldb::eAccessPublic, 0); + clang_type.CompleteTagDeclarationDefinition(); + } + } } } - - if (!opaque_type) - { - opaque_type = target_ast_context->CreateRecordType(NULL, lldb::eAccessPublic, type_name, clang::TTK_Struct, lldb::eLanguageTypeC); - - if (!opaque_type) - return clang_type; - - target_ast_context->StartTagDeclarationDefinition(opaque_type); - - target_ast_context->AddFieldToRecordType(opaque_type, "key", target_ast_context->GetBuiltInType_objc_id(), lldb::eAccessPublic, 0); - target_ast_context->AddFieldToRecordType(opaque_type, "value", target_ast_context->GetBuiltInType_objc_id(), lldb::eAccessPublic, 0); - - target_ast_context->CompleteTagDeclarationDefinition(opaque_type); - } - - clang_type.SetClangType(target_ast_context->getASTContext(), opaque_type); return clang_type; } diff --git a/lldb/source/Expression/ASTDumper.cpp b/lldb/source/Expression/ASTDumper.cpp index b5c7b32e4b3..5210d149e66 100644 --- a/lldb/source/Expression/ASTDumper.cpp +++ b/lldb/source/Expression/ASTDumper.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/Log.h" #include "lldb/Expression/ASTDumper.h" +#include "lldb/Symbol/ClangASTType.h" #include "llvm/Support/raw_ostream.h" @@ -77,7 +78,13 @@ ASTDumper::ASTDumper (lldb::clang_type_t type) { m_dump = clang::QualType::getFromOpaquePtr(type).getAsString(); } - + +ASTDumper::ASTDumper (const ClangASTType &clang_type) +{ + m_dump = clang_type.GetQualType().getAsString(); +} + + const char * ASTDumper::GetCString() { diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index 0fc3db61b8b..49513d740f3 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -238,12 +238,12 @@ ClangASTSource::CompleteType (TagDecl *tag_decl) if (!type) continue; - lldb::clang_type_t opaque_type = type->GetClangFullType(); + ClangASTType clang_type (type->GetClangFullType()); - if (!opaque_type) + if (!clang_type) continue; - const TagType *tag_type = QualType::getFromOpaquePtr(opaque_type)->getAs<TagType>(); + const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>(); if (!tag_type) continue; @@ -277,12 +277,12 @@ ClangASTSource::CompleteType (TagDecl *tag_decl) if (!type) continue; - lldb::clang_type_t opaque_type = type->GetClangFullType(); + ClangASTType clang_type (type->GetClangFullType()); - if (!opaque_type) + if (!clang_type) continue; - const TagType *tag_type = QualType::getFromOpaquePtr(opaque_type)->getAs<TagType>(); + const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>(); if (!tag_type) continue; @@ -346,7 +346,7 @@ ClangASTSource::GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_de if (!complete_type_sp) return NULL; - TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType(), complete_type_sp->GetClangAST()); + TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType()); lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType(); if (!complete_opaque_type) @@ -696,12 +696,11 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, (name_string ? name_string : "<anonymous>")); } - clang::ASTContext *type_ast = type_sp->GetClangAST(); - lldb::clang_type_t full_type = type_sp->GetClangFullType(); + ClangASTType full_type = type_sp->GetClangFullType(); - void *copied_type = GuardedCopyType(m_ast_context, type_ast, full_type); + ClangASTType copied_clang_type (GuardedCopyType(full_type)); - if (!copied_type) + if (!copied_clang_type) { if (log) log->Printf(" CAS::FEVD[%u] - Couldn't export a type", @@ -710,7 +709,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, break; } - context.AddTypeDecl(copied_type); + context.AddTypeDecl(copied_clang_type); } else { @@ -750,13 +749,9 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, name.GetCString()); } - const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr(); + ClangASTType copied_clang_type (GuardedCopyType(types[0])); - clang::QualType runtime_qual_type(runtime_clang_type, 0); - - void *copied_type = GuardedCopyType(m_ast_context, type_vendor->GetClangASTContext(), runtime_qual_type.getAsOpaquePtr()); - - if (!copied_type) + if (!copied_clang_type) { if (log) log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the runtime", @@ -765,7 +760,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, break; } - context.AddTypeDecl(copied_type); + context.AddTypeDecl(copied_clang_type); } while(0); } @@ -1688,42 +1683,43 @@ ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::Name return dyn_cast<NamespaceDecl>(copied_decl); } -void * -ClangASTSource::GuardedCopyType (ASTContext *dest_context, - ASTContext *source_context, - void *clang_type) +ClangASTType +ClangASTSource::GuardedCopyType (const ClangASTType &src_type) { ClangASTMetrics::RegisterLLDBImport(); SetImportInProgress(true); - QualType ret_qual_type = m_ast_importer->CopyType (m_ast_context, source_context, QualType::getFromOpaquePtr(clang_type)); - - void *ret = ret_qual_type.getAsOpaquePtr(); + QualType copied_qual_type = m_ast_importer->CopyType (m_ast_context, src_type.GetASTContext(), src_type.GetQualType()); SetImportInProgress(false); - if (ret && ret_qual_type->getCanonicalTypeInternal().isNull()) + if (copied_qual_type.getAsOpaquePtr() && copied_qual_type->getCanonicalTypeInternal().isNull()) // this shouldn't happen, but we're hardening because the AST importer seems to be generating bad types // on occasion. - return NULL; + return ClangASTType(); - return ret; + return ClangASTType(m_ast_context, copied_qual_type); } clang::NamedDecl * -NameSearchContext::AddVarDecl(void *type) +NameSearchContext::AddVarDecl(const ClangASTType &type) { + assert (type && "Type for variable must be valid!"); + + if (!type.IsValid()) + return NULL; + IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo(); - assert (type && "Type for variable must be non-NULL!"); - - clang::NamedDecl *Decl = VarDecl::Create(*m_ast_source.m_ast_context, + clang::ASTContext *ast = type.GetASTContext(); + + clang::NamedDecl *Decl = VarDecl::Create(*ast, const_cast<DeclContext*>(m_decl_context), SourceLocation(), SourceLocation(), ii, - QualType::getFromOpaquePtr(type), + type.GetQualType(), 0, SC_Static); m_decls.push_back(Decl); @@ -1732,25 +1728,32 @@ NameSearchContext::AddVarDecl(void *type) } clang::NamedDecl * -NameSearchContext::AddFunDecl (void *type) +NameSearchContext::AddFunDecl (const ClangASTType &type) { - assert (type && "Type for variable must be non-NULL!"); + assert (type && "Type for variable must be valid!"); + if (!type.IsValid()) + return NULL; + if (m_function_types.count(type)) return NULL; m_function_types.insert(type); + QualType qual_type (type.GetQualType()); + + clang::ASTContext *ast = type.GetASTContext(); + const bool isInlineSpecified = false; const bool hasWrittenPrototype = true; const bool isConstexprSpecified = false; - clang::FunctionDecl *func_decl = FunctionDecl::Create (*m_ast_source.m_ast_context, + clang::FunctionDecl *func_decl = FunctionDecl::Create (*ast, const_cast<DeclContext*>(m_decl_context), SourceLocation(), SourceLocation(), m_decl_name.getAsIdentifierInfo(), - QualType::getFromOpaquePtr(type), + qual_type, NULL, SC_Static, isInlineSpecified, @@ -1761,7 +1764,6 @@ NameSearchContext::AddFunDecl (void *type) // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do // this, we raid the function's FunctionProtoType for types. - QualType qual_type (QualType::getFromOpaquePtr(type)); const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>(); if (func_proto_type) @@ -1775,7 +1777,7 @@ NameSearchContext::AddFunDecl (void *type) { QualType arg_qual_type (func_proto_type->getArgType(ArgIndex)); - parm_var_decls.push_back(ParmVarDecl::Create (*m_ast_source.m_ast_context, + parm_var_decls.push_back(ParmVarDecl::Create (*ast, const_cast<DeclContext*>(m_decl_context), SourceLocation(), SourceLocation(), @@ -1812,15 +1814,15 @@ NameSearchContext::AddGenericFunDecl() ArrayRef<QualType>(), // argument types proto_info)); - return AddFunDecl(generic_function_type.getAsOpaquePtr()); + return AddFunDecl(ClangASTType (m_ast_source.m_ast_context, generic_function_type)); } clang::NamedDecl * -NameSearchContext::AddTypeDecl(void *type) +NameSearchContext::AddTypeDecl(const ClangASTType &clang_type) { - if (type) + if (clang_type) { - QualType qual_type = QualType::getFromOpaquePtr(type); + QualType qual_type = clang_type.GetQualType(); if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type)) { diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 36b72ddae49..26dd5e725f4 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -128,14 +128,7 @@ ClangExpressionDeclMap::DidParse() { ClangExpressionVariableSP var_sp(m_found_entities.GetVariableAtIndex(entity_index)); if (var_sp) - { - ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(GetParserID()); - - if (parser_vars && parser_vars->m_lldb_value) - delete parser_vars->m_lldb_value; - var_sp->DisableParserVars(GetParserID()); - } } for (size_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->GetSize(); @@ -495,7 +488,7 @@ ClangExpressionDeclMap::GetFunctionInfo ClangExpressionVariable::ParserVars *parser_vars = entity_sp->GetParserVars(GetParserID()); - ptr = parser_vars->m_lldb_value->GetScalar().ULongLong(); + ptr = parser_vars->m_lldb_value.GetScalar().ULongLong(); return true; } @@ -784,11 +777,8 @@ ClangExpressionDeclMap::FindGlobalVariable { VariableSP var_sp = vars.GetVariableAtIndex(i); - if (type->GetASTContext() == var_sp->GetType()->GetClangAST()) - { - if (ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var_sp->GetType()->GetClangFullType())) - return var_sp; - } + if (ClangASTContext::AreTypesSame(*type, var_sp->GetType()->GetClangFullType())) + return var_sp; } } else @@ -1009,30 +999,21 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, if (!this_type) return; - QualType this_qual_type = QualType::getFromOpaquePtr(this_type->GetClangFullType()); - const PointerType *class_pointer_type = this_qual_type->getAs<PointerType>(); + ClangASTType pointee_type = this_type->GetClangForwardType().GetPointeeType(); - if (class_pointer_type) + if (pointee_type.IsValid()) { - QualType class_type = class_pointer_type->getPointeeType(); - - if (!class_type.getAsOpaquePtr()) - return; - if (log) { ASTDumper ast_dumper(this_type->GetClangFullType()); log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString()); } - TypeFromUser class_user_type (class_type.getAsOpaquePtr(), - this_type->GetClangAST()); + TypeFromUser class_user_type(pointee_type); AddOneType(context, class_user_type, current_id); - TypeFromUser this_user_type(this_type->GetClangFullType(), - this_type->GetClangAST()); - + TypeFromUser this_user_type(this_type->GetClangFullType()); m_struct_vars->m_object_pointer_type = this_user_type; return; } @@ -1135,19 +1116,17 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, if (!self_type) return; - QualType self_qual_type = QualType::getFromOpaquePtr(self_type->GetClangFullType()); + ClangASTType self_clang_type = self_type->GetClangFullType(); - if (self_qual_type->isObjCClassType()) + if (self_clang_type.IsObjCClassType()) { return; } - else if (self_qual_type->isObjCObjectPointerType()) + else if (self_clang_type.IsObjCObjectPointerType()) { - const ObjCObjectPointerType *class_pointer_type = self_qual_type->getAs<ObjCObjectPointerType>(); - - QualType class_type = class_pointer_type->getPointeeType(); - - if (!class_type.getAsOpaquePtr()) + self_clang_type = self_clang_type.GetPointeeType(); + + if (!self_clang_type) return; if (log) @@ -1156,13 +1135,11 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString()); } - TypeFromUser class_user_type (class_type.getAsOpaquePtr(), - self_type->GetClangAST()); + TypeFromUser class_user_type (self_clang_type); AddOneType(context, class_user_type, current_id); - TypeFromUser self_user_type(self_type->GetClangFullType(), - self_type->GetClangAST()); + TypeFromUser self_user_type(self_type->GetClangFullType()); m_struct_vars->m_object_pointer_type = self_user_type; return; @@ -1420,14 +1397,11 @@ MaybePromoteToBlockPointerType return block_pointer_type.getAsOpaquePtr(); } -Value * -ClangExpressionDeclMap::GetVariableValue -( - VariableSP &var, - ASTContext *parser_ast_context, - TypeFromUser *user_type, - TypeFromParser *parser_type -) +bool +ClangExpressionDeclMap::GetVariableValue (VariableSP &var, + lldb_private::Value &var_location, + TypeFromUser *user_type, + TypeFromParser *parser_type) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -1437,34 +1411,31 @@ ClangExpressionDeclMap::GetVariableValue { if (log) log->PutCString("Skipped a definition because it has no type"); - return NULL; + return false; } - clang_type_t var_opaque_type = var_type->GetClangFullType(); + ClangASTType var_clang_type = var_type->GetClangFullType(); - if (!var_opaque_type) + if (!var_clang_type) { if (log) log->PutCString("Skipped a definition because it has no Clang type"); - return NULL; + return false; } + // commented out because of <rdar://problem/11024417> ASTContext *ast = var_type->GetClangASTContext().getASTContext(); - + if (!ast) { if (log) log->PutCString("There is no AST context for the current execution context"); - return NULL; + return false; } - - // commented out because of <rdar://problem/11024417> - //var_opaque_type = MaybePromoteToBlockPointerType (ast, var_opaque_type); + //var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type); DWARFExpression &var_location_expr = var->LocationExpression(); - std::unique_ptr<Value> var_location(new Value); - lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS; Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); @@ -1483,41 +1454,34 @@ ClangExpressionDeclMap::GetVariableValue if (var_location_expr.GetExpressionData(const_value_extractor)) { - var_location->operator=(Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize())); - var_location->SetValueType(Value::eValueTypeHostAddress); + var_location = Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize()); + var_location.SetValueType(Value::eValueTypeHostAddress); } else { if (log) log->Printf("Error evaluating constant variable: %s", err.AsCString()); - return NULL; + return false; } } - void *type_to_use = NULL; + ClangASTType type_to_use = GuardedCopyType(var_clang_type); - if (parser_ast_context) + if (!type_to_use) { - type_to_use = GuardedCopyType(parser_ast_context, ast, var_opaque_type); - - if (!type_to_use) - { - if (log) - log->Printf("Couldn't copy a variable's type into the parser's AST context"); - - return NULL; - } + if (log) + log->Printf("Couldn't copy a variable's type into the parser's AST context"); - if (parser_type) - *parser_type = TypeFromParser(type_to_use, parser_ast_context); + return false; } - else - type_to_use = var_opaque_type; - if (var_location.get()->GetContextType() == Value::eContextTypeInvalid) - var_location.get()->SetContext(Value::eContextTypeClangType, type_to_use); + if (parser_type) + *parser_type = TypeFromParser(type_to_use); - if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress) + if (var_location.GetContextType() == Value::eContextTypeInvalid) + var_location.SetClangType(type_to_use); + + if (var_location.GetValueType() == Value::eValueTypeFileAddress) { SymbolContext var_sc; var->CalculateSymbolContext(&var_sc); @@ -1525,21 +1489,21 @@ ClangExpressionDeclMap::GetVariableValue if (!var_sc.module_sp) return NULL; - Address so_addr(var_location->GetScalar().ULongLong(), var_sc.module_sp->GetSectionList()); + Address so_addr(var_location.GetScalar().ULongLong(), var_sc.module_sp->GetSectionList()); lldb::addr_t load_addr = so_addr.GetLoadAddress(target); if (load_addr != LLDB_INVALID_ADDRESS) { - var_location->GetScalar() = load_addr; - var_location->SetValueType(Value::eValueTypeLoadAddress); + var_location.GetScalar() = load_addr; + var_location.SetValueType(Value::eValueTypeLoadAddress); } } if (user_type) - *user_type = TypeFromUser(var_opaque_type, ast); + *user_type = TypeFromUser(var_clang_type); - return var_location.release(); + return true; } void @@ -1551,11 +1515,10 @@ ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP v TypeFromUser ut; TypeFromParser pt; + Value var_location; - Value *var_location = GetVariableValue (var, - m_ast_context, - &ut, - &pt); + if (!GetVariableValue (var, var_location, &ut, &pt)) + return; clang::QualType parser_opaque_type = QualType::getFromOpaquePtr(pt.GetOpaqueQualType()); @@ -1568,17 +1531,14 @@ ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP v CompleteType(tag_type->getDecl()); } - if (!var_location) - return; - - NamedDecl *var_decl; - bool is_reference = ClangASTContext::IsReferenceType(pt.GetOpaqueQualType()); + bool is_reference = pt.IsReferenceType(); + NamedDecl *var_decl = NULL; if (is_reference) - var_decl = context.AddVarDecl(pt.GetOpaqueQualType()); + var_decl = context.AddVarDecl(pt); else - var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(pt.GetASTContext(), pt.GetOpaqueQualType())); + var_decl = context.AddVarDecl(pt.GetLValueReferenceType()); std::string decl_name(context.m_decl_name.getAsString()); ConstString entity_name(decl_name.c_str()); @@ -1613,10 +1573,7 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, TypeFromUser user_type (pvar_sp->GetTypeFromUser()); - TypeFromParser parser_type (GuardedCopyType(m_ast_context, - user_type.GetASTContext(), - user_type.GetOpaqueQualType()), - m_ast_context); + TypeFromParser parser_type (GuardedCopyType(user_type)); if (!parser_type.GetOpaqueQualType()) { @@ -1625,14 +1582,14 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, return; } - NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(parser_type.GetASTContext(), parser_type.GetOpaqueQualType())); + NamedDecl *var_decl = context.AddVarDecl(parser_type.GetLValueReferenceType()); pvar_sp->EnableParserVars(GetParserID()); ClangExpressionVariable::ParserVars *parser_vars = pvar_sp->GetParserVars(GetParserID()); parser_vars->m_parser_type = parser_type; - parser_vars->m_named_decl = var_decl; - parser_vars->m_llvm_value = NULL; - parser_vars->m_lldb_value = NULL; + parser_vars->m_named_decl = var_decl; + parser_vars->m_llvm_value = NULL; + parser_vars->m_lldb_value.Clear(); if (log) { @@ -1657,13 +1614,9 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext(); - TypeFromUser user_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(scratch_ast_context, false)), - scratch_ast_context); - - TypeFromParser parser_type (ClangASTContext::CreateLValueReferenceType(m_ast_context, ClangASTContext::GetVoidPtrType(m_ast_context, false)), - m_ast_context); - - NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); + TypeFromUser user_type (ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType()); + TypeFromParser parser_type (ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType()); + NamedDecl *var_decl = context.AddVarDecl(parser_type); std::string decl_name(context.m_decl_name.getAsString()); ConstString entity_name(decl_name.c_str()); @@ -1674,21 +1627,20 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, m_parser_vars->m_target_info.address_byte_size)); assert (entity.get()); - std::unique_ptr<Value> symbol_location(new Value); - + entity->EnableParserVars(GetParserID()); + ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID()); + const Address &symbol_address = symbol.GetAddress(); lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target); - symbol_location->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); - symbol_location->GetScalar() = symbol_load_addr; - symbol_location->SetValueType(Value::eValueTypeLoadAddress); + //parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); + parser_vars->m_lldb_value.SetClangType(user_type); + parser_vars->m_lldb_value.GetScalar() = symbol_load_addr; + parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress); - entity->EnableParserVars(GetParserID()); - ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID()); parser_vars->m_parser_type = parser_type; parser_vars->m_named_decl = var_decl; parser_vars->m_llvm_value = NULL; - parser_vars->m_lldb_value = symbol_location.release(); parser_vars->m_lldb_sym = &symbol; if (log) @@ -1748,11 +1700,11 @@ ClangExpressionDeclMap::ResolveUnknownTypes() TypeFromUser user_type(copied_type, scratch_ast_context); - parser_vars->m_lldb_value->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); +// parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); + parser_vars->m_lldb_value.SetClangType(user_type); parser_vars->m_parser_type = parser_type; - entity->SetClangAST(user_type.GetASTContext()); - entity->SetClangType(user_type.GetOpaqueQualType()); + entity->SetClangType(user_type); entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType); } @@ -1768,21 +1720,20 @@ ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context, { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - void *ast_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(m_ast_context, - reg_info->encoding, - reg_info->byte_size * 8); + ClangASTType clang_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (m_ast_context, + reg_info->encoding, + reg_info->byte_size * 8); - if (!ast_type) + if (!clang_type) { if (log) log->Printf(" Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str()); return; } - TypeFromParser parser_type (ast_type, - m_ast_context); + TypeFromParser parser_clang_type (clang_type); - NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); + NamedDecl *var_decl = context.AddVarDecl(parser_clang_type); ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), m_parser_vars->m_target_info.byte_order, @@ -1794,10 +1745,10 @@ ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context, entity->SetRegisterInfo (reg_info); entity->EnableParserVars(GetParserID()); ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID()); - parser_vars->m_parser_type = parser_type; - parser_vars->m_named_decl = var_decl; - parser_vars->m_llvm_value = NULL; - parser_vars->m_lldb_value = NULL; + parser_vars->m_parser_type = parser_clang_type; + parser_vars->m_named_decl = var_decl; + parser_vars->m_llvm_value = NULL; + parser_vars->m_lldb_value.Clear(); entity->m_flags |= ClangExpressionVariable::EVBareRegister; if (log) @@ -1809,7 +1760,7 @@ ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context, void ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, - Function* fun, + Function* function, Symbol* symbol, unsigned int current_id) { @@ -1817,51 +1768,46 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - NamedDecl *fun_decl = NULL; - std::unique_ptr<Value> fun_location(new Value); + NamedDecl *function_decl = NULL; const Address *fun_address = NULL; - - // only valid for Functions, not for Symbols - void *fun_opaque_type = NULL; - ASTContext *fun_ast_context = NULL; + ClangASTType function_clang_type; bool is_indirect_function = false; - if (fun) + if (function) { - Type *fun_type = fun->GetType(); + Type *function_type = function->GetType(); - if (!fun_type) + if (!function_type) { if (log) log->PutCString(" Skipped a function because it has no type"); return; } - fun_opaque_type = fun_type->GetClangFullType(); + function_clang_type = function_type->GetClangFullType(); - if (!fun_opaque_type) + if (!function_clang_type) { if (log) log->PutCString(" Skipped a function because it has no Clang type"); return; } - fun_address = &fun->GetAddressRange().GetBaseAddress(); + fun_address = &function->GetAddressRange().GetBaseAddress(); - fun_ast_context = fun_type->GetClangASTContext().getASTContext(); - void *copied_type = GuardedCopyType(m_ast_context, fun_ast_context, fun_opaque_type); - if (copied_type) + ClangASTType copied_function_type = GuardedCopyType(function_clang_type); + if (copied_function_type) { - fun_decl = context.AddFunDecl(copied_type); + function_decl = context.AddFunDecl(copied_function_type); - if (!fun_decl) + if (!function_decl) { if (log) { log->Printf (" Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}", - fun_type->GetName().GetCString(), - fun_type->GetID()); + function_type->GetName().GetCString(), + function_type->GetID()); } return; @@ -1873,8 +1819,8 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, if (log) { log->Printf (" Failed to import the function type '%s' {0x%8.8" PRIx64 "} into the expression parser AST contenxt", - fun_type->GetName().GetCString(), - fun_type->GetID()); + function_type->GetName().GetCString(), + function_type->GetID()); } return; @@ -1883,7 +1829,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, else if (symbol) { fun_address = &symbol->GetAddress(); - fun_decl = context.AddGenericFunDecl(); + function_decl = context.AddGenericFunDecl(); is_indirect_function = symbol->IsIndirect(); } else @@ -1897,10 +1843,22 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target, is_indirect_function); + ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (), + m_parser_vars->m_target_info.byte_order, + m_parser_vars->m_target_info.address_byte_size)); + assert (entity.get()); + + std::string decl_name(context.m_decl_name.getAsString()); + entity->SetName(ConstString(decl_name.c_str())); + entity->SetClangType (function_clang_type); + entity->EnableParserVars(GetParserID()); + + ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID()); + if (load_addr != LLDB_INVALID_ADDRESS) { - fun_location->SetValueType(Value::eValueTypeLoadAddress); - fun_location->GetScalar() = load_addr; + parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress); + parser_vars->m_lldb_value.GetScalar() = load_addr; } else { @@ -1908,28 +1866,17 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, lldb::addr_t file_addr = fun_address->GetFileAddress(); - fun_location->SetValueType(Value::eValueTypeFileAddress); - fun_location->GetScalar() = file_addr; + parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress); + parser_vars->m_lldb_value.GetScalar() = file_addr; } - ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (), - m_parser_vars->m_target_info.byte_order, - m_parser_vars->m_target_info.address_byte_size)); - assert (entity.get()); - std::string decl_name(context.m_decl_name.getAsString()); - entity->SetName(ConstString(decl_name.c_str())); - entity->SetClangType (fun_opaque_type); - entity->SetClangAST (fun_ast_context); - - entity->EnableParserVars(GetParserID()); - ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID()); - parser_vars->m_named_decl = fun_decl; + + parser_vars->m_named_decl = function_decl; parser_vars->m_llvm_value = NULL; - parser_vars->m_lldb_value = fun_location.release(); - + if (log) { - ASTDumper ast_dumper(fun_decl); + ASTDumper ast_dumper(function_decl); StreamString ss; @@ -1937,7 +1884,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, log->Printf(" CEDM::FEVD[%u] Found %s function %s (description %s), returned %s", current_id, - (fun ? "specific" : "generic"), + (function ? "specific" : "generic"), decl_name.c_str(), ss.GetData(), ast_dumper.GetCString()); @@ -1948,12 +1895,9 @@ TypeFromParser ClangExpressionDeclMap::CopyClassType(TypeFromUser &ut, unsigned int current_id) { - ASTContext *parser_ast_context = m_ast_context; - ASTContext *user_ast_context = ut.GetASTContext(); - - void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType()); + ClangASTType copied_clang_type = GuardedCopyType(ut); - if (!copied_type) + if (!copied_clang_type) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -1963,18 +1907,17 @@ ClangExpressionDeclMap::CopyClassType(TypeFromUser &ut, return TypeFromParser(); } - if (ClangASTContext::IsAggregateType(copied_type) && ClangASTContext::GetCompleteType (parser_ast_context, copied_type)) + if (copied_clang_type.IsAggregateType() && copied_clang_type.GetCompleteType ()) { - void *args[1]; + ClangASTType void_clang_type = ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid); + ClangASTType void_ptr_clang_type = void_clang_type.GetPointerType(); - args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false); - - clang_type_t method_type = ClangASTContext::CreateFunctionType (parser_ast_context, - ClangASTContext::GetBuiltInType_void(parser_ast_context), - args, + ClangASTType method_type = ClangASTContext::CreateFunctionType (m_ast_context, + void_clang_type, + &void_ptr_clang_type, 1, false, - ClangASTContext::GetTypeQualifiers(copied_type)); + copied_clang_type.GetTypeQualifiers()); const bool is_virtual = false; const bool is_static = false; @@ -1983,20 +1926,18 @@ ClangExpressionDeclMap::CopyClassType(TypeFromUser &ut, const bool is_attr_used = true; const bool is_artificial = false; - ClangASTContext::AddMethodToCXXRecordType (parser_ast_context, - copied_type, - "$__lldb_expr", - method_type, - lldb::eAccessPublic, - is_virtual, - is_static, - is_inline, - is_explicit, - is_attr_used, - is_artificial); + copied_clang_type.AddMethodToCXXRecordType ("$__lldb_expr", + method_type, + lldb::eAccessPublic, + is_virtual, + is_static, + is_inline, + is_explicit, + is_attr_used, + is_artificial); } - return TypeFromParser(copied_type, parser_ast_context); + return TypeFromParser(copied_clang_type); } void @@ -2004,12 +1945,9 @@ ClangExpressionDeclMap::AddOneType(NameSearchContext &context, TypeFromUser &ut, unsigned int current_id) { - ASTContext *parser_ast_context = m_ast_context; - ASTContext *user_ast_context = ut.GetASTContext(); - - void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType()); + ClangASTType copied_clang_type = GuardedCopyType(ut); - if (!copied_type) + if (!copied_clang_type) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -2019,5 +1957,5 @@ ClangExpressionDeclMap::AddOneType(NameSearchContext &context, return; } - context.AddTypeDecl(copied_type); + context.AddTypeDecl(copied_clang_type); } diff --git a/lldb/source/Expression/ClangExpressionVariable.cpp b/lldb/source/Expression/ClangExpressionVariable.cpp index ec08a0c0af3..0d355ce341c 100644 --- a/lldb/source/Expression/ClangExpressionVariable.cpp +++ b/lldb/source/Expression/ClangExpressionVariable.cpp @@ -74,34 +74,23 @@ ClangExpressionVariable::SetRegisterInfo (const RegisterInfo *reg_info) return m_frozen_sp->GetValue().SetContext (Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_info)); } -lldb::clang_type_t +ClangASTType ClangExpressionVariable::GetClangType() { return m_frozen_sp->GetClangType(); } void -ClangExpressionVariable::SetClangType(lldb::clang_type_t clang_type) +ClangExpressionVariable::SetClangType(const ClangASTType &clang_type) { - m_frozen_sp->GetValue().SetContext(Value::eContextTypeClangType, clang_type); + m_frozen_sp->GetValue().SetClangType(clang_type); } -clang::ASTContext * -ClangExpressionVariable::GetClangAST() -{ - return m_frozen_sp->GetClangAST(); -} - -void -ClangExpressionVariable::SetClangAST (clang::ASTContext *ast) -{ - m_frozen_sp->SetClangAST (ast); -} TypeFromUser ClangExpressionVariable::GetTypeFromUser() { - TypeFromUser tfu (m_frozen_sp->GetClangType(), m_frozen_sp->GetClangAST()); + TypeFromUser tfu (m_frozen_sp->GetClangType()); return tfu; } diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/ClangFunction.cpp index e37a16a4fb7..177138df801 100644 --- a/lldb/source/Expression/ClangFunction.cpp +++ b/lldb/source/Expression/ClangFunction.cpp @@ -51,15 +51,13 @@ using namespace lldb_private; ClangFunction::ClangFunction ( ExecutionContextScope &exe_scope, - ClangASTContext *ast_context, - void *return_qualtype, + const ClangASTType &return_type, const Address& functionAddress, const ValueList &arg_value_list ) : m_function_ptr (NULL), m_function_addr (functionAddress), - m_function_return_qual_type(return_qualtype), - m_clang_ast_context (ast_context), + m_function_return_type(return_type), m_wrapper_function_name ("__lldb_caller_function"), m_wrapper_struct_name ("__lldb_caller_struct"), m_wrapper_args_addrs (), @@ -81,7 +79,7 @@ ClangFunction::ClangFunction ) : m_function_ptr (&function), m_function_addr (), - m_function_return_qual_type (), + m_function_return_type (), m_clang_ast_context (ast_context), m_wrapper_function_name ("__lldb_function_caller"), m_wrapper_struct_name ("__lldb_caller_struct"), @@ -95,7 +93,7 @@ ClangFunction::ClangFunction assert (m_jit_process_wp.lock()); m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress(); - m_function_return_qual_type = m_function_ptr->GetReturnClangType(); + m_function_return_type = m_function_ptr->GetClangType().GetFunctionReturnType(); } //---------------------------------------------------------------------- @@ -114,8 +112,7 @@ ClangFunction::CompileFunction (Stream &errors) // FIXME: How does clang tell us there's no return value? We need to handle that case. unsigned num_errors = 0; - std::string return_type_str (ClangASTType::GetTypeNameForOpaqueQualType (m_clang_ast_context->getASTContext(), - m_function_return_qual_type)); + std::string return_type_str (m_function_return_type.GetTypeName()); // Cons up the function we're going to wrap our call in, then compile it... // We declare the function "extern "C"" because the compiler might be in C++ @@ -137,16 +134,22 @@ ClangFunction::CompileFunction (Stream &errors) // to pull the defined arguments out of the function, then add the types from the // arguments list for the variable arguments. - size_t num_args = UINT32_MAX; + uint32_t num_args = UINT32_MAX; bool trust_function = false; // GetArgumentCount returns -1 for an unprototyped function. + ClangASTType function_clang_type; if (m_function_ptr) { - int num_func_args = m_function_ptr->GetArgumentCount(); - if (num_func_args >= 0) - trust_function = true; - else - num_args = num_func_args; + function_clang_type = m_function_ptr->GetClangType(); + if (function_clang_type) + { + int num_func_args = function_clang_type.GetFunctionArgumentCount(); + if (num_func_args >= 0) + { + trust_function = true; + num_args = num_func_args; + } + } } if (num_args == UINT32_MAX) @@ -160,18 +163,14 @@ ClangFunction::CompileFunction (Stream &errors) if (trust_function) { - lldb::clang_type_t arg_clang_type = m_function_ptr->GetArgumentTypeAtIndex(i); - type_name = ClangASTType::GetTypeNameForOpaqueQualType (m_clang_ast_context->getASTContext(), - arg_clang_type); + type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i).GetTypeName(); } else { - Value *arg_value = m_arg_values.GetValueAtIndex(i); - lldb::clang_type_t clang_qual_type = arg_value->GetClangType (); - if (clang_qual_type != NULL) + ClangASTType clang_qual_type = m_arg_values.GetValueAtIndex(i)->GetClangType (); + if (clang_qual_type) { - type_name = ClangASTType::GetTypeNameForOpaqueQualType (m_clang_ast_context->getASTContext(), - clang_qual_type); + type_name = clang_qual_type.GetTypeName(); } else { @@ -362,11 +361,11 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings) if (arg_value->GetValueType() == Value::eValueTypeHostAddress && - arg_value->GetContextType() == Value::eContextTypeClangType && - ClangASTContext::IsPointerType(arg_value->GetClangType())) + arg_value->GetContextType() == Value::eContextTypeInvalid && + arg_value->GetClangType().IsPointerType()) continue; - const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext()); + const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx); if (!process->WriteScalarToMemory(args_addr_ref + offset, arg_scalar, arg_scalar.GetByteSize(), error)) return false; @@ -464,7 +463,7 @@ ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t arg if (error.Fail()) return false; - ret_value.SetContext (Value::eContextTypeClangType, m_function_return_qual_type); + ret_value.SetClangType(m_function_return_type); ret_value.SetValueType(Value::eValueTypeScalar); return true; } diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index c72c3b10d54..18f7a8daaa1 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -297,21 +297,19 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) return; } - lldb::clang_type_t self_opaque_type = self_type->GetClangForwardType(); + ClangASTType self_clang_type = self_type->GetClangForwardType(); - if (!self_opaque_type) + if (!self_clang_type) { err.SetErrorString(selfErrorString); return; } - - clang::QualType self_qual_type = clang::QualType::getFromOpaquePtr(self_opaque_type); - - if (self_qual_type->isObjCClassType()) + + if (self_clang_type.IsObjCClassType()) { return; } - else if (self_qual_type->isObjCObjectPointerType()) + else if (self_clang_type.IsObjCObjectPointerType()) { m_objectivec = true; m_needs_object_ptr = true; @@ -487,6 +485,26 @@ ClangUserExpression::Parse (Stream &error_stream, m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx)); + class OnExit + { + public: + typedef std::function <void (void)> Callback; + + OnExit (Callback const &callback) : + m_callback(callback) + { + } + + ~OnExit () + { + m_callback(); + } + private: + Callback m_callback; + }; + + OnExit on_exit([this]() { m_expr_decl_map.reset(); }); + if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get())) { error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n"); diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 07cb6881efe..7797205ffb1 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -1195,7 +1195,6 @@ bool DWARFExpression::Evaluate ( ExecutionContextScope *exe_scope, - clang::ASTContext *ast_context, ClangExpressionVariableList *expr_locals, ClangExpressionDeclMap *decl_map, lldb::addr_t loclist_base_load_addr, @@ -1205,14 +1204,13 @@ DWARFExpression::Evaluate ) const { ExecutionContext exe_ctx (exe_scope); - return Evaluate(&exe_ctx, ast_context, expr_locals, decl_map, NULL, loclist_base_load_addr, initial_value_ptr, result, error_ptr); + return Evaluate(&exe_ctx, expr_locals, decl_map, NULL, loclist_base_load_addr, initial_value_ptr, result, error_ptr); } bool DWARFExpression::Evaluate ( ExecutionContext *exe_ctx, - clang::ASTContext *ast_context, ClangExpressionVariableList *expr_locals, ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx, @@ -1269,7 +1267,7 @@ DWARFExpression::Evaluate if (length > 0 && lo_pc <= pc && pc < hi_pc) { - return DWARFExpression::Evaluate (exe_ctx, ast_context, expr_locals, decl_map, reg_ctx, m_data, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr); + return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr); } offset += length; } @@ -1281,7 +1279,7 @@ DWARFExpression::Evaluate } // Not a location list, just a single expression. - return DWARFExpression::Evaluate (exe_ctx, ast_context, expr_locals, decl_map, reg_ctx, m_data, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr); + return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr); } @@ -1290,7 +1288,6 @@ bool DWARFExpression::Evaluate ( ExecutionContext *exe_ctx, - clang::ASTContext *ast_context, ClangExpressionVariableList *expr_locals, ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx, @@ -1769,7 +1766,7 @@ DWARFExpression::Evaluate error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_abs."); return false; } - else if (stack.back().ResolveValue(exe_ctx, ast_context).AbsoluteValue() == false) + else if (stack.back().ResolveValue(exe_ctx).AbsoluteValue() == false) { if (error_ptr) error_ptr->SetErrorString("Failed to take the absolute value of the first stack item."); @@ -1794,7 +1791,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) & tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx); } break; @@ -1815,7 +1812,7 @@ DWARFExpression::Evaluate else { tmp = stack.back(); - if (tmp.ResolveValue(exe_ctx, ast_context).IsZero()) + if (tmp.ResolveValue(exe_ctx).IsZero()) { if (error_ptr) error_ptr->SetErrorString("Divide by zero."); @@ -1824,8 +1821,8 @@ DWARFExpression::Evaluate else { stack.pop_back(); - stack.back() = stack.back().ResolveValue(exe_ctx, ast_context) / tmp.ResolveValue(exe_ctx, ast_context); - if (!stack.back().ResolveValue(exe_ctx, ast_context).IsValid()) + stack.back() = stack.back().ResolveValue(exe_ctx) / tmp.ResolveValue(exe_ctx); + if (!stack.back().ResolveValue(exe_ctx).IsValid()) { if (error_ptr) error_ptr->SetErrorString("Divide failed."); @@ -1852,7 +1849,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) - tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx); } break; @@ -1874,7 +1871,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) % tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx); } break; @@ -1896,7 +1893,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) * tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx); } break; @@ -1914,7 +1911,7 @@ DWARFExpression::Evaluate } else { - if (stack.back().ResolveValue(exe_ctx, ast_context).UnaryNegate() == false) + if (stack.back().ResolveValue(exe_ctx).UnaryNegate() == false) { if (error_ptr) error_ptr->SetErrorString("Unary negate failed."); @@ -1938,7 +1935,7 @@ DWARFExpression::Evaluate } else { - if (stack.back().ResolveValue(exe_ctx, ast_context).OnesComplement() == false) + if (stack.back().ResolveValue(exe_ctx).OnesComplement() == false) { if (error_ptr) error_ptr->SetErrorString("Logical NOT failed."); @@ -1964,7 +1961,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) | tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx); } break; @@ -1985,7 +1982,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) + tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) + tmp.ResolveValue(exe_ctx); } break; @@ -2006,8 +2003,8 @@ DWARFExpression::Evaluate { const uint64_t uconst_value = opcodes.GetULEB128(&offset); // Implicit conversion from a UINT to a Scalar... - stack.back().ResolveValue(exe_ctx, ast_context) += uconst_value; - if (!stack.back().ResolveValue(exe_ctx, ast_context).IsValid()) + stack.back().ResolveValue(exe_ctx) += uconst_value; + if (!stack.back().ResolveValue(exe_ctx).IsValid()) { if (error_ptr) error_ptr->SetErrorString("DW_OP_plus_uconst failed."); @@ -2034,7 +2031,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) <<= tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx); } break; @@ -2056,7 +2053,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - if (stack.back().ResolveValue(exe_ctx, ast_context).ShiftRightLogical(tmp.ResolveValue(exe_ctx, ast_context)) == false) + if (stack.back().ResolveValue(exe_ctx).ShiftRightLogical(tmp.ResolveValue(exe_ctx)) == false) { if (error_ptr) error_ptr->SetErrorString("DW_OP_shr failed."); @@ -2084,7 +2081,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) >>= tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx); } break; @@ -2105,7 +2102,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) ^ tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx); } break; @@ -2149,7 +2146,7 @@ DWARFExpression::Evaluate stack.pop_back(); int16_t bra_offset = (int16_t)opcodes.GetU16(&offset); Scalar zero(0); - if (tmp.ResolveValue(exe_ctx, ast_context) != zero) + if (tmp.ResolveValue(exe_ctx) != zero) { lldb::offset_t new_offset = offset + bra_offset; if (new_offset >= opcodes_offset && new_offset < end_offset) @@ -2184,7 +2181,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) == tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx); } break; @@ -2208,7 +2205,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) >= tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx); } break; @@ -2232,7 +2229,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) > tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx); } break; @@ -2256,7 +2253,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) <= tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx); } break; @@ -2280,7 +2277,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) < tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx); } break; @@ -2304,7 +2301,7 @@ DWARFExpression::Evaluate { tmp = stack.back(); stack.pop_back(); - stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) != tmp.ResolveValue(exe_ctx, ast_context); + stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx); } break; @@ -2457,7 +2454,7 @@ DWARFExpression::Evaluate if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp)) { int64_t breg_offset = opcodes.GetSLEB128(&offset); - tmp.ResolveValue(exe_ctx, ast_context) += (uint64_t)breg_offset; + tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset; tmp.ClearContext(); stack.push_back(tmp); stack.back().SetValueType (Value::eValueTypeLoadAddress); @@ -2481,7 +2478,7 @@ DWARFExpression::Evaluate if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp)) { int64_t breg_offset = opcodes.GetSLEB128(&offset); - tmp.ResolveValue(exe_ctx, ast_context) += (uint64_t)breg_offset; + tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset; tmp.ClearContext(); stack.push_back(tmp); stack.back().SetValueType (Value::eValueTypeLoadAddress); @@ -2630,566 +2627,6 @@ DWARFExpression::Evaluate case DW_OP_stack_value: stack.back().SetValueType(Value::eValueTypeScalar); break; - -#if 0 - //---------------------------------------------------------------------- - // OPCODE: DW_OP_call_ref - // OPERANDS: - // uint32_t absolute DIE offset for 32-bit DWARF or a uint64_t - // absolute DIE offset for 64 bit DWARF. - // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF - // expression. Takes a single operand. In the 32-bit DWARF format, the - // operand is a 4-byte unsigned value; in the 64-bit DWARF format, it - // is an 8-byte unsigned value. The operand is used as the offset of a - // debugging information entry in a .debug_info section which may be - // contained in a shared object for executable other than that - // containing the operator. For references from one shared object or - // executable to another, the relocation must be performed by the - // consumer. - // - // Operand interpretation of DW_OP_call_ref is exactly like that for - // DW_FORM_ref_addr. - // - // This operation transfers control of DWARF expression evaluation - // to the DW_AT_location attribute of the referenced DIE. If there is - // no such attribute, then there is no effect. Execution of the DWARF - // expression of a DW_AT_location attribute may add to and/or remove from - // values on the stack. Execution returns to the point following the call - // when the end of the attribute is reached. Values on the stack at the - // time of the call may be used as parameters by the called expression - // and values left on the stack by the called expression may be used as - // return values by prior agreement between the calling and called - // expressions. - //---------------------------------------------------------------------- - case DW_OP_call_ref: - if (error_ptr) - error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call_ref."); - return false; - - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_array_ref - // OPERANDS: none - // DESCRIPTION: Pops a value off the stack and uses it as the array - // index. Pops a second value off the stack and uses it as the array - // itself. Pushes a value onto the stack representing the element of - // the array specified by the index. - //---------------------------------------------------------------------- - case DW_OP_APPLE_array_ref: - { - if (stack.size() < 2) - { - if (error_ptr) - error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_APPLE_array_ref."); - return false; - } - - Value index_val = stack.back(); - stack.pop_back(); - Value array_val = stack.back(); - stack.pop_back(); - - Scalar &index_scalar = index_val.ResolveValue(exe_ctx, ast_context); - int64_t index = index_scalar.SLongLong(LLONG_MAX); - - if (index == LLONG_MAX) - { - if (error_ptr) - error_ptr->SetErrorString("Invalid array index."); - return false; - } - - if (array_val.GetContextType() != Value::eContextTypeClangType) - { - if (error_ptr) - error_ptr->SetErrorString("Arrays without Clang types are unhandled at this time."); - return false; - } - - if (array_val.GetValueType() != Value::eValueTypeLoadAddress && - array_val.GetValueType() != Value::eValueTypeHostAddress) - { - if (error_ptr) - error_ptr->SetErrorString("Array must be stored in memory."); - return false; - } - - void *array_type = array_val.GetClangType(); - - void *member_type; - uint64_t size = 0; - - if ((!ClangASTContext::IsPointerType(array_type, &member_type)) && - (!ClangASTContext::IsArrayType(array_type, &member_type, &size))) - { - if (error_ptr) - error_ptr->SetErrorString("Array reference from something that is neither a pointer nor an array."); - return false; - } - - if (size && (index >= size || index < 0)) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat("Out of bounds array access. %" PRId64 " is not in [0, %" PRIu64 "]", index, size); - return false; - } - - uint64_t member_bit_size = ClangASTType::GetClangTypeBitWidth(ast_context, member_type); - uint64_t member_bit_align = ClangASTType::GetTypeBitAlign(ast_context, member_type); - uint64_t member_bit_incr = ((member_bit_size + member_bit_align - 1) / member_bit_align) * member_bit_align; - if (member_bit_incr % 8) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat("Array increment is not byte aligned"); - return false; - } - int64_t member_offset = (int64_t)(member_bit_incr / 8) * index; - - Value member; - - member.SetContext(Value::eContextTypeClangType, member_type); - member.SetValueType(array_val.GetValueType()); - - addr_t array_base = (addr_t)array_val.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); - addr_t member_loc = array_base + member_offset; - member.GetScalar() = (uint64_t)member_loc; - - stack.push_back(member); - } - break; - - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_uninit - // OPERANDS: none - // DESCRIPTION: Lets us know that the value is currently not initialized - //---------------------------------------------------------------------- - case DW_OP_APPLE_uninit: - //return eResultTypeErrorUninitialized; - break; // Ignore this as we have seen cases where this value is incorrectly added - - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_assign - // OPERANDS: none - // DESCRIPTION: Pops a value off of the stack and assigns it to the next - // item on the stack which must be something assignable (inferior - // Variable, inferior Type with address, inferior register, or - // expression local variable. - //---------------------------------------------------------------------- - case DW_OP_APPLE_assign: - if (stack.size() < 2) - { - if (error_ptr) - error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_APPLE_assign."); - return false; - } - else - { - tmp = stack.back(); - stack.pop_back(); - Value::ContextType context_type = stack.back().GetContextType(); - StreamString new_value(Stream::eBinary, 4, lldb::endian::InlHostByteOrder()); - switch (context_type) - { - case Value::eContextTypeClangType: - { - void *clang_type = stack.back().GetClangType(); - - if (ClangASTContext::IsAggregateType (clang_type)) - { - Value::ValueType source_value_type = tmp.GetValueType(); - Value::ValueType target_value_type = stack.back().GetValueType(); - - addr_t source_addr = (addr_t)tmp.GetScalar().ULongLong(); - addr_t target_addr = (addr_t)stack.back().GetScalar().ULongLong(); - - const uint64_t byte_size = ClangASTType::GetTypeByteSize(ast_context, clang_type); - - switch (source_value_type) - { - case Value::eValueTypeScalar: - case Value::eValueTypeFileAddress: - break; - - case Value::eValueTypeLoadAddress: - switch (target_value_type) - { - case Value::eValueTypeLoadAddress: - { - DataBufferHeap data; - data.SetByteSize(byte_size); - - Error error; - if (process->ReadMemory (source_addr, data.GetBytes(), byte_size, error) != byte_size) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString()); - return false; - } - - if (process->WriteMemory (target_addr, data.GetBytes(), byte_size, error) != byte_size) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString()); - return false; - } - } - break; - case Value::eValueTypeHostAddress: - if (process->GetByteOrder() != lldb::endian::InlHostByteOrder()) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("Copy of composite types between incompatible byte orders is unimplemented"); - return false; - } - else - { - Error error; - if (process->ReadMemory (source_addr, (uint8_t*)target_addr, byte_size, error) != byte_size) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString()); - return false; - } - } - break; - default: - return false; - } - break; - case Value::eValueTypeHostAddress: - switch (target_value_type) - { - case Value::eValueTypeLoadAddress: - if (process->GetByteOrder() != lldb::endian::InlHostByteOrder()) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("Copy of composite types between incompatible byte orders is unimplemented"); - return false; - } - else - { - Error error; - if (process->WriteMemory (target_addr, (uint8_t*)source_addr, byte_size, error) != byte_size) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString()); - return false; - } - } - case Value::eValueTypeHostAddress: - memcpy ((uint8_t*)target_addr, (uint8_t*)source_addr, byte_size); - break; - default: - return false; - } - } - } - else - { - if (!ClangASTType::SetValueFromScalar (ast_context, - clang_type, - tmp.ResolveValue(exe_ctx, ast_context), - new_value)) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("Couldn't extract a value from an integral type.\n"); - return false; - } - - Value::ValueType value_type = stack.back().GetValueType(); - - switch (value_type) - { - case Value::eValueTypeLoadAddress: - case Value::eValueTypeHostAddress: - { - AddressType address_type = (value_type == Value::eValueTypeLoadAddress ? eAddressTypeLoad : eAddressTypeHost); - lldb::addr_t addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS); - if (!ClangASTType::WriteToMemory (ast_context, - clang_type, - exe_ctx, - addr, - address_type, - new_value)) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("Failed to write value to memory at 0x%" PRIx64 ".\n", addr); - return false; - } - } - break; - - default: - break; - } - } - } - break; - - default: - if (error_ptr) - error_ptr->SetErrorString ("Assign failed."); - return false; - } - } - break; - - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_address_of - // OPERANDS: none - // DESCRIPTION: Pops a value off of the stack and pushed its address. - // The top item on the stack must be a variable, or already be a memory - // location. - //---------------------------------------------------------------------- - case DW_OP_APPLE_address_of: - if (stack.empty()) - { - if (error_ptr) - error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_address_of."); - return false; - } - else - { - Value::ValueType value_type = stack.back().GetValueType(); - switch (value_type) - { - default: - case Value::eValueTypeScalar: // raw scalar value - if (error_ptr) - error_ptr->SetErrorString("Top stack item isn't a memory based object."); - return false; - - case Value::eValueTypeLoadAddress: // load address value - case Value::eValueTypeFileAddress: // file address value - case Value::eValueTypeHostAddress: // host address value (for memory in the process that is using liblldb) - // Taking the address of an object reduces it to the address - // of the value and removes any extra context it had. - //stack.back().SetValueType(Value::eValueTypeScalar); - stack.back().ClearContext(); - break; - } - } - break; - - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_value_of - // OPERANDS: none - // DESCRIPTION: Pops a value off of the stack and pushed its value. - // The top item on the stack must be a variable, expression variable. - //---------------------------------------------------------------------- - case DW_OP_APPLE_value_of: - if (stack.empty()) - { - if (error_ptr) - error_ptr->SetErrorString("Expression stack needs at least 1 items for DW_OP_APPLE_value_of."); - return false; - } - else if (!stack.back().ValueOf(exe_ctx, ast_context)) - { - if (error_ptr) - error_ptr->SetErrorString ("Top stack item isn't a valid candidate for DW_OP_APPLE_value_of."); - return false; - } - break; - - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_deref_type - // OPERANDS: none - // DESCRIPTION: gets the value pointed to by the top stack item - //---------------------------------------------------------------------- - case DW_OP_APPLE_deref_type: - { - if (stack.empty()) - { - if (error_ptr) - error_ptr->SetErrorString("Expression stack needs at least 1 items for DW_OP_APPLE_deref_type."); - return false; - } - - tmp = stack.back(); - stack.pop_back(); - - if (tmp.GetContextType() != Value::eContextTypeClangType) - { - if (error_ptr) - error_ptr->SetErrorString("Item at top of expression stack must have a Clang type"); - return false; - } - - void *ptr_type = tmp.GetClangType(); - void *target_type; - - if (!ClangASTContext::IsPointerType(ptr_type, &target_type)) - { - if (error_ptr) - error_ptr->SetErrorString("Dereferencing a non-pointer type"); - return false; - } - - // TODO do we want all pointers to be dereferenced as load addresses? - Value::ValueType value_type = tmp.GetValueType(); - - tmp.ResolveValue(exe_ctx, ast_context); - - tmp.SetValueType(value_type); - tmp.SetContext(Value::eContextTypeClangType, target_type); - - stack.push_back(tmp); - } - break; - - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_expr_local - // OPERANDS: ULEB128 - // DESCRIPTION: pushes the expression local variable index onto the - // stack and set the appropriate context so we know the stack item is - // an expression local variable index. - //---------------------------------------------------------------------- - case DW_OP_APPLE_expr_local: - { - /* - uint32_t idx = opcodes.GetULEB128(&offset); - if (expr_locals == NULL) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_expr_local(%u) opcode encountered with no local variable list.\n", idx); - return false; - } - Value *expr_local_variable = expr_locals->GetVariableAtIndex(idx); - if (expr_local_variable == NULL) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_expr_local(%u) with invalid index %u.\n", idx, idx); - return false; - } - // The proxy code has been removed. If it is ever re-added, please - // use shared pointers or return by value to avoid possible memory - // leak (there is no leak here, but in general, no returning pointers - // that must be manually freed please. - Value *proxy = expr_local_variable->CreateProxy(); - stack.push_back(*proxy); - delete proxy; - //stack.back().SetContext (Value::eContextTypeClangType, expr_local_variable->GetClangType()); - */ - } - break; - - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_extern - // OPERANDS: ULEB128 - // DESCRIPTION: pushes a proxy for the extern object index onto the - // stack. - //---------------------------------------------------------------------- - case DW_OP_APPLE_extern: - { - /* - uint32_t idx = opcodes.GetULEB128(&offset); - if (!decl_map) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_extern(%u) opcode encountered with no decl map.\n", idx); - return false; - } - Value *extern_var = decl_map->GetValueForIndex(idx); - if (!extern_var) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_extern(%u) with invalid index %u.\n", idx, idx); - return false; - } - // The proxy code has been removed. If it is ever re-added, please - // use shared pointers or return by value to avoid possible memory - // leak (there is no leak here, but in general, no returning pointers - // that must be manually freed please. - Value *proxy = extern_var->CreateProxy(); - stack.push_back(*proxy); - delete proxy; - */ - } - break; - - case DW_OP_APPLE_scalar_cast: - if (stack.empty()) - { - if (error_ptr) - error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_scalar_cast."); - return false; - } - else - { - // Simple scalar cast - if (!stack.back().ResolveValue(exe_ctx, ast_context).Cast((Scalar::Type)opcodes.GetU8(&offset))) - { - if (error_ptr) - error_ptr->SetErrorString("Cast failed."); - return false; - } - } - break; - - - case DW_OP_APPLE_clang_cast: - if (stack.empty()) - { - if (error_ptr) - error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_clang_cast."); - return false; - } - else - { - void *clang_type = (void *)opcodes.GetMaxU64(&offset, sizeof(void*)); - stack.back().SetContext (Value::eContextTypeClangType, clang_type); - } - break; - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_constf - // OPERANDS: 1 byte float length, followed by that many bytes containing - // the constant float data. - // DESCRIPTION: Push a float value onto the expression stack. - //---------------------------------------------------------------------- - case DW_OP_APPLE_constf: // 0xF6 - 1 byte float size, followed by constant float data - { - uint8_t float_length = opcodes.GetU8(&offset); - if (sizeof(float) == float_length) - tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetFloat (&offset); - else if (sizeof(double) == float_length) - tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetDouble (&offset); - else if (sizeof(long double) == float_length) - tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetLongDouble (&offset); - else - { - StreamString new_value; - opcodes.Dump(&new_value, offset, eFormatBytes, 1, float_length, UINT32_MAX, DW_INVALID_ADDRESS, 0, 0); - - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_constf(<%u> %s) unsupported float size.\n", float_length, new_value.GetData()); - return false; - } - tmp.SetValueType(Value::eValueTypeScalar); - tmp.ClearContext(); - stack.push_back(tmp); - } - break; - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_clear - // OPERANDS: none - // DESCRIPTION: Clears the expression stack. - //---------------------------------------------------------------------- - case DW_OP_APPLE_clear: - stack.clear(); - break; - - //---------------------------------------------------------------------- - // OPCODE: DW_OP_APPLE_error - // OPERANDS: none - // DESCRIPTION: Pops a value off of the stack and pushed its value. - // The top item on the stack must be a variable, expression variable. - //---------------------------------------------------------------------- - case DW_OP_APPLE_error: // 0xFF - Stops expression evaluation and returns an error (no args) - if (error_ptr) - error_ptr->SetErrorString ("Generic error."); - return false; -#endif // #if 0 - } } diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index 37b424056e5..711943401db 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -33,6 +33,7 @@ #include "lldb/Expression/IRInterpreter.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangASTType.h" #include <map> @@ -130,7 +131,7 @@ PrintValue(const Value *value, bool truncate = false) } static std::string -PrintType(const Type *type, bool truncate = false) +PrintType(const llvm::Type *type, bool truncate = false) { std::string s; raw_string_ostream rso(s); @@ -565,7 +566,7 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function) &result_decl->getASTContext()); } - if (m_result_type.GetClangTypeBitWidth() == 0) + if (m_result_type.GetBitSize() == 0) { lldb_private::StreamString type_desc_stream; m_result_type.DumpTypeDescription(&type_desc_stream); @@ -592,7 +593,7 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function) if (log) log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64, m_result_name.GetCString(), - m_result_type.GetClangTypeBitWidth() / 8); + m_result_type.GetByteSize()); // Construct a new result global and set up its metadata @@ -1496,22 +1497,14 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr) std::string name (named_decl->getName().str()); - void *opaque_type = NULL; - clang::ASTContext *ast_context = NULL; - - if (clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl)) - { - opaque_type = value_decl->getType().getAsOpaquePtr(); - ast_context = &value_decl->getASTContext(); - } - else - { + clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl); + if (value_decl == NULL) return false; - } + + lldb_private::ClangASTType clang_type(&value_decl->getASTContext(), value_decl->getType()); - clang::QualType qual_type; const Type *value_type = NULL; - + if (name[0] == '$') { // The $__lldb_expr_result name indicates the the return value has allocated as @@ -1523,26 +1516,26 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr) // to the type of $__lldb_expr_result, not the type itself. // // We also do this for any user-declared persistent variables. - - qual_type = ast_context->getPointerType(clang::QualType::getFromOpaquePtr(opaque_type)); + clang_type = clang_type.GetPointerType(); value_type = PointerType::get(global_variable->getType(), 0); } else { - qual_type = clang::QualType::getFromOpaquePtr(opaque_type); value_type = global_variable->getType(); } - - uint64_t value_size = (ast_context->getTypeSize(qual_type) + 7ull) / 8ull; - off_t value_alignment = (ast_context->getTypeAlign(qual_type) + 7ull) / 8ull; + + const uint64_t value_size = clang_type.GetByteSize(); + off_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull; if (log) + { log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRId64 "]", name.c_str(), - qual_type.getAsString().c_str(), - PrintType(value_type).c_str(), + clang_type.GetQualType().getAsString().c_str(), + PrintType(value_type).c_str(), value_size, value_alignment); + } if (named_decl && !m_decl_map->AddValueToStruct(named_decl, diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp index 52dfefd6c99..6236eda1a86 100644 --- a/lldb/source/Expression/Materializer.cpp +++ b/lldb/source/Expression/Materializer.cpp @@ -49,7 +49,7 @@ Materializer::AddStructMember (Entity &entity) void Materializer::Entity::SetSizeAndAlignmentFromType (ClangASTType &type) { - m_size = type.GetTypeByteSize(); + m_size = type.GetByteSize(); uint32_t bit_alignment = type.GetTypeBitAlign(); @@ -100,8 +100,7 @@ public: // Put the location of the spare memory into the live data of the ValueObject. m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope(), - m_persistent_variable_sp->GetTypeFromUser().GetASTContext(), - m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(), + m_persistent_variable_sp->GetTypeFromUser(), m_persistent_variable_sp->GetName(), mem, eAddressTypeLoad, @@ -151,10 +150,12 @@ public: { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + const lldb::addr_t load_addr = process_address + m_offset; + if (log) { - log->Printf("EntityPersistentVariable::Materialize [process_address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]", - (uint64_t)process_address, + log->Printf("EntityPersistentVariable::Materialize [address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]", + (uint64_t)load_addr, m_persistent_variable_sp->GetName().AsCString(), m_persistent_variable_sp->m_flags); } @@ -173,7 +174,7 @@ public: { Error write_error; - map.WriteScalarToMemory(process_address + m_offset, + map.WriteScalarToMemory(load_addr, m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(), map.GetAddressByteSize(), write_error); @@ -190,15 +191,21 @@ public: } } - void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, - lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) + void Dematerialize (lldb::StackFrameSP &frame_sp, + IRMemoryMap &map, + lldb::addr_t process_address, + lldb::addr_t frame_top, + lldb::addr_t frame_bottom, + Error &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + const lldb::addr_t load_addr = process_address + m_offset; + if (log) { - log->Printf("EntityPersistentVariable::Dematerialize [process_address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]", - (uint64_t)process_address, + log->Printf("EntityPersistentVariable::Dematerialize [address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]", + (uint64_t)process_address + m_offset, m_persistent_variable_sp->GetName().AsCString(), m_persistent_variable_sp->m_flags); } @@ -215,7 +222,7 @@ public: lldb::addr_t location; Error read_error; - map.ReadPointerFromMemory(&location, process_address + m_offset, read_error); + map.ReadPointerFromMemory(&location, load_addr, read_error); if (!read_error.Success()) { @@ -224,8 +231,7 @@ public: } m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope (), - m_persistent_variable_sp->GetTypeFromUser().GetASTContext(), - m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(), + m_persistent_variable_sp->GetTypeFromUser(), m_persistent_variable_sp->GetName(), location, eAddressTypeLoad, @@ -319,14 +325,16 @@ public: Error err; - dump_stream.Printf("0x%" PRIx64 ": EntityPersistentVariable (%s)\n", process_address + m_offset, m_persistent_variable_sp->GetName().AsCString()); + const lldb::addr_t load_addr = process_address + m_offset; + + dump_stream.Printf("0x%" PRIx64 ": EntityPersistentVariable (%s)\n", load_addr, m_persistent_variable_sp->GetName().AsCString()); { dump_stream.Printf("Pointer:\n"); DataBufferHeap data (m_size, 0); - map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); + map.ReadMemory(data.GetBytes(), load_addr, m_size, err); if (!err.Success()) { @@ -336,7 +344,7 @@ public: { DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); - extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); dump_stream.PutChar('\n'); } @@ -347,7 +355,7 @@ public: lldb::addr_t target_address; - map.ReadPointerFromMemory (&target_address, process_address + m_offset, err); + map.ReadPointerFromMemory (&target_address, load_addr, err); if (!err.Success()) { @@ -407,17 +415,18 @@ public: // Hard-coding to maximum size of a pointer since all variables are materialized by reference m_size = 8; m_alignment = 8; - m_is_reference = ClangASTContext::IsReferenceType(m_variable_sp->GetType()->GetClangForwardType()); + m_is_reference = m_variable_sp->GetType()->GetClangForwardType().IsReferenceType(); } void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + const lldb::addr_t load_addr = process_address + m_offset; if (log) { - log->Printf("EntityVariable::Materialize [process_address = 0x%" PRIx64 ", m_variable_sp = %s]", - (uint64_t)process_address, + log->Printf("EntityVariable::Materialize [address = 0x%" PRIx64 ", m_variable_sp = %s]", + (uint64_t)load_addr, m_variable_sp->GetName().AsCString()); } @@ -442,7 +451,7 @@ public: lldb::addr_t reference_addr = valobj_extractor.GetAddress(&offset); Error write_error; - map.WritePointerToMemory(process_address + m_offset, reference_addr, write_error); + map.WritePointerToMemory(load_addr, reference_addr, write_error); if (!write_error.Success()) { @@ -462,7 +471,7 @@ public: lldb::addr_t addr_of_valobj_addr = valobj_extractor.GetAddress(&offset); Error write_error; - map.WritePointerToMemory(process_address + m_offset, addr_of_valobj_addr, write_error); + map.WritePointerToMemory(load_addr, addr_of_valobj_addr, write_error); if (!write_error.Success()) { @@ -494,7 +503,7 @@ public: return; } - size_t bit_align = ClangASTType::GetTypeBitAlign(m_variable_sp->GetType()->GetClangAST(), m_variable_sp->GetType()->GetClangLayoutType()); + size_t bit_align = m_variable_sp->GetType()->GetClangLayoutType().GetTypeBitAlign(); size_t byte_align = (bit_align + 7) / 8; Error alloc_error; @@ -520,7 +529,7 @@ public: Error pointer_write_error; - map.WritePointerToMemory(process_address + m_offset, m_temporary_allocation, pointer_write_error); + map.WritePointerToMemory(load_addr, m_temporary_allocation, pointer_write_error); if (!pointer_write_error.Success()) { @@ -530,15 +539,20 @@ public: } } - void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, - lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) + void Dematerialize (lldb::StackFrameSP &frame_sp, + IRMemoryMap &map, + lldb::addr_t process_address, + lldb::addr_t frame_top, + lldb::addr_t frame_bottom, + Error &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + const lldb::addr_t load_addr = process_address + m_offset; if (log) { - log->Printf("EntityVariable::Dematerialize [process_address = 0x%" PRIx64 ", m_variable_sp = %s]", - (uint64_t)process_address, + log->Printf("EntityVariable::Dematerialize [address = 0x%" PRIx64 ", m_variable_sp = %s]", + (uint64_t)load_addr, m_variable_sp->GetName().AsCString()); } @@ -597,8 +611,9 @@ public: void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) { StreamString dump_stream; - - dump_stream.Printf("0x%" PRIx64 ": EntityVariable\n", process_address + m_offset); + + const lldb::addr_t load_addr = process_address + m_offset; + dump_stream.Printf("0x%" PRIx64 ": EntityVariable\n", load_addr); Error err; @@ -609,7 +624,7 @@ public: DataBufferHeap data (m_size, 0); - map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); + map.ReadMemory(data.GetBytes(), load_addr, m_size, err); if (!err.Success()) { @@ -619,7 +634,7 @@ public: { DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); - extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); lldb::offset_t offset; @@ -656,7 +671,7 @@ public: { DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); - extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); dump_stream.PutChar('\n'); } @@ -721,7 +736,9 @@ public: return; } - size_t byte_size = m_type.GetTypeByteSize(); + const lldb::addr_t load_addr = process_address + m_offset; + + size_t byte_size = m_type.GetByteSize(); size_t bit_align = m_type.GetTypeBitAlign(); size_t byte_align = (bit_align + 7) / 8; @@ -738,7 +755,7 @@ public: Error pointer_write_error; - map.WritePointerToMemory(process_address + m_offset, m_temporary_allocation, pointer_write_error); + map.WritePointerToMemory(load_addr, m_temporary_allocation, pointer_write_error); if (!pointer_write_error.Success()) { @@ -747,15 +764,23 @@ public: } } - void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, - lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) + void Dematerialize (lldb::StackFrameSP &frame_sp, + IRMemoryMap &map, + lldb::addr_t process_address, + lldb::addr_t frame_top, + lldb::addr_t frame_bottom, + Error &err) { err.SetErrorString("Tried to detmaterialize a result variable with the normal Dematerialize method"); } void Dematerialize (lldb::ClangExpressionVariableSP &result_variable_sp, - lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, - lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) + lldb::StackFrameSP &frame_sp, + IRMemoryMap &map, + lldb::addr_t process_address, + lldb::addr_t frame_top, + lldb::addr_t frame_bottom, + Error &err) { err.Clear(); @@ -769,8 +794,9 @@ public: lldb::addr_t address; Error read_error; + const lldb::addr_t load_addr = process_address + m_offset; - map.ReadPointerFromMemory (&address, process_address + m_offset, read_error); + map.ReadPointerFromMemory (&address, load_addr, read_error); if (!read_error.Success()) { @@ -809,8 +835,7 @@ public: if (can_persist && m_keep_in_memory) { ret->m_live_sp = ValueObjectConstResult::Create(exe_scope, - m_type.GetASTContext(), - m_type.GetOpaqueQualType(), + m_type, name, address, eAddressTypeLoad, @@ -854,8 +879,10 @@ public: void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) { StreamString dump_stream; - - dump_stream.Printf("0x%" PRIx64 ": EntityResultVariable\n", process_address + m_offset); + + const lldb::addr_t load_addr = process_address + m_offset; + + dump_stream.Printf("0x%" PRIx64 ": EntityResultVariable\n", load_addr); Error err; @@ -866,7 +893,7 @@ public: DataBufferHeap data (m_size, 0); - map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); + map.ReadMemory(data.GetBytes(), load_addr, m_size, err); if (!err.Success()) { @@ -876,7 +903,7 @@ public: { DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); - extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); lldb::offset_t offset; @@ -913,7 +940,7 @@ public: { DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); - extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); dump_stream.PutChar('\n'); } @@ -970,10 +997,12 @@ public: { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + const lldb::addr_t load_addr = process_address + m_offset; + if (log) { - log->Printf("EntitySymbol::Materialize [process_address = 0x%" PRIx64 ", m_symbol = %s]", - (uint64_t)process_address, + log->Printf("EntitySymbol::Materialize [address = 0x%" PRIx64 ", m_symbol = %s]", + (uint64_t)load_addr, m_symbol.GetName().AsCString()); } @@ -999,7 +1028,7 @@ public: Error pointer_write_error; - map.WritePointerToMemory(process_address + m_offset, resolved_address, pointer_write_error); + map.WritePointerToMemory(load_addr, resolved_address, pointer_write_error); if (!pointer_write_error.Success()) { @@ -1008,15 +1037,21 @@ public: } } - void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, - lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) + void Dematerialize (lldb::StackFrameSP &frame_sp, + IRMemoryMap &map, + lldb::addr_t process_address, + lldb::addr_t frame_top, + lldb::addr_t frame_bottom, + Error &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + const lldb::addr_t load_addr = process_address + m_offset; + if (log) { - log->Printf("EntitySymbol::Dematerialize [process_address = 0x%" PRIx64 ", m_symbol = %s]", - (uint64_t)process_address, + log->Printf("EntitySymbol::Dematerialize [address = 0x%" PRIx64 ", m_symbol = %s]", + (uint64_t)load_addr, m_symbol.GetName().AsCString()); } @@ -1029,14 +1064,16 @@ public: Error err; - dump_stream.Printf("0x%" PRIx64 ": EntitySymbol (%s)\n", process_address + m_offset, m_symbol.GetName().AsCString()); + const lldb::addr_t load_addr = process_address + m_offset; + + dump_stream.Printf("0x%" PRIx64 ": EntitySymbol (%s)\n", load_addr, m_symbol.GetName().AsCString()); { dump_stream.Printf("Pointer:\n"); DataBufferHeap data (m_size, 0); - map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); + map.ReadMemory(data.GetBytes(), load_addr, m_size, err); if (!err.Success()) { @@ -1046,7 +1083,7 @@ public: { DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); - extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); dump_stream.PutChar('\n'); } @@ -1088,10 +1125,12 @@ public: { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + const lldb::addr_t load_addr = process_address + m_offset; + if (log) { - log->Printf("EntityRegister::Materialize [process_address = 0x%" PRIx64 ", m_register_info = %s]", - (uint64_t)process_address, + log->Printf("EntityRegister::Materialize [address = 0x%" PRIx64 ", m_register_info = %s]", + (uint64_t)load_addr, m_register_info.name); } @@ -1127,7 +1166,7 @@ public: Error write_error; - map.WriteMemory(process_address + m_offset, register_data.GetDataStart(), register_data.GetByteSize(), write_error); + map.WriteMemory(load_addr, register_data.GetDataStart(), register_data.GetByteSize(), write_error); if (!write_error.Success()) { @@ -1136,15 +1175,21 @@ public: } } - void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, - lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) + void Dematerialize (lldb::StackFrameSP &frame_sp, + IRMemoryMap &map, + lldb::addr_t process_address, + lldb::addr_t frame_top, + lldb::addr_t frame_bottom, + Error &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + const lldb::addr_t load_addr = process_address + m_offset; + if (log) { - log->Printf("EntityRegister::Dematerialize [process_address = 0x%" PRIx64 ", m_register_info = %s]", - (uint64_t)process_address, + log->Printf("EntityRegister::Dematerialize [address = 0x%" PRIx64 ", m_register_info = %s]", + (uint64_t)load_addr, m_register_info.name); } @@ -1160,7 +1205,7 @@ public: lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext(); - map.GetMemoryData(register_data, process_address + m_offset, m_register_info.byte_size, extract_error); + map.GetMemoryData(register_data, load_addr, m_register_info.byte_size, extract_error); if (!extract_error.Success()) { @@ -1183,14 +1228,17 @@ public: Error err; - dump_stream.Printf("0x%" PRIx64 ": EntityRegister (%s)\n", process_address + m_offset, m_register_info.name); + const lldb::addr_t load_addr = process_address + m_offset; + + + dump_stream.Printf("0x%" PRIx64 ": EntityRegister (%s)\n", load_addr, m_register_info.name); { dump_stream.Printf("Value:\n"); DataBufferHeap data (m_size, 0); - map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); + map.ReadMemory(data.GetBytes(), load_addr, m_size, err); if (!err.Success()) { @@ -1200,7 +1248,7 @@ public: { DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); - extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); dump_stream.PutChar('\n'); } diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp index bc63e591cc2..4685c3e759e 100644 --- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp @@ -318,8 +318,6 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread, // For now, assume that the types in the AST values come from the Target's // scratch AST. - clang::ASTContext *ast_context = exe_ctx.GetTargetRef().GetScratchClangASTContext()->getASTContext(); - // Extract the register context so we can read arguments from registers RegisterContext *reg_ctx = thread.GetRegisterContext().get(); @@ -338,18 +336,18 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread, if (!value) return false; - void *value_type = value->GetClangType(); - if (value_type) + ClangASTType clang_type = value->GetClangType(); + if (clang_type) { bool is_signed = false; size_t bit_width = 0; - if (ClangASTContext::IsIntegerType (value_type, is_signed)) + if (clang_type.IsIntegerType (is_signed)) { - bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type); + bit_width = clang_type.GetBitSize(); } - else if (ClangASTContext::IsPointerOrReferenceType (value_type)) + else if (clang_type.IsPointerOrReferenceType ()) { - bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type); + bit_width = clang_type.GetBitSize(); } else { @@ -421,20 +419,20 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread, ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread, - lldb_private::ClangASTType &ast_type) const + lldb_private::ClangASTType &clang_type) const { Value value; ValueObjectSP return_valobj_sp; - void *value_type = ast_type.GetOpaqueQualType(); - if (!value_type) + if (!clang_type) return return_valobj_sp; - clang::ASTContext *ast_context = ast_type.GetASTContext(); + clang::ASTContext *ast_context = clang_type.GetASTContext(); if (!ast_context) return return_valobj_sp; - value.SetContext (Value::eContextTypeClangType, value_type); + //value.SetContext (Value::eContextTypeClangType, clang_type.GetOpaqueQualType()); + value.SetClangType (clang_type); RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) @@ -446,9 +444,9 @@ ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread, // when reading data const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0); - if (ClangASTContext::IsIntegerType (value_type, is_signed)) + if (clang_type.IsIntegerType (is_signed)) { - size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type); + size_t bit_width = clang_type.GetBitSize(); switch (bit_width) { @@ -486,7 +484,7 @@ ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread, break; } } - else if (ClangASTContext::IsPointerType (value_type)) + else if (clang_type.IsPointerType ()) { uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; value.GetScalar() = ptr; @@ -499,11 +497,9 @@ ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread, // If we get here, we have a valid Value, so make our ValueObject out of it: - return_valobj_sp = ValueObjectConstResult::Create( - thread.GetStackFrameAtIndex(0).get(), - ast_type.GetASTContext(), - value, - ConstString("")); + return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), + value, + ConstString("")); return return_valobj_sp; } @@ -517,19 +513,13 @@ ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj return error; } - clang_type_t value_type = new_value_sp->GetClangType(); - if (!value_type) + ClangASTType clang_type = new_value_sp->GetClangType(); + if (!clang_type) { error.SetErrorString ("Null clang type for return value."); return error; } - clang::ASTContext *ast_context = new_value_sp->GetClangAST(); - if (!ast_context) - { - error.SetErrorString ("Null clang AST for return value."); - return error; - } Thread *thread = frame_sp->GetThread().get(); bool is_signed; @@ -539,7 +529,7 @@ ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj RegisterContext *reg_ctx = thread->GetRegisterContext().get(); bool set_it_simple = false; - if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type)) + if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType()) { DataExtractor data; size_t num_bytes = new_value_sp->GetData(data); @@ -573,7 +563,7 @@ ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj error.SetErrorString("We don't support returning longer than 64 bit integer values at present."); } } - else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex)) + else if (clang_type.IsFloatingPointType (count, is_complex)) { if (is_complex) error.SetErrorString ("We don't support returning complex values at present"); diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index d2126bf3556..deb531d937a 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -510,16 +510,12 @@ ABIMacOSX_i386::PrepareNormalCall (Thread &thread, } break; case Value::eValueTypeHostAddress: - switch (val->GetContextType()) { - default: - return false; - case Value::eContextTypeClangType: + ClangASTType clang_type (val->GetClangType()); + if (clang_type) { - void *val_type = val->GetClangType(); - uint32_t cstr_length; - - if (ClangASTContext::IsCStringType (val_type, cstr_length)) + uint32_t cstr_length = 0; + if (clang_type.IsCStringType (cstr_length)) { const char *cstr = (const char*)val->GetScalar().ULongLong(); cstr_length = strlen(cstr); @@ -616,11 +612,6 @@ ABIMacOSX_i386::GetArgumentValues (Thread &thread, unsigned int num_values = values.GetSize(); unsigned int value_index; - // Extract the Clang AST context from the PC so that we can figure out type - // sizes - - clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext(); - // Get the pointer to the first stack argument so we have a place to start // when reading data @@ -647,35 +638,27 @@ ABIMacOSX_i386::GetArgumentValues (Thread &thread, // We currently only support extracting values with Clang QualTypes. // Do we care about others? - switch (value->GetContextType()) + ClangASTType clang_type (value->GetClangType()); + if (clang_type) { - default: - return false; - case Value::eContextTypeClangType: - { - void *value_type = value->GetClangType(); - bool is_signed; - - if (ClangASTContext::IsIntegerType (value_type, is_signed)) - { - size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type); - - ReadIntegerArgument(value->GetScalar(), - bit_width, - is_signed, - thread.GetProcess().get(), - current_stack_argument); - } - else if (ClangASTContext::IsPointerType (value_type)) - { - ReadIntegerArgument(value->GetScalar(), - 32, - false, - thread.GetProcess().get(), - current_stack_argument); - } - } - break; + bool is_signed; + + if (clang_type.IsIntegerType (is_signed)) + { + ReadIntegerArgument(value->GetScalar(), + clang_type.GetBitSize(), + is_signed, + thread.GetProcess().get(), + current_stack_argument); + } + else if (clang_type.IsPointerType()) + { + ReadIntegerArgument(value->GetScalar(), + clang_type.GetBitSize(), + false, + thread.GetProcess().get(), + current_stack_argument); + } } } @@ -692,19 +675,13 @@ ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb return error; } - clang_type_t value_type = new_value_sp->GetClangType(); - if (!value_type) + ClangASTType clang_type = new_value_sp->GetClangType(); + if (!clang_type) { error.SetErrorString ("Null clang type for return value."); return error; } - clang::ASTContext *ast_context = new_value_sp->GetClangAST(); - if (!ast_context) - { - error.SetErrorString ("Null clang AST for return value."); - return error; - } Thread *thread = frame_sp->GetThread().get(); bool is_signed; @@ -714,7 +691,7 @@ ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb RegisterContext *reg_ctx = thread->GetRegisterContext().get(); bool set_it_simple = false; - if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type)) + if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType()) { DataExtractor data; size_t num_bytes = new_value_sp->GetData(data); @@ -748,7 +725,7 @@ ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb error.SetErrorString("We don't support returning longer than 64 bit integer values at present."); } } - else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex)) + else if (clang_type.IsFloatingPointType (count, is_complex)) { if (is_complex) error.SetErrorString ("We don't support returning complex values at present"); @@ -764,20 +741,16 @@ ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb ValueObjectSP ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread, - ClangASTType &ast_type) const + ClangASTType &clang_type) const { Value value; ValueObjectSP return_valobj_sp; - void *value_type = ast_type.GetOpaqueQualType(); - if (!value_type) + if (!clang_type) return return_valobj_sp; - clang::ASTContext *ast_context = ast_type.GetASTContext(); - if (!ast_context) - return return_valobj_sp; - - value.SetContext (Value::eContextTypeClangType, value_type); + //value.SetContext (Value::eContextTypeClangType, clang_type.GetOpaqueQualType()); + value.SetClangType (clang_type); RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) @@ -785,9 +758,9 @@ ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread, bool is_signed; - if (ClangASTContext::IsIntegerType (value_type, is_signed)) + if (clang_type.IsIntegerType (is_signed)) { - size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type); + size_t bit_width = clang_type.GetBitSize(); unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB]; @@ -827,7 +800,7 @@ ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread, break; } } - else if (ClangASTContext::IsPointerType (value_type)) + else if (clang_type.IsPointerType ()) { unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff; @@ -841,11 +814,9 @@ ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread, // If we get here, we have a valid Value, so make our ValueObject out of it: - return_valobj_sp = ValueObjectConstResult::Create( - thread.GetStackFrameAtIndex(0).get(), - ast_type.GetASTContext(), - value, - ConstString("")); + return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), + value, + ConstString("")); return return_valobj_sp; } diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp index a9b002c03df..1ff9124316f 100644 --- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp +++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp @@ -313,14 +313,39 @@ ABISysV_x86_64::PrepareTrivialCall (Thread &thread, Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); if (log) - log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n thread = %p\n sp = 0x%" PRIx64 "\n func_addr = 0x%" PRIx64 "\n return_addr = 0x%" PRIx64 "\n arg1_ptr = %p (0x%" PRIx64 ")\n arg2_ptr = %p (0x%" PRIx64 ")\n arg3_ptr = %p (0x%" PRIx64 ")\n)", - (void*)&thread, + { + StreamString s; + s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, - (uint64_t)return_addr, - arg1_ptr, arg1_ptr ? (uint64_t)*arg1_ptr : (uint64_t) 0, - arg2_ptr, arg2_ptr ? (uint64_t)*arg2_ptr : (uint64_t) 0, - arg3_ptr, arg3_ptr ? (uint64_t)*arg3_ptr : (uint64_t) 0); + (uint64_t)return_addr); + + if (arg1_ptr) + { + s.Printf (", arg1 = 0x%" PRIx64, (uint64_t)*arg1_ptr); + if (arg2_ptr) + { + s.Printf (", arg2 = 0x%" PRIx64, (uint64_t)*arg2_ptr); + if (arg3_ptr) + { + s.Printf (", arg3 = 0x%" PRIx64, (uint64_t)*arg3_ptr); + if (arg4_ptr) + { + s.Printf (", arg4 = 0x%" PRIx64, (uint64_t)*arg4_ptr); + if (arg5_ptr) + { + s.Printf (", arg5 = 0x%" PRIx64, (uint64_t)*arg5_ptr); + if (arg6_ptr) + s.Printf (", arg6 = 0x%" PRIx64, (uint64_t)*arg6_ptr); + } + } + } + } + } + s.PutCString (")"); + log->PutCString(s.GetString().c_str()); + } RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) @@ -461,12 +486,7 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread, { unsigned int num_values = values.GetSize(); unsigned int value_index; - - // For now, assume that the types in the AST values come from the Target's - // scratch AST. - - clang::ASTContext *ast = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext(); - + // Extract the register context so we can read arguments from registers RegisterContext *reg_ctx = thread.GetRegisterContext().get(); @@ -506,39 +526,30 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread, // We currently only support extracting values with Clang QualTypes. // Do we care about others? - switch (value->GetContextType()) - { - default: + ClangASTType clang_type = value->GetClangType(); + if (!clang_type) return false; - case Value::eContextTypeClangType: - { - void *value_type = value->GetClangType(); - bool is_signed; - - if (ClangASTContext::IsIntegerType (value_type, is_signed)) - { - size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type); - - ReadIntegerArgument(value->GetScalar(), - bit_width, - is_signed, - thread, - argument_register_ids, - current_argument_register, - current_stack_argument); - } - else if (ClangASTContext::IsPointerType (value_type)) - { - ReadIntegerArgument(value->GetScalar(), - 64, - false, - thread, - argument_register_ids, - current_argument_register, - current_stack_argument); - } - } - break; + bool is_signed; + + if (clang_type.IsIntegerType (is_signed)) + { + ReadIntegerArgument(value->GetScalar(), + clang_type.GetBitSize(), + is_signed, + thread, + argument_register_ids, + current_argument_register, + current_stack_argument); + } + else if (clang_type.IsPointerType ()) + { + ReadIntegerArgument(value->GetScalar(), + clang_type.GetBitSize(), + false, + thread, + argument_register_ids, + current_argument_register, + current_stack_argument); } } @@ -555,19 +566,13 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb return error; } - clang_type_t value_type = new_value_sp->GetClangType(); - if (!value_type) + ClangASTType clang_type = new_value_sp->GetClangType(); + if (!clang_type) { error.SetErrorString ("Null clang type for return value."); return error; } - clang::ASTContext *ast = new_value_sp->GetClangAST(); - if (!ast) - { - error.SetErrorString ("Null clang AST for return value."); - return error; - } Thread *thread = frame_sp->GetThread().get(); bool is_signed; @@ -577,7 +582,7 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb RegisterContext *reg_ctx = thread->GetRegisterContext().get(); bool set_it_simple = false; - if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type)) + if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType()) { const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0); @@ -597,13 +602,13 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb } } - else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex)) + else if (clang_type.IsFloatingPointType (count, is_complex)) { if (is_complex) error.SetErrorString ("We don't support returning complex values at present"); else { - size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type); + size_t bit_width = clang_type.GetBitSize(); if (bit_width <= 64) { const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0); @@ -640,38 +645,34 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread, - ClangASTType &ast_type) const + ClangASTType &return_clang_type) const { ValueObjectSP return_valobj_sp; Value value; - clang_type_t return_value_type = ast_type.GetOpaqueQualType(); - if (!return_value_type) - return return_valobj_sp; - - clang::ASTContext *ast = ast_type.GetASTContext(); - if (!ast) + if (!return_clang_type) return return_valobj_sp; - value.SetContext (Value::eContextTypeClangType, return_value_type); + //value.SetContext (Value::eContextTypeClangType, return_value_type); + value.SetClangType (return_clang_type); RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) return return_valobj_sp; - const uint32_t type_flags = ClangASTContext::GetTypeInfo (return_value_type, ast, NULL); - if (type_flags & ClangASTContext::eTypeIsScalar) + const uint32_t type_flags = return_clang_type.GetTypeInfo (); + if (type_flags & ClangASTType::eTypeIsScalar) { value.SetValueType(Value::eValueTypeScalar); bool success = false; - if (type_flags & ClangASTContext::eTypeIsInteger) + if (type_flags & ClangASTType::eTypeIsInteger) { // Extract the register context so we can read arguments from registers - const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type); + const size_t byte_size = return_clang_type.GetByteSize(); uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0); - const bool is_signed = (type_flags & ClangASTContext::eTypeIsSigned) != 0; + const bool is_signed = (type_flags & ClangASTType::eTypeIsSigned) != 0; switch (byte_size) { default: @@ -710,15 +711,15 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread, break; } } - else if (type_flags & ClangASTContext::eTypeIsFloat) + else if (type_flags & ClangASTType::eTypeIsFloat) { - if (type_flags & ClangASTContext::eTypeIsComplex) + if (type_flags & ClangASTType::eTypeIsComplex) { // Don't handle complex yet. } else { - const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type); + const size_t byte_size = return_clang_type.GetByteSize(); if (byte_size <= sizeof(long double)) { const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0); @@ -751,24 +752,22 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread, if (success) return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(), - ast_type.GetASTContext(), value, ConstString("")); } - else if (type_flags & ClangASTContext::eTypeIsPointer) + else if (type_flags & ClangASTType::eTypeIsPointer) { unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB]; value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0); value.SetValueType(Value::eValueTypeScalar); return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(), - ast_type.GetASTContext(), value, ConstString("")); } - else if (type_flags & ClangASTContext::eTypeIsVector) + else if (type_flags & ClangASTType::eTypeIsVector) { - const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type); + const size_t byte_size = return_clang_type.GetByteSize(); if (byte_size > 0) { @@ -803,8 +802,7 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread, byte_order, process_sp->GetTarget().GetArchitecture().GetAddressByteSize()); return_valobj_sp = ValueObjectConstResult::Create (&thread, - ast, - return_value_type, + return_clang_type, ConstString(""), data); } @@ -819,29 +817,24 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread, } ValueObjectSP -ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type) const +ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const { ValueObjectSP return_valobj_sp; + + if (!return_clang_type) + return return_valobj_sp; ExecutionContext exe_ctx (thread.shared_from_this()); - return_valobj_sp = GetReturnValueObjectSimple(thread, ast_type); + return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type); if (return_valobj_sp) return return_valobj_sp; - clang_type_t return_value_type = ast_type.GetOpaqueQualType(); - if (!return_value_type) - return return_valobj_sp; - - clang::ASTContext *ast = ast_type.GetASTContext(); - if (!ast) - return return_valobj_sp; - RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); if (!reg_ctx_sp) return return_valobj_sp; - size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, return_value_type); - if (ClangASTContext::IsAggregateType(return_value_type)) + const size_t bit_width = return_clang_type.GetBitSize(); + if (return_clang_type.IsAggregateType()) { Target *target = exe_ctx.GetTargetPtr(); bool is_memory = true; @@ -874,7 +867,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type uint32_t fp_bytes = 0; // Tracks how much of the xmm registers we've consumed so far uint32_t integer_bytes = 0; // Tracks how much of the rax/rds registers we've consumed so far - uint32_t num_children = ClangASTContext::GetNumFields (ast, return_value_type); + const uint32_t num_children = return_clang_type.GetNumFields (); // Since we are in the small struct regime, assume we are not in memory. is_memory = false; @@ -887,8 +880,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type bool is_complex; uint32_t count; - clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast, return_value_type, idx, name, &field_bit_offset, NULL, NULL); - size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast, field_clang_type); + ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL); + const size_t field_bit_width = field_clang_type.GetBitSize(); // If there are any unaligned fields, this is stored in memory. if (field_bit_offset % field_bit_width != 0) @@ -904,7 +897,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type DataExtractor *copy_from_extractor = NULL; uint32_t copy_from_offset = 0; - if (ClangASTContext::IsIntegerType (field_clang_type, is_signed) || ClangASTContext::IsPointerType (field_clang_type)) + if (field_clang_type.IsIntegerType (is_signed) || field_clang_type.IsPointerType ()) { if (integer_bytes < 8) { @@ -937,7 +930,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type return return_valobj_sp; } } - else if (ClangASTContext::IsFloatingPointType (field_clang_type, count, is_complex)) + else if (field_clang_type.IsFloatingPointType (count, is_complex)) { // Structs with long doubles are always passed in memory. if (field_bit_width == 128) @@ -970,14 +963,12 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type else { uint64_t next_field_bit_offset = 0; - clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast, - return_value_type, - idx + 1, - name, - &next_field_bit_offset, - NULL, - NULL); - if (ClangASTContext::IsIntegerType (next_field_clang_type, is_signed)) + ClangASTType next_field_clang_type = return_clang_type.GetFieldAtIndex (idx + 1, + name, + &next_field_bit_offset, + NULL, + NULL); + if (next_field_clang_type.IsIntegerType (is_signed)) in_gpr = true; else { @@ -996,14 +987,12 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type else { uint64_t prev_field_bit_offset = 0; - clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast, - return_value_type, - idx - 1, - name, - &prev_field_bit_offset, - NULL, - NULL); - if (ClangASTContext::IsIntegerType (prev_field_clang_type, is_signed)) + ClangASTType prev_field_clang_type = return_clang_type.GetFieldAtIndex (idx - 1, + name, + &prev_field_bit_offset, + NULL, + NULL); + if (prev_field_clang_type.IsIntegerType (is_signed)) in_gpr = true; else { @@ -1067,8 +1056,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type { // The result is in our data buffer. Let's make a variable object out of it: return_valobj_sp = ValueObjectConstResult::Create (&thread, - ast, - return_value_type, + return_clang_type, ConstString(""), return_ext); } @@ -1087,7 +1075,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type return_valobj_sp = ValueObjectMemory::Create (&thread, "", Address (storage_addr, NULL), - ast_type); + return_clang_type); } } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index b7375d88035..df83b4df50b 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -625,13 +625,15 @@ DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, ValueList argument_values; Value input_value; - void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); - void *clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32); + ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); + ClangASTType clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32); input_value.SetValueType (Value::eValueTypeScalar); - input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type); - argument_values.PushValue(input_value); - argument_values.PushValue(input_value); - input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); + input_value.SetClangType (clang_uint32_type); +// input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type); + argument_values.PushValue (input_value); + argument_values.PushValue (input_value); + input_value.SetClangType (clang_void_ptr_type); + // input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); argument_values.PushValue (input_value); if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values)) diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 8a0d218ab34..247d7b0e7fe 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -37,9 +37,9 @@ static const char *vtable_demangled_prefix = "vtable for "; bool ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value) { - return ClangASTContext::IsPossibleDynamicType(in_value.GetClangAST(), in_value.GetClangType(), NULL, - true, // check for C++ - false); // do not check for ObjC + const bool check_cxx = true; + const bool check_objc = false; + return in_value.GetClangType().IsPossibleDynamicType (NULL, check_cxx, check_objc); } bool @@ -188,7 +188,7 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, type_sp = class_types.GetTypeAtIndex(i); if (type_sp) { - if (ClangASTContext::IsCXXClassType(type_sp->GetClangFullType())) + if (type_sp->GetClangFullType().IsCXXClassType()) { if (log) log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n", @@ -220,18 +220,12 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, // the value we were handed. if (type_sp) { - clang::ASTContext *in_ast_ctx = in_value.GetClangAST (); - clang::ASTContext *this_ast_ctx = type_sp->GetClangAST (); - if (in_ast_ctx == this_ast_ctx) + if (ClangASTContext::AreTypesSame (in_value.GetClangType(), + type_sp->GetClangFullType())) { - if (ClangASTContext::AreTypesSame (in_ast_ctx, - in_value.GetClangType(), - type_sp->GetClangFullType())) - { - // The dynamic type we found was the same type, - // so we don't have a dynamic type here... - return false; - } + // The dynamic type we found was the same type, + // so we don't have a dynamic type here... + return false; } // The offset_to_top is two pointers above the address. diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index 1f3f4e0ca3f..b21d76ca660 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -81,10 +81,10 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon return false; Target *target = exe_ctx.GetTargetPtr(); - if (value.GetClangType()) + ClangASTType clang_type = value.GetClangType(); + if (clang_type) { - clang::QualType value_type = clang::QualType::getFromOpaquePtr (value.GetClangType()); - if (!value_type->isObjCObjectPointerType()) + if (!clang_type.IsObjCObjectPointerType()) { strm.Printf ("Value doesn't point to an ObjC object.\n"); return false; @@ -94,10 +94,11 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon { // If it is not a pointer, see if we can make it into a pointer. ClangASTContext *ast_context = target->GetScratchClangASTContext(); - void *opaque_type_ptr = ast_context->GetBuiltInType_objc_id(); - if (opaque_type_ptr == NULL) - opaque_type_ptr = ast_context->GetVoidPtrType(false); - value.SetContext(Value::eContextTypeClangType, opaque_type_ptr); + ClangASTType opaque_type = ast_context->GetBasicType(eBasicTypeObjCID); + if (!opaque_type) + opaque_type = ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); + //value.SetContext(Value::eContextTypeClangType, opaque_type_ptr); + value.SetClangType (opaque_type); } ValueList arg_value_list; @@ -106,9 +107,10 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon // This is the return value: ClangASTContext *ast_context = target->GetScratchClangASTContext(); - void *return_qualtype = ast_context->GetCStringType(true); + ClangASTType return_clang_type = ast_context->GetCStringType(true); Value ret; - ret.SetContext(Value::eContextTypeClangType, return_qualtype); +// ret.SetContext(Value::eContextTypeClangType, return_clang_type); + ret.SetClangType (return_clang_type); if (exe_ctx.GetFramePtr() == NULL) { @@ -126,8 +128,7 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon // Now we're ready to call the function: ClangFunction func (*exe_ctx.GetBestExecutionContextScope(), - ast_context, - return_qualtype, + return_clang_type, *function_address, arg_value_list); @@ -221,10 +222,9 @@ AppleObjCRuntime::GetPrintForDebuggerAddr() bool AppleObjCRuntime::CouldHaveDynamicValue (ValueObject &in_value) { - return ClangASTContext::IsPossibleDynamicType(in_value.GetClangAST(), in_value.GetClangType(), - NULL, - false, // do not check C++ - true); // check ObjC + return in_value.GetClangType().IsPossibleDynamicType (NULL, + false, // do not check C++ + true); // check ObjC } bool diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index 6d3d4fd5f8d..16ffe0b042a 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -178,13 +178,14 @@ AppleObjCRuntimeV1::CreateObjectChecker(const char *name) //ObjCLanguageRuntime::ObjCISA //AppleObjCRuntimeV1::GetISA(ValueObject& valobj) //{ -//// if (ClangASTType::GetMinimumLanguage(valobj.GetClangAST(),valobj.GetClangType()) != eLanguageTypeObjC) +// ClangASTType valobj_clang_type = valobj.GetClangType(); +//// if (valobj_clang_type.GetMinimumLanguage() != eLanguageTypeObjC) //// return 0; // // // if we get an invalid VO (which might still happen when playing around // // with pointers returned by the expression parser, don't consider this // // a valid ObjC object) -// if (valobj.GetValue().GetContextType() == Value::eContextTypeInvalid) +// if (!valobj.GetClangType().IsValid()) // return 0; // // addr_t isa_pointer = valobj.GetPointerValue(); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 683645a47af..23a0e23e7c5 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -1613,7 +1613,7 @@ AppleObjCRuntimeV2::GetClassDescriptor (ValueObject& valobj) // if we get an invalid VO (which might still happen when playing around // with pointers returned by the expression parser, don't consider this // a valid ObjC object) - if (valobj.GetValue().GetContextType() != Value::eContextTypeInvalid) + if (valobj.GetClangType().IsValid()) { addr_t isa_pointer = valobj.GetPointerValue(); @@ -1719,8 +1719,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table } // Make some types for our arguments - clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); - clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void()); + ClangASTType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); + ClangASTType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType(); if (!m_get_class_info_code.get()) { @@ -1749,19 +1749,17 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table { Value value; value.SetValueType (Value::eValueTypeScalar); - value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type); +// value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type); + value.SetClangType (clang_void_pointer_type); arguments.PushValue (value); - - value.SetValueType (Value::eValueTypeScalar); - value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type); arguments.PushValue (value); value.SetValueType (Value::eValueTypeScalar); - value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); +// value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); + value.SetClangType (clang_uint32_t_type); arguments.PushValue (value); m_get_class_info_function.reset(new ClangFunction (*m_process, - ast, clang_uint32_t_type, function_address, arguments)); @@ -1827,7 +1825,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table Value return_value; return_value.SetValueType (Value::eValueTypeScalar); - return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); + //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); + return_value.SetClangType (clang_uint32_t_type); return_value.GetScalar() = 0; errors.Clear(); @@ -1971,8 +1970,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() } // Make some types for our arguments - clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); - clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void()); + ClangASTType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); + ClangASTType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType(); if (!m_get_shared_cache_class_info_code.get()) { @@ -2001,19 +2000,17 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { Value value; value.SetValueType (Value::eValueTypeScalar); - value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type); + //value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type); + value.SetClangType (clang_void_pointer_type); arguments.PushValue (value); - - value.SetValueType (Value::eValueTypeScalar); - value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type); arguments.PushValue (value); value.SetValueType (Value::eValueTypeScalar); - value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); + //value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); + value.SetClangType (clang_uint32_t_type); arguments.PushValue (value); m_get_shared_cache_class_info_function.reset(new ClangFunction (*m_process, - ast, clang_uint32_t_type, function_address, arguments)); @@ -2079,7 +2076,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() Value return_value; return_value.SetValueType (Value::eValueTypeScalar); - return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); + //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); + return_value.SetClangType (clang_uint32_t_type); return_value.GetScalar() = 0; errors.Clear(); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index a76326eba19..b7c5df200c0 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -512,9 +512,11 @@ AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines (void *baton, ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); ValueList argument_values; Value input_value; - void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); + ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); + input_value.SetValueType (Value::eValueTypeScalar); - input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); + //input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); + input_value.SetClangType (clang_void_ptr_type); argument_values.PushValue(input_value); bool success = abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values); @@ -525,7 +527,6 @@ AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines (void *baton, Error error; DataExtractor data; error = argument_values.GetValueAtIndex(0)->GetValueAsData (&exe_ctx, - clang_ast_context->getASTContext(), data, 0, NULL); @@ -783,13 +784,12 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di // Next make the runner function for our implementation utility function. if (!m_impl_function.get()) { - ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext(); - lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); - m_impl_function.reset(new ClangFunction (thread, - clang_ast_context, - clang_void_ptr_type, - impl_code_address, - dispatch_values)); + ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext(); + ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); + m_impl_function.reset(new ClangFunction (thread, + clang_void_ptr_type, + impl_code_address, + dispatch_values)); errors.Clear(); unsigned num_errors = m_impl_function->CompileFunction(errors); @@ -887,9 +887,10 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool sto ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext(); ValueList argument_values; Value void_ptr_value; - lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); + ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); void_ptr_value.SetValueType (Value::eValueTypeScalar); - void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); + //void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); + void_ptr_value.SetClangType (clang_void_ptr_type); int obj_index; int sel_index; @@ -949,14 +950,14 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool sto Value super_value(*(argument_values.GetValueAtIndex(obj_index))); super_value.GetScalar() += process->GetAddressByteSize(); - super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext()); + super_value.ResolveValue (&exe_ctx); if (super_value.GetScalar().IsValid()) { // isa_value now holds the class pointer. The second word of the class pointer is the super-class pointer: super_value.GetScalar() += process->GetAddressByteSize(); - super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext()); + super_value.ResolveValue (&exe_ctx); if (super_value.GetScalar().IsValid()) isa_addr = super_value.GetScalar().ULongLong(); else @@ -979,7 +980,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool sto Value super_value(*(argument_values.GetValueAtIndex(obj_index))); super_value.GetScalar() += process->GetAddressByteSize(); - super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext()); + super_value.ResolveValue (&exe_ctx); if (super_value.GetScalar().IsValid()) { @@ -1006,7 +1007,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool sto Value isa_value(*(argument_values.GetValueAtIndex(obj_index))); isa_value.SetValueType(Value::eValueTypeLoadAddress); - isa_value.ResolveValue(&exe_ctx, clang_ast_context->getASTContext()); + isa_value.ResolveValue(&exe_ctx); if (isa_value.GetScalar().IsValid()) { isa_addr = isa_value.GetScalar().ULongLong(); @@ -1068,10 +1069,10 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool sto dispatch_values.PushValue (*(argument_values.GetValueAtIndex(sel_index))); Value flag_value; - lldb::clang_type_t clang_int_type - = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32); + ClangASTType clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32); flag_value.SetValueType (Value::eValueTypeScalar); - flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); + //flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); + flag_value.SetClangType (clang_int_type); if (this_dispatch.stret_return) flag_value.GetScalar() = 1; diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index ba1d3b6eb95..499d6d76615 100644 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -76,11 +76,11 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range)) { ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); - lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); + ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); ThreadPlanCallFunction *call_function_thread_plan = new ThreadPlanCallFunction (*thread, mmap_range.GetBaseAddress(), - ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type), + clang_void_ptr_type, stop_other_threads, unwind_on_error, ignore_breakpoints, @@ -222,11 +222,11 @@ bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t const uint32_t timeout_usec = 500000; ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); - lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); + ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); ThreadPlanCallFunction *call_function_thread_plan = new ThreadPlanCallFunction (*thread, *address, - ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type), + clang_void_ptr_type, stop_other_threads, unwind_on_error, ignore_breakpoints); diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index 84343b92425..4d60cf0708b 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -1179,7 +1179,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat dwarfexpr.SetRegisterKind (unwindplan_registerkind); Value result; Error error; - if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, NULL, this, 0, NULL, result, &error)) + if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, this, 0, NULL, result, &error)) { addr_t val; val = result.GetScalar().ULongLong(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index fa2d05819c4..b8d73d4bf2f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -407,11 +407,11 @@ SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope, // }); // } - std::set<clang_type_t> clang_type_set; + std::set<ClangASTType> clang_type_set; size_t num_types_added = 0; for (Type *type : type_set) { - clang_type_t clang_type = type->GetClangForwardType(); + ClangASTType clang_type = type->GetClangForwardType(); if (clang_type_set.find(clang_type) == clang_type_set.end()) { clang_type_set.insert(clang_type); @@ -1424,7 +1424,7 @@ SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu, attributes); const char *name = NULL; Type *lldb_type = NULL; - clang_type_t clang_type = NULL; + ClangASTType clang_type; uint64_t uval64 = 0; bool uval64_valid = false; if (num_attributes > 0) @@ -1465,7 +1465,7 @@ SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu, clang::ASTContext *ast = GetClangASTContext().getASTContext(); if (!clang_type) - clang_type = ast->VoidTy.getAsOpaquePtr(); + clang_type = GetClangASTContext().GetBasicType(eBasicTypeVoid); if (clang_type) { @@ -1475,20 +1475,19 @@ SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu, else template_param_infos.names.push_back(NULL); - clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type)); if (tag == DW_TAG_template_value_parameter && lldb_type != NULL && - ClangASTContext::IsIntegerType (clang_type, is_signed) && + clang_type.IsIntegerType (is_signed) && uval64_valid) { llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed); template_param_infos.args.push_back (clang::TemplateArgument (*ast, llvm::APSInt(apint), - clang_qual_type)); + clang_type.GetQualType())); } else { - template_param_infos.args.push_back (clang::TemplateArgument (clang_qual_type)); + template_param_infos.args.push_back (clang::TemplateArgument (clang_type.GetQualType())); } } else @@ -1565,17 +1564,15 @@ class SymbolFileDWARF::DelayedAddObjCClassProperty public: DelayedAddObjCClassProperty ( - clang::ASTContext *ast, - lldb::clang_type_t class_opaque_type, + const ClangASTType &class_opaque_type, const char *property_name, - lldb::clang_type_t property_opaque_type, // The property type is only required if you don't have an ivar decl + const ClangASTType &property_opaque_type, // The property type is only required if you don't have an ivar decl clang::ObjCIvarDecl *ivar_decl, const char *property_setter_name, const char *property_getter_name, uint32_t property_attributes, const ClangASTMetadata *metadata ) : - m_ast (ast), m_class_opaque_type (class_opaque_type), m_property_name (property_name), m_property_opaque_type (property_opaque_type), @@ -1593,12 +1590,11 @@ public: DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs) { - *this = rhs; + *this = rhs; } DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs) { - m_ast = rhs.m_ast; m_class_opaque_type = rhs.m_class_opaque_type; m_property_name = rhs.m_property_name; m_property_opaque_type = rhs.m_property_opaque_type; @@ -1615,23 +1611,21 @@ public: return *this; } - bool Finalize() const - { - return ClangASTContext::AddObjCClassProperty (m_ast, - m_class_opaque_type, - m_property_name, - m_property_opaque_type, - m_ivar_decl, - m_property_setter_name, - m_property_getter_name, - m_property_attributes, - m_metadata_ap.get()); + bool + Finalize() + { + return m_class_opaque_type.AddObjCClassProperty (m_property_name, + m_property_opaque_type, + m_ivar_decl, + m_property_setter_name, + m_property_getter_name, + m_property_attributes, + m_metadata_ap.get()); } private: - clang::ASTContext *m_ast; - lldb::clang_type_t m_class_opaque_type; + ClangASTType m_class_opaque_type; const char *m_property_name; - lldb::clang_type_t m_property_opaque_type; + ClangASTType m_property_opaque_type; clang::ObjCIvarDecl *m_ivar_decl; const char *m_property_setter_name; const char *m_property_getter_name; @@ -1693,7 +1687,7 @@ SymbolFileDWARF::ParseChildMembers const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *parent_die, - clang_type_t class_clang_type, + ClangASTType &class_clang_type, const LanguageType class_language, std::vector<clang::CXXBaseSpecifier *>& base_classes, std::vector<int>& member_accessibilities, @@ -1772,7 +1766,6 @@ SymbolFileDWARF::ParseChildMembers uint32_t block_length = form_value.Unsigned(); uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); if (DWARFExpression::Evaluate(NULL, // ExecutionContext * - NULL, // clang::ASTContext * NULL, // ClangExpressionVariableList * NULL, // ClangExpressionDeclMap * NULL, // RegisterContext * @@ -1784,7 +1777,7 @@ SymbolFileDWARF::ParseChildMembers memberOffset, NULL)) { - member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); + member_byte_offset = memberOffset.ResolveValue(NULL).UInt(); } } break; @@ -1891,10 +1884,9 @@ SymbolFileDWARF::ParseChildMembers if (var_type) { - GetClangASTContext().AddVariableToRecordType (class_clang_type, - name, - var_type->GetClangLayoutType(), - accessibility); + class_clang_type.AddVariableToRecordType (name, + var_type->GetClangLayoutType(), + accessibility); } break; } @@ -2008,32 +2000,30 @@ SymbolFileDWARF::ParseChildMembers if (anon_field_info.IsValid()) { - clang::FieldDecl *unnamed_bitfield_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type, - NULL, - GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width), - accessibility, - anon_field_info.bit_size); + clang::FieldDecl *unnamed_bitfield_decl = class_clang_type.AddFieldToRecordType (NULL, + GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width), + accessibility, + anon_field_info.bit_size); layout_info.field_offsets.insert(std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset)); } } } - clang_type_t member_clang_type = member_type->GetClangLayoutType(); + ClangASTType member_clang_type = member_type->GetClangLayoutType(); { // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>). // If the current field is at the end of the structure, then there is definitely no room for extra // elements and we override the type to array[0]. - clang_type_t member_array_element_type; + ClangASTType member_array_element_type; uint64_t member_array_size; bool member_array_is_incomplete; - if (GetClangASTContext().IsArrayType(member_clang_type, - &member_array_element_type, - &member_array_size, - &member_array_is_incomplete) && + if (member_clang_type.IsArrayType(&member_array_element_type, + &member_array_size, + &member_array_is_incomplete) && !member_array_is_incomplete) { uint64_t parent_byte_size = parent_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, UINT64_MAX); @@ -2054,11 +2044,10 @@ SymbolFileDWARF::ParseChildMembers } } - field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type, - name, - member_clang_type, - accessibility, - bit_size); + field_decl = class_clang_type.AddFieldToRecordType (name, + member_clang_type, + accessibility, + bit_size); GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset())); @@ -2094,8 +2083,7 @@ SymbolFileDWARF::ParseChildMembers ClangASTMetadata metadata; metadata.SetUserID (MakeUserID(die->GetOffset())); - delayed_properties.push_back(DelayedAddObjCClassProperty(GetClangASTContext().getASTContext(), - class_clang_type, + delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type, prop_name, member_type->GetClangLayoutType(), ivar_decl, @@ -2162,7 +2150,6 @@ SymbolFileDWARF::ParseChildMembers if (DWARFExpression::Evaluate (NULL, NULL, NULL, - NULL, NULL, debug_info_data, block_offset, @@ -2172,7 +2159,7 @@ SymbolFileDWARF::ParseChildMembers memberOffset, NULL)) { - member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); + member_byte_offset = memberOffset.ResolveValue(NULL).UInt(); } } break; @@ -2192,27 +2179,26 @@ SymbolFileDWARF::ParseChildMembers Type *base_class_type = ResolveTypeUID(encoding_uid); assert(base_class_type); - clang_type_t base_class_clang_type = base_class_type->GetClangFullType(); + ClangASTType base_class_clang_type = base_class_type->GetClangFullType(); assert (base_class_clang_type); if (class_language == eLanguageTypeObjC) { - GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type); + class_clang_type.SetObjCSuperClass(base_class_clang_type); } else { - base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type, - accessibility, + base_classes.push_back (base_class_clang_type.CreateBaseClassSpecifier (accessibility, is_virtual, is_base_of_class)); if (is_virtual) { - layout_info.vbase_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type), + layout_info.vbase_offsets.insert(std::make_pair(class_clang_type.GetAsCXXRecordDecl(), clang::CharUnits::fromQuantity(member_byte_offset))); } else { - layout_info.base_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type), + layout_info.base_offsets.insert(std::make_pair(class_clang_type.GetAsCXXRecordDecl(), clang::CharUnits::fromQuantity(member_byte_offset))); } } @@ -2331,35 +2317,35 @@ SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry // SymbolFileDWARF objects to detect if this DWARF file is the one that // can resolve a clang_type. bool -SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type) +SymbolFileDWARF::HasForwardDeclForClangType (const ClangASTType &clang_type) { - clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); - const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); + ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers(); + const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType()); return die != NULL; } -lldb::clang_type_t -SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) +bool +SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) { // We have a struct/union/class/enum that needs to be fully resolved. - clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); - const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); + ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers(); + const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType()); if (die == NULL) { // We have already resolved this type... - return clang_type; + return true; } // Once we start resolving this type, remove it from the forward declaration // map in case anyone child members or other types require this type to get resolved. // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition // are done. - m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers); + m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers.GetOpaqueQualType()); // Disable external storage for this type so we don't get anymore // clang::ExternalASTSource queries for this type. - ClangASTContext::SetHasExternalStorage (clang_type, false); + clang_type.SetHasExternalStorage (false); DWARFDebugInfo* debug_info = DebugInfo(); @@ -2381,8 +2367,6 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type assert (clang_type); DWARFDebugInfoEntry::Attributes attributes; - ClangASTContext &ast = GetClangASTContext(); - switch (tag) { case DW_TAG_structure_type: @@ -2396,13 +2380,12 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type { LanguageType class_language = eLanguageTypeUnknown; - bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type); - if (is_objc_class) + if (clang_type.IsObjCObjectOrInterfaceType()) { class_language = eLanguageTypeObjC; // For objective C we don't start the definition when // the class is created. - ast.StartTagDeclarationDefinition (clang_type); + clang_type.StartTagDeclarationDefinition (); } int tag_decl_kind = -1; @@ -2456,7 +2439,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type if (class_language == eLanguageTypeObjC) { - std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(ast.getASTContext(), clang_type)); + std::string class_str (clang_type.GetTypeName()); if (!class_str.empty()) { @@ -2499,7 +2482,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type } } - for (DelayedPropertyList::const_iterator pi = delayed_properties.begin(), pe = delayed_properties.end(); + for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end(); pi != pe; ++pi) pi->Finalize(); @@ -2511,7 +2494,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type if (class_language != eLanguageTypeObjC) { if (is_a_class && tag_decl_kind != clang::TTK_Class) - ast.SetTagTypeKind (clang_type, clang::TTK_Class); + clang_type.SetTagTypeKind (clang::TTK_Class); } // Since DW_TAG_structure_type gets used for both classes @@ -2528,29 +2511,26 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type { // This is a class and all members that didn't have // their access specified are private. - ast.SetDefaultAccessForRecordFields (clang_type, - eAccessPrivate, - &member_accessibilities.front(), - member_accessibilities.size()); + clang_type.SetDefaultAccessForRecordFields (eAccessPrivate, + &member_accessibilities.front(), + member_accessibilities.size()); } if (!base_classes.empty()) { - ast.SetBaseClassesForClassType (clang_type, - &base_classes.front(), - base_classes.size()); + clang_type.SetBaseClassesForClassType (&base_classes.front(), + base_classes.size()); // Clang will copy each CXXBaseSpecifier in "base_classes" // so we have to free them all. - ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), - base_classes.size()); + ClangASTType::DeleteBaseClassSpecifiers (&base_classes.front(), + base_classes.size()); } } } - ast.BuildIndirectFields (clang_type); - - ast.CompleteTagDeclarationDefinition (clang_type); + clang_type.BuildIndirectFields (); + clang_type.CompleteTagDeclarationDefinition (); if (!layout_info.field_offsets.empty() || !layout_info.base_offsets.empty() || @@ -2561,14 +2541,14 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type if (layout_info.bit_size == 0) layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8; - clang::CXXRecordDecl *record_decl = ClangASTType::GetAsCXXRecordDecl(clang_type); + clang::CXXRecordDecl *record_decl = clang_type.GetAsCXXRecordDecl(); if (record_decl) { if (log) { GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])", - clang_type, + clang_type.GetOpaqueQualType(), record_decl, layout_info.bit_size, layout_info.alignment, @@ -2583,7 +2563,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type { GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }", - clang_type, + clang_type.GetOpaqueQualType(), idx, (uint32_t)pos->second, pos->first->getNameAsString().c_str()); @@ -2596,7 +2576,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type { GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }", - clang_type, + clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(), base_pos->first->getNameAsString().c_str()); @@ -2608,7 +2588,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type { GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }", - clang_type, + clang_type.GetOpaqueQualType(), idx, (uint32_t)vbase_pos->second.getQuantity(), vbase_pos->first->getNameAsString().c_str()); @@ -2623,15 +2603,15 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type return clang_type; case DW_TAG_enumeration_type: - ast.StartTagDeclarationDefinition (clang_type); + clang_type.StartTagDeclarationDefinition (); if (die->HasChildren()) { SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu)); bool is_signed = false; - ast.IsIntegerType(clang_type, is_signed); + clang_type.IsIntegerType(is_signed); ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die); } - ast.CompleteTagDeclarationDefinition (clang_type); + clang_type.CompleteTagDeclarationDefinition (); return clang_type; default: @@ -4142,7 +4122,7 @@ SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc, bool skip_artificial, bool &is_static, TypeList* type_list, - std::vector<clang_type_t>& function_param_types, + std::vector<ClangASTType>& function_param_types, std::vector<clang::ParmVarDecl*>& function_param_decls, unsigned &type_quals, ClangASTContext::TemplateParameterInfos &template_param_infos) @@ -4308,7 +4288,7 @@ size_t SymbolFileDWARF::ParseChildEnumerators ( const SymbolContext& sc, - clang_type_t enumerator_clang_type, + lldb_private::ClangASTType &clang_type, bool is_signed, uint32_t enumerator_byte_size, DWARFCompileUnit* dwarf_cu, @@ -4370,12 +4350,11 @@ SymbolFileDWARF::ParseChildEnumerators if (name && name[0] && got_value) { - GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type, - enumerator_clang_type, - decl, - name, - enum_value, - enumerator_byte_size * 8); + clang_type.AddEnumerationValueToEnumerationType (clang_type.GetEnumerationIntegerType(), + decl, + name, + enum_value, + enumerator_byte_size * 8); ++enumerators_added; } } @@ -4643,7 +4622,7 @@ SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const D Type* type = ResolveType (cu, decl_ctx_die); if (type) { - clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ()); + clang::DeclContext *decl_ctx = type->GetClangForwardType().GetDeclContextForType (); if (decl_ctx) { LinkDeclContextToDIE (decl_ctx, decl_ctx_die); @@ -5671,7 +5650,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, Declaration decl; Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; - clang_type_t clang_type = NULL; + ClangASTType clang_type; dw_attr_t attr; @@ -5744,7 +5723,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, strcmp(type_name_cstr, "decltype(nullptr)") == 0 ) { resolve_state = Type::eResolveStateFull; - clang_type = ast.getASTContext()->NullPtrTy.getAsOpaquePtr(); + clang_type = ast.GetBasicType(eBasicTypeNullPtr); break; } // Fall through to base type below in case we can handle the type there... @@ -5765,7 +5744,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break; } - if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL) + if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL) { bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus); @@ -5784,7 +5763,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, dwarf_cu)); - clang_type = ast.GetBuiltInType_objc_id(); + clang_type = ast.GetBasicType(eBasicTypeObjCID); encoding_data_type = Type::eEncodingIsUID; encoding_uid = LLDB_INVALID_UID; resolve_state = Type::eResolveStateFull; @@ -5797,7 +5776,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, dwarf_cu)); - clang_type = ast.GetBuiltInType_objc_Class(); + clang_type = ast.GetBasicType(eBasicTypeObjCClass); encoding_data_type = Type::eEncodingIsUID; encoding_uid = LLDB_INVALID_UID; resolve_state = Type::eResolveStateFull; @@ -5809,7 +5788,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, dwarf_cu)); - clang_type = ast.GetBuiltInType_objc_selector(); + clang_type = ast.GetBasicType(eBasicTypeObjCSel); encoding_data_type = Type::eEncodingIsUID; encoding_uid = LLDB_INVALID_UID; resolve_state = Type::eResolveStateFull; @@ -5832,7 +5811,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, dwarf_cu)); - clang_type = ast.GetBuiltInType_objc_id(); + clang_type = ast.GetBasicType(eBasicTypeObjCID); encoding_data_type = Type::eEncodingIsUID; encoding_uid = LLDB_INVALID_UID; resolve_state = Type::eResolveStateFull; @@ -6109,8 +6088,8 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, } assert (tag_decl_kind != -1); bool clang_type_was_created = false; - clang_type = m_forward_decl_die_to_clang_type.lookup (die); - if (clang_type == NULL) + clang_type.SetClangType(ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die)); + if (!clang_type) { const DWARFDebugInfoEntry *decl_ctx_die; @@ -6166,7 +6145,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, // Store a forward declaration to this class type in case any // parameters in any class methods need it for the clang // types for function prototypes. - LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); + LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die); type_sp.reset (new Type (MakeUserID(die->GetOffset()), this, type_name_const_str, @@ -6202,27 +6181,21 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, if (die->HasChildren() == false) { // No children for this struct/union/class, lets finish it - ast.StartTagDeclarationDefinition (clang_type); - ast.CompleteTagDeclarationDefinition (clang_type); + clang_type.StartTagDeclarationDefinition (); + clang_type.CompleteTagDeclarationDefinition (); if (tag == DW_TAG_structure_type) // this only applies in C { - clang::QualType qual_type = clang::QualType::getFromOpaquePtr (clang_type); - const clang::RecordType *record_type = qual_type->getAs<clang::RecordType> (); + clang::RecordDecl *record_decl = clang_type.GetAsRecordDecl(); - if (record_type) + if (record_decl) { - clang::RecordDecl *record_decl = record_type->getDecl(); + LayoutInfo layout_info; - if (record_decl) - { - LayoutInfo layout_info; - - layout_info.alignment = 0; - layout_info.bit_size = 0; - - m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info)); - } + layout_info.alignment = 0; + layout_info.bit_size = 0; + + m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info)); } } } @@ -6238,16 +6211,16 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, if (class_language != eLanguageTypeObjC && class_language != eLanguageTypeObjC_plus_plus) - ast.StartTagDeclarationDefinition (clang_type); + clang_type.StartTagDeclarationDefinition (); // Leave this as a forward declaration until we need // to know the details of the type. lldb_private::Type // will automatically call the SymbolFile virtual function // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" // When the definition needs to be defined. - m_forward_decl_die_to_clang_type[die] = clang_type; - m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; - ClangASTContext::SetHasExternalStorage (clang_type, true); + m_forward_decl_die_to_clang_type[die] = clang_type.GetOpaqueQualType(); + m_forward_decl_clang_type_to_die[clang_type.RemoveFastQualifiers().GetOpaqueQualType()] = die; + clang_type.SetHasExternalStorage (true); } } @@ -6303,9 +6276,9 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr); - clang_type_t enumerator_clang_type = NULL; - clang_type = m_forward_decl_die_to_clang_type.lookup (die); - if (clang_type == NULL) + ClangASTType enumerator_clang_type; + clang_type.SetClangType (ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die)); + if (!clang_type) { if (encoding_uid != DW_INVALID_OFFSET) { @@ -6314,7 +6287,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, enumerator_clang_type = enumerator_type->GetClangFullType(); } - if (enumerator_clang_type == NULL) + if (!enumerator_clang_type) enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8); @@ -6326,10 +6299,10 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, } else { - enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type); + enumerator_clang_type = clang_type.GetEnumerationIntegerType (); } - LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); + LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die); type_sp.reset( new Type (MakeUserID(die->GetOffset()), this, @@ -6342,15 +6315,15 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, clang_type, Type::eResolveStateForward)); - ast.StartTagDeclarationDefinition (clang_type); + clang_type.StartTagDeclarationDefinition (); if (die->HasChildren()) { SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu)); bool is_signed = false; - ast.IsIntegerType(enumerator_clang_type, is_signed); + enumerator_clang_type.IsIntegerType(is_signed); ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die); } - ast.CompleteTagDeclarationDefinition (clang_type); + clang_type.CompleteTagDeclarationDefinition (); } } break; @@ -6473,7 +6446,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr); - clang_type_t return_clang_type = NULL; + ClangASTType return_clang_type; Type *func_type = NULL; if (type_die_offset != DW_INVALID_OFFSET) @@ -6482,10 +6455,10 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, if (func_type) return_clang_type = func_type->GetClangForwardType(); else - return_clang_type = ast.GetBuiltInType_void(); + return_clang_type = ast.GetBasicType(eBasicTypeVoid); - std::vector<clang_type_t> function_param_types; + std::vector<ClangASTType> function_param_types; std::vector<clang::ParmVarDecl*> function_param_decls; // Parse the function children for the parameters @@ -6535,7 +6508,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, if (objc_method.IsValid(true)) { SymbolContext empty_sc; - clang_type_t class_opaque_type = NULL; + ClangASTType class_opaque_type; ConstString class_name(objc_method.GetClassName()); if (class_name) { @@ -6544,8 +6517,8 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, if (complete_objc_class_type_sp) { - clang_type_t type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType(); - if (ClangASTContext::IsObjCClassType (type_clang_forward_type)) + ClangASTType type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType(); + if (type_clang_forward_type.IsObjCObjectOrInterfaceType ()) class_opaque_type = type_clang_forward_type; } } @@ -6557,11 +6530,10 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, if (accessibility == eAccessNone) accessibility = eAccessPublic; - clang::ObjCMethodDecl *objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type, - type_name_cstr, - clang_type, - accessibility, - is_artificial); + clang::ObjCMethodDecl *objc_method_decl = class_opaque_type.AddMethodToObjCObjectType (type_name_cstr, + clang_type, + accessibility, + is_artificial); type_handled = objc_method_decl != NULL; if (type_handled) { @@ -6680,10 +6652,10 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, } else { - clang_type_t class_opaque_type = class_type->GetClangForwardType(); - if (ClangASTContext::IsCXXClassType (class_opaque_type)) + ClangASTType class_opaque_type = class_type->GetClangForwardType(); + if (class_opaque_type.IsCXXClassType ()) { - if (ClangASTContext::IsBeingDefined (class_opaque_type)) + if (class_opaque_type.IsBeingDefined ()) { // Neither GCC 4.2 nor clang++ currently set a valid accessibility // in the DWARF for C++ methods... Default to public for now... @@ -6709,16 +6681,15 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const bool is_attr_used = false; - cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type, - type_name_cstr, - clang_type, - accessibility, - is_virtual, - is_static, - is_inline, - is_explicit, - is_attr_used, - is_artificial); + cxx_method_decl = class_opaque_type.AddMethodToCXXRecordType (type_name_cstr, + clang_type, + accessibility, + is_virtual, + is_static, + is_inline, + is_explicit, + is_attr_used, + is_artificial); type_handled = cxx_method_decl != NULL; @@ -6902,7 +6873,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride); if (byte_stride == 0 && bit_stride == 0) byte_stride = element_type->GetByteSize(); - clang_type_t array_element_type = element_type->GetClangForwardType(); + ClangASTType array_element_type = element_type->GetClangForwardType(); uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; uint64_t num_elements = 0; std::vector<uint64_t>::const_reverse_iterator pos; @@ -6961,14 +6932,12 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, Type *pointee_type = ResolveTypeUID(type_die_offset); Type *class_type = ResolveTypeUID(containing_type_die_offset); - clang_type_t pointee_clang_type = pointee_type->GetClangForwardType(); - clang_type_t class_clang_type = class_type->GetClangLayoutType(); + ClangASTType pointee_clang_type = pointee_type->GetClangForwardType(); + ClangASTType class_clang_type = class_type->GetClangLayoutType(); - clang_type = ast.CreateMemberPointerType(pointee_clang_type, - class_clang_type); + clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type); - byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(), - clang_type) / 8; + byte_size = clang_type.GetByteSize(); type_sp.reset( new Type (MakeUserID(die->GetOffset()), this, @@ -7761,7 +7730,7 @@ void SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl) { SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; - clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); + ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); if (clang_type) symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); } @@ -7770,7 +7739,7 @@ void SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl) { SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; - clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); + ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); if (clang_type) symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); } @@ -7844,8 +7813,7 @@ SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context, Type *matching_type = ResolveType (dwarf_cu, die); - lldb::clang_type_t type = matching_type->GetClangForwardType(); - clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type); + clang::QualType qual_type = matching_type->GetClangForwardType().GetQualType(); if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr())) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 0370bc3f595..b6c6d94782d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -107,7 +107,7 @@ public: virtual size_t ParseVariablesForContext (const lldb_private::SymbolContext& sc); virtual lldb_private::Type* ResolveTypeUID(lldb::user_id_t type_uid); - virtual lldb::clang_type_t ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_opaque_type); + virtual bool ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type); virtual lldb_private::Type* ResolveType (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed = true); virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid); @@ -275,7 +275,7 @@ public: } bool - HasForwardDeclForClangType (lldb::clang_type_t clang_type); + HasForwardDeclForClangType (const lldb_private::ClangASTType &clang_type); protected: @@ -347,7 +347,7 @@ protected: const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, - lldb::clang_type_t class_clang_type, + lldb_private::ClangASTType &class_clang_type, const lldb::LanguageType class_language, std::vector<clang::CXXBaseSpecifier *>& base_classes, std::vector<int>& member_accessibilities, @@ -365,14 +365,14 @@ protected: bool skip_artificial, bool &is_static, lldb_private::TypeList* type_list, - std::vector<lldb::clang_type_t>& function_args, + std::vector<lldb_private::ClangASTType>& function_args, std::vector<clang::ParmVarDecl*>& function_param_decls, unsigned &type_quals, lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos); size_t ParseChildEnumerators( const lldb_private::SymbolContext& sc, - lldb::clang_type_t enumerator_qual_type, + lldb_private::ClangASTType &clang_type, bool is_signed, uint32_t enumerator_byte_size, DWARFCompileUnit* dwarf_cu, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 42107efe0aa..a0430e3d52b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -780,11 +780,11 @@ SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) return NULL; } -lldb::clang_type_t -SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) +bool +SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (ClangASTType& clang_type) { // We have a struct/union/class/enum that needs to be fully resolved. - return NULL; + return false; } uint32_t @@ -1385,7 +1385,7 @@ void SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl) { SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; - clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); + ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); if (clang_type) { SymbolFileDWARF *oso_dwarf; @@ -1405,7 +1405,7 @@ void SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl) { SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; - clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); + ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); if (clang_type) { SymbolFileDWARF *oso_dwarf; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index d38bf66725a..06330b98dc1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -77,7 +77,7 @@ public: virtual lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid); virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid); virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid); - virtual lldb::clang_type_t ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type); + virtual bool ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type); virtual uint32_t ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc); virtual uint32_t ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list); virtual uint32_t FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::VariableList& variables); diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 28078693b35..9beba517ec8 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -292,10 +292,10 @@ SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) return NULL; } -lldb::clang_type_t -SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type) +bool +SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_opaque_type) { - return NULL; + return false; } ClangNamespaceDecl diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index 99f0eb16c60..914efe6eb3c 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -78,8 +78,8 @@ public: virtual lldb_private::Type* ResolveTypeUID(lldb::user_id_t type_uid); - virtual lldb::clang_type_t - ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type); + virtual bool + ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type); virtual uint32_t ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc); diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 00ebfaaed2f..b5c658dab86 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -62,6 +62,7 @@ #include "lldb/Core/Flags.h" #include "lldb/Core/Log.h" #include "lldb/Core/RegularExpression.h" +#include "lldb/Core/UniqueCStringMap.h" #include "lldb/Expression/ASTDumper.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/VerifyDecl.h" @@ -77,111 +78,8 @@ using namespace lldb_private; using namespace llvm; using namespace clang; - -static bool -GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true) -{ - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::ConstantArray: - case clang::Type::IncompleteArray: - case clang::Type::VariableArray: - { - const clang::ArrayType *array_type = dyn_cast<clang::ArrayType>(qual_type.getTypePtr()); - - if (array_type) - return GetCompleteQualType (ast, array_type->getElementType(), allow_completion); - } - break; - - case clang::Type::Record: - case clang::Type::Enum: - { - const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr()); - if (tag_type) - { - clang::TagDecl *tag_decl = tag_type->getDecl(); - if (tag_decl) - { - if (tag_decl->isCompleteDefinition()) - return true; - - if (!allow_completion) - return false; - - if (tag_decl->hasExternalLexicalStorage()) - { - if (ast) - { - ExternalASTSource *external_ast_source = ast->getExternalSource(); - if (external_ast_source) - { - external_ast_source->CompleteType(tag_decl); - return !tag_type->isIncompleteType(); - } - } - } - return false; - } - } - - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - { - const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type); - if (objc_class_type) - { - clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - // We currently can't complete objective C types through the newly added ASTContext - // because it only supports TagDecl objects right now... - if (class_interface_decl) - { - if (class_interface_decl->getDefinition()) - return true; - - if (!allow_completion) - return false; - - if (class_interface_decl->hasExternalLexicalStorage()) - { - if (ast) - { - ExternalASTSource *external_ast_source = ast->getExternalSource(); - if (external_ast_source) - { - external_ast_source->CompleteType (class_interface_decl); - return !objc_class_type->isIncompleteType(); - } - } - } - return false; - } - } - } - break; - - case clang::Type::Typedef: - return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion); - - case clang::Type::Elaborated: - return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion); - - case clang::Type::Paren: - return GetCompleteQualType (ast, cast<ParenType>(qual_type)->desugar(), allow_completion); - - default: - break; - } - - return true; -} - -static AccessSpecifier -ConvertAccessTypeToAccessSpecifier (AccessType access) +clang::AccessSpecifier +ClangASTContext::ConvertAccessTypeToAccessSpecifier (AccessType access) { switch (access) { @@ -194,20 +92,6 @@ ConvertAccessTypeToAccessSpecifier (AccessType access) return AS_none; } -static ObjCIvarDecl::AccessControl -ConvertAccessTypeToObjCIvarAccessControl (AccessType access) -{ - switch (access) - { - case eAccessNone: return ObjCIvarDecl::None; - case eAccessPublic: return ObjCIvarDecl::Public; - case eAccessPrivate: return ObjCIvarDecl::Private; - case eAccessProtected: return ObjCIvarDecl::Protected; - case eAccessPackage: return ObjCIvarDecl::Package; - } - return ObjCIvarDecl::None; -} - static void ParseLangArgs @@ -393,7 +277,8 @@ ClangASTContext::ClangASTContext (const char *target_triple) : m_builtins_ap(), m_callback_tag_decl (NULL), m_callback_objc_decl (NULL), - m_callback_baton (NULL) + m_callback_baton (NULL), + m_pointer_byte_size (0) { if (target_triple && target_triple[0]) @@ -429,6 +314,7 @@ ClangASTContext::Clear() m_identifier_table_ap.reset(); m_selector_table_ap.reset(); m_builtins_ap.reset(); + m_pointer_byte_size = 0; } const char * @@ -646,80 +532,279 @@ QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_t return true; return false; } - -clang_type_t +ClangASTType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size) { - ASTContext *ast = getASTContext(); - - assert (ast != NULL); - - return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size); + return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (getASTContext(), encoding, bit_size); } -clang_type_t +ClangASTType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size) { if (!ast) - return NULL; + return ClangASTType(); switch (encoding) { case eEncodingInvalid: if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) - return ast->VoidPtrTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr()); break; case eEncodingUint: if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) - return ast->UnsignedIntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) - return ast->UnsignedLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) - return ast->UnsignedLongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) - return ast->UnsignedInt128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr()); break; case eEncodingSint: if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return ast->CharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) - return ast->ShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) - return ast->IntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->IntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) - return ast->LongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) - return ast->LongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) - return ast->Int128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr()); break; case eEncodingIEEE754: if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy)) - return ast->FloatTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy)) - return ast->DoubleTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy)) - return ast->LongDoubleTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr()); break; case eEncodingVector: // Sanity check that bit_size is a multiple of 8's. if (bit_size && !(bit_size & 0x7u)) - return ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr(); + return ClangASTType (ast, ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr()); break; } - return NULL; + return ClangASTType(); +} + + + +lldb::BasicType +ClangASTContext::GetBasicTypeEnumeration (const ConstString &name) +{ + if (name) + { + typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap; + static TypeNameToBasicTypeMap g_type_map; + static std::once_flag g_once_flag; + std::call_once(g_once_flag, [](){ + // "void" + g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid); + + // "char" + g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar); + g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar); + g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar); + g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar); + g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar); + g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar); + // "short" + g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort); + g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort); + g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort); + g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort); + + // "int" + g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt); + g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt); + g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt); + g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt); + + // "long" + g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong); + g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong); + g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong); + g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong); + + // "long long" + g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong); + g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong); + g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong); + g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong); + + // "int128" + g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128); + g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128); + + // Miscelaneous + g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool); + g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat); + g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble); + g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble); + g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID); + g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel); + g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr); + g_type_map.Sort(); + }); + + return g_type_map.Find(name.GetCString(), eBasicTypeInvalid); + } + return eBasicTypeInvalid; +} + +ClangASTType +ClangASTContext::GetBasicType (ASTContext *ast, const ConstString &name) +{ + if (ast) + { + lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration (name); + return ClangASTContext::GetBasicType (ast, basic_type); + } + return ClangASTType(); +} + +uint32_t +ClangASTContext::GetPointerByteSize () +{ + if (m_pointer_byte_size == 0) + m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid).GetPointerType().GetByteSize(); + return m_pointer_byte_size; +} + +ClangASTType +ClangASTContext::GetBasicType (lldb::BasicType basic_type) +{ + return GetBasicType (getASTContext(), basic_type); +} + +ClangASTType +ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type) +{ + if (ast) + { + clang_type_t clang_type = NULL; + + switch (basic_type) + { + case eBasicTypeInvalid: + case eBasicTypeOther: + break; + case eBasicTypeVoid: + clang_type = ast->VoidTy.getAsOpaquePtr(); + break; + case eBasicTypeChar: + clang_type = ast->CharTy.getAsOpaquePtr(); + break; + case eBasicTypeSignedChar: + clang_type = ast->SignedCharTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedChar: + clang_type = ast->UnsignedCharTy.getAsOpaquePtr(); + break; + case eBasicTypeWChar: + clang_type = ast->getWCharType().getAsOpaquePtr(); + break; + case eBasicTypeSignedWChar: + clang_type = ast->getSignedWCharType().getAsOpaquePtr(); + break; + case eBasicTypeUnsignedWChar: + clang_type = ast->getUnsignedWCharType().getAsOpaquePtr(); + break; + case eBasicTypeChar16: + clang_type = ast->Char16Ty.getAsOpaquePtr(); + break; + case eBasicTypeChar32: + clang_type = ast->Char32Ty.getAsOpaquePtr(); + break; + case eBasicTypeShort: + clang_type = ast->ShortTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedShort: + clang_type = ast->UnsignedShortTy.getAsOpaquePtr(); + break; + case eBasicTypeInt: + clang_type = ast->IntTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedInt: + clang_type = ast->UnsignedIntTy.getAsOpaquePtr(); + break; + case eBasicTypeLong: + clang_type = ast->LongTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedLong: + clang_type = ast->UnsignedLongTy.getAsOpaquePtr(); + break; + case eBasicTypeLongLong: + clang_type = ast->LongLongTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedLongLong: + clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr(); + break; + case eBasicTypeInt128: + clang_type = ast->Int128Ty.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedInt128: + clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr(); + break; + case eBasicTypeBool: + clang_type = ast->BoolTy.getAsOpaquePtr(); + break; + case eBasicTypeHalf: + clang_type = ast->HalfTy.getAsOpaquePtr(); + break; + case eBasicTypeFloat: + clang_type = ast->FloatTy.getAsOpaquePtr(); + break; + case eBasicTypeDouble: + clang_type = ast->DoubleTy.getAsOpaquePtr(); + break; + case eBasicTypeLongDouble: + clang_type = ast->LongDoubleTy.getAsOpaquePtr(); + break; + case eBasicTypeFloatComplex: + clang_type = ast->FloatComplexTy.getAsOpaquePtr(); + break; + case eBasicTypeDoubleComplex: + clang_type = ast->DoubleComplexTy.getAsOpaquePtr(); + break; + case eBasicTypeLongDoubleComplex: + clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr(); + break; + case eBasicTypeObjCID: + clang_type = ast->getObjCIdType().getAsOpaquePtr(); + break; + case eBasicTypeObjCClass: + clang_type = ast->getObjCClassType().getAsOpaquePtr(); + break; + case eBasicTypeObjCSel: + clang_type = ast->getObjCSelType().getAsOpaquePtr(); + break; + case eBasicTypeNullPtr: + clang_type = ast->NullPtrTy.getAsOpaquePtr(); + break; + } + + if (clang_type) + return ClangASTType (ast, clang_type); + } + return ClangASTType(); } -clang_type_t + +ClangASTType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size) { ASTContext *ast = getASTContext(); @@ -735,18 +820,18 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name case DW_ATE_address: if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) - return ast->VoidPtrTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr()); break; case DW_ATE_boolean: if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy)) - return ast->BoolTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->BoolTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) - return ast->UnsignedIntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr()); break; case DW_ATE_lo_user: @@ -755,33 +840,33 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name { if (::strstr(type_name, "complex")) { - clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2); - return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr(); + ClangASTType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2); + return ClangASTType (ast, ast->getComplexType (complex_int_clang_type.GetQualType()).getAsOpaquePtr()); } } break; case DW_ATE_complex_float: if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy)) - return ast->FloatComplexTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->FloatComplexTy.getAsOpaquePtr()); else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy)) - return ast->DoubleComplexTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->DoubleComplexTy.getAsOpaquePtr()); else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy)) - return ast->LongDoubleComplexTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongDoubleComplexTy.getAsOpaquePtr()); else { - clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2); - return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr(); + ClangASTType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2); + return ClangASTType (ast, ast->getComplexType (complex_float_clang_type.GetQualType()).getAsOpaquePtr()); } break; case DW_ATE_float: if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy)) - return ast->FloatTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy)) - return ast->DoubleTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy)) - return ast->LongDoubleTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr()); break; case DW_ATE_signed: @@ -789,47 +874,47 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name { if (streq(type_name, "wchar_t") && QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy)) - return ast->WCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->WCharTy.getAsOpaquePtr()); if (streq(type_name, "void") && QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy)) - return ast->VoidTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->VoidTy.getAsOpaquePtr()); if (strstr(type_name, "long long") && QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) - return ast->LongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr()); if (strstr(type_name, "long") && QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) - return ast->LongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongTy.getAsOpaquePtr()); if (strstr(type_name, "short") && QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) - return ast->ShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr()); if (strstr(type_name, "char")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return ast->CharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) - return ast->SignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr()); } if (strstr(type_name, "int")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) - return ast->IntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->IntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) - return ast->Int128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr()); } } // We weren't able to match up a type name, just search by size if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return ast->CharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) - return ast->ShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) - return ast->IntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->IntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) - return ast->LongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) - return ast->LongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) - return ast->Int128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr()); break; case DW_ATE_signed_char: @@ -838,13 +923,13 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name if (streq(type_name, "signed char")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) - return ast->SignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr()); } } if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return ast->CharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) - return ast->SignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr()); break; case DW_ATE_unsigned: @@ -853,51 +938,51 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name if (strstr(type_name, "long long")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) - return ast->UnsignedLongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr()); } else if (strstr(type_name, "long")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) - return ast->UnsignedLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr()); } else if (strstr(type_name, "short")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); } else if (strstr(type_name, "char")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); } else if (strstr(type_name, "int")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) - return ast->UnsignedIntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) - return ast->UnsignedInt128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr()); } } // We weren't able to match up a type name, just search by size if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) - return ast->UnsignedIntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) - return ast->UnsignedLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) - return ast->UnsignedLongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) - return ast->UnsignedInt128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr()); break; case DW_ATE_unsigned_char: if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); break; case DW_ATE_imaginary_float: @@ -908,11 +993,11 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name { if (streq(type_name, "char16_t")) { - return ast->Char16Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Char16Ty.getAsOpaquePtr()); } else if (streq(type_name, "char32_t")) { - return ast->Char32Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Char32Ty.getAsOpaquePtr()); } } break; @@ -928,89 +1013,27 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name { Host::SystemLog (Host::eSystemLogError, "error: need to add support for DW_TAG_base_type encoded with DW_ATE = 0x%x, bit_size = %u\n", dw_ate, bit_size); } - return NULL; -} - -clang_type_t -ClangASTContext::GetBuiltInType_void(ASTContext *ast) -{ - return ast->VoidTy.getAsOpaquePtr(); + return ClangASTType (); } -clang_type_t -ClangASTContext::GetBuiltInType_bool() -{ - return getASTContext()->BoolTy.getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetBuiltInType_objc_id() -{ - return getASTContext()->getObjCIdType().getAsOpaquePtr(); -} - -lldb::clang_type_t -ClangASTContext::GetBuiltInType_objc_id(clang::ASTContext *ast) -{ - return ast->getObjCIdType().getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetBuiltInType_objc_Class() -{ - return getASTContext()->getObjCClassType().getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetBuiltInType_objc_selector() -{ - return getASTContext()->getObjCSelType().getAsOpaquePtr(); -} - -clang_type_t +ClangASTType ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) { - return ast->UnknownAnyTy.getAsOpaquePtr(); + if (ast) + return ClangASTType (ast, ast->UnknownAnyTy.getAsOpaquePtr()); + return ClangASTType(); } -clang_type_t +ClangASTType ClangASTContext::GetCStringType (bool is_const) { - QualType char_type(getASTContext()->CharTy); + ASTContext *ast = getASTContext(); + QualType char_type(ast->CharTy); if (is_const) char_type.addConst(); - return getASTContext()->getPointerType(char_type).getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetVoidType() -{ - return GetVoidType(getASTContext()); -} - -clang_type_t -ClangASTContext::GetVoidType(ASTContext *ast) -{ - return ast->VoidTy.getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetVoidPtrType (bool is_const) -{ - return GetVoidPtrType(getASTContext(), is_const); -} - -clang_type_t -ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const) -{ - QualType void_ptr_type(ast->VoidPtrTy); - - if (is_const) - void_ptr_type.addConst(); - - return void_ptr_type.getAsOpaquePtr(); + return ClangASTType (ast, ast->getPointerType(char_type).getAsOpaquePtr()); } clang::DeclContext * @@ -1019,21 +1042,20 @@ ClangASTContext::GetTranslationUnitDecl (clang::ASTContext *ast) return ast->getTranslationUnitDecl(); } -clang_type_t +ClangASTType ClangASTContext::CopyType (ASTContext *dst_ast, - ASTContext *src_ast, - clang_type_t clang_type) + ClangASTType src) { FileSystemOptions file_system_options; + ASTContext *src_ast = src.GetASTContext(); FileManager file_manager (file_system_options); ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager, false); - QualType src (QualType::getFromOpaquePtr(clang_type)); - QualType dst (importer.Import(src)); + QualType dst (importer.Import(src.GetQualType())); - return dst.getAsOpaquePtr(); + return ClangASTType (dst_ast, dst.getAsOpaquePtr()); } @@ -1052,16 +1074,19 @@ ClangASTContext::CopyDecl (ASTContext *dst_ast, } bool -ClangASTContext::AreTypesSame (ASTContext *ast, - clang_type_t type1, - clang_type_t type2, +ClangASTContext::AreTypesSame (ClangASTType type1, + ClangASTType type2, bool ignore_qualifiers) { - if (type1 == type2) + ASTContext *ast = type1.GetASTContext(); + if (ast != type2.GetASTContext()) + return false; + + if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType()) return true; - QualType type1_qual = QualType::getFromOpaquePtr(type1); - QualType type2_qual = QualType::getFromOpaquePtr(type2); + QualType type1_qual = type1.GetQualType(); + QualType type2_qual = type2.GetQualType(); if (ignore_qualifiers) { @@ -1069,74 +1094,37 @@ ClangASTContext::AreTypesSame (ASTContext *ast, type2_qual = type2_qual.getUnqualifiedType(); } - return ast->hasSameType (type1_qual, - type2_qual); -} - -#pragma mark CVR modifiers - -clang_type_t -ClangASTContext::AddConstModifier (clang_type_t clang_type) -{ - if (clang_type) - { - QualType result(QualType::getFromOpaquePtr(clang_type)); - result.addConst(); - return result.getAsOpaquePtr(); - } - return NULL; -} - -clang_type_t -ClangASTContext::AddRestrictModifier (clang_type_t clang_type) -{ - if (clang_type) - { - QualType result(QualType::getFromOpaquePtr(clang_type)); - result.getQualifiers().setRestrict (true); - return result.getAsOpaquePtr(); - } - return NULL; -} - -clang_type_t -ClangASTContext::AddVolatileModifier (clang_type_t clang_type) -{ - if (clang_type) - { - QualType result(QualType::getFromOpaquePtr(clang_type)); - result.getQualifiers().setVolatile (true); - return result.getAsOpaquePtr(); - } - return NULL; + return ast->hasSameType (type1_qual, type2_qual); } -clang_type_t +ClangASTType ClangASTContext::GetTypeForDecl (TagDecl *decl) { // No need to call the getASTContext() accessor (which can create the AST // if it isn't created yet, because we can't have created a decl in this // AST if our AST didn't already exist... - if (m_ast_ap.get()) - return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr(); - return NULL; + ASTContext *ast = m_ast_ap.get(); + if (ast) + return ClangASTType (ast, ast->getTagDeclType(decl).getAsOpaquePtr()); + return ClangASTType(); } -clang_type_t +ClangASTType ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl) { // No need to call the getASTContext() accessor (which can create the AST // if it isn't created yet, because we can't have created a decl in this // AST if our AST didn't already exist... - if (m_ast_ap.get()) - return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr(); - return NULL; + ASTContext *ast = m_ast_ap.get(); + if (ast) + return ClangASTType (ast, ast->getObjCInterfaceType(decl).getAsOpaquePtr()); + return ClangASTType(); } #pragma mark Structure, Unions, Classes -clang_type_t +ClangASTType ClangASTContext::CreateRecordType (DeclContext *decl_ctx, AccessType access_type, const char *name, @@ -1181,9 +1169,9 @@ ClangASTContext::CreateRecordType (DeclContext *decl_ctx, if (decl_ctx) decl_ctx->addDecl (decl); - return ast->getTagDeclType(decl).getAsOpaquePtr(); + return ClangASTType(ast, ast->getTagDeclType(decl).getAsOpaquePtr()); } - return NULL; + return ClangASTType(); } static TemplateParameterList * @@ -1385,85 +1373,16 @@ ClangASTContext::CreateClassTemplateSpecializationDecl (DeclContext *decl_ctx, return class_template_specialization_decl; } -lldb::clang_type_t +ClangASTType ClangASTContext::CreateClassTemplateSpecializationType (ClassTemplateSpecializationDecl *class_template_specialization_decl) { if (class_template_specialization_decl) { ASTContext *ast = getASTContext(); if (ast) - return ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr(); - } - return NULL; -} - -bool -ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern) -{ - if (clang_type == NULL) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - { - CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - cxx_record_decl->setHasExternalLexicalStorage (has_extern); - cxx_record_decl->setHasExternalVisibleStorage (has_extern); - return true; - } - } - break; - - case clang::Type::Enum: - { - EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl(); - if (enum_decl) - { - enum_decl->setHasExternalLexicalStorage (has_extern); - enum_decl->setHasExternalVisibleStorage (has_extern); - return true; - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - class_interface_decl->setHasExternalLexicalStorage (has_extern); - class_interface_decl->setHasExternalVisibleStorage (has_extern); - return true; - } - } - } - break; - - case clang::Type::Typedef: - return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern); - - case clang::Type::Elaborated: - return ClangASTContext::SetHasExternalStorage (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern); - - case clang::Type::Paren: - return ClangASTContext::SetHasExternalStorage (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), has_extern); - - default: - break; + return ClangASTType(ast, ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr()); } - return false; + return ClangASTType(); } static bool @@ -1722,364 +1641,8 @@ ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, ui return false; } -CXXMethodDecl * -ClangASTContext::AddMethodToCXXRecordType -( - ASTContext *ast, - clang_type_t record_opaque_type, - const char *name, - clang_type_t method_opaque_type, - lldb::AccessType access, - bool is_virtual, - bool is_static, - bool is_inline, - bool is_explicit, - bool is_attr_used, - bool is_artificial -) -{ - if (!record_opaque_type || !method_opaque_type || !name) - return NULL; - - assert(ast); - - IdentifierTable *identifier_table = &ast->Idents; - - assert(identifier_table); - - QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type)); - - CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl(); - - if (cxx_record_decl == NULL) - return NULL; - - QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); - - CXXMethodDecl *cxx_method_decl = NULL; - - DeclarationName decl_name (&identifier_table->get(name)); - - const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr()); - - if (function_Type == NULL) - return NULL; - - const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type)); - - if (!method_function_prototype) - return NULL; - - unsigned int num_params = method_function_prototype->getNumArgs(); - - CXXDestructorDecl *cxx_dtor_decl(NULL); - CXXConstructorDecl *cxx_ctor_decl(NULL); - - if (is_artificial) - return NULL; // skip everything artificial - - if (name[0] == '~') - { - cxx_dtor_decl = CXXDestructorDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()), - method_qual_type, - NULL, - is_inline, - is_artificial); - cxx_method_decl = cxx_dtor_decl; - } - else if (decl_name == cxx_record_decl->getDeclName()) - { - cxx_ctor_decl = CXXConstructorDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()), - method_qual_type, - NULL, // TypeSourceInfo * - is_explicit, - is_inline, - is_artificial, - false /*is_constexpr*/); - cxx_method_decl = cxx_ctor_decl; - } - else - { - clang::StorageClass SC = is_static ? SC_Static : SC_None; - OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS; - - if (IsOperator (name, op_kind)) - { - if (op_kind != NUM_OVERLOADED_OPERATORS) - { - // Check the number of operator parameters. Sometimes we have - // seen bad DWARF that doesn't correctly describe operators and - // if we try to create a methed and add it to the class, clang - // will assert and crash, so we need to make sure things are - // acceptable. - if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params)) - return NULL; - cxx_method_decl = CXXMethodDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()), - method_qual_type, - NULL, // TypeSourceInfo * - SC, - is_inline, - false /*is_constexpr*/, - SourceLocation()); - } - else if (num_params == 0) - { - // Conversion operators don't take params... - cxx_method_decl = CXXConversionDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()), - method_qual_type, - NULL, // TypeSourceInfo * - is_inline, - is_explicit, - false /*is_constexpr*/, - SourceLocation()); - } - } - - if (cxx_method_decl == NULL) - { - cxx_method_decl = CXXMethodDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (decl_name, SourceLocation()), - method_qual_type, - NULL, // TypeSourceInfo * - SC, - is_inline, - false /*is_constexpr*/, - SourceLocation()); - } - } - - AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access); - - cxx_method_decl->setAccess (access_specifier); - cxx_method_decl->setVirtualAsWritten (is_virtual); - - if (is_attr_used) - cxx_method_decl->addAttr(::new (*ast) UsedAttr(SourceRange(), *ast)); - - // Populate the method decl with parameter decls - - llvm::SmallVector<ParmVarDecl *, 12> params; - - for (unsigned param_index = 0; - param_index < num_params; - ++param_index) - { - params.push_back (ParmVarDecl::Create (*ast, - cxx_method_decl, - SourceLocation(), - SourceLocation(), - NULL, // anonymous - method_function_prototype->getArgType(param_index), - NULL, - SC_None, - NULL)); - } - - cxx_method_decl->setParams (ArrayRef<ParmVarDecl*>(params)); - - cxx_record_decl->addDecl (cxx_method_decl); - - // Sometimes the debug info will mention a constructor (default/copy/move), - // destructor, or assignment operator (copy/move) but there won't be any - // version of this in the code. So we check if the function was artificially - // generated and if it is trivial and this lets the compiler/backend know - // that it can inline the IR for these when it needs to and we can avoid a - // "missing function" error when running expressions. - - if (is_artificial) - { - if (cxx_ctor_decl && - ((cxx_ctor_decl->isDefaultConstructor() && cxx_record_decl->hasTrivialDefaultConstructor ()) || - (cxx_ctor_decl->isCopyConstructor() && cxx_record_decl->hasTrivialCopyConstructor ()) || - (cxx_ctor_decl->isMoveConstructor() && cxx_record_decl->hasTrivialMoveConstructor ()) )) - { - cxx_ctor_decl->setDefaulted(); - cxx_ctor_decl->setTrivial(true); - } - else if (cxx_dtor_decl) - { - if (cxx_record_decl->hasTrivialDestructor()) - { - cxx_dtor_decl->setDefaulted(); - cxx_dtor_decl->setTrivial(true); - } - } - else if ((cxx_method_decl->isCopyAssignmentOperator() && cxx_record_decl->hasTrivialCopyAssignment()) || - (cxx_method_decl->isMoveAssignmentOperator() && cxx_record_decl->hasTrivialMoveAssignment())) - { - cxx_method_decl->setDefaulted(); - cxx_method_decl->setTrivial(true); - } - } - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(cxx_method_decl); -#endif - -// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic()); -// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate()); -// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD()); -// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty()); -// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract()); -// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor()); -// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor()); -// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment()); -// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor()); - return cxx_method_decl; -} - -clang::FieldDecl * -ClangASTContext::AddFieldToRecordType -( - ASTContext *ast, - clang_type_t record_clang_type, - const char *name, - clang_type_t field_type, - AccessType access, - uint32_t bitfield_bit_size -) -{ - if (record_clang_type == NULL || field_type == NULL) - return NULL; - - FieldDecl *field = NULL; - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); - - const clang::Type *clang_type = record_qual_type.getTypePtr(); - if (clang_type) - { - const RecordType *record_type = dyn_cast<RecordType>(clang_type); - - if (record_type) - { - RecordDecl *record_decl = record_type->getDecl(); - - clang::Expr *bit_width = NULL; - if (bitfield_bit_size != 0) - { - APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size); - bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation()); - } - field = FieldDecl::Create (*ast, - record_decl, - SourceLocation(), - SourceLocation(), - name ? &identifier_table->get(name) : NULL, // Identifier - QualType::getFromOpaquePtr(field_type), // Field type - NULL, // TInfo * - bit_width, // BitWidth - false, // Mutable - ICIS_NoInit); // HasInit - - if (!name) { - // Determine whether this field corresponds to an anonymous - // struct or union. - if (const TagType *TagT = field->getType()->getAs<TagType>()) { - if (RecordDecl *Rec = dyn_cast<RecordDecl>(TagT->getDecl())) - if (!Rec->getDeclName()) { - Rec->setAnonymousStructOrUnion(true); - field->setImplicit(); - - } - } - } - - if (field) - { - field->setAccess (ConvertAccessTypeToAccessSpecifier (access)); - - record_decl->addDecl(field); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(field); -#endif - } - } - else - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type); - if (objc_class_type) - { - bool is_synthesized = false; - field = ClangASTContext::AddObjCClassIVar (ast, - record_clang_type, - name, - field_type, - access, - bitfield_bit_size, - is_synthesized); - } - } - } - return field; -} - -clang::VarDecl * -ClangASTContext::AddVariableToRecordType (clang::ASTContext *ast, - lldb::clang_type_t record_opaque_type, - const char *name, - lldb::clang_type_t var_type, - AccessType access) -{ - clang::VarDecl *var_decl = NULL; - - if (record_opaque_type == NULL || var_type == NULL) - return NULL; - - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - const RecordType *record_type = dyn_cast<RecordType>(QualType::getFromOpaquePtr(record_opaque_type).getTypePtr()); - - if (record_type) - { - RecordDecl *record_decl = record_type->getDecl(); - - var_decl = VarDecl::Create (*ast, // ASTContext & - record_decl, // DeclContext * - SourceLocation(), // SourceLocation StartLoc - SourceLocation(), // SourceLocation IdLoc - name ? &identifier_table->get(name) : NULL, // IdentifierInfo * - QualType::getFromOpaquePtr(var_type), // Variable QualType - NULL, // TypeSourceInfo * - SC_Static); // StorageClass - if (var_decl) - { - var_decl->setAccess(ConvertAccessTypeToAccessSpecifier (access)); - record_decl->addDecl(var_decl); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(var_decl); -#endif - } - } - return var_decl; -} - - -static clang::AccessSpecifier UnifyAccessSpecifiers (clang::AccessSpecifier lhs, - clang::AccessSpecifier rhs) +clang::AccessSpecifier +ClangASTContext::UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs) { clang::AccessSpecifier ret = lhs; @@ -2102,115 +1665,6 @@ static clang::AccessSpecifier UnifyAccessSpecifiers (clang::AccessSpecifier lhs, return ret; } -void -ClangASTContext::BuildIndirectFields (clang::ASTContext *ast, - lldb::clang_type_t record_clang_type) -{ - QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); - - const RecordType *record_type = record_qual_type->getAs<RecordType>(); - - if (!record_type) - return; - - RecordDecl *record_decl = record_type->getDecl(); - - if (!record_decl) - return; - - typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector; - - IndirectFieldVector indirect_fields; - RecordDecl::field_iterator field_pos; - RecordDecl::field_iterator field_end_pos = record_decl->field_end(); - RecordDecl::field_iterator last_field_pos = field_end_pos; - for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++) - { - if (field_pos->isAnonymousStructOrUnion()) - { - QualType field_qual_type = field_pos->getType(); - - const RecordType *field_record_type = field_qual_type->getAs<RecordType>(); - - if (!field_record_type) - continue; - - RecordDecl *field_record_decl = field_record_type->getDecl(); - - if (!field_record_decl) - continue; - - for (RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end(); - di != de; - ++di) - { - if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di)) - { - NamedDecl **chain = new (*ast) NamedDecl*[2]; - chain[0] = *field_pos; - chain[1] = nested_field_decl; - IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast, - record_decl, - SourceLocation(), - nested_field_decl->getIdentifier(), - nested_field_decl->getType(), - chain, - 2); - - indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(), - nested_field_decl->getAccess())); - - indirect_fields.push_back(indirect_field); - } - else if (IndirectFieldDecl *nested_indirect_field_decl = dyn_cast<IndirectFieldDecl>(*di)) - { - int nested_chain_size = nested_indirect_field_decl->getChainingSize(); - NamedDecl **chain = new (*ast) NamedDecl*[nested_chain_size + 1]; - chain[0] = *field_pos; - - int chain_index = 1; - for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(), - nce = nested_indirect_field_decl->chain_end(); - nci < nce; - ++nci) - { - chain[chain_index] = *nci; - chain_index++; - } - - IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast, - record_decl, - SourceLocation(), - nested_indirect_field_decl->getIdentifier(), - nested_indirect_field_decl->getType(), - chain, - nested_chain_size + 1); - - indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(), - nested_indirect_field_decl->getAccess())); - - indirect_fields.push_back(indirect_field); - } - } - } - } - - // Check the last field to see if it has an incomplete array type as its - // last member and if it does, the tell the record decl about it - if (last_field_pos != field_end_pos) - { - if (last_field_pos->getType()->isIncompleteArrayType()) - record_decl->hasFlexibleArrayMember(); - } - - for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end(); - ifi < ife; - ++ifi) - { - record_decl->addDecl(*ifi); - } -} - bool ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size) { @@ -2270,76 +1724,9 @@ ClangASTContext::RecordHasFields (const RecordDecl *record_decl) return false; } -void -ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities) -{ - if (clang_type) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - - const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr()); - if (record_type) - { - RecordDecl *record_decl = record_type->getDecl(); - if (record_decl) - { - uint32_t field_idx; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0; - field != field_end; - ++field, ++field_idx) - { - // If no accessibility was assigned, assign the correct one - if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none) - field->setAccess ((AccessSpecifier)default_accessibility); - } - } - } - } -} - -#pragma mark C++ Base Classes - -CXXBaseSpecifier * -ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class) -{ - if (base_class_type) - return new CXXBaseSpecifier (SourceRange(), - is_virtual, - base_of_class, - ConvertAccessTypeToAccessSpecifier (access), - getASTContext()->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)), - SourceLocation()); - return NULL; -} - -void -ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes) -{ - for (unsigned i=0; i<num_base_classes; ++i) - { - delete base_classes[i]; - base_classes[i] = NULL; - } -} - -bool -ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes) -{ - if (class_clang_type) - { - CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - cxx_record_decl->setBases(base_classes, num_base_classes); - return true; - } - } - return false; -} #pragma mark Objective C Classes -clang_type_t +ClangASTType ClangASTContext::CreateObjCClass ( const char *name, @@ -2355,11 +1742,6 @@ ClangASTContext::CreateObjCClass if (decl_ctx == NULL) decl_ctx = ast->getTranslationUnitDecl(); - // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and - // we will need to update this code. I was told to currently always use - // the CXXRecordDecl class since we often don't know from debug information - // if something is struct or a class, so we default to always use the more - // complete definition just in case. ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast, decl_ctx, SourceLocation(), @@ -2372,2286 +1754,7 @@ ClangASTContext::CreateObjCClass if (decl && metadata) SetMetadata(ast, decl, *metadata); - return ast->getObjCInterfaceType(decl).getAsOpaquePtr(); -} - -bool -ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type) -{ - if (class_opaque_type && super_opaque_type) - { - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type)); - const clang::Type *class_type = class_qual_type.getTypePtr(); - const clang::Type *super_type = super_qual_type.getTypePtr(); - if (class_type && super_type) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type); - if (objc_class_type && objc_super_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface(); - if (class_interface_decl && super_interface_decl) - { - class_interface_decl->setSuperClass(super_interface_decl); - return true; - } - } - } - } - return false; -} - - -FieldDecl * -ClangASTContext::AddObjCClassIVar -( - ASTContext *ast, - clang_type_t class_opaque_type, - const char *name, - clang_type_t ivar_opaque_type, - AccessType access, - uint32_t bitfield_bit_size, - bool is_synthesized -) -{ - if (class_opaque_type == NULL || ivar_opaque_type == NULL) - return NULL; - - ObjCIvarDecl *field = NULL; - - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - - const clang::Type *class_type = class_qual_type.getTypePtr(); - if (class_type) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - clang::Expr *bit_width = NULL; - if (bitfield_bit_size != 0) - { - APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size); - bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation()); - } - - field = ObjCIvarDecl::Create (*ast, - class_interface_decl, - SourceLocation(), - SourceLocation(), - name ? &identifier_table->get(name) : NULL, // Identifier - QualType::getFromOpaquePtr(ivar_opaque_type), // Field type - NULL, // TypeSourceInfo * - ConvertAccessTypeToObjCIvarAccessControl (access), - bit_width, - is_synthesized); - - if (field) - { - class_interface_decl->addDecl(field); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(field); -#endif - - return field; - } - } - } - } - return NULL; -} - -bool -ClangASTContext::AddObjCClassProperty -( - ASTContext *ast, - clang_type_t class_opaque_type, - const char *property_name, - clang_type_t property_opaque_type, - ObjCIvarDecl *ivar_decl, - const char *property_setter_name, - const char *property_getter_name, - uint32_t property_attributes, - ClangASTMetadata *metadata -) -{ - if (class_opaque_type == NULL || property_name == NULL || property_name[0] == '\0') - return false; - - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - const clang::Type *class_type = class_qual_type.getTypePtr(); - if (class_type) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - clang_type_t property_opaque_type_to_access = NULL; - - if (property_opaque_type) - property_opaque_type_to_access = property_opaque_type; - else if (ivar_decl) - property_opaque_type_to_access = ivar_decl->getType().getAsOpaquePtr(); - - if (class_interface_decl && property_opaque_type_to_access) - { - clang::TypeSourceInfo *prop_type_source; - if (ivar_decl) - prop_type_source = ast->getTrivialTypeSourceInfo (ivar_decl->getType()); - else - prop_type_source = ast->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(property_opaque_type)); - - ObjCPropertyDecl *property_decl = ObjCPropertyDecl::Create(*ast, - class_interface_decl, - SourceLocation(), // Source Location - &identifier_table->get(property_name), - SourceLocation(), //Source Location for AT - SourceLocation(), //Source location for ( - prop_type_source - ); - - if (property_decl) - { - if (metadata) - SetMetadata(ast, property_decl, *metadata); - - class_interface_decl->addDecl (property_decl); - - Selector setter_sel, getter_sel; - - if (property_setter_name != NULL) - { - std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1); - clang::IdentifierInfo *setter_ident = &identifier_table->get(property_setter_no_colon.c_str()); - setter_sel = ast->Selectors.getSelector(1, &setter_ident); - } - else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) - { - std::string setter_sel_string("set"); - setter_sel_string.push_back(::toupper(property_name[0])); - setter_sel_string.append(&property_name[1]); - clang::IdentifierInfo *setter_ident = &identifier_table->get(setter_sel_string.c_str()); - setter_sel = ast->Selectors.getSelector(1, &setter_ident); - } - property_decl->setSetterName(setter_sel); - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter); - - if (property_getter_name != NULL) - { - clang::IdentifierInfo *getter_ident = &identifier_table->get(property_getter_name); - getter_sel = ast->Selectors.getSelector(0, &getter_ident); - } - else - { - clang::IdentifierInfo *getter_ident = &identifier_table->get(property_name); - getter_sel = ast->Selectors.getSelector(0, &getter_ident); - } - property_decl->setGetterName(getter_sel); - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_getter); - - if (ivar_decl) - property_decl->setPropertyIvarDecl (ivar_decl); - - if (property_attributes & DW_APPLE_PROPERTY_readonly) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readonly); - if (property_attributes & DW_APPLE_PROPERTY_readwrite) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readwrite); - if (property_attributes & DW_APPLE_PROPERTY_assign) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_assign); - if (property_attributes & DW_APPLE_PROPERTY_retain) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_retain); - if (property_attributes & DW_APPLE_PROPERTY_copy) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_copy); - if (property_attributes & DW_APPLE_PROPERTY_nonatomic) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_nonatomic); - - if (!getter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(getter_sel)) - { - QualType result_type = QualType::getFromOpaquePtr(property_opaque_type_to_access); - - const bool isInstance = true; - const bool isVariadic = false; - const bool isSynthesized = false; - const bool isImplicitlyDeclared = true; - const bool isDefined = false; - const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None; - const bool HasRelatedResultType = false; - - ObjCMethodDecl *getter = ObjCMethodDecl::Create(*ast, - SourceLocation(), - SourceLocation(), - getter_sel, - result_type, - NULL, - class_interface_decl, - isInstance, - isVariadic, - isSynthesized, - isImplicitlyDeclared, - isDefined, - impControl, - HasRelatedResultType); - - if (getter && metadata) - SetMetadata(ast, getter, *metadata); - - getter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>()); - - class_interface_decl->addDecl(getter); - } - - if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel)) - { - QualType result_type = ast->VoidTy; - - const bool isInstance = true; - const bool isVariadic = false; - const bool isSynthesized = false; - const bool isImplicitlyDeclared = true; - const bool isDefined = false; - const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None; - const bool HasRelatedResultType = false; - - ObjCMethodDecl *setter = ObjCMethodDecl::Create(*ast, - SourceLocation(), - SourceLocation(), - setter_sel, - result_type, - NULL, - class_interface_decl, - isInstance, - isVariadic, - isSynthesized, - isImplicitlyDeclared, - isDefined, - impControl, - HasRelatedResultType); - - if (setter && metadata) - SetMetadata(ast, setter, *metadata); - - llvm::SmallVector<ParmVarDecl *, 1> params; - - params.push_back (ParmVarDecl::Create (*ast, - setter, - SourceLocation(), - SourceLocation(), - NULL, // anonymous - QualType::getFromOpaquePtr(property_opaque_type_to_access), - NULL, - SC_Auto, - NULL)); - - setter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>()); - - class_interface_decl->addDecl(setter); - } - - return true; - } - } - } - } - return false; -} - -bool -ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass) -{ - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - - const clang::Type *class_type = class_qual_type.getTypePtr(); - if (class_type) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - - if (objc_class_type) - return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass); - } - return false; -} - -bool -ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass) -{ - while (class_interface_decl) - { - if (class_interface_decl->ivar_size() > 0) - return true; - - if (check_superclass) - class_interface_decl = class_interface_decl->getSuperClass(); - else - break; - } - return false; -} - -ObjCMethodDecl * -ClangASTContext::AddMethodToObjCObjectType (ASTContext *ast, - clang_type_t class_opaque_type, - const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") - clang_type_t method_opaque_type, - lldb::AccessType access, - bool is_artificial) -{ - if (class_opaque_type == NULL || method_opaque_type == NULL) - return NULL; - - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - - const clang::Type *class_type = class_qual_type.getTypePtr(); - if (class_type == NULL) - return NULL; - - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - - if (objc_class_type == NULL) - return NULL; - - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl == NULL) - return NULL; - - const char *selector_start = ::strchr (name, ' '); - if (selector_start == NULL) - return NULL; - - selector_start++; - llvm::SmallVector<IdentifierInfo *, 12> selector_idents; - - size_t len = 0; - const char *start; - //printf ("name = '%s'\n", name); - - unsigned num_selectors_with_args = 0; - for (start = selector_start; - start && *start != '\0' && *start != ']'; - start += len) - { - len = ::strcspn(start, ":]"); - bool has_arg = (start[len] == ':'); - if (has_arg) - ++num_selectors_with_args; - selector_idents.push_back (&identifier_table->get (StringRef (start, len))); - if (has_arg) - len += 1; - } - - - if (selector_idents.size() == 0) - return 0; - - clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, - selector_idents.data()); - - QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); - - // Populate the method decl with parameter decls - const clang::Type *method_type(method_qual_type.getTypePtr()); - - if (method_type == NULL) - return NULL; - - const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type)); - - if (!method_function_prototype) - return NULL; - - - bool is_variadic = false; - bool is_synthesized = false; - bool is_defined = false; - ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None; - - const unsigned num_args = method_function_prototype->getNumArgs(); - - if (num_args != num_selectors_with_args) - return NULL; // some debug information is corrupt. We are not going to deal with it. - - ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast, - SourceLocation(), // beginLoc, - SourceLocation(), // endLoc, - method_selector, - method_function_prototype->getResultType(), - NULL, // TypeSourceInfo *ResultTInfo, - GetDeclContextForType (class_opaque_type), - name[0] == '-', - is_variadic, - is_synthesized, - true, // is_implicitly_declared; we force this to true because we don't have source locations - is_defined, - imp_control, - false /*has_related_result_type*/); - - - if (objc_method_decl == NULL) - return NULL; - - if (num_args > 0) - { - llvm::SmallVector<ParmVarDecl *, 12> params; - - for (unsigned param_index = 0; param_index < num_args; ++param_index) - { - params.push_back (ParmVarDecl::Create (*ast, - objc_method_decl, - SourceLocation(), - SourceLocation(), - NULL, // anonymous - method_function_prototype->getArgType(param_index), - NULL, - SC_Auto, - NULL)); - } - - objc_method_decl->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>()); - } - - class_interface_decl->addDecl (objc_method_decl); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(objc_method_decl); -#endif - - return objc_method_decl; -} - -size_t -ClangASTContext::GetNumTemplateArguments (clang::ASTContext *ast, clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl); - if (template_decl) - return template_decl->getTemplateArgs().size(); - } - } - break; - - case clang::Type::Typedef: - return ClangASTContext::GetNumTemplateArguments (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - - case clang::Type::Elaborated: - return ClangASTContext::GetNumTemplateArguments (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - - case clang::Type::Paren: - return ClangASTContext::GetNumTemplateArguments(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - default: - break; - } - } - return 0; -} - -clang_type_t -ClangASTContext::GetTemplateArgument (clang::ASTContext *ast, clang_type_t clang_type, size_t arg_idx, lldb::TemplateArgumentKind &kind) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl); - if (template_decl && arg_idx < template_decl->getTemplateArgs().size()) - { - const TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx]; - switch (template_arg.getKind()) - { - case clang::TemplateArgument::Null: - kind = eTemplateArgumentKindNull; - return NULL; - - case clang::TemplateArgument::Type: - kind = eTemplateArgumentKindType; - return template_arg.getAsType().getAsOpaquePtr(); - - case clang::TemplateArgument::Declaration: - kind = eTemplateArgumentKindDeclaration; - return NULL; - - case clang::TemplateArgument::Integral: - kind = eTemplateArgumentKindIntegral; - return template_arg.getIntegralType().getAsOpaquePtr(); - - case clang::TemplateArgument::Template: - kind = eTemplateArgumentKindTemplate; - return NULL; - - case clang::TemplateArgument::TemplateExpansion: - kind = eTemplateArgumentKindTemplateExpansion; - return NULL; - - case clang::TemplateArgument::Expression: - kind = eTemplateArgumentKindExpression; - return NULL; - - case clang::TemplateArgument::Pack: - kind = eTemplateArgumentKindPack; - return NULL; - - default: - assert (!"Unhandled TemplateArgument::ArgKind"); - kind = eTemplateArgumentKindNull; - return NULL; - } - } - } - } - break; - - case clang::Type::Typedef: - return ClangASTContext::GetTemplateArgument (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), arg_idx, kind); - - case clang::Type::Elaborated: - return ClangASTContext::GetTemplateArgument (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), arg_idx, kind); - - case clang::Type::Paren: - return ClangASTContext::GetTemplateArgument(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), arg_idx, kind); - - default: - break; - } - } - kind = eTemplateArgumentKindNull; - return NULL; -} - -uint32_t -ClangASTContext::GetTypeInfo -( - clang_type_t clang_type, - clang::ASTContext *ast, - clang_type_t *pointee_or_element_clang_type -) -{ - if (clang_type == NULL) - return 0; - - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = NULL; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - { - const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); - - uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue; - switch (builtin_type->getKind()) - { - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - if (ast && pointee_or_element_clang_type) - *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr(); - builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; - break; - - case clang::BuiltinType::ObjCSel: - if (ast && pointee_or_element_clang_type) - *pointee_or_element_clang_type = ast->CharTy.getAsOpaquePtr(); - builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; - break; - - case clang::BuiltinType::Bool: - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::WChar_U: - case clang::BuiltinType::Char16: - case clang::BuiltinType::Char32: - case clang::BuiltinType::UShort: - case clang::BuiltinType::UInt: - case clang::BuiltinType::ULong: - case clang::BuiltinType::ULongLong: - case clang::BuiltinType::UInt128: - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar_S: - case clang::BuiltinType::Short: - case clang::BuiltinType::Int: - case clang::BuiltinType::Long: - case clang::BuiltinType::LongLong: - case clang::BuiltinType::Int128: - case clang::BuiltinType::Float: - case clang::BuiltinType::Double: - case clang::BuiltinType::LongDouble: - builtin_type_flags |= eTypeIsScalar; - if (builtin_type->isInteger()) - { - builtin_type_flags |= eTypeIsInteger; - if (builtin_type->isSignedInteger()) - builtin_type_flags |= eTypeIsSigned; - } - else if (builtin_type->isFloatingPoint()) - builtin_type_flags |= eTypeIsFloat; - break; - default: - break; - } - return builtin_type_flags; - } - - case clang::Type::BlockPointer: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); - return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock; - - case clang::Type::Complex: - { - uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex; - const ComplexType *complex_type = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()); - if (complex_type) - { - QualType complex_element_type (complex_type->getElementType()); - if (complex_element_type->isIntegerType()) - complex_type_flags |= eTypeIsFloat; - else if (complex_element_type->isFloatingType()) - complex_type_flags |= eTypeIsInteger; - } - return complex_type_flags; - } - break; - - case clang::Type::ConstantArray: - case clang::Type::DependentSizedArray: - case clang::Type::IncompleteArray: - case clang::Type::VariableArray: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr(); - return eTypeHasChildren | eTypeIsArray; - - case clang::Type::DependentName: return 0; - case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector; - case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate; - case clang::Type::Decltype: return 0; - - case clang::Type::Enum: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr(); - return eTypeIsEnumeration | eTypeHasValue; - - case clang::Type::Elaborated: - return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - ast, - pointee_or_element_clang_type); - - case clang::Type::Paren: - return ClangASTContext::GetTypeInfo(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - ast, - pointee_or_element_clang_type); - - case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue; - case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue; - case clang::Type::InjectedClassName: return 0; - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(); - return eTypeHasChildren | eTypeIsReference | eTypeHasValue; - - case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue; - - case clang::Type::ObjCObjectPointer: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); - return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue; - - case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; - case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; - - case clang::Type::Pointer: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); - return eTypeHasChildren | eTypeIsPointer | eTypeHasValue; - - case clang::Type::Record: - if (qual_type->getAsCXXRecordDecl()) - return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus; - else - return eTypeHasChildren | eTypeIsStructUnion; - break; - case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate; - case clang::Type::TemplateTypeParm: return eTypeIsTemplate; - case clang::Type::TemplateSpecialization: return eTypeIsTemplate; - - case clang::Type::Typedef: - return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - ast, - pointee_or_element_clang_type); - - case clang::Type::TypeOfExpr: return 0; - case clang::Type::TypeOf: return 0; - case clang::Type::UnresolvedUsing: return 0; - - case clang::Type::ExtVector: - case clang::Type::Vector: - { - uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector; - const VectorType *vector_type = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()); - if (vector_type) - { - if (vector_type->isIntegerType()) - vector_type_flags |= eTypeIsFloat; - else if (vector_type->isFloatingType()) - vector_type_flags |= eTypeIsInteger; - } - return vector_type_flags; - } - default: return 0; - } - return 0; -} - - -#pragma mark Aggregate Types - -bool -ClangASTContext::IsAggregateType (clang_type_t clang_type) -{ - if (clang_type == NULL) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::IncompleteArray: - case clang::Type::VariableArray: - case clang::Type::ConstantArray: - case clang::Type::ExtVector: - case clang::Type::Vector: - case clang::Type::Record: - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - return true; - case clang::Type::Elaborated: - return ClangASTContext::IsAggregateType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Typedef: - return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Paren: - return ClangASTContext::IsAggregateType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr()); - default: - break; - } - // The clang type does have a value - return false; -} - -uint32_t -ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes) -{ - if (clang_type == NULL) - return 0; - - uint32_t num_children = 0; - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - case clang::BuiltinType::ObjCId: // child is Class - case clang::BuiltinType::ObjCClass: // child is Class - num_children = 1; - break; - - default: - break; - } - break; - - case clang::Type::Complex: return 0; - - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - assert(record_decl); - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - if (cxx_record_decl) - { - if (omit_empty_base_classes) - { - // Check each base classes to see if it or any of its - // base classes contain any fields. This can help - // limit the noise in variable views by not having to - // show base classes that contain no members. - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class) - { - const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - - // Skip empty base classes - if (RecordHasFields(base_class_decl) == false) - continue; - - num_children++; - } - } - else - { - // Include all base classes - num_children += cxx_record_decl->getNumBases(); - } - - } - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) - ++num_children; - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - if (superclass_interface_decl) - { - if (omit_empty_base_classes) - { - if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true)) - ++num_children; - } - else - ++num_children; - } - - num_children += class_interface_decl->ivar_size(); - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - { - const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, - pointee_type.getAsOpaquePtr(), - omit_empty_base_classes); - // If this type points to a simple type, then it has 1 child - if (num_pointee_children == 0) - num_children = 1; - else - num_children = num_pointee_children; - } - break; - - case clang::Type::Vector: - case clang::Type::ExtVector: - num_children = cast<VectorType>(qual_type.getTypePtr())->getNumElements(); - break; - - case clang::Type::ConstantArray: - num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); - break; - - case clang::Type::Pointer: - { - const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); - QualType pointee_type (pointer_type->getPointeeType()); - uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, - pointee_type.getAsOpaquePtr(), - omit_empty_base_classes); - if (num_pointee_children == 0) - { - // We have a pointer to a pointee type that claims it has no children. - // We will want to look at - num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr()); - } - else - num_children = num_pointee_children; - } - break; - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - { - const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); - QualType pointee_type = reference_type->getPointeeType(); - uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, - pointee_type.getAsOpaquePtr(), - omit_empty_base_classes); - // If this type points to a simple type, then it has 1 child - if (num_pointee_children == 0) - num_children = 1; - else - num_children = num_pointee_children; - } - break; - - - case clang::Type::Typedef: - num_children = ClangASTContext::GetNumChildren (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - omit_empty_base_classes); - break; - - case clang::Type::Elaborated: - num_children = ClangASTContext::GetNumChildren (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - omit_empty_base_classes); - break; - - case clang::Type::Paren: - num_children = ClangASTContext::GetNumChildren(ast, - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - omit_empty_base_classes); - - break; - default: - break; - } - return num_children; -} - -uint32_t -ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type) -{ - if (clang_type == NULL) - return 0; - - uint32_t count = 0; - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - count = cxx_record_decl->getNumBases(); - } - break; - - case clang::Type::ObjCObjectPointer: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); - if (class_interface_decl && class_interface_decl->getSuperClass()) - count = 1; - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl && class_interface_decl->getSuperClass()) - count = 1; - } - } - break; - - - case clang::Type::Typedef: - count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - break; - - case clang::Type::Elaborated: - count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - break; - - case clang::Type::Paren: - return ClangASTContext::GetNumDirectBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - default: - break; - } - return count; -} - -uint32_t -ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast, - clang_type_t clang_type) -{ - if (clang_type == NULL) - return 0; - - uint32_t count = 0; - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - count = cxx_record_decl->getNumVBases(); - } - break; - - case clang::Type::Typedef: - count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - break; - - case clang::Type::Elaborated: - count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - break; - - case clang::Type::Paren: - count = ClangASTContext::GetNumVirtualBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - break; - - default: - break; - } - return count; -} - -uint32_t -ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type) -{ - if (clang_type == NULL) - return 0; - - uint32_t count = 0; - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr()); - if (record_type) - { - RecordDecl *record_decl = record_type->getDecl(); - if (record_decl) - { - uint32_t field_idx = 0; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) - ++field_idx; - count = field_idx; - } - } - } - break; - - case clang::Type::Typedef: - count = ClangASTContext::GetNumFields (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - break; - - case clang::Type::Elaborated: - count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - break; - - case clang::Type::Paren: - count = ClangASTContext::GetNumFields(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - break; - - case clang::Type::ObjCObjectPointer: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); - - if (class_interface_decl) - count = class_interface_decl->ivar_size(); - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - count = class_interface_decl->ivar_size(); - } - } - break; - - default: - break; - } - return count; -} - -clang_type_t -ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast, - clang_type_t clang_type, - size_t idx, - uint32_t *bit_offset_ptr) -{ - if (clang_type == NULL) - return 0; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - uint32_t curr_idx = 0; - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class, ++curr_idx) - { - if (curr_idx == idx) - { - if (bit_offset_ptr) - { - const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl); - const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - if (base_class->isVirtual()) - *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; - else - *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; - } - return base_class->getType().getAsOpaquePtr(); - } - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - if (idx == 0 && GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); - if (class_interface_decl) - { - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - if (superclass_interface_decl) - { - if (bit_offset_ptr) - *bit_offset_ptr = 0; - return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(); - } - } - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (idx == 0 && GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - if (superclass_interface_decl) - { - if (bit_offset_ptr) - *bit_offset_ptr = 0; - return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(); - } - } - } - } - break; - - - case clang::Type::Typedef: - return ClangASTContext::GetDirectBaseClassAtIndex (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - case clang::Type::Elaborated: - return ClangASTContext::GetDirectBaseClassAtIndex (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - case clang::Type::Paren: - return ClangASTContext::GetDirectBaseClassAtIndex (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - default: - break; - } - return NULL; -} - -clang_type_t -ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast, - clang_type_t clang_type, - size_t idx, - uint32_t *bit_offset_ptr) -{ - if (clang_type == NULL) - return 0; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - uint32_t curr_idx = 0; - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end(); - base_class != base_class_end; - ++base_class, ++curr_idx) - { - if (curr_idx == idx) - { - if (bit_offset_ptr) - { - const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl); - const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; - - } - return base_class->getType().getAsOpaquePtr(); - } - } - } - } - break; - - case clang::Type::Typedef: - return ClangASTContext::GetVirtualBaseClassAtIndex (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - case clang::Type::Elaborated: - return ClangASTContext::GetVirtualBaseClassAtIndex (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - case clang::Type::Paren: - return ClangASTContext::GetVirtualBaseClassAtIndex (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - default: - break; - } - return NULL; -} - -static clang_type_t -GetObjCFieldAtIndex (clang::ASTContext *ast, - ObjCInterfaceDecl * class_interface_decl, - size_t idx, - std::string& name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) -{ - if (class_interface_decl) - { - if (idx < (class_interface_decl->ivar_size())) - { - ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); - uint32_t ivar_idx = 0; - - for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx) - { - if (ivar_idx == idx) - { - const ObjCIvarDecl* ivar_decl = *ivar_pos; - - QualType ivar_qual_type(ivar_decl->getType()); - - name.assign(ivar_decl->getNameAsString()); - - if (bit_offset_ptr) - { - const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl); - *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx); - } - - const bool is_bitfield = ivar_pos->isBitField(); - - if (bitfield_bit_size_ptr) - { - *bitfield_bit_size_ptr = 0; - - if (is_bitfield && ast) - { - Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth(); - llvm::APSInt bitfield_apsint; - if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast)) - { - *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); - } - } - } - if (is_bitfield_ptr) - *is_bitfield_ptr = is_bitfield; - - return ivar_qual_type.getAsOpaquePtr(); - } - } - } - } - return NULL; -} - -clang_type_t -ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast, - clang_type_t clang_type, - size_t idx, - std::string& name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) -{ - if (clang_type == NULL) - return 0; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - uint32_t field_idx = 0; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx) - { - if (idx == field_idx) - { - // Print the member type if requested - // Print the member name and equal sign - name.assign(field->getNameAsString()); - - // Figure out the type byte size (field_type_info.first) and - // alignment (field_type_info.second) from the AST context. - if (bit_offset_ptr) - { - const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl); - *bit_offset_ptr = record_layout.getFieldOffset (field_idx); - } - - const bool is_bitfield = field->isBitField(); - - if (bitfield_bit_size_ptr) - { - *bitfield_bit_size_ptr = 0; - - if (is_bitfield && ast) - { - Expr *bitfield_bit_size_expr = field->getBitWidth(); - llvm::APSInt bitfield_apsint; - if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast)) - { - *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); - } - } - } - if (is_bitfield_ptr) - *is_bitfield_ptr = is_bitfield; - - return field->getType().getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); - return GetObjCFieldAtIndex(ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr); - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - return GetObjCFieldAtIndex(ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr); - } - } - break; - - - case clang::Type::Typedef: - return ClangASTContext::GetFieldAtIndex (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - idx, - name, - bit_offset_ptr, - bitfield_bit_size_ptr, - is_bitfield_ptr); - - case clang::Type::Elaborated: - return ClangASTContext::GetFieldAtIndex (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - idx, - name, - bit_offset_ptr, - bitfield_bit_size_ptr, - is_bitfield_ptr); - - case clang::Type::Paren: - return ClangASTContext::GetFieldAtIndex (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - idx, - name, - bit_offset_ptr, - bitfield_bit_size_ptr, - is_bitfield_ptr); - - default: - break; - } - return NULL; -} - -size_t -ClangASTContext::GetIndexOfFieldWithName (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - const char* name, - lldb::clang_type_t* field_clang_type, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) -{ - unsigned count = ClangASTContext::GetNumFields(ast, clang_type); - lldb::clang_type_t field_clang_type_internal; - std::string field_name; - for (unsigned index = 0; index < count; index++) - { - field_clang_type_internal = ClangASTContext::GetFieldAtIndex(ast, clang_type, index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr); - if ( strcmp(field_name.c_str(), name) == 0 ) - { - if (field_clang_type) - *field_clang_type = field_clang_type_internal; - return index; - } - } - return UINT32_MAX; -} - -lldb::BasicType -ClangASTContext::GetLLDBBasicTypeEnumeration (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - if (type_class == clang::Type::Builtin) - { - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - case clang::BuiltinType::Void: return eBasicTypeVoid; - case clang::BuiltinType::Bool: return eBasicTypeBool; - case clang::BuiltinType::Char_S: return eBasicTypeSignedChar; - case clang::BuiltinType::Char_U: return eBasicTypeUnsignedChar; - case clang::BuiltinType::Char16: return eBasicTypeChar16; - case clang::BuiltinType::Char32: return eBasicTypeChar32; - case clang::BuiltinType::UChar: return eBasicTypeUnsignedChar; - case clang::BuiltinType::SChar: return eBasicTypeSignedChar; - case clang::BuiltinType::WChar_S: return eBasicTypeSignedWChar; - case clang::BuiltinType::WChar_U: return eBasicTypeUnsignedWChar; - case clang::BuiltinType::Short: return eBasicTypeShort; - case clang::BuiltinType::UShort: return eBasicTypeUnsignedShort; - case clang::BuiltinType::Int: return eBasicTypeInt; - case clang::BuiltinType::UInt: return eBasicTypeUnsignedInt; - case clang::BuiltinType::Long: return eBasicTypeLong; - case clang::BuiltinType::ULong: return eBasicTypeUnsignedLong; - case clang::BuiltinType::LongLong: return eBasicTypeLongLong; - case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong; - case clang::BuiltinType::Int128: return eBasicTypeInt128; - case clang::BuiltinType::UInt128: return eBasicTypeUnsignedInt128; - - case clang::BuiltinType::Half: return eBasicTypeHalf; - case clang::BuiltinType::Float: return eBasicTypeFloat; - case clang::BuiltinType::Double: return eBasicTypeDouble; - case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble; - - case clang::BuiltinType::NullPtr: return eBasicTypeNullPtr; - case clang::BuiltinType::ObjCId: return eBasicTypeObjCID; - case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass; - case clang::BuiltinType::ObjCSel: return eBasicTypeObjCSel; - case clang::BuiltinType::Dependent: - case clang::BuiltinType::Overload: - case clang::BuiltinType::BoundMember: - case clang::BuiltinType::PseudoObject: - case clang::BuiltinType::UnknownAny: - case clang::BuiltinType::BuiltinFn: - case clang::BuiltinType::ARCUnbridgedCast: - case clang::BuiltinType::OCLEvent: - case clang::BuiltinType::OCLImage1d: - case clang::BuiltinType::OCLImage1dArray: - case clang::BuiltinType::OCLImage1dBuffer: - case clang::BuiltinType::OCLImage2d: - case clang::BuiltinType::OCLImage2dArray: - case clang::BuiltinType::OCLImage3d: - case clang::BuiltinType::OCLSampler: - return eBasicTypeOther; - } - } - } - - return eBasicTypeInvalid; -} - - - -// If a pointer to a pointee type (the clang_type arg) says that it has no -// children, then we either need to trust it, or override it and return a -// different result. For example, an "int *" has one child that is an integer, -// but a function pointer doesn't have any children. Likewise if a Record type -// claims it has no children, then there really is nothing to show. -uint32_t -ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type) -{ - if (clang_type == NULL) - return 0; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - case clang::BuiltinType::UnknownAny: - case clang::BuiltinType::Void: - case clang::BuiltinType::NullPtr: - case clang::BuiltinType::OCLEvent: - case clang::BuiltinType::OCLImage1d: - case clang::BuiltinType::OCLImage1dArray: - case clang::BuiltinType::OCLImage1dBuffer: - case clang::BuiltinType::OCLImage2d: - case clang::BuiltinType::OCLImage2dArray: - case clang::BuiltinType::OCLImage3d: - case clang::BuiltinType::OCLSampler: - return 0; - case clang::BuiltinType::Bool: - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::WChar_U: - case clang::BuiltinType::Char16: - case clang::BuiltinType::Char32: - case clang::BuiltinType::UShort: - case clang::BuiltinType::UInt: - case clang::BuiltinType::ULong: - case clang::BuiltinType::ULongLong: - case clang::BuiltinType::UInt128: - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar_S: - case clang::BuiltinType::Short: - case clang::BuiltinType::Int: - case clang::BuiltinType::Long: - case clang::BuiltinType::LongLong: - case clang::BuiltinType::Int128: - case clang::BuiltinType::Float: - case clang::BuiltinType::Double: - case clang::BuiltinType::LongDouble: - case clang::BuiltinType::Dependent: - case clang::BuiltinType::Overload: - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - case clang::BuiltinType::ObjCSel: - case clang::BuiltinType::BoundMember: - case clang::BuiltinType::Half: - case clang::BuiltinType::ARCUnbridgedCast: - case clang::BuiltinType::PseudoObject: - case clang::BuiltinType::BuiltinFn: - return 1; - } - break; - - case clang::Type::Complex: return 1; - case clang::Type::Pointer: return 1; - case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them - case clang::Type::LValueReference: return 1; - case clang::Type::RValueReference: return 1; - case clang::Type::MemberPointer: return 0; - case clang::Type::ConstantArray: return 0; - case clang::Type::IncompleteArray: return 0; - case clang::Type::VariableArray: return 0; - case clang::Type::DependentSizedArray: return 0; - case clang::Type::DependentSizedExtVector: return 0; - case clang::Type::Vector: return 0; - case clang::Type::ExtVector: return 0; - case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children... - case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children... - case clang::Type::UnresolvedUsing: return 0; - case clang::Type::Paren: return ClangASTContext::GetNumPointeeChildren (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: return ClangASTContext::GetNumPointeeChildren (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::TypeOfExpr: return 0; - case clang::Type::TypeOf: return 0; - case clang::Type::Decltype: return 0; - case clang::Type::Record: return 0; - case clang::Type::Enum: return 1; - case clang::Type::TemplateTypeParm: return 1; - case clang::Type::SubstTemplateTypeParm: return 1; - case clang::Type::TemplateSpecialization: return 1; - case clang::Type::InjectedClassName: return 0; - case clang::Type::DependentName: return 1; - case clang::Type::DependentTemplateSpecialization: return 1; - case clang::Type::ObjCObject: return 0; - case clang::Type::ObjCInterface: return 0; - case clang::Type::ObjCObjectPointer: return 1; - default: - break; - } - return 0; -} - -clang_type_t -ClangASTContext::GetChildClangTypeAtIndex -( - ExecutionContext *exe_ctx, - const char *parent_name, - clang_type_t parent_clang_type, - 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 -) -{ - if (parent_clang_type) - - return GetChildClangTypeAtIndex (exe_ctx, - getASTContext(), - parent_name, - parent_clang_type, - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - return NULL; -} - -clang_type_t -ClangASTContext::GetChildClangTypeAtIndex -( - ExecutionContext *exe_ctx, - ASTContext *ast, - const char *parent_name, - clang_type_t parent_clang_type, - 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 -) -{ - if (parent_clang_type == NULL) - return NULL; - - QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type)); - const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); - child_bitfield_bit_size = 0; - child_bitfield_bit_offset = 0; - child_is_base_class = false; - - const bool idx_is_valid = idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes); - uint32_t bit_offset; - switch (parent_type_class) - { - case clang::Type::Builtin: - if (idx_is_valid) - { - switch (cast<clang::BuiltinType>(parent_qual_type)->getKind()) - { - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - child_name = "isa"; - child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT; - return ast->ObjCBuiltinClassTy.getAsOpaquePtr(); - - default: - break; - } - } - break; - - case clang::Type::Record: - if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type)) - { - const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - assert(record_decl); - const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl); - uint32_t child_idx = 0; - - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - if (cxx_record_decl) - { - // We might have base classes to print out first - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class) - { - const CXXRecordDecl *base_class_decl = NULL; - - // Skip empty base classes - if (omit_empty_base_classes) - { - base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - if (RecordHasFields(base_class_decl) == false) - continue; - } - - if (idx == child_idx) - { - if (base_class_decl == NULL) - base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - - - if (base_class->isVirtual()) - bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; - else - bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; - - // Base classes should be a multiple of 8 bits in size - child_byte_offset = bit_offset/8; - - child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType()); - - uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType()); - - // Base classes bit sizes should be a multiple of 8 bits in size - assert (clang_type_info_bit_size % 8 == 0); - child_byte_size = clang_type_info_bit_size / 8; - child_is_base_class = true; - return base_class->getType().getAsOpaquePtr(); - } - // We don't increment the child index in the for loop since we might - // be skipping empty base classes - ++child_idx; - } - } - // Make sure index is in range... - uint32_t field_idx = 0; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx) - { - if (idx == child_idx) - { - // Print the member type if requested - // Print the member name and equal sign - child_name.assign(field->getNameAsString().c_str()); - - // Figure out the type byte size (field_type_info.first) and - // alignment (field_type_info.second) from the AST context. - std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType()); - assert(field_idx < record_layout.getFieldCount()); - - child_byte_size = field_type_info.first / 8; - - // Figure out the field offset within the current struct/union/class type - bit_offset = record_layout.getFieldOffset (field_idx); - child_byte_offset = bit_offset / 8; - if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size)) - child_bitfield_bit_offset = bit_offset % 8; - - return field->getType().getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type)) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - uint32_t child_idx = 0; - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - - const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl); - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - if (superclass_interface_decl) - { - if (omit_empty_base_classes) - { - if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0) - { - if (idx == 0) - { - QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl)); - - - child_name.assign(superclass_interface_decl->getNameAsString().c_str()); - - std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr()); - - child_byte_size = ivar_type_info.first / 8; - child_byte_offset = 0; - child_is_base_class = true; - - return ivar_qual_type.getAsOpaquePtr(); - } - - ++child_idx; - } - } - else - ++child_idx; - } - - const uint32_t superclass_idx = child_idx; - - if (idx < (child_idx + class_interface_decl->ivar_size())) - { - ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); - - for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) - { - if (child_idx == idx) - { - ObjCIvarDecl* ivar_decl = *ivar_pos; - - QualType ivar_qual_type(ivar_decl->getType()); - - child_name.assign(ivar_decl->getNameAsString().c_str()); - - std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr()); - - child_byte_size = ivar_type_info.first / 8; - - // Figure out the field offset within the current struct/union/class type - // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since - // that doesn't account for the space taken up by unbacked properties, or from - // the changing size of base classes that are newer than this class. - // So if we have a process around that we can ask about this object, do so. - child_byte_offset = LLDB_INVALID_IVAR_OFFSET; - Process *process = NULL; - if (exe_ctx) - process = exe_ctx->GetProcessPtr(); - if (process) - { - ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime(); - if (objc_runtime != NULL) - { - ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr()); - child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str()); - } - } - - // Setting this to UINT32_MAX to make sure we don't compute it twice... - bit_offset = UINT32_MAX; - - if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET) - { - bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); - child_byte_offset = bit_offset / 8; - } - - // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset - // of a bitfield within its containing object. So regardless of where we get the byte - // offset from, we still need to get the bit offset for bitfields from the layout. - - if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size)) - { - if (bit_offset == UINT32_MAX) - bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); - - child_bitfield_bit_offset = bit_offset % 8; - } - return ivar_qual_type.getAsOpaquePtr(); - } - ++child_idx; - } - } - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - if (idx_is_valid) - { - const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - - if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - child_is_deref_of_parent = false; - bool tmp_child_is_deref_of_parent = false; - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - pointer_type->getPointeeType().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - tmp_child_is_deref_of_parent); - } - else - { - child_is_deref_of_parent = true; - if (parent_name) - { - child_name.assign(1, '*'); - child_name += parent_name; - } - - // We have a pointer to an simple type - if (idx == 0 && GetCompleteQualType(ast, pointee_type)) - { - std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); - assert(clang_type_info.first % 8 == 0); - child_byte_size = clang_type_info.first / 8; - child_byte_offset = 0; - return pointee_type.getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::Vector: - case clang::Type::ExtVector: - if (idx_is_valid) - { - const VectorType *array = cast<VectorType>(parent_qual_type.getTypePtr()); - if (array) - { - if (GetCompleteQualType (ast, array->getElementType())) - { - std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); - - char element_name[64]; - ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); - - child_name.assign(element_name); - assert(field_type_info.first % 8 == 0); - child_byte_size = field_type_info.first / 8; - child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; - return array->getElementType().getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::ConstantArray: - case clang::Type::IncompleteArray: - if (ignore_array_bounds || idx_is_valid) - { - const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr()); - if (array) - { - if (GetCompleteQualType (ast, array->getElementType())) - { - std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); - - char element_name[64]; - ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); - - child_name.assign(element_name); - assert(field_type_info.first % 8 == 0); - child_byte_size = field_type_info.first / 8; - child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; - return array->getElementType().getAsOpaquePtr(); - } - } - } - break; - - - case clang::Type::Pointer: - if (idx_is_valid) - { - const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - - // Don't dereference "void *" pointers - if (pointee_type->isVoidType()) - return NULL; - - if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - child_is_deref_of_parent = false; - bool tmp_child_is_deref_of_parent = false; - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - pointer_type->getPointeeType().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - tmp_child_is_deref_of_parent); - } - else - { - child_is_deref_of_parent = true; - - if (parent_name) - { - child_name.assign(1, '*'); - child_name += parent_name; - } - - // We have a pointer to an simple type - if (idx == 0) - { - std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); - assert(clang_type_info.first % 8 == 0); - child_byte_size = clang_type_info.first / 8; - child_byte_offset = 0; - return pointee_type.getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - if (idx_is_valid) - { - const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr()); - QualType pointee_type(reference_type->getPointeeType()); - clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr(); - if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type)) - { - child_is_deref_of_parent = false; - bool tmp_child_is_deref_of_parent = false; - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - pointee_clang_type, - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - tmp_child_is_deref_of_parent); - } - else - { - if (parent_name) - { - child_name.assign(1, '&'); - child_name += parent_name; - } - - // We have a pointer to an simple type - if (idx == 0) - { - std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); - assert(clang_type_info.first % 8 == 0); - child_byte_size = clang_type_info.first / 8; - child_byte_offset = 0; - return pointee_type.getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::Typedef: - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - break; - - case clang::Type::Elaborated: - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - - case clang::Type::Paren: - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - llvm::cast<clang::ParenType>(parent_qual_type)->desugar().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - - - default: - break; - } - return NULL; + return ClangASTType (ast, ast->getObjCInterfaceType(decl)); } static inline bool @@ -4660,8 +1763,8 @@ BaseSpecifierIsEmpty (const CXXBaseSpecifier *b) return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false; } -static uint32_t -GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes) +uint32_t +ClangASTContext::GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes) { uint32_t num_bases = 0; if (cxx_record_decl) @@ -4689,739 +1792,6 @@ GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_cl } -static uint32_t -GetIndexForRecordBase -( - const RecordDecl *record_decl, - const CXXBaseSpecifier *base_spec, - bool omit_empty_base_classes -) -{ - uint32_t child_idx = 0; - - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - -// const char *super_name = record_decl->getNameAsCString(); -// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString(); -// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name); -// - if (cxx_record_decl) - { - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class) - { - if (omit_empty_base_classes) - { - if (BaseSpecifierIsEmpty (base_class)) - continue; - } - -// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name, -// child_idx, -// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); -// -// - if (base_class == base_spec) - return child_idx; - ++child_idx; - } - } - - return UINT32_MAX; -} - - -static uint32_t -GetIndexForRecordChild -( - const RecordDecl *record_decl, - NamedDecl *canonical_decl, - bool omit_empty_base_classes -) -{ - uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes); - -// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); -// -//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString()); -// if (cxx_record_decl) -// { -// CXXRecordDecl::base_class_const_iterator base_class, base_class_end; -// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); -// base_class != base_class_end; -// ++base_class) -// { -// if (omit_empty_base_classes) -// { -// if (BaseSpecifierIsEmpty (base_class)) -// continue; -// } -// -//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", -//// record_decl->getNameAsCString(), -//// canonical_decl->getNameAsCString(), -//// child_idx, -//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); -// -// -// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); -// if (curr_base_class_decl == canonical_decl) -// { -// return child_idx; -// } -// ++child_idx; -// } -// } -// -// const uint32_t num_bases = child_idx; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); - field != field_end; - ++field, ++child_idx) - { -// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n", -// record_decl->getNameAsCString(), -// canonical_decl->getNameAsCString(), -// child_idx - num_bases, -// field->getNameAsCString()); - - if (field->getCanonicalDecl() == canonical_decl) - return child_idx; - } - - return UINT32_MAX; -} - -// Look for a child member (doesn't include base classes, but it does include -// their members) in the type hierarchy. Returns an index path into "clang_type" -// on how to reach the appropriate member. -// -// class A -// { -// public: -// int m_a; -// int m_b; -// }; -// -// class B -// { -// }; -// -// class C : -// public B, -// public A -// { -// }; -// -// If we have a clang type that describes "class C", and we wanted to looked -// "m_b" in it: -// -// With omit_empty_base_classes == false we would get an integer array back with: -// { 1, 1 } -// The first index 1 is the child index for "class A" within class C -// The second index 1 is the child index for "m_b" within class A -// -// With omit_empty_base_classes == true we would get an integer array back with: -// { 0, 1 } -// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count) -// The second index 1 is the child index for "m_b" within class A - -size_t -ClangASTContext::GetIndexOfChildMemberWithName -( - ASTContext *ast, - clang_type_t clang_type, - const char *name, - bool omit_empty_base_classes, - std::vector<uint32_t>& child_indexes -) -{ - if (clang_type && name && name[0]) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - - assert(record_decl); - uint32_t child_idx = 0; - - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - - // Try and find a field that matches NAME - RecordDecl::field_iterator field, field_end; - StringRef name_sref(name); - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); - field != field_end; - ++field, ++child_idx) - { - if (field->getName().equals (name_sref)) - { - // We have to add on the number of base classes to this index! - child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes)); - return child_indexes.size(); - } - } - - if (cxx_record_decl) - { - const RecordDecl *parent_record_decl = cxx_record_decl; - - //printf ("parent = %s\n", parent_record_decl->getNameAsCString()); - - //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl(); - // Didn't find things easily, lets let clang do its thang... - IdentifierInfo & ident_ref = ast->Idents.get(name_sref); - DeclarationName decl_name(&ident_ref); - - CXXBasePaths paths; - if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember, - decl_name.getAsOpaquePtr(), - paths)) - { - CXXBasePaths::const_paths_iterator path, path_end = paths.end(); - for (path = paths.begin(); path != path_end; ++path) - { - const size_t num_path_elements = path->size(); - for (size_t e=0; e<num_path_elements; ++e) - { - CXXBasePathElement elem = (*path)[e]; - - child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes); - if (child_idx == UINT32_MAX) - { - child_indexes.clear(); - return 0; - } - else - { - child_indexes.push_back (child_idx); - parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl()); - } - } - for (NamedDecl *path_decl : path->Decls) - { - child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes); - if (child_idx == UINT32_MAX) - { - child_indexes.clear(); - return 0; - } - else - { - child_indexes.push_back (child_idx); - } - } - } - return child_indexes.size(); - } - } - - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - StringRef name_sref(name); - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - uint32_t child_idx = 0; - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - - for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) - { - const ObjCIvarDecl* ivar_decl = *ivar_pos; - - if (ivar_decl->getName().equals (name_sref)) - { - if ((!omit_empty_base_classes && superclass_interface_decl) || - ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) - ++child_idx; - - child_indexes.push_back (child_idx); - return child_indexes.size(); - } - } - - if (superclass_interface_decl) - { - // The super class index is always zero for ObjC classes, - // so we push it onto the child indexes in case we find - // an ivar in our superclass... - child_indexes.push_back (0); - - if (GetIndexOfChildMemberWithName (ast, - ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes)) - { - // We did find an ivar in a superclass so just - // return the results! - return child_indexes.size(); - } - - // We didn't find an ivar matching "name" in our - // superclass, pop the superclass zero index that - // we pushed on above. - child_indexes.pop_back(); - } - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - { - return GetIndexOfChildMemberWithName (ast, - cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - } - break; - - - case clang::Type::ConstantArray: - { -// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); -// const uint64_t element_count = array->getSize().getLimitedValue(); -// -// if (idx < element_count) -// { -// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); -// -// char element_name[32]; -// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); -// -// child_name.assign(element_name); -// assert(field_type_info.first % 8 == 0); -// child_byte_size = field_type_info.first / 8; -// child_byte_offset = idx * child_byte_size; -// return array->getElementType().getAsOpaquePtr(); -// } - } - break; - -// case clang::Type::MemberPointerType: -// { -// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); -// QualType pointee_type = mem_ptr_type->getPointeeType(); -// -// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) -// { -// return GetIndexOfChildWithName (ast, -// mem_ptr_type->getPointeeType().getAsOpaquePtr(), -// name); -// } -// } -// break; -// - case clang::Type::LValueReference: - case clang::Type::RValueReference: - { - const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); - QualType pointee_type = reference_type->getPointeeType(); - - if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - return GetIndexOfChildMemberWithName (ast, - reference_type->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - } - } - break; - - case clang::Type::Pointer: - { - const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - - if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - return GetIndexOfChildMemberWithName (ast, - pointer_type->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - } - else - { -// if (parent_name) -// { -// child_name.assign(1, '*'); -// child_name += parent_name; -// } -// -// // We have a pointer to an simple type -// if (idx == 0) -// { -// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); -// assert(clang_type_info.first % 8 == 0); -// child_byte_size = clang_type_info.first / 8; -// child_byte_offset = 0; -// return pointee_type.getAsOpaquePtr(); -// } - } - } - break; - - case clang::Type::Typedef: - return GetIndexOfChildMemberWithName (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - - case clang::Type::Elaborated: - return GetIndexOfChildMemberWithName (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - - case clang::Type::Paren: - return GetIndexOfChildMemberWithName (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - - default: - break; - } - } - return 0; -} - - -// Get the index of the child of "clang_type" whose name matches. This function -// doesn't descend into the children, but only looks one level deep and name -// matches can include base class names. - -uint32_t -ClangASTContext::GetIndexOfChildWithName -( - ASTContext *ast, - clang_type_t clang_type, - const char *name, - bool omit_empty_base_classes -) -{ - if (clang_type && name && name[0]) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - - assert(record_decl); - uint32_t child_idx = 0; - - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - - if (cxx_record_decl) - { - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class) - { - // Skip empty base classes - CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false) - continue; - - std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(ast, base_class->getType())); - if (base_class_type_name.compare (name) == 0) - return child_idx; - ++child_idx; - } - } - - // Try and find a field that matches NAME - RecordDecl::field_iterator field, field_end; - StringRef name_sref(name); - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); - field != field_end; - ++field, ++child_idx) - { - if (field->getName().equals (name_sref)) - return child_idx; - } - - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - StringRef name_sref(name); - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - uint32_t child_idx = 0; - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - - for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) - { - const ObjCIvarDecl* ivar_decl = *ivar_pos; - - if (ivar_decl->getName().equals (name_sref)) - { - if ((!omit_empty_base_classes && superclass_interface_decl) || - ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) - ++child_idx; - - return child_idx; - } - } - - if (superclass_interface_decl) - { - if (superclass_interface_decl->getName().equals (name_sref)) - return 0; - } - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - { - return GetIndexOfChildWithName (ast, - cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - } - break; - - case clang::Type::ConstantArray: - { -// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); -// const uint64_t element_count = array->getSize().getLimitedValue(); -// -// if (idx < element_count) -// { -// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); -// -// char element_name[32]; -// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); -// -// child_name.assign(element_name); -// assert(field_type_info.first % 8 == 0); -// child_byte_size = field_type_info.first / 8; -// child_byte_offset = idx * child_byte_size; -// return array->getElementType().getAsOpaquePtr(); -// } - } - break; - -// case clang::Type::MemberPointerType: -// { -// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); -// QualType pointee_type = mem_ptr_type->getPointeeType(); -// -// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) -// { -// return GetIndexOfChildWithName (ast, -// mem_ptr_type->getPointeeType().getAsOpaquePtr(), -// name); -// } -// } -// break; -// - case clang::Type::LValueReference: - case clang::Type::RValueReference: - { - const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); - QualType pointee_type = reference_type->getPointeeType(); - - if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - return GetIndexOfChildWithName (ast, - reference_type->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - } - } - break; - - case clang::Type::Pointer: - { - const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - - if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - return GetIndexOfChildWithName (ast, - pointer_type->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - } - else - { -// if (parent_name) -// { -// child_name.assign(1, '*'); -// child_name += parent_name; -// } -// -// // We have a pointer to an simple type -// if (idx == 0) -// { -// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); -// assert(clang_type_info.first % 8 == 0); -// child_byte_size = clang_type_info.first / 8; -// child_byte_offset = 0; -// return pointee_type.getAsOpaquePtr(); -// } - } - } - break; - - case clang::Type::Elaborated: - return GetIndexOfChildWithName (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - - case clang::Type::Paren: - return GetIndexOfChildWithName (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - name, - omit_empty_base_classes); - - case clang::Type::Typedef: - return GetIndexOfChildWithName (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - - default: - break; - } - } - return UINT32_MAX; -} - -#pragma mark TagType - -bool -ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind) -{ - if (tag_clang_type) - { - QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type)); - const clang::Type *clang_type = tag_qual_type.getTypePtr(); - if (clang_type) - { - const TagType *tag_type = dyn_cast<TagType>(clang_type); - if (tag_type) - { - TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl()); - if (tag_decl) - { - tag_decl->setTagKind ((TagDecl::TagKind)kind); - return true; - } - } - } - } - return false; -} - - -#pragma mark DeclContext Functions - -DeclContext * -ClangASTContext::GetDeclContextForType (clang_type_t clang_type) -{ - if (clang_type == NULL) - return NULL; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::UnaryTransform: break; - case clang::Type::FunctionNoProto: break; - case clang::Type::FunctionProto: break; - case clang::Type::IncompleteArray: break; - case clang::Type::VariableArray: break; - case clang::Type::ConstantArray: break; - case clang::Type::DependentSizedArray: break; - case clang::Type::ExtVector: break; - case clang::Type::DependentSizedExtVector: break; - case clang::Type::Vector: break; - case clang::Type::Builtin: break; - case clang::Type::BlockPointer: break; - case clang::Type::Pointer: break; - case clang::Type::LValueReference: break; - case clang::Type::RValueReference: break; - case clang::Type::MemberPointer: break; - case clang::Type::Complex: break; - case clang::Type::ObjCObject: break; - case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface(); - case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr()); - case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl(); - case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl(); - case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Paren: return ClangASTContext::GetDeclContextForType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr()); - case clang::Type::TypeOfExpr: break; - case clang::Type::TypeOf: break; - case clang::Type::Decltype: break; - //case clang::Type::QualifiedName: break; - case clang::Type::TemplateSpecialization: break; - case clang::Type::DependentTemplateSpecialization: break; - case clang::Type::TemplateTypeParm: break; - case clang::Type::SubstTemplateTypeParm: break; - case clang::Type::SubstTemplateTypeParmPack:break; - case clang::Type::PackExpansion: break; - case clang::Type::UnresolvedUsing: break; - case clang::Type::Attributed: break; - case clang::Type::Auto: break; - case clang::Type::InjectedClassName: break; - case clang::Type::DependentName: break; - case clang::Type::Atomic: break; - } - // No DeclContext in this type... - return NULL; -} - #pragma mark Namespace Declarations NamespaceDecl * @@ -5527,7 +1897,11 @@ ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *d #pragma mark Function Types FunctionDecl * -ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *name, clang_type_t function_clang_type, int storage, bool is_inline) +ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, + const char *name, + const ClangASTType &function_clang_type, + int storage, + bool is_inline) { FunctionDecl *func_decl = NULL; ASTContext *ast = getASTContext(); @@ -5545,7 +1919,7 @@ ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *n SourceLocation(), SourceLocation(), DeclarationName (&ast->Idents.get(name)), - QualType::getFromOpaquePtr(function_clang_type), + function_clang_type.GetQualType(), NULL, (FunctionDecl::StorageClass)storage, is_inline, @@ -5559,7 +1933,7 @@ ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *n SourceLocation(), SourceLocation(), DeclarationName (), - QualType::getFromOpaquePtr(function_clang_type), + function_clang_type.GetQualType(), NULL, (FunctionDecl::StorageClass)storage, is_inline, @@ -5576,10 +1950,10 @@ ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *n return func_decl; } -clang_type_t +ClangASTType ClangASTContext::CreateFunctionType (ASTContext *ast, - clang_type_t result_type, - clang_type_t *args, + const ClangASTType& result_type, + const ClangASTType *args, unsigned num_args, bool is_variadic, unsigned type_quals) @@ -5587,7 +1961,7 @@ ClangASTContext::CreateFunctionType (ASTContext *ast, assert (ast != NULL); std::vector<QualType> qual_type_args; for (unsigned i=0; i<num_args; ++i) - qual_type_args.push_back (QualType::getFromOpaquePtr(args[i])); + qual_type_args.push_back (args[i].GetQualType()); // TODO: Detect calling convention in DWARF? FunctionProtoType::ExtProtoInfo proto_info; @@ -5598,13 +1972,13 @@ ClangASTContext::CreateFunctionType (ASTContext *ast, proto_info.NumExceptions = 0; proto_info.Exceptions = NULL; - return ast->getFunctionType (QualType::getFromOpaquePtr(result_type), - qual_type_args, - proto_info).getAsOpaquePtr(); + return ClangASTType (ast, ast->getFunctionType (result_type.GetQualType(), + qual_type_args, + proto_info).getAsOpaquePtr()); } ParmVarDecl * -ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage) +ClangASTContext::CreateParameterDeclaration (const char *name, const ClangASTType ¶m_type, int storage) { ASTContext *ast = getASTContext(); assert (ast != NULL); @@ -5613,7 +1987,7 @@ ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t para SourceLocation(), SourceLocation(), name && name[0] ? &ast->Idents.get(name) : NULL, - QualType::getFromOpaquePtr(param_type), + param_type.GetQualType(), NULL, (VarDecl::StorageClass)storage, 0); @@ -5629,21 +2003,19 @@ ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl #pragma mark Array Types -clang_type_t -ClangASTContext::CreateArrayType (clang_type_t element_type, +ClangASTType +ClangASTContext::CreateArrayType (const ClangASTType &element_type, size_t element_count, bool is_vector) { - if (element_type) + if (element_type.IsValid()) { ASTContext *ast = getASTContext(); assert (ast != NULL); - QualType element_qual_type(QualType::getFromOpaquePtr(element_type)); - if (is_vector) { - return ast->getExtVectorType(element_qual_type, element_count).getAsOpaquePtr(); + return ClangASTType (ast, ast->getExtVectorType(element_type.GetQualType(), element_count).getAsOpaquePtr()); } else { @@ -5651,129 +2023,38 @@ ClangASTContext::CreateArrayType (clang_type_t element_type, llvm::APInt ap_element_count (64, element_count); if (element_count == 0) { - return ast->getIncompleteArrayType(element_qual_type, - ArrayType::Normal, - 0).getAsOpaquePtr(); - + return ClangASTType (ast, ast->getIncompleteArrayType (element_type.GetQualType(), + ArrayType::Normal, + 0).getAsOpaquePtr()); } else { - return ast->getConstantArrayType(element_qual_type, - ap_element_count, - ArrayType::Normal, - 0).getAsOpaquePtr(); // ElemQuals - } - } - } - return NULL; -} - - -#pragma mark TagDecl - -bool -ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::Type *t = qual_type.getTypePtr(); - if (t) - { - const TagType *tag_type = dyn_cast<TagType>(t); - if (tag_type) - { - TagDecl *tag_decl = tag_type->getDecl(); - if (tag_decl) - { - tag_decl->startDefinition(); - return true; - } - } - - const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(t); - if (object_type) - { - ObjCInterfaceDecl *interface_decl = object_type->getInterface(); - if (interface_decl) - { - interface_decl->startDefinition(); - return true; - } + return ClangASTType (ast, ast->getConstantArrayType (element_type.GetQualType(), + ap_element_count, + ArrayType::Normal, + 0).getAsOpaquePtr()); } } } - return false; + return ClangASTType(); } -bool -ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - - if (cxx_record_decl) - { - cxx_record_decl->completeDefinition(); - - return true; - } - - const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr()); - - if (enum_type) - { - EnumDecl *enum_decl = enum_type->getDecl(); - - if (enum_decl) - { - /// TODO This really needs to be fixed. - - unsigned NumPositiveBits = 1; - unsigned NumNegativeBits = 0; - - ASTContext *ast = getASTContext(); - - QualType promotion_qual_type; - // If the enum integer type is less than an integer in bit width, - // then we must promote it to an integer size. - if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy)) - { - if (enum_decl->getIntegerType()->isSignedIntegerType()) - promotion_qual_type = ast->IntTy; - else - promotion_qual_type = ast->UnsignedIntTy; - } - else - promotion_qual_type = enum_decl->getIntegerType(); - - enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); - return true; - } - } - } - return false; -} #pragma mark Enumeration Types -clang_type_t +ClangASTType ClangASTContext::CreateEnumerationType ( const char *name, DeclContext *decl_ctx, const Declaration &decl, - clang_type_t integer_qual_type + const ClangASTType &integer_clang_type ) { // TODO: Do something intelligent with the Declaration object passed in // like maybe filling in the SourceLocation with it... ASTContext *ast = getASTContext(); - assert (ast != NULL); // TODO: ask about these... // const bool IsScoped = false; @@ -5793,896 +2074,13 @@ ClangASTContext::CreateEnumerationType if (enum_decl) { // TODO: check if we should be setting the promotion type too? - enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type)); + enum_decl->setIntegerType(integer_clang_type.GetQualType()); enum_decl->setAccess(AS_public); // TODO respect what's in the debug info - return ast->getTagDeclType(enum_decl).getAsOpaquePtr(); - } - return NULL; -} - -clang_type_t -ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type) -{ - QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); - - const clang::Type *clang_type = enum_qual_type.getTypePtr(); - if (clang_type) - { - const EnumType *enum_type = dyn_cast<EnumType>(clang_type); - if (enum_type) - { - EnumDecl *enum_decl = enum_type->getDecl(); - if (enum_decl) - return enum_decl->getIntegerType().getAsOpaquePtr(); - } - } - return NULL; -} -bool -ClangASTContext::AddEnumerationValueToEnumerationType -( - clang_type_t enum_clang_type, - clang_type_t enumerator_clang_type, - const Declaration &decl, - const char *name, - int64_t enum_value, - uint32_t enum_value_bit_size -) -{ - if (enum_clang_type && enumerator_clang_type && name) - { - // TODO: Do something intelligent with the Declaration object passed in - // like maybe filling in the SourceLocation with it... - ASTContext *ast = getASTContext(); - IdentifierTable *identifier_table = getIdentifierTable(); - - assert (ast != NULL); - assert (identifier_table != NULL); - QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); - - bool is_signed = false; - IsIntegerType (enumerator_clang_type, is_signed); - const clang::Type *clang_type = enum_qual_type.getTypePtr(); - if (clang_type) - { - const EnumType *enum_type = dyn_cast<EnumType>(clang_type); - - if (enum_type) - { - llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed); - enum_llvm_apsint = enum_value; - EnumConstantDecl *enumerator_decl = - EnumConstantDecl::Create (*ast, - enum_type->getDecl(), - SourceLocation(), - name ? &identifier_table->get(name) : NULL, // Identifier - QualType::getFromOpaquePtr(enumerator_clang_type), - NULL, - enum_llvm_apsint); - - if (enumerator_decl) - { - enum_type->getDecl()->addDecl(enumerator_decl); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(enumerator_decl); -#endif - - return true; - } - } - } - } - return false; -} - -#pragma mark Pointers & References - -clang_type_t -ClangASTContext::CreatePointerType (clang_type_t clang_type) -{ - return CreatePointerType (getASTContext(), clang_type); -} - -clang_type_t -ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type) -{ - if (ast && clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); - - default: - return ast->getPointerType(qual_type).getAsOpaquePtr(); - } - } - return NULL; -} - -clang_type_t -ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast, - clang_type_t clang_type) -{ - if (clang_type) - return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); - return NULL; -} - -clang_type_t -ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast, - clang_type_t clang_type) -{ - if (clang_type) - return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); - return NULL; -} - -clang_type_t -ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type) -{ - if (clang_pointee_type && clang_pointee_type) - return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type), - QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr(); - return NULL; -} - -uint64_t -ClangASTContext::GetPointerBitSize () -{ - ASTContext *ast = getASTContext(); - return ast->getTypeSize(ast->VoidPtrTy); -} - -bool -ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast, - clang_type_t clang_type, - clang_type_t *dynamic_pointee_type, - bool check_cplusplus, - bool check_objc) -{ - QualType pointee_qual_type; - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type).getCanonicalType()); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - bool success = false; - switch (type_class) - { - case clang::Type::Builtin: - if (check_objc && cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId) - { - if (dynamic_pointee_type) - *dynamic_pointee_type = clang_type; - return true; - } - break; - - case clang::Type::ObjCObjectPointer: - if (check_objc) - { - if (dynamic_pointee_type) - *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - } - break; - - case clang::Type::Pointer: - pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType(); - success = true; - break; - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType(); - success = true; - break; - - case clang::Type::Typedef: - return ClangASTContext::IsPossibleDynamicType (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - dynamic_pointee_type, - check_cplusplus, - check_objc); - - case clang::Type::Elaborated: - return ClangASTContext::IsPossibleDynamicType (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - dynamic_pointee_type, - check_cplusplus, - check_objc); - - case clang::Type::Paren: - return ClangASTContext::IsPossibleDynamicType (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - dynamic_pointee_type, - check_cplusplus, - check_objc); - default: - break; - } - - if (success) - { - // Check to make sure what we are pointing too is a possible dynamic C++ type - // We currently accept any "void *" (in case we have a class that has been - // watered down to an opaque pointer) and virtual C++ classes. - const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass(); - switch (pointee_type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind()) - { - case clang::BuiltinType::UnknownAny: - case clang::BuiltinType::Void: - if (dynamic_pointee_type) - *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr(); - return true; - - case clang::BuiltinType::NullPtr: - case clang::BuiltinType::Bool: - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::WChar_U: - case clang::BuiltinType::Char16: - case clang::BuiltinType::Char32: - case clang::BuiltinType::UShort: - case clang::BuiltinType::UInt: - case clang::BuiltinType::ULong: - case clang::BuiltinType::ULongLong: - case clang::BuiltinType::UInt128: - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar_S: - case clang::BuiltinType::Short: - case clang::BuiltinType::Int: - case clang::BuiltinType::Long: - case clang::BuiltinType::LongLong: - case clang::BuiltinType::Int128: - case clang::BuiltinType::Float: - case clang::BuiltinType::Double: - case clang::BuiltinType::LongDouble: - case clang::BuiltinType::Dependent: - case clang::BuiltinType::Overload: - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - case clang::BuiltinType::ObjCSel: - case clang::BuiltinType::BoundMember: - case clang::BuiltinType::Half: - case clang::BuiltinType::ARCUnbridgedCast: - case clang::BuiltinType::PseudoObject: - case clang::BuiltinType::BuiltinFn: - case clang::BuiltinType::OCLEvent: - case clang::BuiltinType::OCLImage1d: - case clang::BuiltinType::OCLImage1dArray: - case clang::BuiltinType::OCLImage1dBuffer: - case clang::BuiltinType::OCLImage2d: - case clang::BuiltinType::OCLImage2dArray: - case clang::BuiltinType::OCLImage3d: - case clang::BuiltinType::OCLSampler: - break; - } - break; - - case clang::Type::Record: - if (check_cplusplus) - { - CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - bool is_complete = cxx_record_decl->isCompleteDefinition(); - - if (is_complete) - success = cxx_record_decl->isDynamicClass(); - else - { - ClangASTMetadata *metadata = GetMetadata (ast, cxx_record_decl); - if (metadata) - success = metadata->GetIsDynamicCXXType(); - else - { - is_complete = ClangASTContext::GetCompleteType (ast, pointee_qual_type.getAsOpaquePtr()); - if (is_complete) - success = cxx_record_decl->isDynamicClass(); - else - success = false; - } - } - - if (success) - { - if (dynamic_pointee_type) - *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr(); - return true; - } - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (check_objc) - { - if (dynamic_pointee_type) - *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr(); - return true; - } - break; - - default: - break; - } - } - } - if (dynamic_pointee_type) - *dynamic_pointee_type = NULL; - return false; -} - - -bool -ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type) -{ - return IsPossibleDynamicType (ast, - clang_type, - dynamic_pointee_type, - true, // Check for dynamic C++ types - false); // Check for dynamic ObjC types -} - -bool -ClangASTContext::IsReferenceType (clang_type_t clang_type, clang_type_t *target_type) -{ - if (clang_type == NULL) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - - switch (type_class) - { - case clang::Type::LValueReference: - if (target_type) - *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); - return true; - case clang::Type::RValueReference: - if (target_type) - *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); - return true; - case clang::Type::Typedef: - return ClangASTContext::IsReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: - return ClangASTContext::IsReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Paren: - return ClangASTContext::IsReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - default: - break; - } - - return false; -} - -bool -ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type) -{ - if (clang_type == NULL) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - default: - break; - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - return true; - } - return false; - case clang::Type::ObjCObjectPointer: - if (target_type) - *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::BlockPointer: - if (target_type) - *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::Pointer: - if (target_type) - *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::MemberPointer: - if (target_type) - *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::LValueReference: - if (target_type) - *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); - return true; - case clang::Type::RValueReference: - if (target_type) - *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); - return true; - case clang::Type::Typedef: - return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: - return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Paren: - return ClangASTContext::IsPointerOrReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - default: - break; - } - return false; -} - -bool -ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed) -{ - if (!clang_type) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); - - if (builtin_type) - { - if (builtin_type->isInteger()) - { - is_signed = builtin_type->isSignedInteger(); - return true; - } - } - - return false; -} - -bool -ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t *target_type) -{ - if (target_type) - *target_type = NULL; - - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - default: - break; - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - return true; - } - return false; - case clang::Type::ObjCObjectPointer: - if (target_type) - *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::BlockPointer: - if (target_type) - *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::Pointer: - if (target_type) - *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::MemberPointer: - if (target_type) - *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::Typedef: - return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type); - case clang::Type::Elaborated: - return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type); - case clang::Type::Paren: - return ClangASTContext::IsPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), target_type); - default: - break; - } - } - return false; -} - -bool -ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal())) - { - clang::BuiltinType::Kind kind = BT->getKind(); - if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble) - { - count = 1; - is_complex = false; - return true; - } - } - else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal())) - { - if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex)) - { - count = 2; - is_complex = true; - return true; - } - } - else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal())) - { - if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex)) - { - count = VT->getNumElements(); - is_complex = false; - return true; - } - } - } - return false; -} - -bool -ClangASTContext::IsScalarType (lldb::clang_type_t clang_type) -{ - bool is_signed; - if (ClangASTContext::IsIntegerType(clang_type, is_signed)) - return true; - - uint32_t count; - bool is_complex; - return ClangASTContext::IsFloatingPointType(clang_type, count, is_complex) && !is_complex; -} - -bool -ClangASTContext::IsPointerToScalarType (lldb::clang_type_t clang_type) -{ - if (!IsPointerType(clang_type)) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - lldb::clang_type_t pointee_type = qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr(); - return IsScalarType(pointee_type); -} - -bool -ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type) -{ - clang_type = GetAsArrayType(clang_type, NULL, NULL, NULL); - - if (clang_type == 0) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - lldb::clang_type_t item_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr(); - return IsScalarType(item_type); -} - - -bool -ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - class_name.assign (cxx_record_decl->getIdentifier()->getNameStart()); - return true; - } - } - class_name.clear(); - return false; -} - - -bool -ClangASTContext::IsCXXClassType (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - if (qual_type->getAsCXXRecordDecl() != NULL) - return true; - } - return false; -} - -bool -ClangASTContext::IsBeingDefined (lldb::clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type); - if (tag_type) - return tag_type->isBeingDefined(); - } - return false; -} - -bool -ClangASTContext::IsObjCClassType (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - if (qual_type->isObjCObjectOrInterfaceType()) - return true; - } - return false; -} - -bool -ClangASTContext::IsObjCObjectPointerType (lldb::clang_type_t clang_type, clang_type_t *class_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - if (qual_type->isObjCObjectPointerType()) - { - if (class_type) - { - *class_type = NULL; - - if (!qual_type->isObjCClassType() && - !qual_type->isObjCIdType()) - { - const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type); - if (!obj_pointer_type) - *class_type = NULL; - else - *class_type = QualType(obj_pointer_type->getInterfaceType(), 0).getAsOpaquePtr(); - } - } - return true; - } - } - return false; -} - -bool -ClangASTContext::GetObjCClassName (lldb::clang_type_t clang_type, - std::string &class_name) -{ - if (!clang_type) - return false; - - const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(QualType::getFromOpaquePtr(clang_type)); - if (!object_type) - return false; - - const ObjCInterfaceDecl *interface = object_type->getInterface(); - if (!interface) - return false; - - class_name = interface->getNameAsString(); - return true; -} - -bool -ClangASTContext::IsCharType (clang_type_t clang_type) -{ - if (clang_type) - return QualType::getFromOpaquePtr(clang_type)->isCharType(); - return false; -} - -bool -ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length) -{ - clang_type_t pointee_or_element_clang_type = NULL; - Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type)); - - if (pointee_or_element_clang_type == NULL) - return false; - - if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer)) - { - QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type)); - - if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType()) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - if (type_flags.Test (eTypeIsArray)) - { - // We know the size of the array and it could be a C string - // since it is an array of characters - length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); - return true; - } - else - { - length = 0; - return true; - } - - } - } - return false; -} - -bool -ClangASTContext::IsFunctionPointerType (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - if (qual_type->isFunctionPointerType()) - return true; - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - default: - break; - case clang::Type::Typedef: - return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: - return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Paren: - return ClangASTContext::IsFunctionPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - { - const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); - if (reference_type) - return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr()); - } - break; - } - } - return false; -} - -size_t -ClangASTContext::GetArraySize (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::ConstantArray: - { - const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr()); - if (array) - return array->getSize().getLimitedValue(); - } - break; - - case clang::Type::Typedef: - return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - - case clang::Type::Elaborated: - return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - - case clang::Type::Paren: - return ClangASTContext::GetArraySize(cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - default: - break; - } - } - return 0; -} - -clang_type_t -ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size, bool *is_incomplete) -{ - if (is_incomplete) - *is_incomplete = false; - if (!clang_type) - return 0; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - default: - break; - - case clang::Type::ConstantArray: - if (member_type) - *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr(); - if (size) - *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX); - return clang_type; - - case clang::Type::IncompleteArray: - if (member_type) - *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr(); - if (size) - *size = 0; - if (is_incomplete) - *is_incomplete = true; - return clang_type; - - case clang::Type::VariableArray: - if (member_type) - *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr(); - if (size) - *size = 0; - return clang_type; - - case clang::Type::DependentSizedArray: - if (member_type) - *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr(); - if (size) - *size = 0; - return clang_type; - - case clang::Type::Typedef: - return ClangASTContext::GetAsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - member_type, - size, - is_incomplete); - - case clang::Type::Elaborated: - return ClangASTContext::GetAsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - member_type, - size, - is_incomplete); - case clang::Type::Paren: - return ClangASTContext::GetAsArrayType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - member_type, - size, - is_incomplete); - } - return 0; -} - - -#pragma mark Typedefs - -clang_type_t -ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - ASTContext *ast = getASTContext(); - IdentifierTable *identifier_table = getIdentifierTable(); - assert (ast != NULL); - assert (identifier_table != NULL); - if (decl_ctx == NULL) - decl_ctx = ast->getTranslationUnitDecl(); - TypedefDecl *decl = TypedefDecl::Create (*ast, - decl_ctx, - SourceLocation(), - SourceLocation(), - name ? &identifier_table->get(name) : NULL, // Identifier - ast->getTrivialTypeSourceInfo(qual_type)); - - //decl_ctx->addDecl (decl); - - decl->setAccess(AS_public); // TODO respect proper access specifier - - // Get a uniqued QualType for the typedef decl type - return ast->getTypedefType (decl).getAsOpaquePtr(); + return ClangASTType (ast, ast->getTagDeclType(enum_decl).getAsOpaquePtr()); } - return NULL; + return ClangASTType(); } // Disable this for now since I can't seem to get a nicely formatted float @@ -6726,103 +2124,23 @@ ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, D // return false; //} -size_t -ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - uint32_t count = 0; - bool is_complex = false; - if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) - { - // TODO: handle complex and vector types - if (count != 1) - return false; - StringRef s_sref(s); - APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref); - - const uint64_t bit_size = ast->getTypeSize (qual_type); - const uint64_t byte_size = bit_size / 8; - if (dst_size >= byte_size) - { - if (bit_size == sizeof(float)*8) - { - float float32 = ap_float.convertToFloat(); - ::memcpy (dst, &float32, byte_size); - return byte_size; - } - else if (bit_size >= 64) - { - llvm::APInt ap_int(ap_float.bitcastToAPInt()); - ::memcpy (dst, ap_int.getRawData(), byte_size); - return byte_size; - } - } - } - } - return 0; -} - -lldb::clang_type_t +ClangASTType ClangASTContext::GetFloatTypeFromBitSize (clang::ASTContext *ast, size_t bit_size) { if (ast) { if (bit_size == ast->getTypeSize(ast->FloatTy)) - return ast->FloatTy.getAsOpaquePtr(); + return ClangASTType(ast, ast->FloatTy.getAsOpaquePtr()); else if (bit_size == ast->getTypeSize(ast->DoubleTy)) - return ast->DoubleTy.getAsOpaquePtr(); + return ClangASTType(ast, ast->DoubleTy.getAsOpaquePtr()); else if (bit_size == ast->getTypeSize(ast->LongDoubleTy)) - return ast->LongDoubleTy.getAsOpaquePtr(); + return ClangASTType(ast, ast->LongDoubleTy.getAsOpaquePtr()); else if (bit_size == ast->getTypeSize(ast->HalfTy)) - return ast->HalfTy.getAsOpaquePtr(); + return ClangASTType(ast, ast->HalfTy.getAsOpaquePtr()); } - return NULL; -} - -unsigned -ClangASTContext::GetTypeQualifiers(clang_type_t clang_type) -{ - assert (clang_type); - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - return qual_type.getQualifiers().getCVRQualifiers(); -} - -bool -ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type) -{ - if (clang_type == NULL) - return false; - - return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type)); -} - - -bool -ClangASTContext::GetCompleteType (clang_type_t clang_type) -{ - return ClangASTContext::GetCompleteType (getASTContext(), clang_type); -} - -bool -ClangASTContext::IsCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type) -{ - if (clang_type == NULL) - return false; - - return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type), false); // just check but don't let it actually complete -} - - -bool -ClangASTContext::IsCompleteType (clang_type_t clang_type) -{ - return ClangASTContext::IsCompleteType (getASTContext(), clang_type); + return ClangASTType(); } bool diff --git a/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp index 1439c305682..15294962045 100644 --- a/lldb/source/Symbol/ClangASTImporter.cpp +++ b/lldb/source/Symbol/ClangASTImporter.cpp @@ -568,8 +568,8 @@ ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from } } -clang::Decl -*ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to) +clang::Decl * +ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to) { ClangASTMetrics::RegisterClangImport(); diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index c6c5c05838a..c2fbe27f175 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -13,10 +13,13 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" +#include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclGroup.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/Type.h" @@ -36,9 +39,9 @@ #include "lldb/Core/Scalar.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamString.h" -#include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" +#include "lldb/Symbol/VerifyDecl.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -46,211 +49,655 @@ using namespace lldb; using namespace lldb_private; +using namespace clang; +using namespace llvm; - -ClangASTType::~ClangASTType() +static bool +GetCompleteQualType (ASTContext *ast, QualType qual_type, bool allow_completion = true) { + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::ConstantArray: + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + { + const ArrayType *array_type = dyn_cast<ArrayType>(qual_type.getTypePtr()); + + if (array_type) + return GetCompleteQualType (ast, array_type->getElementType(), allow_completion); + } + break; + + case clang::Type::Record: + case clang::Type::Enum: + { + const TagType *tag_type = dyn_cast<TagType>(qual_type.getTypePtr()); + if (tag_type) + { + TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) + { + if (tag_decl->isCompleteDefinition()) + return true; + + if (!allow_completion) + return false; + + if (tag_decl->hasExternalLexicalStorage()) + { + if (ast) + { + ExternalASTSource *external_ast_source = ast->getExternalSource(); + if (external_ast_source) + { + external_ast_source->CompleteType(tag_decl); + return !tag_type->isIncompleteType(); + } + } + } + return false; + } + } + + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added ASTContext + // because it only supports TagDecl objects right now... + if (class_interface_decl) + { + if (class_interface_decl->getDefinition()) + return true; + + if (!allow_completion) + return false; + + if (class_interface_decl->hasExternalLexicalStorage()) + { + if (ast) + { + ExternalASTSource *external_ast_source = ast->getExternalSource(); + if (external_ast_source) + { + external_ast_source->CompleteType (class_interface_decl); + return !objc_class_type->isIncompleteType(); + } + } + } + return false; + } + } + } + break; + + case clang::Type::Typedef: + return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion); + + case clang::Type::Elaborated: + return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion); + + case clang::Type::Paren: + return GetCompleteQualType (ast, cast<ParenType>(qual_type)->desugar(), allow_completion); + + default: + break; + } + + return true; } -std::string -ClangASTType::GetTypeNameForQualType (clang::ASTContext *ast, clang::QualType qual_type) +static ObjCIvarDecl::AccessControl +ConvertAccessTypeToObjCIvarAccessControl (AccessType access) { - std::string type_name; - - clang::PrintingPolicy printing_policy (ast->getPrintingPolicy()); - printing_policy.SuppressTagKeyword = true; - printing_policy.LangOpts.WChar = true; - const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>(); - if (typedef_type) - { - const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); - type_name = typedef_decl->getQualifiedNameAsString(printing_policy); - } - else + switch (access) { - type_name = qual_type.getAsString(printing_policy); + case eAccessNone: return ObjCIvarDecl::None; + case eAccessPublic: return ObjCIvarDecl::Public; + case eAccessPrivate: return ObjCIvarDecl::Private; + case eAccessProtected: return ObjCIvarDecl::Protected; + case eAccessPackage: return ObjCIvarDecl::Package; } - return type_name; + return ObjCIvarDecl::None; } -std::string -ClangASTType::GetTypeNameForOpaqueQualType (clang::ASTContext *ast, clang_type_t opaque_qual_type) +//---------------------------------------------------------------------- +// Tests +//---------------------------------------------------------------------- + +ClangASTType::ClangASTType (clang::ASTContext *ast, + clang::QualType qual_type) : + m_type (qual_type.getAsOpaquePtr()), + m_ast (ast) { - return GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(opaque_qual_type)); } -ClangASTType -ClangASTType::GetCanonicalType (clang::ASTContext *ast, lldb::clang_type_t opaque_qual_type) +ClangASTType::~ClangASTType() { - if (ast && opaque_qual_type) - return ClangASTType (ast, - clang::QualType::getFromOpaquePtr(opaque_qual_type).getCanonicalType().getAsOpaquePtr()); - return ClangASTType(); } -ConstString -ClangASTType::GetConstTypeName () +//---------------------------------------------------------------------- +// Tests +//---------------------------------------------------------------------- + +bool +ClangASTType::IsAggregateType () const { - // TODO: verify if we actually need to complete a type just to get its type name???? - if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type)) - return ConstString("<invalid>"); - return GetConstTypeName (m_ast, m_type); + if (!IsValid()) + return false; + + QualType qual_type (GetCanonicalQualType()); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + case clang::Type::ConstantArray: + case clang::Type::ExtVector: + case clang::Type::Vector: + case clang::Type::Record: + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + return true; + case clang::Type::Elaborated: + return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsAggregateType(); + case clang::Type::Typedef: + return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsAggregateType(); + case clang::Type::Paren: + return ClangASTType(m_ast, cast<ParenType>(qual_type)->desugar()).IsAggregateType(); + default: + break; + } + // The clang type does have a value + return false; } -ConstString -ClangASTType::GetConstQualifiedTypeName () +bool +ClangASTType::IsArrayType (ClangASTType *element_type_ptr, + uint64_t *size, + bool *is_incomplete) const { - // TODO: verify if we actually need to complete a type just to get its fully qualified type name???? - if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type)) - return ConstString("<invalid>"); - return GetConstQualifiedTypeName (m_ast, m_type); + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + default: + break; + + case clang::Type::ConstantArray: + if (element_type_ptr) + element_type_ptr->SetClangType (m_ast, cast<ConstantArrayType>(qual_type)->getElementType()); + if (size) + *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX); + return true; + + case clang::Type::IncompleteArray: + if (element_type_ptr) + element_type_ptr->SetClangType (m_ast, cast<IncompleteArrayType>(qual_type)->getElementType()); + if (size) + *size = 0; + if (is_incomplete) + *is_incomplete = true; + return true; + + case clang::Type::VariableArray: + if (element_type_ptr) + element_type_ptr->SetClangType (m_ast, cast<VariableArrayType>(qual_type)->getElementType()); + if (size) + *size = 0; + return true; + + case clang::Type::DependentSizedArray: + if (element_type_ptr) + element_type_ptr->SetClangType (m_ast, cast<DependentSizedArrayType>(qual_type)->getElementType()); + if (size) + *size = 0; + return true; + + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsArrayType (element_type_ptr, + size, + is_incomplete); + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsArrayType (element_type_ptr, + size, + is_incomplete); + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsArrayType (element_type_ptr, + size, + is_incomplete); + } + } + if (element_type_ptr) + element_type_ptr->Clear(); + if (size) + *size = 0; + if (is_incomplete) + *is_incomplete = false; + return 0; } -ConstString -ClangASTType::GetConstQualifiedTypeName (clang::ASTContext *ast, clang_type_t clang_type) -{ - if (ast == NULL || clang_type == NULL) - return ConstString("<invalid>"); - return ConstString (GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(clang_type)).c_str()); +bool +ClangASTType::IsCharType () const +{ + if (!IsValid()) + return false; + return GetQualType().getUnqualifiedType()->isCharType(); } -ConstString -ClangASTType::GetConstTypeName (clang::ASTContext *ast, clang_type_t clang_type) +bool +ClangASTType::IsCompleteType () const { - if (!clang_type) - return ConstString("<invalid>"); - - std::string type_name (GetTypeNameForOpaqueQualType(ast, clang_type)); - ConstString const_type_name; - if (type_name.empty()) - const_type_name.SetCString ("<invalid>"); - else - const_type_name.SetCString(type_name.c_str()); - return const_type_name; + if (!IsValid()) + return false; + const bool allow_completion = false; + return GetCompleteQualType (m_ast, GetQualType(), allow_completion); } -clang_type_t -ClangASTType::GetPointeeType () const +bool +ClangASTType::IsConst() const { - return GetPointeeType (m_type); + return GetQualType().isConstQualified(); } -clang_type_t -ClangASTType::GetPointeeType (clang_type_t clang_type) +bool +ClangASTType::IsCStringType (uint32_t &length) const { - if (clang_type) - { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - - return qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr(); + ClangASTType pointee_or_element_clang_type; + length = 0; + Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type)); + + if (!pointee_or_element_clang_type.IsValid()) + return false; + + if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer)) + { + if (pointee_or_element_clang_type.IsCharType()) + { + if (type_flags.Test (eTypeIsArray)) + { + // We know the size of the array and it could be a C string + // since it is an array of characters + length = cast<ConstantArrayType>(GetCanonicalQualType().getTypePtr())->getSize().getLimitedValue(); + } + return true; + + } } - return NULL; + return false; } -lldb::clang_type_t -ClangASTType::GetArrayElementType (uint64_t& stride) +bool +ClangASTType::IsFunctionType (bool *is_variadic_ptr) const { - return GetArrayElementType(m_ast, m_type, stride); + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + + if (qual_type->isFunctionType()) + { + if (is_variadic_ptr) + { + const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr()); + if (function_proto_type) + *is_variadic_ptr = function_proto_type->isVariadic(); + else + *is_variadic_ptr = false; + } + return true; + } + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + default: + break; + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionType(); + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsFunctionType(); + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsFunctionType(); + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + { + const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); + if (reference_type) + return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionType(); + } + break; + } + } + return false; } -lldb::clang_type_t -ClangASTType::GetArrayElementType (clang::ASTContext* ast, - lldb::clang_type_t opaque_clang_qual_type, - uint64_t& stride) + +bool +ClangASTType::IsFunctionPointerType () const { - if (opaque_clang_qual_type) + if (IsValid()) { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)); - - lldb::clang_type_t ret_type = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified().getAsOpaquePtr(); - - // TODO: the real stride will be >= this value.. find the real one! - stride = GetTypeByteSize(ast, ret_type); + QualType qual_type (GetCanonicalQualType()); - return ret_type; + if (qual_type->isFunctionPointerType()) + return true; + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + default: + break; + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionPointerType(); + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsFunctionPointerType(); + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsFunctionPointerType(); + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + { + const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); + if (reference_type) + return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionPointerType(); + } + break; + } } - return NULL; + return false; } -lldb::clang_type_t -ClangASTType::GetPointerType () const +bool +ClangASTType::IsIntegerType (bool &is_signed) const { - return GetPointerType (m_ast, m_type); + if (!IsValid()) + return false; + + QualType qual_type (GetCanonicalQualType()); + const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); + + if (builtin_type) + { + if (builtin_type->isInteger()) + { + is_signed = builtin_type->isSignedInteger(); + return true; + } + } + + return false; } -lldb::clang_type_t -ClangASTType::GetPointerType (clang::ASTContext *ast_context, - lldb::clang_type_t opaque_clang_qual_type) +bool +ClangASTType::IsPointerType (ClangASTType *pointee_type) const { - if (opaque_clang_qual_type) + if (IsValid()) { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)); - - return ast_context->getPointerType(qual_type).getAsOpaquePtr(); + QualType qual_type (GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Builtin: + switch (cast<clang::BuiltinType>(qual_type)->getKind()) + { + default: + break; + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + return true; + } + return false; + case clang::Type::ObjCObjectPointer: + if (pointee_type) + pointee_type->SetClangType (m_ast, cast<ObjCObjectPointerType>(qual_type)->getPointeeType()); + return true; + case clang::Type::BlockPointer: + if (pointee_type) + pointee_type->SetClangType (m_ast, cast<BlockPointerType>(qual_type)->getPointeeType()); + return true; + case clang::Type::Pointer: + if (pointee_type) + pointee_type->SetClangType (m_ast, cast<PointerType>(qual_type)->getPointeeType()); + return true; + case clang::Type::MemberPointer: + if (pointee_type) + pointee_type->SetClangType (m_ast, cast<MemberPointerType>(qual_type)->getPointeeType()); + return true; + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerType(pointee_type); + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsPointerType(pointee_type); + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsPointerType(pointee_type); + default: + break; + } } - return NULL; + if (pointee_type) + pointee_type->Clear(); + return false; } -ClangASTType -ClangASTType::GetFullyUnqualifiedType () + +bool +ClangASTType::IsPointerOrReferenceType (ClangASTType *pointee_type) const { - return GetFullyUnqualifiedType(m_ast, m_type); + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Builtin: + switch (cast<clang::BuiltinType>(qual_type)->getKind()) + { + default: + break; + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + return true; + } + return false; + case clang::Type::ObjCObjectPointer: + if (pointee_type) + pointee_type->SetClangType(m_ast, cast<ObjCObjectPointerType>(qual_type)->getPointeeType()); + return true; + case clang::Type::BlockPointer: + if (pointee_type) + pointee_type->SetClangType(m_ast, cast<BlockPointerType>(qual_type)->getPointeeType()); + return true; + case clang::Type::Pointer: + if (pointee_type) + pointee_type->SetClangType(m_ast, cast<PointerType>(qual_type)->getPointeeType()); + return true; + case clang::Type::MemberPointer: + if (pointee_type) + pointee_type->SetClangType(m_ast, cast<MemberPointerType>(qual_type)->getPointeeType()); + return true; + case clang::Type::LValueReference: + if (pointee_type) + pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar()); + return true; + case clang::Type::RValueReference: + if (pointee_type) + pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar()); + return true; + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerOrReferenceType(pointee_type); + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsPointerOrReferenceType(pointee_type); + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsPointerOrReferenceType(pointee_type); + default: + break; + } + } + if (pointee_type) + pointee_type->Clear(); + return false; } -static clang::QualType GetFullyUnqualifiedType_Impl (clang::QualType Ty, - clang::ASTContext * ctx) + +bool +ClangASTType::IsReferenceType (ClangASTType *pointee_type) const { - if (Ty->isPointerType()) - Ty = ctx->getPointerType(GetFullyUnqualifiedType_Impl(Ty->getPointeeType(),ctx)); - else - Ty = Ty.getUnqualifiedType(); - Ty.removeLocalConst(); - Ty.removeLocalRestrict(); - Ty.removeLocalVolatile(); - return Ty; + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + + switch (type_class) + { + case clang::Type::LValueReference: + if (pointee_type) + pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar()); + return true; + case clang::Type::RValueReference: + if (pointee_type) + pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar()); + return true; + case clang::Type::Typedef: + return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsReferenceType(pointee_type); + case clang::Type::Elaborated: + return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsReferenceType(pointee_type); + case clang::Type::Paren: + return ClangASTType(m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsReferenceType(pointee_type); + + default: + break; + } + } + if (pointee_type) + pointee_type->Clear(); + return false; } -ClangASTType -ClangASTType::GetFullyUnqualifiedType (clang::ASTContext *ast_context, lldb::clang_type_t clang_type) +bool +ClangASTType::IsFloatingPointType (uint32_t &count, bool &is_complex) const { - return ClangASTType(ast_context,GetFullyUnqualifiedType_Impl(clang::QualType::getFromOpaquePtr(clang_type),ast_context).getAsOpaquePtr()); + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + + if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal())) + { + clang::BuiltinType::Kind kind = BT->getKind(); + if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble) + { + count = 1; + is_complex = false; + return true; + } + } + else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal())) + { + if (ClangASTType (m_ast, CT->getElementType()).IsFloatingPointType (count, is_complex)) + { + count = 2; + is_complex = true; + return true; + } + } + else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal())) + { + if (ClangASTType (m_ast, VT->getElementType()).IsFloatingPointType (count, is_complex)) + { + count = VT->getNumElements(); + is_complex = false; + return true; + } + } + } + count = 0; + is_complex = false; + return false; } -lldb::Encoding -ClangASTType::GetEncoding (uint64_t &count) + +bool +ClangASTType::IsDefined() const { - return GetEncoding(m_type, count); + if (!IsValid()) + return false; + + QualType qual_type(GetQualType()); + const TagType *tag_type = dyn_cast<TagType>(qual_type.getTypePtr()); + if (tag_type) + { + TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) + return tag_decl->isCompleteDefinition(); + return false; + } + else + { + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + if (class_interface_decl) + return class_interface_decl->getDefinition() != NULL; + return false; + } + } + return true; } +bool +ClangASTType::IsObjCClassType () const +{ + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + + const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type); -lldb::LanguageType -ClangASTType::GetMinimumLanguage () + if (obj_pointer_type) + return obj_pointer_type->isObjCClassType(); + } + return false; +} + +bool +ClangASTType::IsObjCObjectOrInterfaceType () const { - return ClangASTType::GetMinimumLanguage (m_ast, - m_type); + if (IsValid()) + return GetCanonicalQualType()->isObjCObjectOrInterfaceType(); + return false; } bool -ClangASTType::IsPolymorphicClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type) +ClangASTType::IsPolymorphicClass () const { - if (clang_type) + if (IsValid()) { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type).getCanonicalType()); + QualType qual_type(GetCanonicalQualType()); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: - if (ClangASTContext::GetCompleteType (ast_context, clang_type)) + if (GetCompleteType()) { - const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr()); - const clang::RecordDecl *record_decl = record_type->getDecl(); + const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); if (record_decl) { - const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); + const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); if (cxx_record_decl) return cxx_record_decl->isPolymorphic(); } @@ -264,13 +711,661 @@ ClangASTType::IsPolymorphicClass (clang::ASTContext *ast_context, lldb::clang_ty return false; } +bool +ClangASTType::IsPossibleDynamicType (ClangASTType *dynamic_pointee_type, + bool check_cplusplus, + bool check_objc) const +{ + QualType pointee_qual_type; + if (m_type) + { + QualType qual_type (GetCanonicalQualType()); + bool success = false; + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Builtin: + if (check_objc && cast<BuiltinType>(qual_type)->getKind() == BuiltinType::ObjCId) + { + if (dynamic_pointee_type) + dynamic_pointee_type->SetClangType(m_ast, m_type); + return true; + } + break; + + case clang::Type::ObjCObjectPointer: + if (check_objc) + { + if (dynamic_pointee_type) + dynamic_pointee_type->SetClangType(m_ast, cast<ObjCObjectPointerType>(qual_type)->getPointeeType()); + return true; + } + break; + + case clang::Type::Pointer: + pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType(); + success = true; + break; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType(); + success = true; + break; + + case clang::Type::Typedef: + return ClangASTType (m_ast, + cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPossibleDynamicType (dynamic_pointee_type, + check_cplusplus, + check_objc); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, + cast<ElaboratedType>(qual_type)->getNamedType()).IsPossibleDynamicType (dynamic_pointee_type, + check_cplusplus, + check_objc); + + case clang::Type::Paren: + return ClangASTType (m_ast, + cast<ParenType>(qual_type)->desugar()).IsPossibleDynamicType (dynamic_pointee_type, + check_cplusplus, + check_objc); + default: + break; + } + + if (success) + { + // Check to make sure what we are pointing too is a possible dynamic C++ type + // We currently accept any "void *" (in case we have a class that has been + // watered down to an opaque pointer) and virtual C++ classes. + const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass(); + switch (pointee_type_class) + { + case clang::Type::Builtin: + switch (cast<BuiltinType>(pointee_qual_type)->getKind()) + { + case BuiltinType::UnknownAny: + case BuiltinType::Void: + if (dynamic_pointee_type) + dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type); + return true; + + case BuiltinType::NullPtr: + case BuiltinType::Bool: + case BuiltinType::Char_U: + case BuiltinType::UChar: + case BuiltinType::WChar_U: + case BuiltinType::Char16: + case BuiltinType::Char32: + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + case BuiltinType::UInt128: + case BuiltinType::Char_S: + case BuiltinType::SChar: + case BuiltinType::WChar_S: + case BuiltinType::Short: + case BuiltinType::Int: + case BuiltinType::Long: + case BuiltinType::LongLong: + case BuiltinType::Int128: + case BuiltinType::Float: + case BuiltinType::Double: + case BuiltinType::LongDouble: + case BuiltinType::Dependent: + case BuiltinType::Overload: + case BuiltinType::ObjCId: + case BuiltinType::ObjCClass: + case BuiltinType::ObjCSel: + case BuiltinType::BoundMember: + case BuiltinType::Half: + case BuiltinType::ARCUnbridgedCast: + case BuiltinType::PseudoObject: + case BuiltinType::BuiltinFn: + case BuiltinType::OCLEvent: + case BuiltinType::OCLImage1d: + case BuiltinType::OCLImage1dArray: + case BuiltinType::OCLImage1dBuffer: + case BuiltinType::OCLImage2d: + case BuiltinType::OCLImage2dArray: + case BuiltinType::OCLImage3d: + case BuiltinType::OCLSampler: + break; + } + break; + + case clang::Type::Record: + if (check_cplusplus) + { + CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + bool is_complete = cxx_record_decl->isCompleteDefinition(); + + if (is_complete) + success = cxx_record_decl->isDynamicClass(); + else + { + ClangASTMetadata *metadata = ClangASTContext::GetMetadata (m_ast, cxx_record_decl); + if (metadata) + success = metadata->GetIsDynamicCXXType(); + else + { + is_complete = ClangASTType(m_ast, pointee_qual_type).GetCompleteType(); + if (is_complete) + success = cxx_record_decl->isDynamicClass(); + else + success = false; + } + } + + if (success) + { + if (dynamic_pointee_type) + dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type); + return true; + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (check_objc) + { + if (dynamic_pointee_type) + dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type); + return true; + } + break; + + default: + break; + } + } + } + if (dynamic_pointee_type) + dynamic_pointee_type->Clear(); + return false; +} + + +bool +ClangASTType::IsScalarType () const +{ + if (!IsValid()) + return false; + + return (GetTypeInfo (NULL) & eTypeIsScalar) != 0; +} + +bool +ClangASTType::IsTypedefType () const +{ + if (!IsValid()) + return false; + return GetQualType()->getTypeClass() == clang::Type::Typedef; +} + +bool +ClangASTType::IsVoidType () const +{ + if (!IsValid()) + return false; + return GetCanonicalQualType()->isVoidType(); +} + +bool +ClangASTType::IsPointerToScalarType () const +{ + if (!IsValid()) + return false; + + return IsPointerType() && GetPointeeType().IsScalarType(); +} + +bool +ClangASTType::IsArrayOfScalarType () const +{ + ClangASTType element_type; + if (IsArrayType(&element_type, NULL, NULL)) + return element_type.IsScalarType(); + return false; +} + + +bool +ClangASTType::GetCXXClassName (std::string &class_name) const +{ + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + + CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + class_name.assign (cxx_record_decl->getIdentifier()->getNameStart()); + return true; + } + } + class_name.clear(); + return false; +} + + +bool +ClangASTType::IsCXXClassType () const +{ + if (!IsValid()) + return false; + + QualType qual_type (GetCanonicalQualType()); + if (qual_type->getAsCXXRecordDecl() != NULL) + return true; + return false; +} + +bool +ClangASTType::IsBeingDefined () const +{ + if (!IsValid()) + return false; + QualType qual_type (GetCanonicalQualType()); + const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type); + if (tag_type) + return tag_type->isBeingDefined(); + return false; +} + +bool +ClangASTType::IsObjCObjectPointerType (ClangASTType *class_type_ptr) +{ + if (!IsValid()) + return false; + + QualType qual_type (GetCanonicalQualType()); + + if (qual_type->isObjCObjectPointerType()) + { + if (class_type_ptr) + { + if (!qual_type->isObjCClassType() && + !qual_type->isObjCIdType()) + { + const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type); + if (obj_pointer_type == NULL) + class_type_ptr->Clear(); + else + class_type_ptr->SetClangType (m_ast, QualType(obj_pointer_type->getInterfaceType(), 0)); + } + } + return true; + } + if (class_type_ptr) + class_type_ptr->Clear(); + return false; +} + +bool +ClangASTType::GetObjCClassName (std::string &class_name) +{ + if (!IsValid()) + return false; + + QualType qual_type (GetCanonicalQualType()); + + const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(qual_type); + if (object_type) + { + const ObjCInterfaceDecl *interface = object_type->getInterface(); + if (interface) + { + class_name = interface->getNameAsString(); + return true; + } + } + return false; +} + + +//---------------------------------------------------------------------- +// Type Completion +//---------------------------------------------------------------------- + +bool +ClangASTType::GetCompleteType () const +{ + if (!IsValid()) + return false; + const bool allow_completion = true; + return GetCompleteQualType (m_ast, GetQualType(), allow_completion); +} + +//---------------------------------------------------------------------- +// AST related queries +//---------------------------------------------------------------------- +size_t +ClangASTType::GetPointerByteSize () const +{ + if (m_ast) + return m_ast->getTypeSize(m_ast->VoidPtrTy) / 8; + return 0; +} + +ConstString +ClangASTType::GetConstQualifiedTypeName () const +{ + return GetConstTypeName (); +} + +ConstString +ClangASTType::GetConstTypeName () const +{ + if (IsValid()) + { + std::string type_name (GetTypeName()); + if (!type_name.empty()) + return ConstString (type_name.c_str()); + } + return ConstString("<invalid>"); +} + +std::string +ClangASTType::GetTypeName () const +{ + std::string type_name; + if (IsValid()) + { + PrintingPolicy printing_policy (m_ast->getPrintingPolicy()); + QualType qual_type(GetQualType()); + printing_policy.SuppressTagKeyword = true; + printing_policy.LangOpts.WChar = true; + const TypedefType *typedef_type = qual_type->getAs<TypedefType>(); + if (typedef_type) + { + const TypedefNameDecl *typedef_decl = typedef_type->getDecl(); + type_name = typedef_decl->getQualifiedNameAsString(printing_policy); + } + else + { + type_name = qual_type.getAsString(printing_policy); + } + } + return type_name; +} + + +uint32_t +ClangASTType::GetTypeInfo (ClangASTType *pointee_or_element_clang_type) const +{ + if (!IsValid()) + return 0; + + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->Clear(); + + QualType qual_type (GetQualType()); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Builtin: + { + const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); + + uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue; + switch (builtin_type->getKind()) + { + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetClangType(m_ast, m_ast->ObjCBuiltinClassTy); + builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; + break; + + case clang::BuiltinType::ObjCSel: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetClangType(m_ast, m_ast->CharTy); + builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; + break; + + case clang::BuiltinType::Bool: + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + case clang::BuiltinType::WChar_U: + case clang::BuiltinType::Char16: + case clang::BuiltinType::Char32: + case clang::BuiltinType::UShort: + case clang::BuiltinType::UInt: + case clang::BuiltinType::ULong: + case clang::BuiltinType::ULongLong: + case clang::BuiltinType::UInt128: + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + case clang::BuiltinType::WChar_S: + case clang::BuiltinType::Short: + case clang::BuiltinType::Int: + case clang::BuiltinType::Long: + case clang::BuiltinType::LongLong: + case clang::BuiltinType::Int128: + case clang::BuiltinType::Float: + case clang::BuiltinType::Double: + case clang::BuiltinType::LongDouble: + builtin_type_flags |= eTypeIsScalar; + if (builtin_type->isInteger()) + { + builtin_type_flags |= eTypeIsInteger; + if (builtin_type->isSignedInteger()) + builtin_type_flags |= eTypeIsSigned; + } + else if (builtin_type->isFloatingPoint()) + builtin_type_flags |= eTypeIsFloat; + break; + default: + break; + } + return builtin_type_flags; + } + + case clang::Type::BlockPointer: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType()); + return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock; + + case clang::Type::Complex: + { + uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex; + const ComplexType *complex_type = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()); + if (complex_type) + { + QualType complex_element_type (complex_type->getElementType()); + if (complex_element_type->isIntegerType()) + complex_type_flags |= eTypeIsFloat; + else if (complex_element_type->isFloatingType()) + complex_type_flags |= eTypeIsInteger; + } + return complex_type_flags; + } + break; + + case clang::Type::ConstantArray: + case clang::Type::DependentSizedArray: + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetClangType(m_ast, cast<ArrayType>(qual_type.getTypePtr())->getElementType()); + return eTypeHasChildren | eTypeIsArray; + + case clang::Type::DependentName: return 0; + case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector; + case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate; + case clang::Type::Decltype: return 0; + + case clang::Type::Enum: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetClangType(m_ast, cast<EnumType>(qual_type)->getDecl()->getIntegerType()); + return eTypeIsEnumeration | eTypeHasValue; + + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetTypeInfo (pointee_or_element_clang_type); + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetTypeInfo (pointee_or_element_clang_type); + + case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue; + case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue; + case clang::Type::InjectedClassName: return 0; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetClangType(m_ast, cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType()); + return eTypeHasChildren | eTypeIsReference | eTypeHasValue; + + case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue; + + case clang::Type::ObjCObjectPointer: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType()); + return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue; + + case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; + case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; + + case clang::Type::Pointer: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType()); + return eTypeHasChildren | eTypeIsPointer | eTypeHasValue; + + case clang::Type::Record: + if (qual_type->getAsCXXRecordDecl()) + return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus; + else + return eTypeHasChildren | eTypeIsStructUnion; + break; + case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate; + case clang::Type::TemplateTypeParm: return eTypeIsTemplate; + case clang::Type::TemplateSpecialization: return eTypeIsTemplate; + + case clang::Type::Typedef: + return eTypeIsTypedef | ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTypeInfo (pointee_or_element_clang_type); + case clang::Type::TypeOfExpr: return 0; + case clang::Type::TypeOf: return 0; + case clang::Type::UnresolvedUsing: return 0; + + case clang::Type::ExtVector: + case clang::Type::Vector: + { + uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector; + const VectorType *vector_type = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()); + if (vector_type) + { + if (vector_type->isIntegerType()) + vector_type_flags |= eTypeIsFloat; + else if (vector_type->isFloatingType()) + vector_type_flags |= eTypeIsInteger; + } + return vector_type_flags; + } + default: return 0; + } + return 0; +} + + + +lldb::LanguageType +ClangASTType::GetMinimumLanguage () +{ + if (!IsValid()) + return lldb::eLanguageTypeC; + + // If the type is a reference, then resolve it to what it refers to first: + QualType qual_type (GetCanonicalQualType().getNonReferenceType()); + if (qual_type->isAnyPointerType()) + { + if (qual_type->isObjCObjectPointerType()) + return lldb::eLanguageTypeObjC; + + QualType pointee_type (qual_type->getPointeeType()); + if (pointee_type->getPointeeCXXRecordDecl() != NULL) + return lldb::eLanguageTypeC_plus_plus; + if (pointee_type->isObjCObjectOrInterfaceType()) + return lldb::eLanguageTypeObjC; + if (pointee_type->isObjCClassType()) + return lldb::eLanguageTypeObjC; + if (pointee_type.getTypePtr() == m_ast->ObjCBuiltinIdTy.getTypePtr()) + return lldb::eLanguageTypeObjC; + } + else + { + if (qual_type->isObjCObjectOrInterfaceType()) + return lldb::eLanguageTypeObjC; + if (qual_type->getAsCXXRecordDecl()) + return lldb::eLanguageTypeC_plus_plus; + switch (qual_type->getTypeClass()) + { + default: + break; + case clang::Type::Builtin: + switch (cast<BuiltinType>(qual_type)->getKind()) + { + default: + case BuiltinType::Void: + case BuiltinType::Bool: + case BuiltinType::Char_U: + case BuiltinType::UChar: + case BuiltinType::WChar_U: + case BuiltinType::Char16: + case BuiltinType::Char32: + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + case BuiltinType::UInt128: + case BuiltinType::Char_S: + case BuiltinType::SChar: + case BuiltinType::WChar_S: + case BuiltinType::Short: + case BuiltinType::Int: + case BuiltinType::Long: + case BuiltinType::LongLong: + case BuiltinType::Int128: + case BuiltinType::Float: + case BuiltinType::Double: + case BuiltinType::LongDouble: + break; + + case BuiltinType::NullPtr: + return eLanguageTypeC_plus_plus; + + case BuiltinType::ObjCId: + case BuiltinType::ObjCClass: + case BuiltinType::ObjCSel: + return eLanguageTypeObjC; + + case BuiltinType::Dependent: + case BuiltinType::Overload: + case BuiltinType::BoundMember: + case BuiltinType::UnknownAny: + break; + } + break; + case clang::Type::Typedef: + return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMinimumLanguage(); + } + } + return lldb::eLanguageTypeC; +} + lldb::TypeClass -ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type) +ClangASTType::GetTypeClass () const { - if (clang_type == NULL) + if (!IsValid()) return lldb::eTypeClassInvalid; - - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); + + QualType qual_type(GetQualType()); switch (qual_type->getTypeClass()) { @@ -299,10 +1394,9 @@ ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t c case clang::Type::ObjCObject: return lldb::eTypeClassObjCObject; case clang::Type::ObjCInterface: return lldb::eTypeClassObjCInterface; case clang::Type::Record: - if (ClangASTContext::GetCompleteType (ast_context, clang_type)) { - const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr()); - const clang::RecordDecl *record_decl = record_type->getDecl(); + const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); if (record_decl->isUnion()) return lldb::eTypeClassUnion; else if (record_decl->isStruct()) @@ -315,10 +1409,10 @@ ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t c case clang::Type::Typedef: return lldb::eTypeClassTypedef; case clang::Type::UnresolvedUsing: break; case clang::Type::Paren: - return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); + return ClangASTType(m_ast, cast<ParenType>(qual_type)->desugar()).GetTypeClass(); case clang::Type::Elaborated: - return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - + return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetTypeClass(); + case clang::Type::Attributed: break; case clang::Type::TemplateTypeParm: break; case clang::Type::SubstTemplateTypeParm: break; @@ -337,439 +1431,4120 @@ ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t c } // We don't know hot to display this type... return lldb::eTypeClassOther; + +} +void +ClangASTType::SetClangType (clang::ASTContext *ast, clang::QualType qual_type) +{ + m_ast = ast; + m_type = qual_type.getAsOpaquePtr(); } +unsigned +ClangASTType::GetTypeQualifiers() const +{ + if (IsValid()) + return GetQualType().getQualifiers().getCVRQualifiers(); + return 0; +} -lldb::LanguageType -ClangASTType::GetMinimumLanguage (clang::ASTContext *ctx, - lldb::clang_type_t clang_type) +//---------------------------------------------------------------------- +// Creating related types +//---------------------------------------------------------------------- + +ClangASTType +ClangASTType::AddConstModifier () const { - if (clang_type == NULL) - return lldb::eLanguageTypeC; + if (m_type) + { + QualType result(GetQualType()); + result.addConst(); + return ClangASTType (m_ast, result); + } + return ClangASTType(); +} - // If the type is a reference, then resolve it to what it refers to first: - clang::QualType qual_type (clang::QualType::getFromOpaquePtr(clang_type).getNonReferenceType()); - if (qual_type->isAnyPointerType()) +ClangASTType +ClangASTType::AddRestrictModifier () const +{ + if (m_type) { - if (qual_type->isObjCObjectPointerType()) - return lldb::eLanguageTypeObjC; + QualType result(GetQualType()); + result.getQualifiers().setRestrict (true); + return ClangASTType (m_ast, result); + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::AddVolatileModifier () const +{ + if (m_type) + { + QualType result(GetQualType()); + result.getQualifiers().setVolatile (true); + return ClangASTType (m_ast, result); + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::GetArrayElementType (uint64_t& stride) const +{ + if (IsValid()) + { + QualType qual_type(GetCanonicalQualType()); + + ClangASTType element_type (m_ast, qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified()); + + // TODO: the real stride will be >= this value.. find the real one! + stride = element_type.GetByteSize(); + + return element_type; - clang::QualType pointee_type (qual_type->getPointeeType()); - if (pointee_type->getPointeeCXXRecordDecl() != NULL) - return lldb::eLanguageTypeC_plus_plus; - if (pointee_type->isObjCObjectOrInterfaceType()) - return lldb::eLanguageTypeObjC; - if (pointee_type->isObjCClassType()) - return lldb::eLanguageTypeObjC; - if (pointee_type.getTypePtr() == ctx->ObjCBuiltinIdTy.getTypePtr()) - return lldb::eLanguageTypeObjC; } + return ClangASTType(); +} + +ClangASTType +ClangASTType::GetCanonicalType () const +{ + if (IsValid()) + return ClangASTType (m_ast, GetCanonicalQualType()); + return ClangASTType(); +} + +static QualType +GetFullyUnqualifiedType_Impl (ASTContext *ast, QualType qual_type) +{ + if (qual_type->isPointerType()) + qual_type = ast->getPointerType(GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType())); else + qual_type = qual_type.getUnqualifiedType(); + qual_type.removeLocalConst(); + qual_type.removeLocalRestrict(); + qual_type.removeLocalVolatile(); + return qual_type; +} + +ClangASTType +ClangASTType::GetFullyUnqualifiedType () const +{ + if (IsValid()) + return ClangASTType(m_ast, GetFullyUnqualifiedType_Impl(m_ast, GetQualType())); + return ClangASTType(); +} + + +int +ClangASTType::GetFunctionArgumentCount () const +{ + if (IsValid()) + { + const FunctionProtoType* func = dyn_cast<FunctionProtoType>(GetCanonicalQualType()); + if (func) + return func->getNumArgs(); + } + return -1; +} + +ClangASTType +ClangASTType::GetFunctionArgumentTypeAtIndex (size_t idx) +{ + if (IsValid()) + { + const FunctionProtoType* func = dyn_cast<FunctionProtoType>(GetCanonicalQualType()); + if (func) + { + const uint32_t num_args = func->getNumArgs(); + if (idx < num_args) + return ClangASTType(m_ast, func->getArgType(idx)); + } + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::GetFunctionReturnType () const +{ + if (IsValid()) + { + QualType qual_type(GetCanonicalQualType()); + const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr()); + if (func) + return ClangASTType(m_ast, func->getResultType()); + } + return ClangASTType(); +} + + +ClangASTType +ClangASTType::GetLValueReferenceType () const +{ + if (IsValid()) + { + return ClangASTType(m_ast, m_ast->getLValueReferenceType(GetQualType())); + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::GetRValueReferenceType () const +{ + if (IsValid()) { + return ClangASTType(m_ast, m_ast->getRValueReferenceType(GetQualType())); + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::GetNonReferenceType () const +{ + if (IsValid()) + return ClangASTType(m_ast, GetQualType().getNonReferenceType()); + return ClangASTType(); +} + +ClangASTType +ClangASTType::CreateTypedefType (const char *typedef_name, + clang::DeclContext *decl_ctx) const +{ + if (IsValid() && typedef_name && typedef_name[0]) + { + QualType qual_type (GetQualType()); + if (decl_ctx == NULL) + decl_ctx = m_ast->getTranslationUnitDecl(); + TypedefDecl *decl = TypedefDecl::Create (*m_ast, + decl_ctx, + SourceLocation(), + SourceLocation(), + &m_ast->Idents.get(typedef_name), + m_ast->getTrivialTypeSourceInfo(qual_type)); + + decl->setAccess(AS_public); // TODO respect proper access specifier + + // Get a uniqued QualType for the typedef decl type + return ClangASTType (m_ast, m_ast->getTypedefType (decl)); + } + return ClangASTType(); + +} + +ClangASTType +ClangASTType::GetPointeeType () const +{ + if (m_type) + { + QualType qual_type(GetQualType()); + return ClangASTType (m_ast, qual_type.getTypePtr()->getPointeeType()); + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::GetPointerType () const +{ + if (IsValid()) + { + QualType qual_type (GetQualType()); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + return ClangASTType(m_ast, m_ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr()); + + default: + return ClangASTType(m_ast, m_ast->getPointerType(qual_type).getAsOpaquePtr()); + } + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::GetTypedefedType () const +{ + if (IsValid()) + { + const TypedefType *typedef_type = dyn_cast<TypedefType>(GetQualType()); + if (typedef_type) + return ClangASTType (m_ast, typedef_type->getDecl()->getUnderlyingType()); + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::RemoveFastQualifiers () const +{ + if (m_type) + { + QualType qual_type(GetQualType()); + qual_type.getQualifiers().removeFastQualifiers(); + return ClangASTType (m_ast, qual_type); + } + return ClangASTType(); +} + + +//---------------------------------------------------------------------- +// Create related types using the current type's AST +//---------------------------------------------------------------------- + +ClangASTType +ClangASTType::GetBasicTypeFromAST (lldb::BasicType basic_type) const +{ + if (IsValid()) + return ClangASTContext::GetBasicType(m_ast, basic_type); + return ClangASTType(); +} +//---------------------------------------------------------------------- +// Exploring the type +//---------------------------------------------------------------------- + +uint64_t +ClangASTType::GetBitSize () const +{ + if (GetCompleteType ()) + { + QualType qual_type(GetCanonicalQualType()); + const uint32_t bit_size = m_ast->getTypeSize (qual_type); + if (bit_size == 0) + { + if (qual_type->isIncompleteArrayType()) + return m_ast->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified()); + } if (qual_type->isObjCObjectOrInterfaceType()) - return lldb::eLanguageTypeObjC; - if (qual_type->getAsCXXRecordDecl()) - return lldb::eLanguageTypeC_plus_plus; - switch (qual_type->getTypeClass()) + return bit_size + m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy); + return bit_size; + } + return 0; +} + +uint64_t +ClangASTType::GetByteSize () const +{ + return (GetBitSize () + 7) / 8; +} + +size_t +ClangASTType::GetTypeBitAlign () const +{ + if (GetCompleteType ()) + return m_ast->getTypeAlign(GetQualType()); + return 0; +} + + +lldb::Encoding +ClangASTType::GetEncoding (uint64_t &count) const +{ + if (!IsValid()) + return lldb::eEncodingInvalid; + + count = 1; + QualType qual_type(GetCanonicalQualType()); + + switch (qual_type->getTypeClass()) + { + case clang::Type::UnaryTransform: + break; + + case clang::Type::FunctionNoProto: + case clang::Type::FunctionProto: + break; + + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + break; + + case clang::Type::ConstantArray: + break; + + case clang::Type::ExtVector: + case clang::Type::Vector: + // TODO: Set this to more than one??? + break; + + case clang::Type::Builtin: + switch (cast<BuiltinType>(qual_type)->getKind()) { - default: + default: assert(0 && "Unknown builtin type!"); + case BuiltinType::Void: break; - case clang::Type::Builtin: - switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) + + case BuiltinType::Bool: + case BuiltinType::Char_S: + case BuiltinType::SChar: + case BuiltinType::WChar_S: + case BuiltinType::Char16: + case BuiltinType::Char32: + case BuiltinType::Short: + case BuiltinType::Int: + case BuiltinType::Long: + case BuiltinType::LongLong: + case BuiltinType::Int128: return lldb::eEncodingSint; + + case BuiltinType::Char_U: + case BuiltinType::UChar: + case BuiltinType::WChar_U: + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + case BuiltinType::UInt128: return lldb::eEncodingUint; + + case BuiltinType::Float: + case BuiltinType::Double: + case BuiltinType::LongDouble: return lldb::eEncodingIEEE754; + + case BuiltinType::ObjCClass: + case BuiltinType::ObjCId: + case BuiltinType::ObjCSel: return lldb::eEncodingUint; + + case BuiltinType::NullPtr: return lldb::eEncodingUint; + } + break; + // All pointer types are represented as unsigned integer encodings. + // We may nee to add a eEncodingPointer if we ever need to know the + // difference + case clang::Type::ObjCObjectPointer: + case clang::Type::BlockPointer: + case clang::Type::Pointer: + case clang::Type::LValueReference: + case clang::Type::RValueReference: + case clang::Type::MemberPointer: return lldb::eEncodingUint; + case clang::Type::Complex: + { + lldb::Encoding encoding = lldb::eEncodingIEEE754; + if (qual_type->isComplexType()) + encoding = lldb::eEncodingIEEE754; + else { - default: - case clang::BuiltinType::Void: - case clang::BuiltinType::Bool: - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::WChar_U: - case clang::BuiltinType::Char16: - case clang::BuiltinType::Char32: - case clang::BuiltinType::UShort: - case clang::BuiltinType::UInt: - case clang::BuiltinType::ULong: - case clang::BuiltinType::ULongLong: - case clang::BuiltinType::UInt128: - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar_S: - case clang::BuiltinType::Short: - case clang::BuiltinType::Int: - case clang::BuiltinType::Long: - case clang::BuiltinType::LongLong: - case clang::BuiltinType::Int128: - case clang::BuiltinType::Float: - case clang::BuiltinType::Double: - case clang::BuiltinType::LongDouble: - break; + const ComplexType *complex_type = qual_type->getAsComplexIntegerType(); + if (complex_type) + encoding = ClangASTType(m_ast, complex_type->getElementType()).GetEncoding(count); + else + encoding = lldb::eEncodingSint; + } + count = 2; + return encoding; + } + + case clang::Type::ObjCInterface: break; + case clang::Type::Record: break; + case clang::Type::Enum: return lldb::eEncodingSint; + case clang::Type::Typedef: + return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetEncoding(count); + + case clang::Type::Elaborated: + return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count); + + case clang::Type::Paren: + return ClangASTType(m_ast, cast<ParenType>(qual_type)->desugar()).GetEncoding(count); + + case clang::Type::DependentSizedArray: + case clang::Type::DependentSizedExtVector: + case clang::Type::UnresolvedUsing: + case clang::Type::Attributed: + case clang::Type::TemplateTypeParm: + case clang::Type::SubstTemplateTypeParm: + case clang::Type::SubstTemplateTypeParmPack: + case clang::Type::Auto: + case clang::Type::InjectedClassName: + case clang::Type::DependentName: + case clang::Type::DependentTemplateSpecialization: + case clang::Type::PackExpansion: + case clang::Type::ObjCObject: + + case clang::Type::TypeOfExpr: + case clang::Type::TypeOf: + case clang::Type::Decltype: + case clang::Type::TemplateSpecialization: + case clang::Type::Atomic: + break; + + } + count = 0; + return lldb::eEncodingInvalid; +} - case clang::BuiltinType::NullPtr: - return eLanguageTypeC_plus_plus; +lldb::Format +ClangASTType::GetFormat () const +{ + if (!IsValid()) + return lldb::eFormatDefault; + + QualType qual_type(GetCanonicalQualType()); + + switch (qual_type->getTypeClass()) + { + case clang::Type::UnaryTransform: + break; + + case clang::Type::FunctionNoProto: + case clang::Type::FunctionProto: + break; + + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + break; + + case clang::Type::ConstantArray: + return lldb::eFormatVoid; // no value + + case clang::Type::ExtVector: + case clang::Type::Vector: + break; + + case clang::Type::Builtin: + switch (cast<BuiltinType>(qual_type)->getKind()) + { + //default: assert(0 && "Unknown builtin type!"); + case BuiltinType::UnknownAny: + case BuiltinType::Void: + case BuiltinType::BoundMember: + break; + + case BuiltinType::Bool: return lldb::eFormatBoolean; + case BuiltinType::Char_S: + case BuiltinType::SChar: + case BuiltinType::WChar_S: + case BuiltinType::Char_U: + case BuiltinType::UChar: + case BuiltinType::WChar_U: return lldb::eFormatChar; + case BuiltinType::Char16: return lldb::eFormatUnicode16; + case BuiltinType::Char32: return lldb::eFormatUnicode32; + case BuiltinType::UShort: return lldb::eFormatUnsigned; + case BuiltinType::Short: return lldb::eFormatDecimal; + case BuiltinType::UInt: return lldb::eFormatUnsigned; + case BuiltinType::Int: return lldb::eFormatDecimal; + case BuiltinType::ULong: return lldb::eFormatUnsigned; + case BuiltinType::Long: return lldb::eFormatDecimal; + case BuiltinType::ULongLong: return lldb::eFormatUnsigned; + case BuiltinType::LongLong: return lldb::eFormatDecimal; + case BuiltinType::UInt128: return lldb::eFormatUnsigned; + case BuiltinType::Int128: return lldb::eFormatDecimal; + case BuiltinType::Float: return lldb::eFormatFloat; + case BuiltinType::Double: return lldb::eFormatFloat; + case BuiltinType::LongDouble: return lldb::eFormatFloat; + case BuiltinType::NullPtr: + case BuiltinType::Overload: + case BuiltinType::Dependent: + case BuiltinType::ObjCId: + case BuiltinType::ObjCClass: + case BuiltinType::ObjCSel: + case BuiltinType::Half: + case BuiltinType::ARCUnbridgedCast: + case BuiltinType::PseudoObject: + case BuiltinType::BuiltinFn: + case BuiltinType::OCLEvent: + case BuiltinType::OCLImage1d: + case BuiltinType::OCLImage1dArray: + case BuiltinType::OCLImage1dBuffer: + case BuiltinType::OCLImage2d: + case BuiltinType::OCLImage2dArray: + case BuiltinType::OCLImage3d: + case BuiltinType::OCLSampler: + return lldb::eFormatHex; + } + break; + case clang::Type::ObjCObjectPointer: return lldb::eFormatHex; + case clang::Type::BlockPointer: return lldb::eFormatHex; + case clang::Type::Pointer: return lldb::eFormatHex; + case clang::Type::LValueReference: + case clang::Type::RValueReference: return lldb::eFormatHex; + case clang::Type::MemberPointer: break; + case clang::Type::Complex: + { + if (qual_type->isComplexType()) + return lldb::eFormatComplex; + else + return lldb::eFormatComplexInteger; + } + case clang::Type::ObjCInterface: break; + case clang::Type::Record: break; + case clang::Type::Enum: return lldb::eFormatEnum; + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetFormat(); + case clang::Type::Auto: + return ClangASTType (m_ast, cast<AutoType>(qual_type)->desugar()).GetFormat(); + case clang::Type::Paren: + return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetFormat(); + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetFormat(); + case clang::Type::DependentSizedArray: + case clang::Type::DependentSizedExtVector: + case clang::Type::UnresolvedUsing: + case clang::Type::Attributed: + case clang::Type::TemplateTypeParm: + case clang::Type::SubstTemplateTypeParm: + case clang::Type::SubstTemplateTypeParmPack: + case clang::Type::InjectedClassName: + case clang::Type::DependentName: + case clang::Type::DependentTemplateSpecialization: + case clang::Type::PackExpansion: + case clang::Type::ObjCObject: + + case clang::Type::TypeOfExpr: + case clang::Type::TypeOf: + case clang::Type::Decltype: + case clang::Type::TemplateSpecialization: + case clang::Type::Atomic: + break; + } + // We don't know hot to display this type... + return lldb::eFormatBytes; +} + +static bool +ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass) +{ + while (class_interface_decl) + { + if (class_interface_decl->ivar_size() > 0) + return true; + + if (check_superclass) + class_interface_decl = class_interface_decl->getSuperClass(); + else + break; + } + return false; +} + +uint32_t +ClangASTType::GetNumChildren (bool omit_empty_base_classes) const +{ + if (!IsValid()) + return 0; + + uint32_t num_children = 0; + QualType qual_type(GetQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Builtin: + switch (cast<BuiltinType>(qual_type)->getKind()) + { + case BuiltinType::ObjCId: // child is Class + case BuiltinType::ObjCClass: // child is Class + num_children = 1; + break; + + default: + break; + } + break; + + case clang::Type::Complex: return 0; + + case clang::Type::Record: + if (GetCompleteQualType (m_ast, qual_type)) + { + const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); + assert(record_decl); + const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); + if (cxx_record_decl) + { + if (omit_empty_base_classes) + { + // Check each base classes to see if it or any of its + // base classes contain any fields. This can help + // limit the noise in variable views by not having to + // show base classes that contain no members. + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; + ++base_class) + { + const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); + + // Skip empty base classes + if (ClangASTContext::RecordHasFields(base_class_decl) == false) + continue; + + num_children++; + } + } + else + { + // Include all base classes + num_children += cxx_record_decl->getNumBases(); + } - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - case clang::BuiltinType::ObjCSel: - return eLanguageTypeObjC; + } + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) + ++num_children; + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteQualType (m_ast, qual_type)) + { + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + if (superclass_interface_decl) + { + if (omit_empty_base_classes) + { + if (ObjCDeclHasIVars (superclass_interface_decl, true)) + ++num_children; + } + else + ++num_children; + } + + num_children += class_interface_decl->ivar_size(); + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + { + const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr()); + QualType pointee_type = pointer_type->getPointeeType(); + uint32_t num_pointee_children = ClangASTType (m_ast,pointee_type).GetNumChildren (omit_empty_base_classes); + // If this type points to a simple type, then it has 1 child + if (num_pointee_children == 0) + num_children = 1; + else + num_children = num_pointee_children; + } + break; + + case clang::Type::Vector: + case clang::Type::ExtVector: + num_children = cast<VectorType>(qual_type.getTypePtr())->getNumElements(); + break; + + case clang::Type::ConstantArray: + num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); + break; + + case clang::Type::Pointer: + { + const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); + QualType pointee_type (pointer_type->getPointeeType()); + uint32_t num_pointee_children = ClangASTType (m_ast,pointee_type).GetNumChildren (omit_empty_base_classes); + if (num_pointee_children == 0) + { + // We have a pointer to a pointee type that claims it has no children. + // We will want to look at + num_children = ClangASTType (m_ast, pointee_type).GetNumPointeeChildren(); + } + else + num_children = num_pointee_children; + } + break; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + { + const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); + QualType pointee_type = reference_type->getPointeeType(); + uint32_t num_pointee_children = ClangASTType (m_ast, pointee_type).GetNumChildren (omit_empty_base_classes); + // If this type points to a simple type, then it has 1 child + if (num_pointee_children == 0) + num_children = 1; + else + num_children = num_pointee_children; + } + break; + + + case clang::Type::Typedef: + num_children = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumChildren (omit_empty_base_classes); + break; + + case clang::Type::Elaborated: + num_children = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumChildren (omit_empty_base_classes); + break; + + case clang::Type::Paren: + num_children = ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetNumChildren (omit_empty_base_classes); + break; + default: + break; + } + return num_children; +} +lldb::BasicType +ClangASTType::GetBasicTypeEnumeration () const +{ + if (IsValid()) + { + QualType qual_type(GetQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + if (type_class == clang::Type::Builtin) + { + switch (cast<clang::BuiltinType>(qual_type)->getKind()) + { + case clang::BuiltinType::Void: return eBasicTypeVoid; + case clang::BuiltinType::Bool: return eBasicTypeBool; + case clang::BuiltinType::Char_S: return eBasicTypeSignedChar; + case clang::BuiltinType::Char_U: return eBasicTypeUnsignedChar; + case clang::BuiltinType::Char16: return eBasicTypeChar16; + case clang::BuiltinType::Char32: return eBasicTypeChar32; + case clang::BuiltinType::UChar: return eBasicTypeUnsignedChar; + case clang::BuiltinType::SChar: return eBasicTypeSignedChar; + case clang::BuiltinType::WChar_S: return eBasicTypeSignedWChar; + case clang::BuiltinType::WChar_U: return eBasicTypeUnsignedWChar; + case clang::BuiltinType::Short: return eBasicTypeShort; + case clang::BuiltinType::UShort: return eBasicTypeUnsignedShort; + case clang::BuiltinType::Int: return eBasicTypeInt; + case clang::BuiltinType::UInt: return eBasicTypeUnsignedInt; + case clang::BuiltinType::Long: return eBasicTypeLong; + case clang::BuiltinType::ULong: return eBasicTypeUnsignedLong; + case clang::BuiltinType::LongLong: return eBasicTypeLongLong; + case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong; + case clang::BuiltinType::Int128: return eBasicTypeInt128; + case clang::BuiltinType::UInt128: return eBasicTypeUnsignedInt128; + + case clang::BuiltinType::Half: return eBasicTypeHalf; + case clang::BuiltinType::Float: return eBasicTypeFloat; + case clang::BuiltinType::Double: return eBasicTypeDouble; + case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble; + + case clang::BuiltinType::NullPtr: return eBasicTypeNullPtr; + case clang::BuiltinType::ObjCId: return eBasicTypeObjCID; + case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass; + case clang::BuiltinType::ObjCSel: return eBasicTypeObjCSel; case clang::BuiltinType::Dependent: case clang::BuiltinType::Overload: case clang::BuiltinType::BoundMember: + case clang::BuiltinType::PseudoObject: case clang::BuiltinType::UnknownAny: - break; + case clang::BuiltinType::BuiltinFn: + case clang::BuiltinType::ARCUnbridgedCast: + case clang::BuiltinType::OCLEvent: + case clang::BuiltinType::OCLImage1d: + case clang::BuiltinType::OCLImage1dArray: + case clang::BuiltinType::OCLImage1dBuffer: + case clang::BuiltinType::OCLImage2d: + case clang::BuiltinType::OCLImage2dArray: + case clang::BuiltinType::OCLImage3d: + case clang::BuiltinType::OCLSampler: + return eBasicTypeOther; + } + } + } + return eBasicTypeInvalid; +} + + +#pragma mark Aggregate Types + +uint32_t +ClangASTType::GetNumDirectBaseClasses () const +{ + if (!IsValid()) + return 0; + + uint32_t count = 0; + QualType qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteType()) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + count = cxx_record_decl->getNumBases(); + } + break; + + case clang::Type::ObjCObjectPointer: + if (GetCompleteType()) + { + const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); + if (class_interface_decl && class_interface_decl->getSuperClass()) + count = 1; + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType()) + { + const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl && class_interface_decl->getSuperClass()) + count = 1; + } + } + break; + + + case clang::Type::Typedef: + count = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumDirectBaseClasses (); + break; + + case clang::Type::Elaborated: + count = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumDirectBaseClasses (); + break; + + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumDirectBaseClasses (); + + default: + break; + } + return count; +} + +uint32_t +ClangASTType::GetNumVirtualBaseClasses () const +{ + if (!IsValid()) + return 0; + + uint32_t count = 0; + QualType qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteType()) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + count = cxx_record_decl->getNumVBases(); + } + break; + + case clang::Type::Typedef: + count = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumVirtualBaseClasses(); + break; + + case clang::Type::Elaborated: + count = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumVirtualBaseClasses(); + break; + + case clang::Type::Paren: + count = ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumVirtualBaseClasses(); + break; + + default: + break; + } + return count; +} + +uint32_t +ClangASTType::GetNumFields () const +{ + if (!IsValid()) + return 0; + + uint32_t count = 0; + QualType qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteType()) + { + const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr()); + if (record_type) + { + RecordDecl *record_decl = record_type->getDecl(); + if (record_decl) + { + uint32_t field_idx = 0; + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) + ++field_idx; + count = field_idx; + } + } + } + break; + + case clang::Type::Typedef: + count = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumFields(); + break; + + case clang::Type::Elaborated: + count = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumFields(); + break; + + case clang::Type::Paren: + count = ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumFields(); + break; + + case clang::Type::ObjCObjectPointer: + if (GetCompleteType()) + { + const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); + + if (class_interface_decl) + count = class_interface_decl->ivar_size(); + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType()) + { + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + count = class_interface_decl->ivar_size(); + } + } + break; + + default: + break; + } + return count; +} + +ClangASTType +ClangASTType::GetDirectBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) const +{ + if (!IsValid()) + return ClangASTType(); + + QualType qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteType()) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + uint32_t curr_idx = 0; + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; + ++base_class, ++curr_idx) + { + if (curr_idx == idx) + { + if (bit_offset_ptr) + { + const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl); + const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); + if (base_class->isVirtual()) + *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; + else + *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; + } + return ClangASTType (m_ast, base_class->getType()); + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + if (idx == 0 && GetCompleteType()) + { + const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); + if (class_interface_decl) + { + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + if (superclass_interface_decl) + { + if (bit_offset_ptr) + *bit_offset_ptr = 0; + return ClangASTType (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl)); + } + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (idx == 0 && GetCompleteType()) + { + const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + if (superclass_interface_decl) + { + if (bit_offset_ptr) + *bit_offset_ptr = 0; + return ClangASTType (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl)); + } + } + } + } + break; + + + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr); + + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr); + + default: + break; + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::GetVirtualBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) const +{ + if (!IsValid()) + return ClangASTType(); + + QualType qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteType()) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + uint32_t curr_idx = 0; + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end(); + base_class != base_class_end; + ++base_class, ++curr_idx) + { + if (curr_idx == idx) + { + if (bit_offset_ptr) + { + const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl); + const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); + *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; + + } + return ClangASTType (m_ast, base_class->getType()); + } + } + } + } + break; + + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr); + + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr); + + default: + break; + } + return ClangASTType(); +} + +static clang_type_t +GetObjCFieldAtIndex (clang::ASTContext *ast, + ObjCInterfaceDecl *class_interface_decl, + size_t idx, + std::string& name, + uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) +{ + if (class_interface_decl) + { + if (idx < (class_interface_decl->ivar_size())) + { + ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); + uint32_t ivar_idx = 0; + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx) + { + if (ivar_idx == idx) + { + const ObjCIvarDecl* ivar_decl = *ivar_pos; + + QualType ivar_qual_type(ivar_decl->getType()); + + name.assign(ivar_decl->getNameAsString()); + + if (bit_offset_ptr) + { + const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl); + *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx); + } + + const bool is_bitfield = ivar_pos->isBitField(); + + if (bitfield_bit_size_ptr) + { + *bitfield_bit_size_ptr = 0; + + if (is_bitfield && ast) + { + Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth(); + llvm::APSInt bitfield_apsint; + if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast)) + { + *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); + } + } + } + if (is_bitfield_ptr) + *is_bitfield_ptr = is_bitfield; + + return ivar_qual_type.getAsOpaquePtr(); + } + } + } + } + return NULL; +} + +ClangASTType +ClangASTType::GetFieldAtIndex (size_t idx, + std::string& name, + uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) const +{ + if (!IsValid()) + return ClangASTType(); + + QualType qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteType()) + { + const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); + uint32_t field_idx = 0; + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx) + { + if (idx == field_idx) + { + // Print the member type if requested + // Print the member name and equal sign + name.assign(field->getNameAsString()); + + // Figure out the type byte size (field_type_info.first) and + // alignment (field_type_info.second) from the AST context. + if (bit_offset_ptr) + { + const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl); + *bit_offset_ptr = record_layout.getFieldOffset (field_idx); + } + + const bool is_bitfield = field->isBitField(); + + if (bitfield_bit_size_ptr) + { + *bitfield_bit_size_ptr = 0; + + if (is_bitfield) + { + Expr *bitfield_bit_size_expr = field->getBitWidth(); + llvm::APSInt bitfield_apsint; + if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *m_ast)) + { + *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); + } + } + } + if (is_bitfield_ptr) + *is_bitfield_ptr = is_bitfield; + + return ClangASTType (m_ast, field->getType()); + } + } } break; + + case clang::Type::ObjCObjectPointer: + if (GetCompleteType()) + { + const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); + return ClangASTType (m_ast, GetObjCFieldAtIndex(m_ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr)); + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType()) + { + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + return ClangASTType (m_ast, GetObjCFieldAtIndex(m_ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr)); + } + } + break; + + case clang::Type::Typedef: - return GetMinimumLanguage(ctx, - llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()). + GetFieldAtIndex (idx, + name, + bit_offset_ptr, + bitfield_bit_size_ptr, + is_bitfield_ptr); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()). + GetFieldAtIndex (idx, + name, + bit_offset_ptr, + bitfield_bit_size_ptr, + is_bitfield_ptr); + + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()). + GetFieldAtIndex (idx, + name, + bit_offset_ptr, + bitfield_bit_size_ptr, + is_bitfield_ptr); + + default: + break; + } + return ClangASTType(); +} + +uint32_t +ClangASTType::GetIndexOfFieldWithName (const char* name, + ClangASTType* field_clang_type_ptr, + uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) const +{ + unsigned count = GetNumFields(); + std::string field_name; + for (unsigned index = 0; index < count; index++) + { + ClangASTType field_clang_type (GetFieldAtIndex(index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr)); + if (strcmp(field_name.c_str(), name) == 0) + { + if (field_clang_type_ptr) + *field_clang_type_ptr = field_clang_type; + return index; } } - return lldb::eLanguageTypeC; + return UINT32_MAX; } -lldb::Encoding -ClangASTType::GetEncoding (clang_type_t clang_type, uint64_t &count) +// If a pointer to a pointee type (the clang_type arg) says that it has no +// children, then we either need to trust it, or override it and return a +// different result. For example, an "int *" has one child that is an integer, +// but a function pointer doesn't have any children. Likewise if a Record type +// claims it has no children, then there really is nothing to show. +uint32_t +ClangASTType::GetNumPointeeChildren () const { - count = 1; - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); + if (!IsValid()) + return 0; + + QualType qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Builtin: + switch (cast<clang::BuiltinType>(qual_type)->getKind()) + { + case clang::BuiltinType::UnknownAny: + case clang::BuiltinType::Void: + case clang::BuiltinType::NullPtr: + case clang::BuiltinType::OCLEvent: + case clang::BuiltinType::OCLImage1d: + case clang::BuiltinType::OCLImage1dArray: + case clang::BuiltinType::OCLImage1dBuffer: + case clang::BuiltinType::OCLImage2d: + case clang::BuiltinType::OCLImage2dArray: + case clang::BuiltinType::OCLImage3d: + case clang::BuiltinType::OCLSampler: + return 0; + case clang::BuiltinType::Bool: + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + case clang::BuiltinType::WChar_U: + case clang::BuiltinType::Char16: + case clang::BuiltinType::Char32: + case clang::BuiltinType::UShort: + case clang::BuiltinType::UInt: + case clang::BuiltinType::ULong: + case clang::BuiltinType::ULongLong: + case clang::BuiltinType::UInt128: + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + case clang::BuiltinType::WChar_S: + case clang::BuiltinType::Short: + case clang::BuiltinType::Int: + case clang::BuiltinType::Long: + case clang::BuiltinType::LongLong: + case clang::BuiltinType::Int128: + case clang::BuiltinType::Float: + case clang::BuiltinType::Double: + case clang::BuiltinType::LongDouble: + case clang::BuiltinType::Dependent: + case clang::BuiltinType::Overload: + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + case clang::BuiltinType::ObjCSel: + case clang::BuiltinType::BoundMember: + case clang::BuiltinType::Half: + case clang::BuiltinType::ARCUnbridgedCast: + case clang::BuiltinType::PseudoObject: + case clang::BuiltinType::BuiltinFn: + return 1; + } + break; + + case clang::Type::Complex: return 1; + case clang::Type::Pointer: return 1; + case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them + case clang::Type::LValueReference: return 1; + case clang::Type::RValueReference: return 1; + case clang::Type::MemberPointer: return 0; + case clang::Type::ConstantArray: return 0; + case clang::Type::IncompleteArray: return 0; + case clang::Type::VariableArray: return 0; + case clang::Type::DependentSizedArray: return 0; + case clang::Type::DependentSizedExtVector: return 0; + case clang::Type::Vector: return 0; + case clang::Type::ExtVector: return 0; + case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children... + case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children... + case clang::Type::UnresolvedUsing: return 0; + case clang::Type::Paren: return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumPointeeChildren (); + case clang::Type::Typedef: return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumPointeeChildren (); + case clang::Type::Elaborated: return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumPointeeChildren (); + case clang::Type::TypeOfExpr: return 0; + case clang::Type::TypeOf: return 0; + case clang::Type::Decltype: return 0; + case clang::Type::Record: return 0; + case clang::Type::Enum: return 1; + case clang::Type::TemplateTypeParm: return 1; + case clang::Type::SubstTemplateTypeParm: return 1; + case clang::Type::TemplateSpecialization: return 1; + case clang::Type::InjectedClassName: return 0; + case clang::Type::DependentName: return 1; + case clang::Type::DependentTemplateSpecialization: return 1; + case clang::Type::ObjCObject: return 0; + case clang::Type::ObjCInterface: return 0; + case clang::Type::ObjCObjectPointer: return 1; + default: + break; + } + return 0; +} - switch (qual_type->getTypeClass()) + +ClangASTType +ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, + const char *parent_name, + 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) const +{ + if (!IsValid()) + return ClangASTType(); + + QualType parent_qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); + child_bitfield_bit_size = 0; + child_bitfield_bit_offset = 0; + child_is_base_class = false; + + const bool idx_is_valid = idx < GetNumChildren (omit_empty_base_classes); + uint32_t bit_offset; + switch (parent_type_class) { - case clang::Type::UnaryTransform: - break; + case clang::Type::Builtin: + if (idx_is_valid) + { + switch (cast<clang::BuiltinType>(parent_qual_type)->getKind()) + { + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + child_name = "isa"; + child_byte_size = m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy) / CHAR_BIT; + return ClangASTType (m_ast, m_ast->ObjCBuiltinClassTy); + + default: + break; + } + } + break; - case clang::Type::FunctionNoProto: - case clang::Type::FunctionProto: - break; + case clang::Type::Record: + if (idx_is_valid && GetCompleteType()) + { + const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); + assert(record_decl); + const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl); + uint32_t child_idx = 0; + + const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); + if (cxx_record_decl) + { + // We might have base classes to print out first + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; + ++base_class) + { + const CXXRecordDecl *base_class_decl = NULL; + + // Skip empty base classes + if (omit_empty_base_classes) + { + base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); + if (ClangASTContext::RecordHasFields(base_class_decl) == false) + continue; + } + + if (idx == child_idx) + { + if (base_class_decl == NULL) + base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); + + + if (base_class->isVirtual()) + bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; + else + bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; + + // Base classes should be a multiple of 8 bits in size + child_byte_offset = bit_offset/8; + ClangASTType base_class_clang_type(m_ast, base_class->getType()); + child_name = base_class_clang_type.GetTypeName(); + uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize(); + + // Base classes bit sizes should be a multiple of 8 bits in size + assert (base_class_clang_type_bit_size % 8 == 0); + child_byte_size = base_class_clang_type_bit_size / 8; + child_is_base_class = true; + return base_class_clang_type; + } + // We don't increment the child index in the for loop since we might + // be skipping empty base classes + ++child_idx; + } + } + // Make sure index is in range... + uint32_t field_idx = 0; + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx) + { + if (idx == child_idx) + { + // Print the member type if requested + // Print the member name and equal sign + child_name.assign(field->getNameAsString().c_str()); + + // Figure out the type byte size (field_type_info.first) and + // alignment (field_type_info.second) from the AST context. + ClangASTType field_clang_type (m_ast, field->getType()); + assert(field_idx < record_layout.getFieldCount()); + child_byte_size = field_clang_type.GetByteSize(); + + // Figure out the field offset within the current struct/union/class type + bit_offset = record_layout.getFieldOffset (field_idx); + child_byte_offset = bit_offset / 8; + if (ClangASTContext::FieldIsBitfield (m_ast, *field, child_bitfield_bit_size)) + child_bitfield_bit_offset = bit_offset % 8; + + return field_clang_type; + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (idx_is_valid && GetCompleteType()) + { + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + uint32_t child_idx = 0; + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + + const ASTRecordLayout &interface_layout = m_ast->getASTObjCInterfaceLayout(class_interface_decl); + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + if (superclass_interface_decl) + { + if (omit_empty_base_classes) + { + ClangASTType base_class_clang_type (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl)); + if (base_class_clang_type.GetNumChildren(omit_empty_base_classes) > 0) + { + if (idx == 0) + { + QualType ivar_qual_type(m_ast->getObjCInterfaceType(superclass_interface_decl)); + + + child_name.assign(superclass_interface_decl->getNameAsString().c_str()); + + std::pair<uint64_t, unsigned> ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr()); + + child_byte_size = ivar_type_info.first / 8; + child_byte_offset = 0; + child_is_base_class = true; + + return ClangASTType (m_ast, ivar_qual_type); + } + + ++child_idx; + } + } + else + ++child_idx; + } + + const uint32_t superclass_idx = child_idx; + + if (idx < (child_idx + class_interface_decl->ivar_size())) + { + ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) + { + if (child_idx == idx) + { + ObjCIvarDecl* ivar_decl = *ivar_pos; + + QualType ivar_qual_type(ivar_decl->getType()); + + child_name.assign(ivar_decl->getNameAsString().c_str()); + + std::pair<uint64_t, unsigned> ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr()); + + child_byte_size = ivar_type_info.first / 8; + + // Figure out the field offset within the current struct/union/class type + // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since + // that doesn't account for the space taken up by unbacked properties, or from + // the changing size of base classes that are newer than this class. + // So if we have a process around that we can ask about this object, do so. + child_byte_offset = LLDB_INVALID_IVAR_OFFSET; + Process *process = NULL; + if (exe_ctx) + process = exe_ctx->GetProcessPtr(); + if (process) + { + ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime(); + if (objc_runtime != NULL) + { + ClangASTType parent_ast_type (m_ast, parent_qual_type); + child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str()); + } + } + + // Setting this to UINT32_MAX to make sure we don't compute it twice... + bit_offset = UINT32_MAX; + + if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET) + { + bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); + child_byte_offset = bit_offset / 8; + } + + // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset + // of a bitfield within its containing object. So regardless of where we get the byte + // offset from, we still need to get the bit offset for bitfields from the layout. + + if (ClangASTContext::FieldIsBitfield (m_ast, ivar_decl, child_bitfield_bit_size)) + { + if (bit_offset == UINT32_MAX) + bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); + + child_bitfield_bit_offset = bit_offset % 8; + } + return ClangASTType (m_ast, ivar_qual_type); + } + ++child_idx; + } + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + if (idx_is_valid) + { + ClangASTType pointee_clang_type (GetPointeeType()); + + if (transparent_pointers && pointee_clang_type.IsAggregateType()) + { + child_is_deref_of_parent = false; + bool tmp_child_is_deref_of_parent = false; + return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx, + parent_name, + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + tmp_child_is_deref_of_parent); + } + else + { + child_is_deref_of_parent = true; + if (parent_name) + { + child_name.assign(1, '*'); + child_name += parent_name; + } + + // We have a pointer to an simple type + if (idx == 0 && pointee_clang_type.GetCompleteType()) + { + child_byte_size = pointee_clang_type.GetByteSize(); + child_byte_offset = 0; + return pointee_clang_type; + } + } + } + break; + + case clang::Type::Vector: + case clang::Type::ExtVector: + if (idx_is_valid) + { + const VectorType *array = cast<VectorType>(parent_qual_type.getTypePtr()); + if (array) + { + ClangASTType element_type (m_ast, array->getElementType()); + if (element_type.GetCompleteType()) + { + char element_name[64]; + ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); + child_name.assign(element_name); + child_byte_size = element_type.GetByteSize(); + child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; + return element_type; + } + } + } + break; + + case clang::Type::ConstantArray: + case clang::Type::IncompleteArray: + if (ignore_array_bounds || idx_is_valid) + { + const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr()); + if (array) + { + ClangASTType element_type (m_ast, array->getElementType()); + if (element_type.GetCompleteType()) + { + char element_name[64]; + ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); + child_name.assign(element_name); + child_byte_size = element_type.GetByteSize(); + child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; + return element_type; + } + } + } + break; + + + case clang::Type::Pointer: + if (idx_is_valid) + { + ClangASTType pointee_clang_type (GetPointeeType()); + + // Don't dereference "void *" pointers + if (pointee_clang_type.IsVoidType()) + return ClangASTType(); + + if (transparent_pointers && pointee_clang_type.IsAggregateType ()) + { + child_is_deref_of_parent = false; + bool tmp_child_is_deref_of_parent = false; + return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx, + parent_name, + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + tmp_child_is_deref_of_parent); + } + else + { + child_is_deref_of_parent = true; + + if (parent_name) + { + child_name.assign(1, '*'); + child_name += parent_name; + } + + // We have a pointer to an simple type + if (idx == 0) + { + child_byte_size = pointee_clang_type.GetByteSize(); + child_byte_offset = 0; + return pointee_clang_type; + } + } + } + break; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + if (idx_is_valid) + { + const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr()); + ClangASTType pointee_clang_type (m_ast, reference_type->getPointeeType()); + if (transparent_pointers && pointee_clang_type.IsAggregateType ()) + { + child_is_deref_of_parent = false; + bool tmp_child_is_deref_of_parent = false; + return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx, + parent_name, + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + tmp_child_is_deref_of_parent); + } + else + { + if (parent_name) + { + child_name.assign(1, '&'); + child_name += parent_name; + } + + // We have a pointer to an simple type + if (idx == 0) + { + child_byte_size = pointee_clang_type.GetByteSize(); + child_byte_offset = 0; + return pointee_clang_type; + } + } + } + break; + + case clang::Type::Typedef: + { + ClangASTType typedefed_clang_type (m_ast, cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType()); + return typedefed_clang_type.GetChildClangTypeAtIndex (exe_ctx, + parent_name, + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); + } + break; + + case clang::Type::Elaborated: + { + ClangASTType elaborated_clang_type (m_ast, cast<ElaboratedType>(parent_qual_type)->getNamedType()); + return elaborated_clang_type.GetChildClangTypeAtIndex (exe_ctx, + parent_name, + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); + } + + case clang::Type::Paren: + { + ClangASTType paren_clang_type (m_ast, llvm::cast<clang::ParenType>(parent_qual_type)->desugar()); + return paren_clang_type.GetChildClangTypeAtIndex (exe_ctx, + parent_name, + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); + } + + + default: + break; + } + return ClangASTType(); +} - case clang::Type::IncompleteArray: - case clang::Type::VariableArray: - break; +static inline bool +BaseSpecifierIsEmpty (const CXXBaseSpecifier *b) +{ + return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false; +} - case clang::Type::ConstantArray: - break; +static uint32_t +GetIndexForRecordBase +( + const RecordDecl *record_decl, + const CXXBaseSpecifier *base_spec, + bool omit_empty_base_classes + ) +{ + uint32_t child_idx = 0; + + const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); + + // const char *super_name = record_decl->getNameAsCString(); + // const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString(); + // printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name); + // + if (cxx_record_decl) + { + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; + ++base_class) + { + if (omit_empty_base_classes) + { + if (BaseSpecifierIsEmpty (base_class)) + continue; + } + + // printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name, + // child_idx, + // base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); + // + // + if (base_class == base_spec) + return child_idx; + ++child_idx; + } + } + + return UINT32_MAX; +} - case clang::Type::ExtVector: - case clang::Type::Vector: - // TODO: Set this to more than one??? - break; - case clang::Type::Builtin: - switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) - { - default: assert(0 && "Unknown builtin type!"); - case clang::BuiltinType::Void: - break; - - case clang::BuiltinType::Bool: - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar_S: - case clang::BuiltinType::Char16: - case clang::BuiltinType::Char32: - case clang::BuiltinType::Short: - case clang::BuiltinType::Int: - case clang::BuiltinType::Long: - case clang::BuiltinType::LongLong: - case clang::BuiltinType::Int128: return lldb::eEncodingSint; - - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::WChar_U: - case clang::BuiltinType::UShort: - case clang::BuiltinType::UInt: - case clang::BuiltinType::ULong: - case clang::BuiltinType::ULongLong: - case clang::BuiltinType::UInt128: return lldb::eEncodingUint; - - case clang::BuiltinType::Float: - case clang::BuiltinType::Double: - case clang::BuiltinType::LongDouble: return lldb::eEncodingIEEE754; - - case clang::BuiltinType::ObjCClass: - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCSel: return lldb::eEncodingUint; +static uint32_t +GetIndexForRecordChild (const RecordDecl *record_decl, + NamedDecl *canonical_decl, + bool omit_empty_base_classes) +{ + uint32_t child_idx = ClangASTContext::GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), + omit_empty_base_classes); + + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); + field != field_end; + ++field, ++child_idx) + { + if (field->getCanonicalDecl() == canonical_decl) + return child_idx; + } + + return UINT32_MAX; +} + +// Look for a child member (doesn't include base classes, but it does include +// their members) in the type hierarchy. Returns an index path into "clang_type" +// on how to reach the appropriate member. +// +// class A +// { +// public: +// int m_a; +// int m_b; +// }; +// +// class B +// { +// }; +// +// class C : +// public B, +// public A +// { +// }; +// +// If we have a clang type that describes "class C", and we wanted to looked +// "m_b" in it: +// +// With omit_empty_base_classes == false we would get an integer array back with: +// { 1, 1 } +// The first index 1 is the child index for "class A" within class C +// The second index 1 is the child index for "m_b" within class A +// +// With omit_empty_base_classes == true we would get an integer array back with: +// { 0, 1 } +// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count) +// The second index 1 is the child index for "m_b" within class A - case clang::BuiltinType::NullPtr: return lldb::eEncodingUint; +size_t +ClangASTType::GetIndexOfChildMemberWithName (const char *name, + bool omit_empty_base_classes, + std::vector<uint32_t>& child_indexes) const +{ + if (IsValid() && name && name[0]) + { + QualType qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteType ()) + { + const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); + + assert(record_decl); + uint32_t child_idx = 0; + + const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); + + // Try and find a field that matches NAME + RecordDecl::field_iterator field, field_end; + StringRef name_sref(name); + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); + field != field_end; + ++field, ++child_idx) + { + if (field->getName().equals (name_sref)) + { + // We have to add on the number of base classes to this index! + child_indexes.push_back (child_idx + ClangASTContext::GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes)); + return child_indexes.size(); + } + } + + if (cxx_record_decl) + { + const RecordDecl *parent_record_decl = cxx_record_decl; + + //printf ("parent = %s\n", parent_record_decl->getNameAsCString()); + + //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl(); + // Didn't find things easily, lets let clang do its thang... + IdentifierInfo & ident_ref = m_ast->Idents.get(name_sref); + DeclarationName decl_name(&ident_ref); + + CXXBasePaths paths; + if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember, + decl_name.getAsOpaquePtr(), + paths)) + { + CXXBasePaths::const_paths_iterator path, path_end = paths.end(); + for (path = paths.begin(); path != path_end; ++path) + { + const size_t num_path_elements = path->size(); + for (size_t e=0; e<num_path_elements; ++e) + { + CXXBasePathElement elem = (*path)[e]; + + child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes); + if (child_idx == UINT32_MAX) + { + child_indexes.clear(); + return 0; + } + else + { + child_indexes.push_back (child_idx); + parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl()); + } + } + for (NamedDecl *path_decl : path->Decls) + { + child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes); + if (child_idx == UINT32_MAX) + { + child_indexes.clear(); + return 0; + } + else + { + child_indexes.push_back (child_idx); + } + } + } + return child_indexes.size(); + } + } + + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType ()) + { + StringRef name_sref(name); + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + uint32_t child_idx = 0; + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) + { + const ObjCIvarDecl* ivar_decl = *ivar_pos; + + if (ivar_decl->getName().equals (name_sref)) + { + if ((!omit_empty_base_classes && superclass_interface_decl) || + ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) + ++child_idx; + + child_indexes.push_back (child_idx); + return child_indexes.size(); + } + } + + if (superclass_interface_decl) + { + // The super class index is always zero for ObjC classes, + // so we push it onto the child indexes in case we find + // an ivar in our superclass... + child_indexes.push_back (0); + + ClangASTType superclass_clang_type (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl)); + if (superclass_clang_type.GetIndexOfChildMemberWithName (name, + omit_empty_base_classes, + child_indexes)) + { + // We did find an ivar in a superclass so just + // return the results! + return child_indexes.size(); + } + + // We didn't find an ivar matching "name" in our + // superclass, pop the superclass zero index that + // we pushed on above. + child_indexes.pop_back(); + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + { + ClangASTType objc_object_clang_type (m_ast, cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType()); + return objc_object_clang_type.GetIndexOfChildMemberWithName (name, + omit_empty_base_classes, + child_indexes); + } + break; + + + case clang::Type::ConstantArray: + { + // const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); + // const uint64_t element_count = array->getSize().getLimitedValue(); + // + // if (idx < element_count) + // { + // std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); + // + // char element_name[32]; + // ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); + // + // child_name.assign(element_name); + // assert(field_type_info.first % 8 == 0); + // child_byte_size = field_type_info.first / 8; + // child_byte_offset = idx * child_byte_size; + // return array->getElementType().getAsOpaquePtr(); + // } + } + break; + + // case clang::Type::MemberPointerType: + // { + // MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); + // QualType pointee_type = mem_ptr_type->getPointeeType(); + // + // if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) + // { + // return GetIndexOfChildWithName (ast, + // mem_ptr_type->getPointeeType().getAsOpaquePtr(), + // name); + // } + // } + // break; + // + case clang::Type::LValueReference: + case clang::Type::RValueReference: + { + const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); + QualType pointee_type(reference_type->getPointeeType()); + ClangASTType pointee_clang_type (m_ast, pointee_type); + + if (pointee_clang_type.IsAggregateType ()) + { + return pointee_clang_type.GetIndexOfChildMemberWithName (name, + omit_empty_base_classes, + child_indexes); + } + } + break; + + case clang::Type::Pointer: + { + ClangASTType pointee_clang_type (GetPointeeType()); + + if (pointee_clang_type.IsAggregateType ()) + { + return pointee_clang_type.GetIndexOfChildMemberWithName (name, + omit_empty_base_classes, + child_indexes); + } + } + break; + + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildMemberWithName (name, + omit_empty_base_classes, + child_indexes); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildMemberWithName (name, + omit_empty_base_classes, + child_indexes); + + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildMemberWithName (name, + omit_empty_base_classes, + child_indexes); + + default: + break; } - break; - // All pointer types are represented as unsigned integer encodings. - // We may nee to add a eEncodingPointer if we ever need to know the - // difference - case clang::Type::ObjCObjectPointer: - case clang::Type::BlockPointer: - case clang::Type::Pointer: - case clang::Type::LValueReference: - case clang::Type::RValueReference: - case clang::Type::MemberPointer: return lldb::eEncodingUint; - case clang::Type::Complex: + } + return 0; +} + + +// Get the index of the child of "clang_type" whose name matches. This function +// doesn't descend into the children, but only looks one level deep and name +// matches can include base class names. + +uint32_t +ClangASTType::GetIndexOfChildWithName (const char *name, bool omit_empty_base_classes) const +{ + if (IsValid() && name && name[0]) + { + QualType qual_type(GetCanonicalQualType()); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + + switch (type_class) { - lldb::Encoding encoding = lldb::eEncodingIEEE754; - if (qual_type->isComplexType()) - encoding = lldb::eEncodingIEEE754; - else + case clang::Type::Record: + if (GetCompleteType ()) + { + const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); + + assert(record_decl); + uint32_t child_idx = 0; + + const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); + + if (cxx_record_decl) + { + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; + ++base_class) + { + // Skip empty base classes + CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); + if (omit_empty_base_classes && ClangASTContext::RecordHasFields(base_class_decl) == false) + continue; + + ClangASTType base_class_clang_type (m_ast, base_class->getType()); + std::string base_class_type_name (base_class_clang_type.GetTypeName()); + if (base_class_type_name.compare (name) == 0) + return child_idx; + ++child_idx; + } + } + + // Try and find a field that matches NAME + RecordDecl::field_iterator field, field_end; + StringRef name_sref(name); + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); + field != field_end; + ++field, ++child_idx) + { + if (field->getName().equals (name_sref)) + return child_idx; + } + + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType()) + { + StringRef name_sref(name); + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + uint32_t child_idx = 0; + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) + { + const ObjCIvarDecl* ivar_decl = *ivar_pos; + + if (ivar_decl->getName().equals (name_sref)) + { + if ((!omit_empty_base_classes && superclass_interface_decl) || + ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) + ++child_idx; + + return child_idx; + } + } + + if (superclass_interface_decl) + { + if (superclass_interface_decl->getName().equals (name_sref)) + return 0; + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + { + ClangASTType pointee_clang_type (m_ast, cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType()); + return pointee_clang_type.GetIndexOfChildWithName (name, omit_empty_base_classes); + } + break; + + case clang::Type::ConstantArray: { - const clang::ComplexType *complex_type = qual_type->getAsComplexIntegerType(); - if (complex_type) - encoding = GetEncoding (complex_type->getElementType().getAsOpaquePtr(), count); - else - encoding = lldb::eEncodingSint; + // const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); + // const uint64_t element_count = array->getSize().getLimitedValue(); + // + // if (idx < element_count) + // { + // std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); + // + // char element_name[32]; + // ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); + // + // child_name.assign(element_name); + // assert(field_type_info.first % 8 == 0); + // child_byte_size = field_type_info.first / 8; + // child_byte_offset = idx * child_byte_size; + // return array->getElementType().getAsOpaquePtr(); + // } } - count = 2; - return encoding; + break; + + // case clang::Type::MemberPointerType: + // { + // MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); + // QualType pointee_type = mem_ptr_type->getPointeeType(); + // + // if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) + // { + // return GetIndexOfChildWithName (ast, + // mem_ptr_type->getPointeeType().getAsOpaquePtr(), + // name); + // } + // } + // break; + // + case clang::Type::LValueReference: + case clang::Type::RValueReference: + { + const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); + ClangASTType pointee_type (m_ast, reference_type->getPointeeType()); + + if (pointee_type.IsAggregateType ()) + { + return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes); + } + } + break; + + case clang::Type::Pointer: + { + const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); + ClangASTType pointee_type (m_ast, pointer_type->getPointeeType()); + + if (pointee_type.IsAggregateType ()) + { + return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes); + } + else + { + // if (parent_name) + // { + // child_name.assign(1, '*'); + // child_name += parent_name; + // } + // + // // We have a pointer to an simple type + // if (idx == 0) + // { + // std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); + // assert(clang_type_info.first % 8 == 0); + // child_byte_size = clang_type_info.first / 8; + // child_byte_offset = 0; + // return pointee_type.getAsOpaquePtr(); + // } + } + } + break; + + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildWithName (name, omit_empty_base_classes); + + case clang::Type::Paren: + return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildWithName (name, omit_empty_base_classes); + + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildWithName (name, omit_empty_base_classes); + + default: + break; } + } + return UINT32_MAX; +} - case clang::Type::ObjCInterface: break; - case clang::Type::Record: break; - case clang::Type::Enum: return lldb::eEncodingSint; - case clang::Type::Typedef: - return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count); - case clang::Type::Elaborated: - return ClangASTType::GetEncoding (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), count); +size_t +ClangASTType::GetNumTemplateArguments () const +{ + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteType ()) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl); + if (template_decl) + return template_decl->getTemplateArgs().size(); + } + } + break; + + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumTemplateArguments(); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumTemplateArguments(); + + case clang::Type::Paren: + return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetNumTemplateArguments(); + + default: + break; + } + } + return 0; +} - case clang::Type::Paren: - return ClangASTType::GetEncoding (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), count); - - case clang::Type::DependentSizedArray: - case clang::Type::DependentSizedExtVector: - case clang::Type::UnresolvedUsing: - case clang::Type::Attributed: - case clang::Type::TemplateTypeParm: - case clang::Type::SubstTemplateTypeParm: - case clang::Type::SubstTemplateTypeParmPack: - case clang::Type::Auto: - case clang::Type::InjectedClassName: - case clang::Type::DependentName: - case clang::Type::DependentTemplateSpecialization: - case clang::Type::PackExpansion: - case clang::Type::ObjCObject: - - case clang::Type::TypeOfExpr: - case clang::Type::TypeOf: - case clang::Type::Decltype: - case clang::Type::TemplateSpecialization: - case clang::Type::Atomic: - break; +ClangASTType +ClangASTType::GetTemplateArgument (size_t arg_idx, lldb::TemplateArgumentKind &kind) const +{ + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteType ()) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl); + if (template_decl && arg_idx < template_decl->getTemplateArgs().size()) + { + const TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx]; + switch (template_arg.getKind()) + { + case clang::TemplateArgument::Null: + kind = eTemplateArgumentKindNull; + return ClangASTType(); + + case clang::TemplateArgument::Type: + kind = eTemplateArgumentKindType; + return ClangASTType(m_ast, template_arg.getAsType()); + + case clang::TemplateArgument::Declaration: + kind = eTemplateArgumentKindDeclaration; + return ClangASTType(); + + case clang::TemplateArgument::Integral: + kind = eTemplateArgumentKindIntegral; + return ClangASTType(m_ast, template_arg.getIntegralType()); + + case clang::TemplateArgument::Template: + kind = eTemplateArgumentKindTemplate; + return ClangASTType(); + + case clang::TemplateArgument::TemplateExpansion: + kind = eTemplateArgumentKindTemplateExpansion; + return ClangASTType(); + + case clang::TemplateArgument::Expression: + kind = eTemplateArgumentKindExpression; + return ClangASTType(); + + case clang::TemplateArgument::Pack: + kind = eTemplateArgumentKindPack; + return ClangASTType(); + + default: + assert (!"Unhandled TemplateArgument::ArgKind"); + break; + } + } + } + } + break; + + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTemplateArgument (arg_idx, kind); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetTemplateArgument (arg_idx, kind); + + case clang::Type::Paren: + return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetTemplateArgument (arg_idx, kind); + + default: + break; + } + } + kind = eTemplateArgumentKindNull; + return ClangASTType (); +} +static bool +IsOperator (const char *name, OverloadedOperatorKind &op_kind) +{ + if (name == NULL || name[0] == '\0') + return false; + +#define OPERATOR_PREFIX "operator" +#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1) + + const char *post_op_name = NULL; + + bool no_space = true; + + if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH)) + return false; + + post_op_name = name + OPERATOR_PREFIX_LENGTH; + + if (post_op_name[0] == ' ') + { + post_op_name++; + no_space = false; } - count = 0; - return lldb::eEncodingInvalid; + +#undef OPERATOR_PREFIX +#undef OPERATOR_PREFIX_LENGTH + + // This is an operator, set the overloaded operator kind to invalid + // in case this is a conversion operator... + op_kind = NUM_OVERLOADED_OPERATORS; + + switch (post_op_name[0]) + { + default: + if (no_space) + return false; + break; + case 'n': + if (no_space) + return false; + if (strcmp (post_op_name, "new") == 0) + op_kind = OO_New; + else if (strcmp (post_op_name, "new[]") == 0) + op_kind = OO_Array_New; + break; + + case 'd': + if (no_space) + return false; + if (strcmp (post_op_name, "delete") == 0) + op_kind = OO_Delete; + else if (strcmp (post_op_name, "delete[]") == 0) + op_kind = OO_Array_Delete; + break; + + case '+': + if (post_op_name[1] == '\0') + op_kind = OO_Plus; + else if (post_op_name[2] == '\0') + { + if (post_op_name[1] == '=') + op_kind = OO_PlusEqual; + else if (post_op_name[1] == '+') + op_kind = OO_PlusPlus; + } + break; + + case '-': + if (post_op_name[1] == '\0') + op_kind = OO_Minus; + else if (post_op_name[2] == '\0') + { + switch (post_op_name[1]) + { + case '=': op_kind = OO_MinusEqual; break; + case '-': op_kind = OO_MinusMinus; break; + case '>': op_kind = OO_Arrow; break; + } + } + else if (post_op_name[3] == '\0') + { + if (post_op_name[2] == '*') + op_kind = OO_ArrowStar; break; + } + break; + + case '*': + if (post_op_name[1] == '\0') + op_kind = OO_Star; + else if (post_op_name[1] == '=' && post_op_name[2] == '\0') + op_kind = OO_StarEqual; + break; + + case '/': + if (post_op_name[1] == '\0') + op_kind = OO_Slash; + else if (post_op_name[1] == '=' && post_op_name[2] == '\0') + op_kind = OO_SlashEqual; + break; + + case '%': + if (post_op_name[1] == '\0') + op_kind = OO_Percent; + else if (post_op_name[1] == '=' && post_op_name[2] == '\0') + op_kind = OO_PercentEqual; + break; + + + case '^': + if (post_op_name[1] == '\0') + op_kind = OO_Caret; + else if (post_op_name[1] == '=' && post_op_name[2] == '\0') + op_kind = OO_CaretEqual; + break; + + case '&': + if (post_op_name[1] == '\0') + op_kind = OO_Amp; + else if (post_op_name[2] == '\0') + { + switch (post_op_name[1]) + { + case '=': op_kind = OO_AmpEqual; break; + case '&': op_kind = OO_AmpAmp; break; + } + } + break; + + case '|': + if (post_op_name[1] == '\0') + op_kind = OO_Pipe; + else if (post_op_name[2] == '\0') + { + switch (post_op_name[1]) + { + case '=': op_kind = OO_PipeEqual; break; + case '|': op_kind = OO_PipePipe; break; + } + } + break; + + case '~': + if (post_op_name[1] == '\0') + op_kind = OO_Tilde; + break; + + case '!': + if (post_op_name[1] == '\0') + op_kind = OO_Exclaim; + else if (post_op_name[1] == '=' && post_op_name[2] == '\0') + op_kind = OO_ExclaimEqual; + break; + + case '=': + if (post_op_name[1] == '\0') + op_kind = OO_Equal; + else if (post_op_name[1] == '=' && post_op_name[2] == '\0') + op_kind = OO_EqualEqual; + break; + + case '<': + if (post_op_name[1] == '\0') + op_kind = OO_Less; + else if (post_op_name[2] == '\0') + { + switch (post_op_name[1]) + { + case '<': op_kind = OO_LessLess; break; + case '=': op_kind = OO_LessEqual; break; + } + } + else if (post_op_name[3] == '\0') + { + if (post_op_name[2] == '=') + op_kind = OO_LessLessEqual; + } + break; + + case '>': + if (post_op_name[1] == '\0') + op_kind = OO_Greater; + else if (post_op_name[2] == '\0') + { + switch (post_op_name[1]) + { + case '>': op_kind = OO_GreaterGreater; break; + case '=': op_kind = OO_GreaterEqual; break; + } + } + else if (post_op_name[1] == '>' && + post_op_name[2] == '=' && + post_op_name[3] == '\0') + { + op_kind = OO_GreaterGreaterEqual; + } + break; + + case ',': + if (post_op_name[1] == '\0') + op_kind = OO_Comma; + break; + + case '(': + if (post_op_name[1] == ')' && post_op_name[2] == '\0') + op_kind = OO_Call; + break; + + case '[': + if (post_op_name[1] == ']' && post_op_name[2] == '\0') + op_kind = OO_Subscript; + break; + } + + return true; } -lldb::Format -ClangASTType::GetFormat () +static inline bool +check_op_param (uint32_t op_kind, bool unary, bool binary, uint32_t num_params) { - return GetFormat (m_type); + // Special-case call since it can take any number of operands + if(op_kind == OO_Call) + return true; + + // The parameter count doens't include "this" + if (num_params == 0) + return unary; + if (num_params == 1) + return binary; + else + return false; } -lldb::Format -ClangASTType::GetFormat (clang_type_t clang_type) +clang::RecordDecl * +ClangASTType::GetAsRecordDecl () const { - if (clang_type == NULL) - return lldb::eFormatDefault; + const RecordType *record_type = dyn_cast<RecordType>(GetCanonicalQualType()); + if (record_type) + return record_type->getDecl(); + return NULL; +} + +clang::CXXRecordDecl * +ClangASTType::GetAsCXXRecordDecl () const +{ + return GetCanonicalQualType()->getAsCXXRecordDecl(); +} + +ObjCInterfaceDecl * +ClangASTType::GetAsObjCInterfaceDecl () const +{ + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(GetCanonicalQualType()); + if (objc_class_type) + return objc_class_type->getInterface(); + return NULL; +} + +clang::FieldDecl * +ClangASTType::AddFieldToRecordType (const char *name, + const ClangASTType &field_clang_type, + AccessType access, + uint32_t bitfield_bit_size) +{ + if (!IsValid() || !field_clang_type.IsValid()) + return NULL; + + FieldDecl *field = NULL; + + clang::Expr *bit_width = NULL; + if (bitfield_bit_size != 0) + { + APInt bitfield_bit_size_apint(m_ast->getTypeSize(m_ast->IntTy), bitfield_bit_size); + bit_width = new (*m_ast)IntegerLiteral (*m_ast, bitfield_bit_size_apint, m_ast->IntTy, SourceLocation()); + } + + RecordDecl *record_decl = GetAsRecordDecl (); + if (record_decl) + { + field = FieldDecl::Create (*m_ast, + record_decl, + SourceLocation(), + SourceLocation(), + name ? &m_ast->Idents.get(name) : NULL, // Identifier + field_clang_type.GetQualType(), // Field type + NULL, // TInfo * + bit_width, // BitWidth + false, // Mutable + ICIS_NoInit); // HasInit - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); + if (!name) + { + // Determine whether this field corresponds to an anonymous + // struct or union. + if (const TagType *TagT = field->getType()->getAs<TagType>()) { + if (RecordDecl *Rec = dyn_cast<RecordDecl>(TagT->getDecl())) + if (!Rec->getDeclName()) { + Rec->setAnonymousStructOrUnion(true); + field->setImplicit(); + + } + } + } + + if (field) + { + field->setAccess (ClangASTContext::ConvertAccessTypeToAccessSpecifier (access)); + + record_decl->addDecl(field); + +#ifdef LLDB_CONFIGURATION_DEBUG + VerifyDecl(field); +#endif + } + } + else + { + ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl (); + + if (class_interface_decl) + { + const bool is_synthesized = false; + + field_clang_type.GetCompleteType(); + + field = ObjCIvarDecl::Create (*m_ast, + class_interface_decl, + SourceLocation(), + SourceLocation(), + name ? &m_ast->Idents.get(name) : NULL, // Identifier + field_clang_type.GetQualType(), // Field type + NULL, // TypeSourceInfo * + ConvertAccessTypeToObjCIvarAccessControl (access), + bit_width, + is_synthesized); + + if (field) + { + class_interface_decl->addDecl(field); + +#ifdef LLDB_CONFIGURATION_DEBUG + VerifyDecl(field); +#endif + } + } + } + return field; +} - switch (qual_type->getTypeClass()) +void +ClangASTType::BuildIndirectFields () +{ + RecordDecl *record_decl = GetAsRecordDecl(); + + if (!record_decl) + return; + + typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector; + + IndirectFieldVector indirect_fields; + RecordDecl::field_iterator field_pos; + RecordDecl::field_iterator field_end_pos = record_decl->field_end(); + RecordDecl::field_iterator last_field_pos = field_end_pos; + for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++) { - case clang::Type::UnaryTransform: - break; + if (field_pos->isAnonymousStructOrUnion()) + { + QualType field_qual_type = field_pos->getType(); + + const RecordType *field_record_type = field_qual_type->getAs<RecordType>(); + + if (!field_record_type) + continue; + + RecordDecl *field_record_decl = field_record_type->getDecl(); + + if (!field_record_decl) + continue; + + for (RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end(); + di != de; + ++di) + { + if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di)) + { + NamedDecl **chain = new (*m_ast) NamedDecl*[2]; + chain[0] = *field_pos; + chain[1] = nested_field_decl; + IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*m_ast, + record_decl, + SourceLocation(), + nested_field_decl->getIdentifier(), + nested_field_decl->getType(), + chain, + 2); + + indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(), + nested_field_decl->getAccess())); + + indirect_fields.push_back(indirect_field); + } + else if (IndirectFieldDecl *nested_indirect_field_decl = dyn_cast<IndirectFieldDecl>(*di)) + { + int nested_chain_size = nested_indirect_field_decl->getChainingSize(); + NamedDecl **chain = new (*m_ast) NamedDecl*[nested_chain_size + 1]; + chain[0] = *field_pos; + + int chain_index = 1; + for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(), + nce = nested_indirect_field_decl->chain_end(); + nci < nce; + ++nci) + { + chain[chain_index] = *nci; + chain_index++; + } + + IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*m_ast, + record_decl, + SourceLocation(), + nested_indirect_field_decl->getIdentifier(), + nested_indirect_field_decl->getType(), + chain, + nested_chain_size + 1); + + indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(), + nested_indirect_field_decl->getAccess())); + + indirect_fields.push_back(indirect_field); + } + } + } + } + + // Check the last field to see if it has an incomplete array type as its + // last member and if it does, the tell the record decl about it + if (last_field_pos != field_end_pos) + { + if (last_field_pos->getType()->isIncompleteArrayType()) + record_decl->hasFlexibleArrayMember(); + } + + for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end(); + ifi < ife; + ++ifi) + { + record_decl->addDecl(*ifi); + } +} + +clang::VarDecl * +ClangASTType::AddVariableToRecordType (const char *name, + const ClangASTType &var_type, + AccessType access) +{ + clang::VarDecl *var_decl = NULL; + + if (!IsValid() || !var_type.IsValid()) + return NULL; + + RecordDecl *record_decl = GetAsRecordDecl (); + if (record_decl) + { + var_decl = VarDecl::Create (*m_ast, // ASTContext & + record_decl, // DeclContext * + SourceLocation(), // SourceLocation StartLoc + SourceLocation(), // SourceLocation IdLoc + name ? &m_ast->Idents.get(name) : NULL, // IdentifierInfo * + var_type.GetQualType(), // Variable QualType + NULL, // TypeSourceInfo * + SC_Static); // StorageClass + if (var_decl) + { + var_decl->setAccess(ClangASTContext::ConvertAccessTypeToAccessSpecifier (access)); + record_decl->addDecl(var_decl); + +#ifdef LLDB_CONFIGURATION_DEBUG + VerifyDecl(var_decl); +#endif + } + } + return var_decl; +} + + +CXXMethodDecl * +ClangASTType::AddMethodToCXXRecordType (const char *name, + const ClangASTType &method_clang_type, + lldb::AccessType access, + bool is_virtual, + bool is_static, + bool is_inline, + bool is_explicit, + bool is_attr_used, + bool is_artificial) +{ + if (!IsValid() || !method_clang_type.IsValid() || name == NULL || name[0] == '\0') + return NULL; + + QualType record_qual_type(GetCanonicalQualType()); + + CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl(); + + if (cxx_record_decl == NULL) + return NULL; + + QualType method_qual_type (method_clang_type.GetQualType()); + + CXXMethodDecl *cxx_method_decl = NULL; + + DeclarationName decl_name (&m_ast->Idents.get(name)); + + const clang::FunctionType *function_type = dyn_cast<FunctionType>(method_qual_type.getTypePtr()); + + if (function_type == NULL) + return NULL; + + const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_type)); + + if (!method_function_prototype) + return NULL; + + unsigned int num_params = method_function_prototype->getNumArgs(); + + CXXDestructorDecl *cxx_dtor_decl(NULL); + CXXConstructorDecl *cxx_ctor_decl(NULL); + + if (is_artificial) + return NULL; // skip everything artificial + + if (name[0] == '~') + { + cxx_dtor_decl = CXXDestructorDecl::Create (*m_ast, + cxx_record_decl, + SourceLocation(), + DeclarationNameInfo (m_ast->DeclarationNames.getCXXDestructorName (m_ast->getCanonicalType (record_qual_type)), SourceLocation()), + method_qual_type, + NULL, + is_inline, + is_artificial); + cxx_method_decl = cxx_dtor_decl; + } + else if (decl_name == cxx_record_decl->getDeclName()) + { + cxx_ctor_decl = CXXConstructorDecl::Create (*m_ast, + cxx_record_decl, + SourceLocation(), + DeclarationNameInfo (m_ast->DeclarationNames.getCXXConstructorName (m_ast->getCanonicalType (record_qual_type)), SourceLocation()), + method_qual_type, + NULL, // TypeSourceInfo * + is_explicit, + is_inline, + is_artificial, + false /*is_constexpr*/); + cxx_method_decl = cxx_ctor_decl; + } + else + { + clang::StorageClass SC = is_static ? SC_Static : SC_None; + OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS; - case clang::Type::FunctionNoProto: - case clang::Type::FunctionProto: - break; + if (IsOperator (name, op_kind)) + { + if (op_kind != NUM_OVERLOADED_OPERATORS) + { + // Check the number of operator parameters. Sometimes we have + // seen bad DWARF that doesn't correctly describe operators and + // if we try to create a methed and add it to the class, clang + // will assert and crash, so we need to make sure things are + // acceptable. + if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params)) + return NULL; + cxx_method_decl = CXXMethodDecl::Create (*m_ast, + cxx_record_decl, + SourceLocation(), + DeclarationNameInfo (m_ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()), + method_qual_type, + NULL, // TypeSourceInfo * + SC, + is_inline, + false /*is_constexpr*/, + SourceLocation()); + } + else if (num_params == 0) + { + // Conversion operators don't take params... + cxx_method_decl = CXXConversionDecl::Create (*m_ast, + cxx_record_decl, + SourceLocation(), + DeclarationNameInfo (m_ast->DeclarationNames.getCXXConversionFunctionName (m_ast->getCanonicalType (function_type->getResultType())), SourceLocation()), + method_qual_type, + NULL, // TypeSourceInfo * + is_inline, + is_explicit, + false /*is_constexpr*/, + SourceLocation()); + } + } + + if (cxx_method_decl == NULL) + { + cxx_method_decl = CXXMethodDecl::Create (*m_ast, + cxx_record_decl, + SourceLocation(), + DeclarationNameInfo (decl_name, SourceLocation()), + method_qual_type, + NULL, // TypeSourceInfo * + SC, + is_inline, + false /*is_constexpr*/, + SourceLocation()); + } + } + + AccessSpecifier access_specifier = ClangASTContext::ConvertAccessTypeToAccessSpecifier (access); + + cxx_method_decl->setAccess (access_specifier); + cxx_method_decl->setVirtualAsWritten (is_virtual); + + if (is_attr_used) + cxx_method_decl->addAttr(::new (*m_ast) UsedAttr(SourceRange(), *m_ast)); + + // Populate the method decl with parameter decls + + llvm::SmallVector<ParmVarDecl *, 12> params; + + for (unsigned param_index = 0; + param_index < num_params; + ++param_index) + { + params.push_back (ParmVarDecl::Create (*m_ast, + cxx_method_decl, + SourceLocation(), + SourceLocation(), + NULL, // anonymous + method_function_prototype->getArgType(param_index), + NULL, + SC_None, + NULL)); + } + + cxx_method_decl->setParams (ArrayRef<ParmVarDecl*>(params)); + + cxx_record_decl->addDecl (cxx_method_decl); + + // Sometimes the debug info will mention a constructor (default/copy/move), + // destructor, or assignment operator (copy/move) but there won't be any + // version of this in the code. So we check if the function was artificially + // generated and if it is trivial and this lets the compiler/backend know + // that it can inline the IR for these when it needs to and we can avoid a + // "missing function" error when running expressions. + + if (is_artificial) + { + if (cxx_ctor_decl && + ((cxx_ctor_decl->isDefaultConstructor() && cxx_record_decl->hasTrivialDefaultConstructor ()) || + (cxx_ctor_decl->isCopyConstructor() && cxx_record_decl->hasTrivialCopyConstructor ()) || + (cxx_ctor_decl->isMoveConstructor() && cxx_record_decl->hasTrivialMoveConstructor ()) )) + { + cxx_ctor_decl->setDefaulted(); + cxx_ctor_decl->setTrivial(true); + } + else if (cxx_dtor_decl) + { + if (cxx_record_decl->hasTrivialDestructor()) + { + cxx_dtor_decl->setDefaulted(); + cxx_dtor_decl->setTrivial(true); + } + } + else if ((cxx_method_decl->isCopyAssignmentOperator() && cxx_record_decl->hasTrivialCopyAssignment()) || + (cxx_method_decl->isMoveAssignmentOperator() && cxx_record_decl->hasTrivialMoveAssignment())) + { + cxx_method_decl->setDefaulted(); + cxx_method_decl->setTrivial(true); + } + } + +#ifdef LLDB_CONFIGURATION_DEBUG + VerifyDecl(cxx_method_decl); +#endif + + // printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic()); + // printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate()); + // printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD()); + // printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty()); + // printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract()); + // printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor()); + // printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor()); + // printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment()); + // printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor()); + return cxx_method_decl; +} - case clang::Type::IncompleteArray: - case clang::Type::VariableArray: - break; - case clang::Type::ConstantArray: - return lldb::eFormatVoid; // no value +#pragma mark C++ Base Classes - case clang::Type::ExtVector: - case clang::Type::Vector: - break; +CXXBaseSpecifier * +ClangASTType::CreateBaseClassSpecifier (AccessType access, bool is_virtual, bool base_of_class) +{ + if (IsValid()) + return new CXXBaseSpecifier (SourceRange(), + is_virtual, + base_of_class, + ClangASTContext::ConvertAccessTypeToAccessSpecifier (access), + m_ast->getTrivialTypeSourceInfo (GetQualType()), + SourceLocation()); + return NULL; +} + +void +ClangASTType::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes) +{ + for (unsigned i=0; i<num_base_classes; ++i) + { + delete base_classes[i]; + base_classes[i] = NULL; + } +} - case clang::Type::Builtin: - switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) - { - //default: assert(0 && "Unknown builtin type!"); - case clang::BuiltinType::UnknownAny: - case clang::BuiltinType::Void: - case clang::BuiltinType::BoundMember: - break; - - case clang::BuiltinType::Bool: return lldb::eFormatBoolean; - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar_S: - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::WChar_U: return lldb::eFormatChar; - case clang::BuiltinType::Char16: return lldb::eFormatUnicode16; - case clang::BuiltinType::Char32: return lldb::eFormatUnicode32; - case clang::BuiltinType::UShort: return lldb::eFormatUnsigned; - case clang::BuiltinType::Short: return lldb::eFormatDecimal; - case clang::BuiltinType::UInt: return lldb::eFormatUnsigned; - case clang::BuiltinType::Int: return lldb::eFormatDecimal; - case clang::BuiltinType::ULong: return lldb::eFormatUnsigned; - case clang::BuiltinType::Long: return lldb::eFormatDecimal; - case clang::BuiltinType::ULongLong: return lldb::eFormatUnsigned; - case clang::BuiltinType::LongLong: return lldb::eFormatDecimal; - case clang::BuiltinType::UInt128: return lldb::eFormatUnsigned; - case clang::BuiltinType::Int128: return lldb::eFormatDecimal; - case clang::BuiltinType::Float: return lldb::eFormatFloat; - case clang::BuiltinType::Double: return lldb::eFormatFloat; - case clang::BuiltinType::LongDouble: return lldb::eFormatFloat; - case clang::BuiltinType::NullPtr: - case clang::BuiltinType::Overload: - case clang::BuiltinType::Dependent: - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - case clang::BuiltinType::ObjCSel: - case clang::BuiltinType::Half: - case clang::BuiltinType::ARCUnbridgedCast: - case clang::BuiltinType::PseudoObject: - case clang::BuiltinType::BuiltinFn: - case clang::BuiltinType::OCLEvent: - case clang::BuiltinType::OCLImage1d: - case clang::BuiltinType::OCLImage1dArray: - case clang::BuiltinType::OCLImage1dBuffer: - case clang::BuiltinType::OCLImage2d: - case clang::BuiltinType::OCLImage2dArray: - case clang::BuiltinType::OCLImage3d: - case clang::BuiltinType::OCLSampler: - return lldb::eFormatHex; +bool +ClangASTType::SetBaseClassesForClassType (CXXBaseSpecifier const * const *base_classes, + unsigned num_base_classes) +{ + if (IsValid()) + { + CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(); + if (cxx_record_decl) + { + cxx_record_decl->setBases(base_classes, num_base_classes); + return true; } - break; - case clang::Type::ObjCObjectPointer: return lldb::eFormatHex; - case clang::Type::BlockPointer: return lldb::eFormatHex; - case clang::Type::Pointer: return lldb::eFormatHex; - case clang::Type::LValueReference: - case clang::Type::RValueReference: return lldb::eFormatHex; - case clang::Type::MemberPointer: break; - case clang::Type::Complex: + } + return false; +} + +bool +ClangASTType::SetObjCSuperClass (const ClangASTType &superclass_clang_type) +{ + if (IsValid() && superclass_clang_type.IsValid()) + { + ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl (); + ObjCInterfaceDecl *super_interface_decl = superclass_clang_type.GetAsObjCInterfaceDecl (); + if (class_interface_decl && super_interface_decl) { - if (qual_type->isComplexType()) - return lldb::eFormatComplex; + class_interface_decl->setSuperClass(super_interface_decl); + return true; + } + } + return false; +} + +bool +ClangASTType::AddObjCClassProperty (const char *property_name, + const ClangASTType &property_clang_type, + ObjCIvarDecl *ivar_decl, + const char *property_setter_name, + const char *property_getter_name, + uint32_t property_attributes, + ClangASTMetadata *metadata) +{ + if (!IsValid() || !property_clang_type.IsValid() || property_name == NULL || property_name[0] == '\0') + return false; + + ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl (); + + if (class_interface_decl) + { + ClangASTType property_clang_type_to_access; + + if (property_clang_type.IsValid()) + property_clang_type_to_access = property_clang_type; + else if (ivar_decl) + property_clang_type_to_access = ClangASTType (m_ast, ivar_decl->getType()); + + if (class_interface_decl && property_clang_type_to_access.IsValid()) + { + clang::TypeSourceInfo *prop_type_source; + if (ivar_decl) + prop_type_source = m_ast->getTrivialTypeSourceInfo (ivar_decl->getType()); else - return lldb::eFormatComplexInteger; + prop_type_source = m_ast->getTrivialTypeSourceInfo (property_clang_type.GetQualType()); + + ObjCPropertyDecl *property_decl = ObjCPropertyDecl::Create (*m_ast, + class_interface_decl, + SourceLocation(), // Source Location + &m_ast->Idents.get(property_name), + SourceLocation(), //Source Location for AT + SourceLocation(), //Source location for ( + prop_type_source); + + if (property_decl) + { + if (metadata) + ClangASTContext::SetMetadata(m_ast, property_decl, *metadata); + + class_interface_decl->addDecl (property_decl); + + Selector setter_sel, getter_sel; + + if (property_setter_name != NULL) + { + std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1); + clang::IdentifierInfo *setter_ident = &m_ast->Idents.get(property_setter_no_colon.c_str()); + setter_sel = m_ast->Selectors.getSelector(1, &setter_ident); + } + else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) + { + std::string setter_sel_string("set"); + setter_sel_string.push_back(::toupper(property_name[0])); + setter_sel_string.append(&property_name[1]); + clang::IdentifierInfo *setter_ident = &m_ast->Idents.get(setter_sel_string.c_str()); + setter_sel = m_ast->Selectors.getSelector(1, &setter_ident); + } + property_decl->setSetterName(setter_sel); + property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter); + + if (property_getter_name != NULL) + { + clang::IdentifierInfo *getter_ident = &m_ast->Idents.get(property_getter_name); + getter_sel = m_ast->Selectors.getSelector(0, &getter_ident); + } + else + { + clang::IdentifierInfo *getter_ident = &m_ast->Idents.get(property_name); + getter_sel = m_ast->Selectors.getSelector(0, &getter_ident); + } + property_decl->setGetterName(getter_sel); + property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_getter); + + if (ivar_decl) + property_decl->setPropertyIvarDecl (ivar_decl); + + if (property_attributes & DW_APPLE_PROPERTY_readonly) + property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readonly); + if (property_attributes & DW_APPLE_PROPERTY_readwrite) + property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readwrite); + if (property_attributes & DW_APPLE_PROPERTY_assign) + property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_assign); + if (property_attributes & DW_APPLE_PROPERTY_retain) + property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_retain); + if (property_attributes & DW_APPLE_PROPERTY_copy) + property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_copy); + if (property_attributes & DW_APPLE_PROPERTY_nonatomic) + property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_nonatomic); + + if (!getter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(getter_sel)) + { + const bool isInstance = true; + const bool isVariadic = false; + const bool isSynthesized = false; + const bool isImplicitlyDeclared = true; + const bool isDefined = false; + const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None; + const bool HasRelatedResultType = false; + + ObjCMethodDecl *getter = ObjCMethodDecl::Create (*m_ast, + SourceLocation(), + SourceLocation(), + getter_sel, + property_clang_type_to_access.GetQualType(), + NULL, + class_interface_decl, + isInstance, + isVariadic, + isSynthesized, + isImplicitlyDeclared, + isDefined, + impControl, + HasRelatedResultType); + + if (getter && metadata) + ClangASTContext::SetMetadata(m_ast, getter, *metadata); + + getter->setMethodParams(*m_ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>()); + + class_interface_decl->addDecl(getter); + } + + if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel)) + { + QualType result_type = m_ast->VoidTy; + + const bool isInstance = true; + const bool isVariadic = false; + const bool isSynthesized = false; + const bool isImplicitlyDeclared = true; + const bool isDefined = false; + const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None; + const bool HasRelatedResultType = false; + + ObjCMethodDecl *setter = ObjCMethodDecl::Create (*m_ast, + SourceLocation(), + SourceLocation(), + setter_sel, + result_type, + NULL, + class_interface_decl, + isInstance, + isVariadic, + isSynthesized, + isImplicitlyDeclared, + isDefined, + impControl, + HasRelatedResultType); + + if (setter && metadata) + ClangASTContext::SetMetadata(m_ast, setter, *metadata); + + llvm::SmallVector<ParmVarDecl *, 1> params; + + params.push_back (ParmVarDecl::Create (*m_ast, + setter, + SourceLocation(), + SourceLocation(), + NULL, // anonymous + property_clang_type_to_access.GetQualType(), + NULL, + SC_Auto, + NULL)); + + setter->setMethodParams(*m_ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>()); + + class_interface_decl->addDecl(setter); + } + + return true; + } + } + } + return false; +} + +bool +ClangASTType::IsObjCClassTypeAndHasIVars (bool check_superclass) const +{ + ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl (); + if (class_interface_decl) + return ObjCDeclHasIVars (class_interface_decl, check_superclass); + return false; +} + + +ObjCMethodDecl * +ClangASTType::AddMethodToObjCObjectType (const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") + const ClangASTType &method_clang_type, + lldb::AccessType access, + bool is_artificial) +{ + if (!IsValid() || !method_clang_type.IsValid()) + return NULL; + + ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(); + + if (class_interface_decl == NULL) + return NULL; + + const char *selector_start = ::strchr (name, ' '); + if (selector_start == NULL) + return NULL; + + selector_start++; + llvm::SmallVector<IdentifierInfo *, 12> selector_idents; + + size_t len = 0; + const char *start; + //printf ("name = '%s'\n", name); + + unsigned num_selectors_with_args = 0; + for (start = selector_start; + start && *start != '\0' && *start != ']'; + start += len) + { + len = ::strcspn(start, ":]"); + bool has_arg = (start[len] == ':'); + if (has_arg) + ++num_selectors_with_args; + selector_idents.push_back (&m_ast->Idents.get (StringRef (start, len))); + if (has_arg) + len += 1; + } + + + if (selector_idents.size() == 0) + return 0; + + clang::Selector method_selector = m_ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, + selector_idents.data()); + + QualType method_qual_type (method_clang_type.GetQualType()); + + // Populate the method decl with parameter decls + const clang::Type *method_type(method_qual_type.getTypePtr()); + + if (method_type == NULL) + return NULL; + + const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type)); + + if (!method_function_prototype) + return NULL; + + + bool is_variadic = false; + bool is_synthesized = false; + bool is_defined = false; + ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None; + + const unsigned num_args = method_function_prototype->getNumArgs(); + + if (num_args != num_selectors_with_args) + return NULL; // some debug information is corrupt. We are not going to deal with it. + + ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*m_ast, + SourceLocation(), // beginLoc, + SourceLocation(), // endLoc, + method_selector, + method_function_prototype->getResultType(), + NULL, // TypeSourceInfo *ResultTInfo, + GetDeclContextForType (), + name[0] == '-', + is_variadic, + is_synthesized, + true, // is_implicitly_declared; we force this to true because we don't have source locations + is_defined, + imp_control, + false /*has_related_result_type*/); + + + if (objc_method_decl == NULL) + return NULL; + + if (num_args > 0) + { + llvm::SmallVector<ParmVarDecl *, 12> params; + + for (unsigned param_index = 0; param_index < num_args; ++param_index) + { + params.push_back (ParmVarDecl::Create (*m_ast, + objc_method_decl, + SourceLocation(), + SourceLocation(), + NULL, // anonymous + method_function_prototype->getArgType(param_index), + NULL, + SC_Auto, + NULL)); + } + + objc_method_decl->setMethodParams(*m_ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>()); + } + + class_interface_decl->addDecl (objc_method_decl); + +#ifdef LLDB_CONFIGURATION_DEBUG + VerifyDecl(objc_method_decl); +#endif + + return objc_method_decl; +} + + +clang::DeclContext * +ClangASTType::GetDeclContextForType () const +{ + if (!IsValid()) + return NULL; + + QualType qual_type(GetCanonicalQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::UnaryTransform: break; + case clang::Type::FunctionNoProto: break; + case clang::Type::FunctionProto: break; + case clang::Type::IncompleteArray: break; + case clang::Type::VariableArray: break; + case clang::Type::ConstantArray: break; + case clang::Type::DependentSizedArray: break; + case clang::Type::ExtVector: break; + case clang::Type::DependentSizedExtVector: break; + case clang::Type::Vector: break; + case clang::Type::Builtin: break; + case clang::Type::BlockPointer: break; + case clang::Type::Pointer: break; + case clang::Type::LValueReference: break; + case clang::Type::RValueReference: break; + case clang::Type::MemberPointer: break; + case clang::Type::Complex: break; + case clang::Type::ObjCObject: break; + case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface(); + case clang::Type::ObjCObjectPointer: return ClangASTType (m_ast, cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType()).GetDeclContextForType(); + case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl(); + case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl(); + case clang::Type::Typedef: return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDeclContextForType(); + case clang::Type::Elaborated: return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetDeclContextForType(); + case clang::Type::Paren: return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetDeclContextForType(); + case clang::Type::TypeOfExpr: break; + case clang::Type::TypeOf: break; + case clang::Type::Decltype: break; + //case clang::Type::QualifiedName: break; + case clang::Type::TemplateSpecialization: break; + case clang::Type::DependentTemplateSpecialization: break; + case clang::Type::TemplateTypeParm: break; + case clang::Type::SubstTemplateTypeParm: break; + case clang::Type::SubstTemplateTypeParmPack:break; + case clang::Type::PackExpansion: break; + case clang::Type::UnresolvedUsing: break; + case clang::Type::Attributed: break; + case clang::Type::Auto: break; + case clang::Type::InjectedClassName: break; + case clang::Type::DependentName: break; + case clang::Type::Atomic: break; + } + // No DeclContext in this type... + return NULL; +} + +bool +ClangASTType::SetDefaultAccessForRecordFields (int default_accessibility, + int *assigned_accessibilities, + size_t num_assigned_accessibilities) +{ + if (IsValid()) + { + RecordDecl *record_decl = GetAsRecordDecl(); + if (record_decl) + { + uint32_t field_idx; + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0; + field != field_end; + ++field, ++field_idx) + { + // If no accessibility was assigned, assign the correct one + if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none) + field->setAccess ((AccessSpecifier)default_accessibility); + } + return true; + } + } + return false; +} + + +bool +ClangASTType::SetHasExternalStorage (bool has_extern) +{ + if (!IsValid()) + return false; + + QualType qual_type (GetCanonicalQualType()); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + { + CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + cxx_record_decl->setHasExternalLexicalStorage (has_extern); + cxx_record_decl->setHasExternalVisibleStorage (has_extern); + return true; + } + } + break; + + case clang::Type::Enum: + { + EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl(); + if (enum_decl) + { + enum_decl->setHasExternalLexicalStorage (has_extern); + enum_decl->setHasExternalVisibleStorage (has_extern); + return true; + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + class_interface_decl->setHasExternalLexicalStorage (has_extern); + class_interface_decl->setHasExternalVisibleStorage (has_extern); + return true; + } + } } - case clang::Type::ObjCInterface: break; - case clang::Type::Record: break; - case clang::Type::Enum: return lldb::eFormatEnum; - case clang::Type::Typedef: - return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Auto: - return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr()); - case clang::Type::Paren: - return ClangASTType::GetFormat(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - case clang::Type::Elaborated: - return ClangASTType::GetFormat(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::DependentSizedArray: - case clang::Type::DependentSizedExtVector: - case clang::Type::UnresolvedUsing: - case clang::Type::Attributed: - case clang::Type::TemplateTypeParm: - case clang::Type::SubstTemplateTypeParm: - case clang::Type::SubstTemplateTypeParmPack: - case clang::Type::InjectedClassName: - case clang::Type::DependentName: - case clang::Type::DependentTemplateSpecialization: - case clang::Type::PackExpansion: - case clang::Type::ObjCObject: - - case clang::Type::TypeOfExpr: - case clang::Type::TypeOf: - case clang::Type::Decltype: - case clang::Type::TemplateSpecialization: - case clang::Type::Atomic: + break; + + case clang::Type::Typedef: + return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).SetHasExternalStorage (has_extern); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).SetHasExternalStorage (has_extern); + + case clang::Type::Paren: + return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).SetHasExternalStorage (has_extern); + + default: break; } - // We don't know hot to display this type... - return lldb::eFormatBytes; + return false; } +bool +ClangASTType::SetTagTypeKind (int kind) const +{ + if (IsValid()) + { + QualType tag_qual_type(GetQualType()); + const clang::Type *clang_type = tag_qual_type.getTypePtr(); + if (clang_type) + { + const TagType *tag_type = dyn_cast<TagType>(clang_type); + if (tag_type) + { + TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl()); + if (tag_decl) + { + tag_decl->setTagKind ((TagDecl::TagKind)kind); + return true; + } + } + } + } + return false; +} -void -ClangASTType::DumpValue -( - ExecutionContext *exe_ctx, - Stream *s, - lldb::Format format, - const lldb_private::DataExtractor &data, - lldb::offset_t data_byte_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 -) -{ - return DumpValue (m_ast, - m_type, - exe_ctx, - s, - format, - data, - data_byte_offset, - data_byte_size, - bitfield_bit_size, - bitfield_bit_offset, - show_types, - show_summary, - verbose, - depth); -} - + +#pragma mark TagDecl + +bool +ClangASTType::StartTagDeclarationDefinition () +{ + if (IsValid()) + { + QualType qual_type (GetQualType()); + const clang::Type *t = qual_type.getTypePtr(); + if (t) + { + const TagType *tag_type = dyn_cast<TagType>(t); + if (tag_type) + { + TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) + { + tag_decl->startDefinition(); + return true; + } + } + + const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(t); + if (object_type) + { + ObjCInterfaceDecl *interface_decl = object_type->getInterface(); + if (interface_decl) + { + interface_decl->startDefinition(); + return true; + } + } + } + } + return false; +} + +bool +ClangASTType::CompleteTagDeclarationDefinition () +{ + if (IsValid()) + { + QualType qual_type (GetQualType()); + + CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + + if (cxx_record_decl) + { + cxx_record_decl->completeDefinition(); + + return true; + } + + const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr()); + + if (enum_type) + { + EnumDecl *enum_decl = enum_type->getDecl(); + + if (enum_decl) + { + /// TODO This really needs to be fixed. + + unsigned NumPositiveBits = 1; + unsigned NumNegativeBits = 0; + + QualType promotion_qual_type; + // If the enum integer type is less than an integer in bit width, + // then we must promote it to an integer size. + if (m_ast->getTypeSize(enum_decl->getIntegerType()) < m_ast->getTypeSize(m_ast->IntTy)) + { + if (enum_decl->getIntegerType()->isSignedIntegerType()) + promotion_qual_type = m_ast->IntTy; + else + promotion_qual_type = m_ast->UnsignedIntTy; + } + else + promotion_qual_type = enum_decl->getIntegerType(); + + enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); + return true; + } + } + } + return false; +} + + + + + + + +bool +ClangASTType::AddEnumerationValueToEnumerationType (const ClangASTType &enumerator_clang_type, + const Declaration &decl, + const char *name, + int64_t enum_value, + uint32_t enum_value_bit_size) +{ + if (IsValid() && enumerator_clang_type.IsValid() && name && name[0]) + { + QualType enum_qual_type (GetCanonicalQualType()); + + bool is_signed = false; + enumerator_clang_type.IsIntegerType (is_signed); + const clang::Type *clang_type = enum_qual_type.getTypePtr(); + if (clang_type) + { + const EnumType *enum_type = dyn_cast<EnumType>(clang_type); + + if (enum_type) + { + llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed); + enum_llvm_apsint = enum_value; + EnumConstantDecl *enumerator_decl = + EnumConstantDecl::Create (*m_ast, + enum_type->getDecl(), + SourceLocation(), + name ? &m_ast->Idents.get(name) : NULL, // Identifier + enumerator_clang_type.GetQualType(), + NULL, + enum_llvm_apsint); + + if (enumerator_decl) + { + enum_type->getDecl()->addDecl(enumerator_decl); + +#ifdef LLDB_CONFIGURATION_DEBUG + VerifyDecl(enumerator_decl); +#endif + + return true; + } + } + } + } + return false; +} + + +ClangASTType +ClangASTType::GetEnumerationIntegerType () const +{ + QualType enum_qual_type (GetCanonicalQualType()); + const clang::Type *clang_type = enum_qual_type.getTypePtr(); + if (clang_type) + { + const EnumType *enum_type = dyn_cast<EnumType>(clang_type); + if (enum_type) + { + EnumDecl *enum_decl = enum_type->getDecl(); + if (enum_decl) + return ClangASTType (m_ast, enum_decl->getIntegerType()); + } + } + return ClangASTType(); +} + +ClangASTType +ClangASTType::CreateMemberPointerType (const ClangASTType &pointee_type) const +{ + if (IsValid() && pointee_type.IsValid()) + { + return ClangASTType (m_ast, m_ast->getMemberPointerType (pointee_type.GetQualType(), + GetQualType().getTypePtr())); + } + return ClangASTType(); +} + + +size_t +ClangASTType::ConvertStringToFloatValue (const char *s, uint8_t *dst, size_t dst_size) const +{ + if (IsValid()) + { + QualType qual_type (GetCanonicalQualType()); + uint32_t count = 0; + bool is_complex = false; + if (IsFloatingPointType (count, is_complex)) + { + // TODO: handle complex and vector types + if (count != 1) + return false; + + StringRef s_sref(s); + APFloat ap_float(m_ast->getFloatTypeSemantics(qual_type), s_sref); + + const uint64_t bit_size = m_ast->getTypeSize (qual_type); + const uint64_t byte_size = bit_size / 8; + if (dst_size >= byte_size) + { + if (bit_size == sizeof(float)*8) + { + float float32 = ap_float.convertToFloat(); + ::memcpy (dst, &float32, byte_size); + return byte_size; + } + else if (bit_size >= 64) + { + llvm::APInt ap_int(ap_float.bitcastToAPInt()); + ::memcpy (dst, ap_int.getRawData(), byte_size); + return byte_size; + } + } + } + } + return 0; +} + + + +//---------------------------------------------------------------------- +// Dumping types +//---------------------------------------------------------------------- #define DEPTH_INCREMENT 2 + void -ClangASTType::DumpValue -( - clang::ASTContext *ast_context, - clang_type_t clang_type, - ExecutionContext *exe_ctx, - Stream *s, - lldb::Format format, - const lldb_private::DataExtractor &data, - lldb::offset_t data_byte_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 -) -{ - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); +ClangASTType::DumpValue (ExecutionContext *exe_ctx, + Stream *s, + lldb::Format format, + const lldb_private::DataExtractor &data, + lldb::offset_t data_byte_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) +{ + if (!IsValid()) + return; + + QualType qual_type(GetQualType()); switch (qual_type->getTypeClass()) { case clang::Type::Record: - if (ClangASTContext::GetCompleteType (ast_context, clang_type)) + if (GetCompleteType ()) { - const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr()); - const clang::RecordDecl *record_decl = record_type->getDecl(); + const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); assert(record_decl); uint32_t field_bit_offset = 0; uint32_t field_byte_offset = 0; - const clang::ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl); + const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl); uint32_t child_idx = 0; - - const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); + const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); if (cxx_record_decl) { // We might have base classes to print out first - clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); base_class != base_class_end; ++base_class) { - const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl()); + const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); // Skip empty base classes if (verbose == false && ClangASTContext::RecordHasFields(base_class_decl) == false) @@ -786,35 +5561,34 @@ ClangASTType::DumpValue else s->PutChar(','); - clang::QualType base_class_qual_type = base_class->getType(); + QualType base_class_qual_type = base_class->getType(); std::string base_class_type_name(base_class_qual_type.getAsString()); // Indent and print the base class type name s->Printf("\n%*s%s ", depth + DEPTH_INCREMENT, "", base_class_type_name.c_str()); - std::pair<uint64_t, unsigned> base_class_type_info = ast_context->getTypeInfo(base_class_qual_type); + std::pair<uint64_t, unsigned> base_class_type_info = m_ast->getTypeInfo(base_class_qual_type); // Dump the value of the member - DumpValue (ast_context, // The clang AST context for this type - base_class_qual_type.getAsOpaquePtr(),// The clang type we want to dump - exe_ctx, - s, // Stream to dump to - ClangASTType::GetFormat(base_class_qual_type.getAsOpaquePtr()), // The format with which to display the member - data, // Data buffer containing all bytes for this type - data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from - base_class_type_info.first / 8, // Size of this type in bytes - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, // Boolean indicating if we should show the variable types - show_summary, // Boolean indicating if we should show a summary for the current type - verbose, // Verbose output? - depth + DEPTH_INCREMENT); // Scope depth for any types that have children + ClangASTType base_clang_type(m_ast, base_class_qual_type); + base_clang_type.DumpValue (exe_ctx, + s, // Stream to dump to + base_clang_type.GetFormat(), // The format with which to display the member + data, // Data buffer containing all bytes for this type + data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from + base_class_type_info.first / 8, // Size of this type in bytes + 0, // Bitfield bit size + 0, // Bitfield bit offset + show_types, // Boolean indicating if we should show the variable types + show_summary, // Boolean indicating if we should show a summary for the current type + verbose, // Verbose output? + depth + DEPTH_INCREMENT); // Scope depth for any types that have children ++child_idx; } } uint32_t field_idx = 0; - clang::RecordDecl::field_iterator field, field_end; + RecordDecl::field_iterator field, field_end; for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx) { // Print the starting squiggly bracket (if this is the @@ -828,18 +5602,18 @@ ClangASTType::DumpValue // Indent s->Printf("\n%*s", depth + DEPTH_INCREMENT, ""); - clang::QualType field_type = field->getType(); + QualType field_type = field->getType(); // Print the member type if requested // Figure out the type byte size (field_type_info.first) and // alignment (field_type_info.second) from the AST context. - std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field_type); + std::pair<uint64_t, unsigned> field_type_info = m_ast->getTypeInfo(field_type); assert(field_idx < record_layout.getFieldCount()); // Figure out the field offset within the current struct/union/class type field_bit_offset = record_layout.getFieldOffset (field_idx); field_byte_offset = field_bit_offset / 8; uint32_t field_bitfield_bit_size = 0; uint32_t field_bitfield_bit_offset = 0; - if (ClangASTContext::FieldIsBitfield (ast_context, *field, field_bitfield_bit_size)) + if (ClangASTContext::FieldIsBitfield (m_ast, *field, field_bitfield_bit_size)) field_bitfield_bit_offset = field_bit_offset % 8; if (show_types) @@ -855,20 +5629,19 @@ ClangASTType::DumpValue // Dump the value of the member - DumpValue (ast_context, // The clang AST context for this type - field_type.getAsOpaquePtr(), // The clang type we want to dump - exe_ctx, - s, // Stream to dump to - ClangASTType::GetFormat(field_type.getAsOpaquePtr()), // The format with which to display the member - data, // Data buffer containing all bytes for this type - data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from - field_type_info.first / 8, // Size of this type in bytes - field_bitfield_bit_size, // Bitfield bit size - field_bitfield_bit_offset, // Bitfield bit offset - show_types, // Boolean indicating if we should show the variable types - show_summary, // Boolean indicating if we should show a summary for the current type - verbose, // Verbose output? - depth + DEPTH_INCREMENT); // Scope depth for any types that have children + ClangASTType field_clang_type (m_ast, field_type); + field_clang_type.DumpValue (exe_ctx, + s, // Stream to dump to + field_clang_type.GetFormat(), // The format with which to display the member + data, // Data buffer containing all bytes for this type + data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from + field_type_info.first / 8, // Size of this type in bytes + field_bitfield_bit_size, // Bitfield bit size + field_bitfield_bit_offset, // Bitfield bit offset + show_types, // Boolean indicating if we should show the variable types + show_summary, // Boolean indicating if we should show a summary for the current type + verbose, // Verbose output? + depth + DEPTH_INCREMENT); // Scope depth for any types that have children } // Indent the trailing squiggly bracket @@ -878,12 +5651,12 @@ ClangASTType::DumpValue return; case clang::Type::Enum: - if (ClangASTContext::GetCompleteType (ast_context, clang_type)) + if (GetCompleteType ()) { - const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr()); - const clang::EnumDecl *enum_decl = enum_type->getDecl(); + const EnumType *enum_type = cast<EnumType>(qual_type.getTypePtr()); + const EnumDecl *enum_decl = enum_type->getDecl(); assert(enum_decl); - clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; + EnumDecl::enumerator_iterator enum_pos, enum_end_pos; lldb::offset_t offset = data_byte_offset; const int64_t enum_value = data.GetMaxU64Bitfield(&offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset); for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos) @@ -902,9 +5675,9 @@ ClangASTType::DumpValue case clang::Type::ConstantArray: { - const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr()); + const ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr()); bool is_array_of_characters = false; - clang::QualType element_qual_type = array->getElementType(); + QualType element_qual_type = array->getElementType(); const clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr(); if (canonical_type) @@ -912,7 +5685,7 @@ ClangASTType::DumpValue const uint64_t element_count = array->getSize().getLimitedValue(); - std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(element_qual_type); + std::pair<uint64_t, unsigned> field_type_info = m_ast->getTypeInfo(element_qual_type); uint32_t element_idx = 0; uint32_t element_offset = 0; @@ -928,7 +5701,8 @@ ClangASTType::DumpValue } else { - lldb::Format element_format = ClangASTType::GetFormat(element_qual_type.getAsOpaquePtr()); + ClangASTType element_clang_type(m_ast, element_qual_type); + lldb::Format element_format = element_clang_type.GetFormat(); for (element_idx = 0; element_idx < element_count; ++element_idx) { @@ -947,20 +5721,18 @@ ClangASTType::DumpValue element_offset = element_idx * element_stride; // Dump the value of the member - DumpValue (ast_context, // The clang AST context for this type - element_qual_type.getAsOpaquePtr(), // The clang type we want to dump - exe_ctx, - s, // Stream to dump to - element_format, // The format with which to display the element - data, // Data buffer containing all bytes for this type - data_byte_offset + element_offset,// Offset into "data" where to grab value from - element_byte_size, // Size of this type in bytes - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, // Boolean indicating if we should show the variable types - show_summary, // Boolean indicating if we should show a summary for the current type - verbose, // Verbose output? - depth + DEPTH_INCREMENT); // Scope depth for any types that have children + element_clang_type.DumpValue (exe_ctx, + s, // Stream to dump to + element_format, // The format with which to display the element + data, // Data buffer containing all bytes for this type + data_byte_offset + element_offset,// Offset into "data" where to grab value from + element_byte_size, // Size of this type in bytes + 0, // Bitfield bit size + 0, // Bitfield bit offset + show_types, // Boolean indicating if we should show the variable types + show_summary, // Boolean indicating if we should show a summary for the current type + verbose, // Verbose output? + depth + DEPTH_INCREMENT); // Scope depth for any types that have children } // Indent the trailing squiggly bracket @@ -972,115 +5744,98 @@ ClangASTType::DumpValue case clang::Type::Typedef: { - clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType(); - lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr()); - std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type); + QualType typedef_qual_type = cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(); + + ClangASTType typedef_clang_type (m_ast, typedef_qual_type); + lldb::Format typedef_format = typedef_clang_type.GetFormat(); + std::pair<uint64_t, unsigned> typedef_type_info = m_ast->getTypeInfo(typedef_qual_type); uint64_t typedef_byte_size = typedef_type_info.first / 8; - return DumpValue (ast_context, // The clang AST context for this type - typedef_qual_type.getAsOpaquePtr(), // The clang type we want to dump - exe_ctx, - s, // Stream to dump to - typedef_format, // The format with which to display the element - data, // Data buffer containing all bytes for this type - data_byte_offset, // Offset into "data" where to grab value from - typedef_byte_size, // Size of this type in bytes - bitfield_bit_size, // Bitfield bit size - bitfield_bit_offset,// Bitfield bit offset - show_types, // Boolean indicating if we should show the variable types - show_summary, // Boolean indicating if we should show a summary for the current type - verbose, // Verbose output? - depth); // Scope depth for any types that have children + return typedef_clang_type.DumpValue (exe_ctx, + s, // Stream to dump to + typedef_format, // The format with which to display the element + data, // Data buffer containing all bytes for this type + data_byte_offset, // Offset into "data" where to grab value from + typedef_byte_size, // Size of this type in bytes + bitfield_bit_size, // Bitfield bit size + bitfield_bit_offset,// Bitfield bit offset + show_types, // Boolean indicating if we should show the variable types + show_summary, // Boolean indicating if we should show a summary for the current type + verbose, // Verbose output? + depth); // Scope depth for any types that have children } break; case clang::Type::Elaborated: { - clang::QualType elaborated_qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(); - lldb::Format elaborated_format = ClangASTType::GetFormat(elaborated_qual_type.getAsOpaquePtr()); - std::pair<uint64_t, unsigned> elaborated_type_info = ast_context->getTypeInfo(elaborated_qual_type); + QualType elaborated_qual_type = cast<ElaboratedType>(qual_type)->getNamedType(); + ClangASTType elaborated_clang_type (m_ast, elaborated_qual_type); + lldb::Format elaborated_format = elaborated_clang_type.GetFormat(); + std::pair<uint64_t, unsigned> elaborated_type_info = m_ast->getTypeInfo(elaborated_qual_type); uint64_t elaborated_byte_size = elaborated_type_info.first / 8; - return DumpValue (ast_context, // The clang AST context for this type - elaborated_qual_type.getAsOpaquePtr(), // The clang type we want to dump - exe_ctx, - s, // Stream to dump to - elaborated_format, // The format with which to display the element - data, // Data buffer containing all bytes for this type - data_byte_offset, // Offset into "data" where to grab value from - elaborated_byte_size, // Size of this type in bytes - bitfield_bit_size, // Bitfield bit size - bitfield_bit_offset,// Bitfield bit offset - show_types, // Boolean indicating if we should show the variable types - show_summary, // Boolean indicating if we should show a summary for the current type - verbose, // Verbose output? - depth); // Scope depth for any types that have children + return elaborated_clang_type.DumpValue (exe_ctx, + s, // Stream to dump to + elaborated_format, // The format with which to display the element + data, // Data buffer containing all bytes for this type + data_byte_offset, // Offset into "data" where to grab value from + elaborated_byte_size, // Size of this type in bytes + bitfield_bit_size, // Bitfield bit size + bitfield_bit_offset,// Bitfield bit offset + show_types, // Boolean indicating if we should show the variable types + show_summary, // Boolean indicating if we should show a summary for the current type + verbose, // Verbose output? + depth); // Scope depth for any types that have children } break; case clang::Type::Paren: - { - clang::QualType desugar_qual_type = llvm::cast<clang::ParenType>(qual_type)->desugar(); - lldb::Format desugar_format = ClangASTType::GetFormat(desugar_qual_type.getAsOpaquePtr()); - std::pair<uint64_t, unsigned> desugar_type_info = ast_context->getTypeInfo(desugar_qual_type); - uint64_t desugar_byte_size = desugar_type_info.first / 8; - - return DumpValue (ast_context, // The clang AST context for this type - desugar_qual_type.getAsOpaquePtr(), // The clang type we want to dump - exe_ctx, - s, // Stream to dump to - desugar_format, // The format with which to display the element - data, // Data buffer containing all bytes for this type - data_byte_offset, // Offset into "data" where to grab value from - desugar_byte_size, // Size of this type in bytes - bitfield_bit_size, // Bitfield bit size - bitfield_bit_offset,// Bitfield bit offset - show_types, // Boolean indicating if we should show the variable types - show_summary, // Boolean indicating if we should show a summary for the current type - verbose, // Verbose output? - depth); // Scope depth for any types that have children - } + { + QualType desugar_qual_type = cast<ParenType>(qual_type)->desugar(); + ClangASTType desugar_clang_type (m_ast, desugar_qual_type); + + lldb::Format desugar_format = desugar_clang_type.GetFormat(); + std::pair<uint64_t, unsigned> desugar_type_info = m_ast->getTypeInfo(desugar_qual_type); + uint64_t desugar_byte_size = desugar_type_info.first / 8; + + return desugar_clang_type.DumpValue (exe_ctx, + s, // Stream to dump to + desugar_format, // The format with which to display the element + data, // Data buffer containing all bytes for this type + data_byte_offset, // Offset into "data" where to grab value from + desugar_byte_size, // Size of this type in bytes + bitfield_bit_size, // Bitfield bit size + bitfield_bit_offset,// Bitfield bit offset + show_types, // Boolean indicating if we should show the variable types + show_summary, // Boolean indicating if we should show a summary for the current type + verbose, // Verbose output? + depth); // Scope depth for any types that have children + } break; default: // We are down the a scalar type that we just need to display. - data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset); + data.Dump(s, + data_byte_offset, + format, + data_byte_size, + 1, + UINT32_MAX, + LLDB_INVALID_ADDRESS, + bitfield_bit_size, + bitfield_bit_offset); if (show_summary) - DumpSummary (ast_context, clang_type, exe_ctx, s, data, data_byte_offset, data_byte_size); + DumpSummary (exe_ctx, s, data, data_byte_offset, data_byte_size); break; } } -bool -ClangASTType::DumpTypeValue (Stream *s, - lldb::Format format, - const lldb_private::DataExtractor &data, - lldb::offset_t byte_offset, - size_t byte_size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope) -{ - return DumpTypeValue (m_ast, - m_type, - s, - format, - data, - byte_offset, - byte_size, - bitfield_bit_size, - bitfield_bit_offset, - exe_scope); -} - bool -ClangASTType::DumpTypeValue (clang::ASTContext *ast_context, - clang_type_t clang_type, - Stream *s, +ClangASTType::DumpTypeValue (Stream *s, lldb::Format format, const lldb_private::DataExtractor &data, lldb::offset_t byte_offset, @@ -1089,47 +5844,48 @@ ClangASTType::DumpTypeValue (clang::ASTContext *ast_context, uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - if (ClangASTContext::IsAggregateType (clang_type)) + if (!IsValid()) + return false; + if (IsAggregateType()) { - return 0; + return false; } else { + QualType qual_type(GetQualType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) { case clang::Type::Typedef: { - clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType(); + QualType typedef_qual_type = cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(); + ClangASTType typedef_clang_type (m_ast, typedef_qual_type); if (format == eFormatDefault) - format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr()); - std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type); + format = typedef_clang_type.GetFormat(); + std::pair<uint64_t, unsigned> typedef_type_info = m_ast->getTypeInfo(typedef_qual_type); uint64_t typedef_byte_size = typedef_type_info.first / 8; - return ClangASTType::DumpTypeValue (ast_context, // The clang AST context for this type - typedef_qual_type.getAsOpaquePtr(), // The clang type we want to dump - s, - format, // The format with which to display the element - data, // Data buffer containing all bytes for this type - byte_offset, // Offset into "data" where to grab value from - typedef_byte_size, // Size of this type in bytes - bitfield_bit_size, // Size in bits of a bitfield value, if zero don't treat as a bitfield - bitfield_bit_offset, // Offset in bits of a bitfield value if bitfield_bit_size != 0 - exe_scope); + return typedef_clang_type.DumpTypeValue (s, + format, // The format with which to display the element + data, // Data buffer containing all bytes for this type + byte_offset, // Offset into "data" where to grab value from + typedef_byte_size, // Size of this type in bytes + bitfield_bit_size, // Size in bits of a bitfield value, if zero don't treat as a bitfield + bitfield_bit_offset, // Offset in bits of a bitfield value if bitfield_bit_size != 0 + exe_scope); } break; case clang::Type::Enum: // If our format is enum or default, show the enumeration value as // its enumeration string value, else just display it as requested. - if ((format == eFormatEnum || format == eFormatDefault) && ClangASTContext::GetCompleteType (ast_context, clang_type)) + if ((format == eFormatEnum || format == eFormatDefault) && GetCompleteType ()) { - const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr()); - const clang::EnumDecl *enum_decl = enum_type->getDecl(); + const EnumType *enum_type = cast<EnumType>(qual_type.getTypePtr()); + const EnumDecl *enum_decl = enum_type->getDecl(); assert(enum_decl); - clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; + EnumDecl::enumerator_iterator enum_pos, enum_end_pos; const bool is_signed = qual_type->isSignedIntegerOrEnumerationType(); lldb::offset_t offset = byte_offset; if (is_signed) @@ -1241,38 +5997,14 @@ ClangASTType::DumpTypeValue (clang::ASTContext *ast_context, void -ClangASTType::DumpSummary -( - ExecutionContext *exe_ctx, - Stream *s, - const lldb_private::DataExtractor &data, - lldb::offset_t data_byte_offset, - size_t data_byte_size -) -{ - return DumpSummary (m_ast, - m_type, - exe_ctx, - s, - data, - data_byte_offset, - data_byte_size); -} - -void -ClangASTType::DumpSummary -( - clang::ASTContext *ast_context, - clang_type_t clang_type, - ExecutionContext *exe_ctx, - Stream *s, - const lldb_private::DataExtractor &data, - lldb::offset_t data_byte_offset, - size_t data_byte_size -) +ClangASTType::DumpSummary (ExecutionContext *exe_ctx, + Stream *s, + const lldb_private::DataExtractor &data, + lldb::offset_t data_byte_offset, + size_t data_byte_size) { uint32_t length = 0; - if (ClangASTContext::IsCStringType (clang_type, length)) + if (IsCStringType (length)) { if (exe_ctx) { @@ -1312,104 +6044,8 @@ ClangASTType::DumpSummary } } -uint64_t -ClangASTType::GetClangTypeByteSize () -{ - return (GetClangTypeBitWidth (m_ast, m_type) + 7) / 8; -} - -uint64_t -ClangASTType::GetClangTypeByteSize (clang::ASTContext *ast_context, clang_type_t clang_type) -{ - return (GetClangTypeBitWidth (ast_context, clang_type) + 7) / 8; -} - -uint64_t -ClangASTType::GetClangTypeBitWidth () -{ - return GetClangTypeBitWidth (m_ast, m_type); -} - -uint64_t -ClangASTType::GetClangTypeBitWidth (clang::ASTContext *ast_context, clang_type_t clang_type) -{ - if (ClangASTContext::GetCompleteType (ast_context, clang_type)) - { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - const uint32_t bit_size = ast_context->getTypeSize (qual_type); - if (bit_size == 0) - { - if (qual_type->isIncompleteArrayType()) - return ast_context->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified()); - } - return bit_size; - } - return 0; -} - -size_t -ClangASTType::GetTypeBitAlign () -{ - return GetTypeBitAlign (m_ast, m_type); -} - -size_t -ClangASTType::GetTypeBitAlign (clang::ASTContext *ast_context, clang_type_t clang_type) -{ - if (ClangASTContext::GetCompleteType (ast_context, clang_type)) - return ast_context->getTypeAlign(clang::QualType::getFromOpaquePtr(clang_type)); - return 0; -} - - -bool -ClangASTType::IsDefined() -{ - return ClangASTType::IsDefined (m_type); -} - -bool -ClangASTType::IsDefined (clang_type_t clang_type) -{ - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()); - if (tag_type) - { - clang::TagDecl *tag_decl = tag_type->getDecl(); - if (tag_decl) - return tag_decl->isCompleteDefinition(); - return false; - } - else - { - const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); - if (objc_class_type) - { - clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - if (class_interface_decl) - return class_interface_decl->getDefinition() != NULL; - return false; - } - } - return true; -} - -bool -ClangASTType::IsConst() -{ - return ClangASTType::IsConst (m_type); -} - -bool -ClangASTType::IsConst (lldb::clang_type_t clang_type) -{ - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - - return qual_type.isConstQualified(); -} - void -ClangASTType::DumpTypeDescription () +ClangASTType::DumpTypeDescription () const { StreamFile s (stdout, false); DumpTypeDescription (&s); @@ -1421,22 +6057,14 @@ ClangASTType::DumpTypeDescription () } void -ClangASTType::DumpTypeDescription (Stream *s) +ClangASTType::DumpTypeDescription (Stream *s) const { - return DumpTypeDescription (m_ast, m_type, s); -} - -// Dump the full description of a type. For classes this means all of the -// ivars and member functions, for structs/unions all of the members. -void -ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, clang_type_t clang_type, Stream *s) -{ - if (clang_type) + if (IsValid()) { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); + QualType qual_type(GetQualType()); - llvm::SmallVector<char, 1024> buf; - llvm::raw_svector_ostream llvm_ostrm (buf); + SmallVector<char, 1024> buf; + raw_svector_ostream llvm_ostrm (buf); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) @@ -1444,16 +6072,16 @@ ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, clang_type_t case clang::Type::ObjCObject: case clang::Type::ObjCInterface: { - ClangASTContext::GetCompleteType (ast_context, clang_type); + GetCompleteType (); - const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); assert (objc_class_type); if (objc_class_type) { - clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); if (class_interface_decl) { - clang::PrintingPolicy policy = ast_context->getPrintingPolicy(); + PrintingPolicy policy = m_ast->getPrintingPolicy(); class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel()); } } @@ -1462,10 +6090,10 @@ ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, clang_type_t case clang::Type::Typedef: { - const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>(); + const TypedefType *typedef_type = qual_type->getAs<TypedefType>(); if (typedef_type) { - const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); + const TypedefNameDecl *typedef_decl = typedef_type->getDecl(); std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString()); if (!clang_typedef_name.empty()) { @@ -1477,38 +6105,34 @@ ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, clang_type_t break; case clang::Type::Elaborated: - DumpTypeDescription (ast_context, - llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - s); + ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).DumpTypeDescription(s); return; case clang::Type::Paren: - DumpTypeDescription (ast_context, - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - s); + ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).DumpTypeDescription(s); return; case clang::Type::Record: { - ClangASTContext::GetCompleteType (ast_context, clang_type); + GetCompleteType (); - const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr()); - const clang::RecordDecl *record_decl = record_type->getDecl(); - const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); + const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); + const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); if (cxx_record_decl) - cxx_record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel()); + cxx_record_decl->print(llvm_ostrm, m_ast->getPrintingPolicy(), s->GetIndentLevel()); else - record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel()); + record_decl->print(llvm_ostrm, m_ast->getPrintingPolicy(), s->GetIndentLevel()); } break; default: { - const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()); + const TagType *tag_type = dyn_cast<TagType>(qual_type.getTypePtr()); if (tag_type) { - clang::TagDecl *tag_decl = tag_type->getDecl(); + TagDecl *tag_decl = tag_type->getDecl(); if (tag_decl) tag_decl->print(llvm_ostrm, 0); } @@ -1530,49 +6154,27 @@ ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, clang_type_t } bool -ClangASTType::GetValueAsScalar -( - const lldb_private::DataExtractor &data, - lldb::offset_t data_byte_offset, - size_t data_byte_size, - Scalar &value -) -{ - return GetValueAsScalar (m_ast, - m_type, - data, - data_byte_offset, - data_byte_size, - value); -} - -bool -ClangASTType::GetValueAsScalar -( - clang::ASTContext *ast_context, - clang_type_t clang_type, - const lldb_private::DataExtractor &data, - lldb::offset_t data_byte_offset, - size_t data_byte_size, - Scalar &value -) +ClangASTType::GetValueAsScalar (const lldb_private::DataExtractor &data, + lldb::offset_t data_byte_offset, + size_t data_byte_size, + Scalar &value) const { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); + if (!IsValid()) + return false; - if (ClangASTContext::IsAggregateType (clang_type)) + if (IsAggregateType ()) { return false; // Aggregate types don't have scalar values } else { uint64_t count = 0; - lldb::Encoding encoding = GetEncoding (clang_type, count); + lldb::Encoding encoding = GetEncoding (count); if (encoding == lldb::eEncodingInvalid || count != 1) return false; - uint64_t bit_width = ast_context->getTypeSize(qual_type); - uint64_t byte_size = (bit_width + 7 ) / 8; + const uint64_t byte_size = GetByteSize(); lldb::offset_t offset = data_byte_offset; switch (encoding) { @@ -1690,31 +6292,17 @@ ClangASTType::GetValueAsScalar bool ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm) { - return SetValueFromScalar (m_ast, m_type, value, strm); -} - -bool -ClangASTType::SetValueFromScalar -( - clang::ASTContext *ast_context, - clang_type_t clang_type, - const Scalar &value, - Stream &strm -) -{ - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - // Aggregate types don't have scalar values - if (!ClangASTContext::IsAggregateType (clang_type)) + if (!IsAggregateType ()) { strm.GetFlags().Set(Stream::eBinary); uint64_t count = 0; - lldb::Encoding encoding = GetEncoding (clang_type, count); + lldb::Encoding encoding = GetEncoding (count); if (encoding == lldb::eEncodingInvalid || count != 1) return false; - const uint64_t bit_width = ast_context->getTypeSize(qual_type); + const uint64_t bit_width = GetBitSize(); // This function doesn't currently handle non-byte aligned assignments if ((bit_width % 8) != 0) return false; @@ -1783,66 +6371,24 @@ ClangASTType::ReadFromMemory (lldb_private::ExecutionContext *exe_ctx, AddressType address_type, lldb_private::DataExtractor &data) { - return ReadFromMemory (m_ast, - m_type, - exe_ctx, - addr, - address_type, - data); -} - -uint64_t -ClangASTType::GetTypeByteSize() const -{ - return GetTypeByteSize (m_ast, m_type); -} - -uint64_t -ClangASTType::GetTypeByteSize(clang::ASTContext *ast_context, lldb::clang_type_t opaque_clang_qual_type) -{ - - if (ClangASTContext::GetCompleteType (ast_context, opaque_clang_qual_type)) - { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)); - - uint64_t byte_size = (ast_context->getTypeSize (qual_type) + (uint64_t)7) / (uint64_t)8; - - if (ClangASTContext::IsObjCClassType(opaque_clang_qual_type)) - byte_size += ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / 8; // isa - - return byte_size; - } - return 0; -} - + if (!IsValid()) + return false; -bool -ClangASTType::ReadFromMemory (clang::ASTContext *ast_context, - clang_type_t clang_type, - lldb_private::ExecutionContext *exe_ctx, - lldb::addr_t addr, - AddressType address_type, - lldb_private::DataExtractor &data) -{ + // Can't convert a file address to anything valid without more + // context (which Module it came from) if (address_type == eAddressTypeFile) - { - // Can't convert a file address to anything valid without more - // context (which Module it came from) return false; - } - if (!ClangASTContext::GetCompleteType(ast_context, clang_type)) + if (!GetCompleteType()) return false; - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - - const uint64_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8; + const uint64_t byte_size = GetByteSize(); if (data.GetByteSize() < byte_size) { lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0')); data.SetData(data_sp); } - + uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size); if (dst != NULL) { @@ -1870,41 +6416,23 @@ ClangASTType::ReadFromMemory (clang::ASTContext *ast_context, } bool -ClangASTType::WriteToMemory -( - lldb_private::ExecutionContext *exe_ctx, - lldb::addr_t addr, - AddressType address_type, - StreamString &new_value -) +ClangASTType::WriteToMemory (lldb_private::ExecutionContext *exe_ctx, + lldb::addr_t addr, + AddressType address_type, + StreamString &new_value) { - return WriteToMemory (m_ast, - m_type, - exe_ctx, - addr, - address_type, - new_value); -} + if (!IsValid()) + return false; -bool -ClangASTType::WriteToMemory -( - clang::ASTContext *ast_context, - clang_type_t clang_type, - lldb_private::ExecutionContext *exe_ctx, - lldb::addr_t addr, - AddressType address_type, - StreamString &new_value -) -{ + // Can't convert a file address to anything valid without more + // context (which Module it came from) if (address_type == eAddressTypeFile) - { - // Can't convert a file address to anything valid without more - // context (which Module it came from) return false; - } - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - const uint64_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8; + + if (!GetCompleteType()) + return false; + + const uint64_t byte_size = GetByteSize(); if (byte_size > 0) { @@ -1930,21 +6458,13 @@ ClangASTType::WriteToMemory } -lldb::clang_type_t -ClangASTType::RemoveFastQualifiers (lldb::clang_type_t clang_type) -{ - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - qual_type.getQualifiers().removeFastQualifiers(); - return qual_type.getAsOpaquePtr(); -} - -clang::CXXRecordDecl * -ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type) -{ - if (opaque_clang_qual_type) - return clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl(); - return NULL; -} +//CXXRecordDecl * +//ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type) +//{ +// if (opaque_clang_qual_type) +// return QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl(); +// return NULL; +//} bool lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs) @@ -1959,190 +6479,4 @@ lldb_private::operator != (const lldb_private::ClangASTType &lhs, const lldb_pri return lhs.GetASTContext() != rhs.GetASTContext() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType(); } -lldb::BasicType -ClangASTType::GetBasicTypeEnumeration (const ConstString &name) -{ - if (name) - { - typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap; - static TypeNameToBasicTypeMap g_type_map; - static std::once_flag g_once_flag; - std::call_once(g_once_flag, [](){ - // "void" - g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid); - - // "char" - g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar); - g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar); - g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar); - g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar); - g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar); - g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar); - // "short" - g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort); - g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort); - g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort); - g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort); - - // "int" - g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt); - g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt); - g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt); - g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt); - - // "long" - g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong); - g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong); - g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong); - g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong); - - // "long long" - g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong); - g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong); - g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong); - g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong); - - // "int128" - g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128); - g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128); - - // Miscelaneous - g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool); - g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat); - g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble); - g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble); - g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID); - g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel); - g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr); - g_type_map.Sort(); - }); - - return g_type_map.Find(name.GetCString(), eBasicTypeInvalid); - } - return eBasicTypeInvalid; -} - -ClangASTType -ClangASTType::GetBasicType (clang::ASTContext *ast, const ConstString &name) -{ - if (ast) - { - lldb::BasicType basic_type = ClangASTType::GetBasicTypeEnumeration (name); - return ClangASTType::GetBasicType (ast, basic_type); - } - return ClangASTType(); -} - -ClangASTType -ClangASTType::GetBasicType (clang::ASTContext *ast, lldb::BasicType type) -{ - if (ast) - { - clang_type_t clang_type = NULL; - - switch (type) - { - case eBasicTypeInvalid: - case eBasicTypeOther: - break; - case eBasicTypeVoid: - clang_type = ast->VoidTy.getAsOpaquePtr(); - break; - case eBasicTypeChar: - clang_type = ast->CharTy.getAsOpaquePtr(); - break; - case eBasicTypeSignedChar: - clang_type = ast->SignedCharTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedChar: - clang_type = ast->UnsignedCharTy.getAsOpaquePtr(); - break; - case eBasicTypeWChar: - clang_type = ast->getWCharType().getAsOpaquePtr(); - break; - case eBasicTypeSignedWChar: - clang_type = ast->getSignedWCharType().getAsOpaquePtr(); - break; - case eBasicTypeUnsignedWChar: - clang_type = ast->getUnsignedWCharType().getAsOpaquePtr(); - break; - case eBasicTypeChar16: - clang_type = ast->Char16Ty.getAsOpaquePtr(); - break; - case eBasicTypeChar32: - clang_type = ast->Char32Ty.getAsOpaquePtr(); - break; - case eBasicTypeShort: - clang_type = ast->ShortTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedShort: - clang_type = ast->UnsignedShortTy.getAsOpaquePtr(); - break; - case eBasicTypeInt: - clang_type = ast->IntTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedInt: - clang_type = ast->UnsignedIntTy.getAsOpaquePtr(); - break; - case eBasicTypeLong: - clang_type = ast->LongTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedLong: - clang_type = ast->UnsignedLongTy.getAsOpaquePtr(); - break; - case eBasicTypeLongLong: - clang_type = ast->LongLongTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedLongLong: - clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr(); - break; - case eBasicTypeInt128: - clang_type = ast->Int128Ty.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedInt128: - clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr(); - break; - case eBasicTypeBool: - clang_type = ast->BoolTy.getAsOpaquePtr(); - break; - case eBasicTypeHalf: - clang_type = ast->HalfTy.getAsOpaquePtr(); - break; - case eBasicTypeFloat: - clang_type = ast->FloatTy.getAsOpaquePtr(); - break; - case eBasicTypeDouble: - clang_type = ast->DoubleTy.getAsOpaquePtr(); - break; - case eBasicTypeLongDouble: - clang_type = ast->LongDoubleTy.getAsOpaquePtr(); - break; - case eBasicTypeFloatComplex: - clang_type = ast->FloatComplexTy.getAsOpaquePtr(); - break; - case eBasicTypeDoubleComplex: - clang_type = ast->DoubleComplexTy.getAsOpaquePtr(); - break; - case eBasicTypeLongDoubleComplex: - clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr(); - break; - case eBasicTypeObjCID: - clang_type = ast->ObjCBuiltinIdTy.getAsOpaquePtr(); - break; - case eBasicTypeObjCClass: - clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr(); - break; - case eBasicTypeObjCSel: - clang_type = ast->ObjCBuiltinSelTy.getAsOpaquePtr(); - break; - case eBasicTypeNullPtr: - clang_type = ast->NullPtrTy.getAsOpaquePtr(); - break; - } - - if (clang_type) - return ClangASTType (ast, clang_type); - } - return ClangASTType(); -} diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index 594cb3922e6..31334a6df8d 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -12,13 +12,10 @@ #include "lldb/Core/Section.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ClangASTType.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" -#include "clang/AST/Type.h" -#include "clang/AST/CanonicalType.h" #include "llvm/Support/Casting.h" using namespace lldb; @@ -484,64 +481,13 @@ Function::GetType() const return m_type; } -clang_type_t -Function::GetReturnClangType () +ClangASTType +Function::GetClangType() { - Type *type = GetType(); - if (type) - { - clang::QualType clang_type (clang::QualType::getFromOpaquePtr(type->GetClangFullType())); - const clang::FunctionType *function_type = llvm::dyn_cast<clang::FunctionType> (clang_type); - if (function_type) - return function_type->getResultType().getAsOpaquePtr(); - } - return NULL; -} - -int -Function::GetArgumentCount () -{ - clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangFullType())); - assert (clang_type->isFunctionType()); - if (!clang_type->isFunctionProtoType()) - return -1; - - const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(clang_type); - if (function_proto_type != NULL) - return function_proto_type->getNumArgs(); - - return 0; -} - -clang_type_t -Function::GetArgumentTypeAtIndex (size_t idx) -{ - clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangFullType())); - const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(clang_type); - if (function_proto_type) - { - unsigned num_args = function_proto_type->getNumArgs(); - if (idx >= num_args) - return NULL; - - return (function_proto_type->arg_type_begin())[idx].getAsOpaquePtr(); - } - return NULL; -} - -bool -Function::IsVariadic () -{ - const clang::Type *clang_type = static_cast<clang::QualType *>(GetType()->GetClangFullType())->getTypePtr(); - assert (clang_type->isFunctionType()); - if (!clang_type->isFunctionProtoType()) - return false; - - const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(clang_type); - if (function_proto_type) - return function_proto_type->isVariadic(); - - return false; + Type *function_type = GetType(); + if (function_type) + return function_type->GetClangFullType(); + return ClangASTType(); } uint32_t diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 0646a40b5b4..0af2359e1da 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -83,7 +83,7 @@ Type::Type user_id_t encoding_uid, EncodingDataType encoding_uid_type, const Declaration& decl, - clang_type_t clang_type, + const ClangASTType &clang_type, ResolveState clang_type_resolve_state ) : std::enable_shared_from_this<Type> (), @@ -113,7 +113,7 @@ Type::Type () : m_encoding_uid_type (eEncodingInvalid), m_byte_size (0), m_decl (), - m_clang_type (NULL) + m_clang_type () { m_flags.clang_type_resolve_state = eResolveStateUnresolved; m_flags.is_complete_objc_class = false; @@ -172,10 +172,10 @@ Type::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name) bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose); m_decl.Dump(s, show_fullpaths); - if (m_clang_type) + if (m_clang_type.IsValid()) { *s << ", clang_type = \""; - ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s); + GetClangForwardType().DumpTypeDescription(s); *s << '"'; } else if (m_encoding_uid != LLDB_INVALID_UID) @@ -220,11 +220,10 @@ Type::Dump (Stream *s, bool show_context) bool show_fullpaths = false; m_decl.Dump (s,show_fullpaths); - if (m_clang_type) + if (m_clang_type.IsValid()) { - *s << ", clang_type = " << m_clang_type << ' '; - - ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s); + *s << ", clang_type = " << m_clang_type.GetOpaqueQualType() << ' '; + GetClangForwardType().DumpTypeDescription (s); } else if (m_encoding_uid != LLDB_INVALID_UID) { @@ -254,10 +253,7 @@ const ConstString & Type::GetName() { if (!m_name) - { - if (ResolveClangType(eResolveStateForward)) - m_name = ClangASTType::GetConstTypeName (GetClangASTContext ().getASTContext(), m_clang_type); - } + m_name = GetClangForwardType().GetConstTypeName(); return m_name; } @@ -292,20 +288,18 @@ Type::DumpValue s->PutCString(") "); } - ClangASTType::DumpValue (GetClangAST (), - m_clang_type, - exe_ctx, - s, - format == lldb::eFormatDefault ? GetFormat() : format, - data, - data_byte_offset, - GetByteSize(), - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, - show_summary, - verbose, - 0); + GetClangForwardType().DumpValue (exe_ctx, + s, + format == lldb::eFormatDefault ? GetFormat() : format, + data, + data_byte_offset, + GetByteSize(), + 0, // Bitfield bit size + 0, // Bitfield bit offset + show_types, + show_summary, + verbose, + 0); } } @@ -339,10 +333,7 @@ Type::GetByteSize() if (encoding_type) m_byte_size = encoding_type->GetByteSize(); if (m_byte_size == 0) - { - uint32_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangLayoutType()); - m_byte_size = (bit_width + 7 ) / 8; - } + m_byte_size = GetClangLayoutType().GetByteSize(); } break; @@ -350,7 +341,7 @@ Type::GetByteSize() case eEncodingIsPointerUID: case eEncodingIsLValueReferenceUID: case eEncodingIsRValueReferenceUID: - m_byte_size = m_symbol_file->GetClangASTContext().GetPointerBitSize() / 8; + m_byte_size = m_symbol_file->GetClangASTContext().GetPointerByteSize(); break; } } @@ -361,21 +352,13 @@ Type::GetByteSize() uint32_t Type::GetNumChildren (bool omit_empty_base_classes) { - if (ResolveClangType(eResolveStateForward)) - { - return ClangASTContext::GetNumChildren (m_symbol_file->GetClangASTContext().getASTContext(), - m_clang_type, - omit_empty_base_classes); - } - return 0; + return GetClangForwardType().GetNumChildren(omit_empty_base_classes); } bool Type::IsAggregateType () { - if (ResolveClangType(eResolveStateForward)) - return ClangASTContext::IsAggregateType (m_clang_type); - return false; + return GetClangForwardType().IsAggregateType(); } lldb::TypeSP @@ -396,10 +379,7 @@ Type::GetTypedefType() lldb::Format Type::GetFormat () { - // Make sure we resolve our type if it already hasn't been. - if (!ResolveClangType(eResolveStateForward)) - return lldb::eFormatInvalid; - return ClangASTType::GetFormat (m_clang_type); + return GetClangForwardType().GetFormat(); } @@ -408,14 +388,9 @@ lldb::Encoding Type::GetEncoding (uint64_t &count) { // Make sure we resolve our type if it already hasn't been. - if (!ResolveClangType(eResolveStateForward)) - return lldb::eEncodingInvalid; - - return ClangASTType::GetEncoding (m_clang_type, count); + return GetClangForwardType().GetEncoding(count); } - - bool Type::DumpValueInMemory ( @@ -514,7 +489,7 @@ bool Type::ResolveClangType (ResolveState clang_type_resolve_state) { Type *encoding_type = NULL; - if (m_clang_type == NULL) + if (!m_clang_type.IsValid()) { encoding_type = GetEncodingType(); if (encoding_type) @@ -522,42 +497,44 @@ Type::ResolveClangType (ResolveState clang_type_resolve_state) switch (m_encoding_uid_type) { case eEncodingIsUID: - if (encoding_type->ResolveClangType(clang_type_resolve_state)) { - m_clang_type = encoding_type->m_clang_type; - m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state; + ClangASTType encoding_clang_type = encoding_type->GetClangForwardType(); + if (encoding_clang_type.IsValid()) + { + m_clang_type = encoding_clang_type; + m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state; + } } break; case eEncodingIsConstUID: - m_clang_type = ClangASTContext::AddConstModifier (encoding_type->GetClangForwardType()); + m_clang_type = encoding_type->GetClangForwardType().AddConstModifier(); break; case eEncodingIsRestrictUID: - m_clang_type = ClangASTContext::AddRestrictModifier (encoding_type->GetClangForwardType()); + m_clang_type = encoding_type->GetClangForwardType().AddRestrictModifier(); break; case eEncodingIsVolatileUID: - m_clang_type = ClangASTContext::AddVolatileModifier (encoding_type->GetClangForwardType()); + m_clang_type = encoding_type->GetClangForwardType().AddVolatileModifier(); break; case eEncodingIsTypedefUID: - m_clang_type = CreateClangTypedefType (this, encoding_type); - // Clear the name so it can get fully qualified in case the - // typedef is in a namespace. + m_clang_type = encoding_type->GetClangForwardType().CreateTypedefType (GetName().AsCString(), + GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID())); m_name.Clear(); break; case eEncodingIsPointerUID: - m_clang_type = CreateClangPointerType (encoding_type); + m_clang_type = encoding_type->GetClangForwardType().GetPointerType(); break; case eEncodingIsLValueReferenceUID: - m_clang_type = CreateClangLValueReferenceType (encoding_type); + m_clang_type = encoding_type->GetClangForwardType().GetLValueReferenceType(); break; case eEncodingIsRValueReferenceUID: - m_clang_type = CreateClangRValueReferenceType (encoding_type); + m_clang_type = encoding_type->GetClangForwardType().GetRValueReferenceType(); break; default: @@ -568,7 +545,7 @@ Type::ResolveClangType (ResolveState clang_type_resolve_state) else { // We have no encoding type, return void? - clang_type_t void_clang_type = GetClangASTContext().GetBuiltInType_void(); + ClangASTType void_clang_type (ClangASTContext::GetBasicType(GetClangASTContext().getASTContext(), eBasicTypeVoid)); switch (m_encoding_uid_type) { case eEncodingIsUID: @@ -576,31 +553,32 @@ Type::ResolveClangType (ResolveState clang_type_resolve_state) break; case eEncodingIsConstUID: - m_clang_type = ClangASTContext::AddConstModifier (void_clang_type); + m_clang_type = void_clang_type.AddConstModifier (); break; case eEncodingIsRestrictUID: - m_clang_type = ClangASTContext::AddRestrictModifier (void_clang_type); + m_clang_type = void_clang_type.AddRestrictModifier (); break; case eEncodingIsVolatileUID: - m_clang_type = ClangASTContext::AddVolatileModifier (void_clang_type); + m_clang_type = void_clang_type.AddVolatileModifier (); break; case eEncodingIsTypedefUID: - m_clang_type = GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL); + m_clang_type = void_clang_type.CreateTypedefType (GetName().AsCString(), + GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID())); break; case eEncodingIsPointerUID: - m_clang_type = GetClangASTContext().CreatePointerType (void_clang_type); + m_clang_type = void_clang_type.GetPointerType (); break; case eEncodingIsLValueReferenceUID: - m_clang_type = GetClangASTContext().CreateLValueReferenceType (void_clang_type); + m_clang_type = void_clang_type.GetLValueReferenceType (); break; case eEncodingIsRValueReferenceUID: - m_clang_type = GetClangASTContext().CreateRValueReferenceType (void_clang_type); + m_clang_type = void_clang_type.GetRValueReferenceType (); break; default: @@ -611,13 +589,12 @@ Type::ResolveClangType (ResolveState clang_type_resolve_state) } // Check if we have a forward reference to a class/struct/union/enum? - if (m_clang_type && m_flags.clang_type_resolve_state < clang_type_resolve_state) + if (m_clang_type.IsValid() && m_flags.clang_type_resolve_state < clang_type_resolve_state) { m_flags.clang_type_resolve_state = eResolveStateFull; - if (!ClangASTType::IsDefined (m_clang_type)) + if (!m_clang_type.IsDefined ()) { - // We have a forward declaration, we need to resolve it to a complete - // definition. + // We have a forward declaration, we need to resolve it to a complete definition. m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type); } } @@ -648,7 +625,7 @@ Type::ResolveClangType (ResolveState clang_type_resolve_state) encoding_type->ResolveClangType (encoding_clang_type_resolve_state); } } - return m_clang_type != NULL; + return m_clang_type.IsValid(); } uint32_t Type::GetEncodingMask () @@ -661,33 +638,27 @@ Type::GetEncodingMask () return encoding_mask; } -clang_type_t +ClangASTType Type::GetClangFullType () { ResolveClangType(eResolveStateFull); return m_clang_type; } -clang_type_t +ClangASTType Type::GetClangLayoutType () { ResolveClangType(eResolveStateLayout); return m_clang_type; } -clang_type_t +ClangASTType Type::GetClangForwardType () { ResolveClangType (eResolveStateForward); return m_clang_type; } -clang::ASTContext * -Type::GetClangAST () -{ - return GetClangASTContext().getASTContext(); -} - ClangASTContext & Type::GetClangASTContext () { @@ -710,6 +681,8 @@ Type::Compare(const Type &a, const Type &b) } +#if 0 // START REMOVE +// Move this into ClangASTType void * Type::CreateClangPointerType (Type *type) { @@ -739,6 +712,7 @@ Type::CreateClangRValueReferenceType (Type *type) assert(type); return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType()); } +#endif // END REMOVE bool Type::IsRealObjCClass() @@ -747,7 +721,7 @@ Type::IsRealObjCClass() // those don't have any information. We could extend this to only return true for "full // definitions" if we can figure that out. - if (ClangASTContext::IsObjCClassType(m_clang_type) && GetByteSize() != 0) + if (m_clang_type.IsObjCObjectOrInterfaceType() && GetByteSize() != 0) return true; else return false; @@ -756,8 +730,7 @@ Type::IsRealObjCClass() ConstString Type::GetQualifiedName () { - ConstString qualified_name (ClangASTType::GetTypeNameForOpaqueQualType (GetClangASTContext ().getASTContext(), GetClangForwardType()).c_str()); - return qualified_name; + return GetClangForwardType().GetConstTypeName(); } @@ -938,12 +911,13 @@ TypeAndOrName::HasTypeSP () } TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) : - m_clang_ast_type(clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()), + m_clang_ast_type(clang_ast_type), m_type_sp() -{} +{ +} TypeImpl::TypeImpl(const lldb::TypeSP& type) : - m_clang_ast_type(type->GetClangAST(), type->GetClangFullType()), + m_clang_ast_type(type->GetClangForwardType()), m_type_sp(type) { } @@ -953,7 +927,7 @@ TypeImpl::SetType (const lldb::TypeSP &type_sp) { if (type_sp) { - m_clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType()); + m_clang_ast_type = type_sp->GetClangForwardType(); m_type_sp = type_sp; } else @@ -998,9 +972,7 @@ TypeImpl::GetDescription (lldb_private::Stream &strm, { if (m_clang_ast_type.IsValid()) { - ClangASTType::DumpTypeDescription (m_clang_ast_type.GetASTContext(), - m_clang_ast_type.GetOpaqueQualType(), - &strm); + m_clang_ast_type.DumpTypeDescription (&strm); } else { @@ -1013,6 +985,6 @@ ConstString TypeImpl::GetName () { if (m_clang_ast_type.IsValid()) - return m_clang_ast_type.GetConstQualifiedTypeName(); + return m_clang_ast_type.GetConstTypeName(); return ConstString(); } diff --git a/lldb/source/Symbol/TypeHierarchyNavigator.cpp b/lldb/source/Symbol/TypeHierarchyNavigator.cpp deleted file mode 100644 index e046204fd7d..00000000000 --- a/lldb/source/Symbol/TypeHierarchyNavigator.cpp +++ /dev/null @@ -1,122 +0,0 @@ -//===-- TypeHierarchyNavigator.cpp -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "clang/AST/ASTContext.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/TypeHierarchyNavigator.h" - -using namespace lldb; -using namespace lldb_private; - -bool -TypeHierarchyNavigator::LoopThrough(TypeHierarchyNavigatorCallback callback, - void* callback_baton) -{ - return LoopThrough(m_root_type, - callback, - eRootType, - (callback_baton ? callback_baton : m_default_callback_baton)); -} - -bool -TypeHierarchyNavigator::LoopThrough(const clang::QualType& qual_type, - TypeHierarchyNavigatorCallback callback, - RelationshipToCurrentType reason_why_here, - void* callback_baton) -{ - if (qual_type.isNull()) - return true; - clang::QualType type = qual_type.getUnqualifiedType(); - type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict(); - const clang::Type* typePtr = type.getTypePtrOrNull(); - if (!typePtr) - return true; - if (!callback(type, reason_why_here, callback_baton)) - return false; - // look for a "base type", whatever that means - if (typePtr->isReferenceType()) - { - if (LoopThrough(type.getNonReferenceType(), callback, eStrippedReference, callback_baton) == false) - return false; - } - if (typePtr->isPointerType()) - { - if (LoopThrough(typePtr->getPointeeType(), callback, eStrippedPointer, callback_baton) == false) - return false; - } - if (typePtr->isObjCObjectPointerType()) - { - /* - for some reason, C++ can quite easily obtain the type hierarchy for a ValueObject - even if the VO represent a pointer-to-class, as long as the typePtr is right - Objective-C on the other hand cannot really complete an @interface when - the VO refers to a pointer-to-@interface - */ - Error error; - ValueObject* target = m_value_object.Dereference(error).get(); - if (error.Fail() || !target) - return true; - if (LoopThrough(typePtr->getPointeeType(), callback, eStrippedPointer, callback_baton) == false) - return false; - } - const clang::ObjCObjectType *objc_class_type = typePtr->getAs<clang::ObjCObjectType>(); - if (objc_class_type) - { - clang::ASTContext *ast = m_value_object.GetClangAST(); - if (ClangASTContext::GetCompleteType(ast, m_value_object.GetClangType()) && !objc_class_type->isObjCId()) - { - clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - if (class_interface_decl) - { - clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - if (superclass_interface_decl) - { - clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl)); - return LoopThrough(ivar_qual_type, callback, eObjCBaseClass, callback_baton); - } - } - } - } - // for C++ classes, navigate up the hierarchy - if (typePtr->isRecordType()) - { - clang::CXXRecordDecl* record = typePtr->getAsCXXRecordDecl(); - if (record) - { - if (!record->hasDefinition()) - ClangASTContext::GetCompleteType(m_value_object.GetClangAST(), m_value_object.GetClangType()); - if (record->hasDefinition()) - { - clang::CXXRecordDecl::base_class_iterator pos,end; - if ( record->getNumBases() > 0) - { - end = record->bases_end(); - for (pos = record->bases_begin(); pos != end; pos++) - if (LoopThrough(pos->getType(), callback, eCXXBaseClass, callback_baton) == false) - return false; - } - if (record->getNumVBases() > 0) - { - end = record->vbases_end(); - for (pos = record->vbases_begin(); pos != end; pos++) - if (LoopThrough(pos->getType(), callback, eCXXVBaseClass, callback_baton) == false) - return false; - } - } - } - } - // try to strip typedef chains - const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>(); - if (type_tdef) - return LoopThrough(type_tdef->getDecl()->getUnderlyingType(), callback, eStrippedTypedef, callback_baton); - else - return true; -} diff --git a/lldb/source/Symbol/TypeList.cpp b/lldb/source/Symbol/TypeList.cpp index df0723e48f2..a033edd22e1 100644 --- a/lldb/source/Symbol/TypeList.cpp +++ b/lldb/source/Symbol/TypeList.cpp @@ -259,8 +259,7 @@ TypeList::RemoveMismatchedTypes (const std::string &type_scope, if (type_class != eTypeClassAny) { - match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(), - the_type->GetClangForwardType()); + match_type_class = the_type->GetClangForwardType().GetTypeClass (); if ((match_type_class & type_class) == 0) continue; } @@ -349,43 +348,9 @@ TypeList::RemoveMismatchedTypes (TypeClass type_class) for (pos = m_types.begin(); pos != end; ++pos) { Type* the_type = pos->second.get(); - TypeClass match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(), - the_type->GetClangForwardType()); + TypeClass match_type_class = the_type->GetClangForwardType().GetTypeClass (); if (match_type_class & type_class) matching_types.insert (*pos); } m_types.swap(matching_types); } - -//void * -//TypeList::CreateClangPointerType (Type *type) -//{ -// assert(type); -// return m_ast.CreatePointerType(type->GetClangForwardType()); -//} -// -//void * -//TypeList::CreateClangTypedefType (Type *typedef_type, Type *base_type) -//{ -// assert(typedef_type && base_type); -// return m_ast.CreateTypedefType (typedef_type->GetName().AsCString(), -// base_type->GetClangForwardType(), -// typedef_type->GetSymbolFile()->GetClangDeclContextForTypeUID(typedef_type->GetID())); -//} -// -//void * -//TypeList::CreateClangLValueReferenceType (Type *type) -//{ -// assert(type); -// return m_ast.CreateLValueReferenceType(type->GetClangForwardType()); -//} -// -//void * -//TypeList::CreateClangRValueReferenceType (Type *type) -//{ -// assert(type); -// return m_ast.CreateRValueReferenceType (type->GetClangForwardType()); -//} -// - - diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index bcbea2f1563..36439b56162 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -547,18 +547,13 @@ PrivateAutoCompleteMembers (StackFrame *frame, { // We are in a type parsing child members - const uint32_t num_bases = ClangASTContext::GetNumDirectBaseClasses(clang_type.GetASTContext(), - clang_type.GetOpaqueQualType()); + const uint32_t num_bases = clang_type.GetNumDirectBaseClasses(); if (num_bases > 0) { for (uint32_t i = 0; i < num_bases; ++i) { - ClangASTType base_class_type (clang_type.GetASTContext(), - ClangASTContext::GetDirectBaseClassAtIndex (clang_type.GetASTContext(), - clang_type.GetOpaqueQualType(), - i, - NULL)); + ClangASTType base_class_type (clang_type.GetDirectBaseClassAtIndex (i, NULL)); PrivateAutoCompleteMembers (frame, partial_member_name, @@ -570,18 +565,13 @@ PrivateAutoCompleteMembers (StackFrame *frame, } } - const uint32_t num_vbases = ClangASTContext::GetNumVirtualBaseClasses(clang_type.GetASTContext(), - clang_type.GetOpaqueQualType()); + const uint32_t num_vbases = clang_type.GetNumVirtualBaseClasses(); if (num_vbases > 0) { for (uint32_t i = 0; i < num_vbases; ++i) { - ClangASTType vbase_class_type (clang_type.GetASTContext(), - ClangASTContext::GetVirtualBaseClassAtIndex(clang_type.GetASTContext(), - clang_type.GetOpaqueQualType(), - i, - NULL)); + ClangASTType vbase_class_type (clang_type.GetVirtualBaseClassAtIndex(i,NULL)); PrivateAutoCompleteMembers (frame, partial_member_name, @@ -594,8 +584,7 @@ PrivateAutoCompleteMembers (StackFrame *frame, } // We are in a type parsing child members - const uint32_t num_fields = ClangASTContext::GetNumFields(clang_type.GetASTContext(), - clang_type.GetOpaqueQualType()); + const uint32_t num_fields = clang_type.GetNumFields(); if (num_fields > 0) { @@ -603,20 +592,13 @@ PrivateAutoCompleteMembers (StackFrame *frame, { std::string member_name; - lldb::clang_type_t member_type = ClangASTContext::GetFieldAtIndex (clang_type.GetASTContext(), - clang_type.GetOpaqueQualType(), - i, - member_name, - NULL, - NULL, - NULL); + ClangASTType member_clang_type = clang_type.GetFieldAtIndex (i, member_name, NULL, NULL, NULL); if (partial_member_name.empty() || member_name.find(partial_member_name) == 0) { if (member_name == partial_member_name) { - ClangASTType member_clang_type (clang_type.GetASTContext(), member_type); PrivateAutoComplete (frame, partial_path, prefix_path + member_name, // Anything that has been resolved already will be in here @@ -683,7 +665,7 @@ PrivateAutoComplete (StackFrame *frame, case eTypeClassPointer: { bool omit_empty_base_classes = true; - if (ClangASTContext::GetNumChildren (clang_type.GetASTContext(), clang_type.GetPointeeType(), omit_empty_base_classes) > 0) + if (clang_type.GetNumChildren (omit_empty_base_classes) > 0) matches.AppendString (prefix_path + "->"); else { @@ -747,7 +729,7 @@ PrivateAutoComplete (StackFrame *frame, { case lldb::eTypeClassPointer: { - ClangASTType pointee_type(clang_type.GetASTContext(), clang_type.GetPointeeType()); + ClangASTType pointee_type(clang_type.GetPointeeType()); if (partial_path[2]) { // If there is more after the "->", then search deeper @@ -859,7 +841,7 @@ PrivateAutoComplete (StackFrame *frame, Type *variable_type = variable->GetType(); if (variable_type) { - ClangASTType variable_clang_type (variable_type->GetClangAST(), variable_type->GetClangForwardType()); + ClangASTType variable_clang_type (variable_type->GetClangForwardType()); PrivateAutoComplete (frame, remaining_partial_path, prefix_path + token, // Anything that has been resolved already will be in here diff --git a/lldb/source/Target/ObjCLanguageRuntime.cpp b/lldb/source/Target/ObjCLanguageRuntime.cpp index 1aeb7255bcb..64ddfcc6c79 100644 --- a/lldb/source/Target/ObjCLanguageRuntime.cpp +++ b/lldb/source/Target/ObjCLanguageRuntime.cpp @@ -131,7 +131,7 @@ ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name) { TypeSP type_sp (types.GetTypeAtIndex(i)); - if (ClangASTContext::IsObjCClassType(type_sp->GetClangForwardType())) + if (type_sp->GetClangForwardType().IsObjCObjectOrInterfaceType()) { if (type_sp->IsCompleteObjCClass()) { @@ -532,7 +532,7 @@ ObjCLanguageRuntime::GetClassDescriptor (ValueObject& valobj) // if we get an invalid VO (which might still happen when playing around // with pointers returned by the expression parser, don't consider this // a valid ObjC object) - if (valobj.GetValue().GetContextType() != Value::eContextTypeInvalid) + if (valobj.GetClangType().IsValid()) { addr_t isa_pointer = valobj.GetPointerValue(); if (isa_pointer != LLDB_INVALID_ADDRESS) diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index b0293be89b0..3c4c43d9f44 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -645,9 +645,9 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, { // Make sure we aren't trying to deref an objective // C ivar if this is not allowed - const uint32_t pointer_type_flags = ClangASTContext::GetTypeInfo (valobj_sp->GetClangType(), NULL, NULL); - if ((pointer_type_flags & ClangASTContext::eTypeIsObjC) && - (pointer_type_flags & ClangASTContext::eTypeIsPointer)) + const uint32_t pointer_type_flags = valobj_sp->GetClangType().GetTypeInfo (NULL); + if ((pointer_type_flags & ClangASTType::eTypeIsObjC) && + (pointer_type_flags & ClangASTType::eTypeIsPointer)) { // This was an objective C object pointer and // it was requested we skip any fragile ivars @@ -759,7 +759,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, if (end && *end == ']' && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go { - if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref) + if (valobj_sp->GetClangType().IsPointerToScalarType() && deref) { // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr // and extract bit low out of it. reading array item low @@ -777,7 +777,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, valobj_sp = temp; deref = false; } - else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref) + else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref) { // what we have is *arr[low]. the most similar C++ syntax is to get arr[0] // (an operation that is equivalent to deref-ing arr) @@ -802,9 +802,9 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, { bool is_objc_pointer = true; - if (ClangASTType::GetMinimumLanguage(valobj_sp->GetClangAST(), valobj_sp->GetClangType()) != eLanguageTypeObjC) + if (valobj_sp->GetClangType().GetMinimumLanguage() != eLanguageTypeObjC) is_objc_pointer = false; - else if (!ClangASTContext::IsPointerType(valobj_sp->GetClangType())) + else if (!valobj_sp->GetClangType().IsPointerType()) is_objc_pointer = false; if (no_synth_child && is_objc_pointer) @@ -861,7 +861,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, } } } - else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL, &is_incomplete_array)) + else if (valobj_sp->GetClangType().IsArrayType (NULL, NULL, &is_incomplete_array)) { // Pass false to dynamic_value here so we can tell the difference between // no dynamic value and no member of this type... @@ -878,7 +878,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, var_expr_path_strm.GetString().c_str()); } } - else if (ClangASTContext::IsScalarType(valobj_sp->GetClangType())) + else if (valobj_sp->GetClangType().IsScalarType()) { // this is a bitfield asking to display just one bit child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true); @@ -961,7 +961,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, final_index = temp; } - if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref) + if (valobj_sp->GetClangType().IsPointerToScalarType() && deref) { // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr // and extract bits low thru high out of it. reading array items low thru high @@ -979,7 +979,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, valobj_sp = temp; deref = false; } - else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref) + else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref) { // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0] // (an operation that is equivalent to deref-ing arr) @@ -1122,7 +1122,7 @@ StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) if (m_sc.function->GetFrameBaseExpression().IsLocationList()) loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr()); - if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) + if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) { // We should really have an error if evaluate returns, but in case // we don't, lets set the error to something at least. @@ -1131,7 +1131,7 @@ StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) } else { - m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL); + m_frame_base = expr_value.ResolveValue(&exe_ctx); } } else diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 508238de458..12ec40f6be3 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -1677,13 +1677,12 @@ Thread::ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return Type *function_type = sc.function->GetType(); if (function_type) { - clang_type_t return_type = sc.function->GetReturnClangType(); + ClangASTType return_type = sc.function->GetClangType().GetFunctionReturnType(); if (return_type) { - ClangASTType ast_type (function_type->GetClangAST(), return_type); StreamString s; - ast_type.DumpTypeDescription(&s); - ValueObjectSP cast_value_sp = return_value_sp->Cast(ast_type); + return_type.DumpTypeDescription(&s); + ValueObjectSP cast_value_sp = return_value_sp->Cast(return_type); if (cast_value_sp) { cast_value_sp->SetFormat(eFormatHex); diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp index 71ccf80428b..ba529587437 100644 --- a/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/lldb/source/Target/ThreadPlanStepOut.cpp @@ -464,17 +464,12 @@ ThreadPlanStepOut::CalculateReturnValue () if (m_immediate_step_from_function != NULL) { - Type *return_type = m_immediate_step_from_function->GetType(); - lldb::clang_type_t return_clang_type = m_immediate_step_from_function->GetReturnClangType(); - if (return_type && return_clang_type) + ClangASTType return_clang_type = m_immediate_step_from_function->GetClangType().GetFunctionReturnType(); + if (return_clang_type) { - ClangASTType ast_type (return_type->GetClangAST(), return_clang_type); - lldb::ABISP abi_sp = m_thread.GetProcess()->GetABI(); if (abi_sp) - { - m_return_valobj_sp = abi_sp->GetReturnValueObject(m_thread, ast_type); - } + m_return_valobj_sp = abi_sp->GetReturnValueObject(m_thread, return_clang_type); } } } diff --git a/lldb/source/Target/ThreadPlanTracer.cpp b/lldb/source/Target/ThreadPlanTracer.cpp index 7242b8e4218..af6cef7ecc5 100644 --- a/lldb/source/Target/ThreadPlanTracer.cpp +++ b/lldb/source/Target/ThreadPlanTracer.cpp @@ -136,8 +136,7 @@ ThreadPlanAssemblyTracer::GetIntPointerType() if (exe_module) { - m_intptr_type = TypeFromUser(exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, target_sp->GetArchitecture().GetAddressByteSize() * 8), - exe_module->GetClangASTContext().getASTContext()); + m_intptr_type = TypeFromUser(exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, target_sp->GetArchitecture().GetAddressByteSize() * 8)); } } } @@ -243,7 +242,8 @@ ThreadPlanAssemblyTracer::Log () { Value value; value.SetValueType (Value::eValueTypeScalar); - value.SetContext (Value::eContextTypeClangType, intptr_type.GetOpaqueQualType()); +// value.SetContext (Value::eContextTypeClangType, intptr_type.GetOpaqueQualType()); + value.SetClangType (intptr_type); value_list.PushValue (value); } diff --git a/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py b/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py index b91c9e86261..955bd6dd902 100644 --- a/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py +++ b/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py @@ -111,7 +111,9 @@ class TestObjCIvarsInBlocks(TestBase): expr = frame.EvaluateExpression("(ret)") self.assertTrue (expr, "Successfully got a local variable in a block in a class method.") - self.assertTrue (expr.GetValueAsSigned (error) == 5, "The local variable in the block was what we expected.") + ret_value_signed = expr.GetValueAsSigned (error) + print 'ret_value_signed = %i' % (ret_value_signed) + self.assertTrue (ret_value_signed == 5, "The local variable in the block was what we expected.") if __name__ == '__main__': import atexit |