diff options
Diffstat (limited to 'source/Symbol/ClangASTContext.cpp')
-rw-r--r-- | source/Symbol/ClangASTContext.cpp | 1360 |
1 files changed, 681 insertions, 679 deletions
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp index 621bd1615f80..02882ef2ef4d 100644 --- a/source/Symbol/ClangASTContext.cpp +++ b/source/Symbol/ClangASTContext.cpp @@ -63,21 +63,24 @@ #include "llvm/Support/Signals.h" +#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h" +#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h" +#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/Flags.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/RegularExpression.h" +#include "lldb/Core/Scalar.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Core/UniqueCStringMap.h" -#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h" -#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h" -#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" +#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/VerifyDecl.h" @@ -86,8 +89,10 @@ #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/LLDBAssert.h" #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" +#include "Plugins/SymbolFile/PDB/PDBASTParser.h" #include <stdio.h> @@ -105,7 +110,10 @@ namespace return language == eLanguageTypeUnknown || // Clang is the default type system Language::LanguageIsC (language) || Language::LanguageIsCPlusPlus (language) || - Language::LanguageIsObjC (language); + Language::LanguageIsObjC (language) || + // Use Clang for Rust until there is a proper language plugin for it + language == eLanguageTypeRust || + language == eLanguageTypeExtRenderScript; } } @@ -332,22 +340,7 @@ ClangASTContext::ClangASTContext (const char *target_triple) : //---------------------------------------------------------------------- ClangASTContext::~ClangASTContext() { - if (m_ast_ap.get()) - { - GetASTMap().Erase(m_ast_ap.get()); - if (!m_ast_owned) - m_ast_ap.release(); - } - - m_builtins_ap.reset(); - m_selector_table_ap.reset(); - m_identifier_table_ap.reset(); - m_target_info_ap.reset(); - m_target_options_rp.reset(); - m_diagnostics_engine_ap.reset(); - m_source_manager_ap.reset(); - m_language_options_ap.reset(); - m_ast_ap.reset(); + Finalize(); } ConstString @@ -471,6 +464,27 @@ ClangASTContext::Terminate() PluginManager::UnregisterPlugin (CreateInstance); } +void +ClangASTContext::Finalize() +{ + if (m_ast_ap.get()) + { + GetASTMap().Erase(m_ast_ap.get()); + if (!m_ast_owned) + m_ast_ap.release(); + } + + m_builtins_ap.reset(); + m_selector_table_ap.reset(); + m_identifier_table_ap.reset(); + m_target_info_ap.reset(); + m_target_options_rp.reset(); + m_diagnostics_engine_ap.reset(); + m_source_manager_ap.reset(); + m_language_options_ap.reset(); + m_ast_ap.reset(); + m_scratch_ast_source_ap.reset(); +} void ClangASTContext::Clear() @@ -678,8 +692,9 @@ public: { m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); } - - void HandleDiagnostic (DiagnosticsEngine::Level DiagLevel, const Diagnostic &info) + + void + HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) { if (m_log) { @@ -707,11 +722,11 @@ ClangASTContext::getDiagnosticConsumer() return m_diagnostic_consumer_ap.get(); } -std::shared_ptr<TargetOptions> & +std::shared_ptr<clang::TargetOptions> & ClangASTContext::getTargetOptions() { if (m_target_options_rp.get() == nullptr && !m_target_triple.empty()) { - m_target_options_rp = std::make_shared<TargetOptions>(); + m_target_options_rp = std::make_shared<clang::TargetOptions>(); if (m_target_options_rp.get() != nullptr) m_target_options_rp->Triple = m_target_triple; } @@ -773,8 +788,8 @@ ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding break; case eEncodingSint: - if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return CompilerType (ast, ast->CharTy); + if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) + return CompilerType (ast, ast->SignedCharTy); if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) return CompilerType (ast, ast->ShortTy); if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) @@ -901,113 +916,12 @@ ClangASTContext::GetBasicType (lldb::BasicType basic_type) CompilerType ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type) { - if (ast) - { - lldb::opaque_compiler_type_t clang_type = nullptr; - - 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 CompilerType (GetASTContext(ast), clang_type); - } + if (!ast) + return CompilerType(); + lldb::opaque_compiler_type_t clang_type = GetOpaqueCompilerType(ast, basic_type); + + if (clang_type) + return CompilerType(GetASTContext(ast), clang_type); return CompilerType(); } @@ -1049,7 +963,7 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name if (::strstr(type_name, "complex")) { CompilerType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2); - return CompilerType (ast, ast->getComplexType (GetQualType(complex_int_clang_type))); + return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_int_clang_type))); } } break; @@ -1064,7 +978,7 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name else { CompilerType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2); - return CompilerType (ast, ast->getComplexType (GetQualType(complex_float_clang_type))); + return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_float_clang_type))); } break; @@ -1294,9 +1208,9 @@ ClangASTContext::AreTypesSame (CompilerType type1, if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType()) return true; - QualType type1_qual = GetQualType(type1); - QualType type2_qual = GetQualType(type2); - + QualType type1_qual = ClangUtil::GetQualType(type1); + QualType type2_qual = ClangUtil::GetQualType(type2); + if (ignore_qualifiers) { type1_qual = type1_qual.getUnqualifiedType(); @@ -1488,9 +1402,7 @@ ClangASTContext::CreateFunctionTemplateSpecializationInfo (FunctionDecl *func_de clang::FunctionTemplateDecl *func_tmpl_decl, const TemplateParameterInfos &infos) { - TemplateArgumentList template_args (TemplateArgumentList::OnStack, - infos.args.data(), - infos.args.size()); + TemplateArgumentList template_args (TemplateArgumentList::OnStack, infos.args); func_decl->setFunctionTemplateSpecialization (func_tmpl_decl, &template_args, @@ -1588,8 +1500,7 @@ ClangASTContext::CreateClassTemplateSpecializationDecl (DeclContext *decl_ctx, SourceLocation(), SourceLocation(), class_template_decl, - &template_param_infos.args.front(), - template_param_infos.args.size(), + template_param_infos.args, nullptr); class_template_specialization_decl->setSpecializationKind(TSK_ExplicitSpecialization); @@ -1652,25 +1563,14 @@ ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, ui clang::AccessSpecifier ClangASTContext::UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs) { - clang::AccessSpecifier ret = lhs; - // Make the access equal to the stricter of the field and the nested field's access - switch (ret) - { - case clang::AS_none: - break; - case clang::AS_private: - break; - case clang::AS_protected: - if (rhs == AS_private) - ret = AS_private; - break; - case clang::AS_public: - ret = rhs; - break; - } - - return ret; + if (lhs == AS_none || rhs == AS_none) + return AS_none; + if (lhs == AS_private || rhs == AS_private) + return AS_private; + if (lhs == AS_protected || rhs == AS_protected) + return AS_protected; + return AS_public; } bool @@ -1884,6 +1784,17 @@ ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *d return namespace_decl; } +NamespaceDecl * +ClangASTContext::GetUniqueNamespaceDeclaration (clang::ASTContext *ast, + const char *name, + clang::DeclContext *decl_ctx) +{ + ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast); + if (ast_ctx == nullptr) + return nullptr; + + return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx); +} clang::BlockDecl * ClangASTContext::CreateBlockDeclaration (clang::DeclContext *ctx) @@ -1977,6 +1888,78 @@ ClangASTContext::CreateVariableDeclaration (clang::DeclContext *decl_context, co return nullptr; } +lldb::opaque_compiler_type_t +ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type) +{ + switch (basic_type) + { + case eBasicTypeVoid: + return ast->VoidTy.getAsOpaquePtr(); + case eBasicTypeChar: + return ast->CharTy.getAsOpaquePtr(); + case eBasicTypeSignedChar: + return ast->SignedCharTy.getAsOpaquePtr(); + case eBasicTypeUnsignedChar: + return ast->UnsignedCharTy.getAsOpaquePtr(); + case eBasicTypeWChar: + return ast->getWCharType().getAsOpaquePtr(); + case eBasicTypeSignedWChar: + return ast->getSignedWCharType().getAsOpaquePtr(); + case eBasicTypeUnsignedWChar: + return ast->getUnsignedWCharType().getAsOpaquePtr(); + case eBasicTypeChar16: + return ast->Char16Ty.getAsOpaquePtr(); + case eBasicTypeChar32: + return ast->Char32Ty.getAsOpaquePtr(); + case eBasicTypeShort: + return ast->ShortTy.getAsOpaquePtr(); + case eBasicTypeUnsignedShort: + return ast->UnsignedShortTy.getAsOpaquePtr(); + case eBasicTypeInt: + return ast->IntTy.getAsOpaquePtr(); + case eBasicTypeUnsignedInt: + return ast->UnsignedIntTy.getAsOpaquePtr(); + case eBasicTypeLong: + return ast->LongTy.getAsOpaquePtr(); + case eBasicTypeUnsignedLong: + return ast->UnsignedLongTy.getAsOpaquePtr(); + case eBasicTypeLongLong: + return ast->LongLongTy.getAsOpaquePtr(); + case eBasicTypeUnsignedLongLong: + return ast->UnsignedLongLongTy.getAsOpaquePtr(); + case eBasicTypeInt128: + return ast->Int128Ty.getAsOpaquePtr(); + case eBasicTypeUnsignedInt128: + return ast->UnsignedInt128Ty.getAsOpaquePtr(); + case eBasicTypeBool: + return ast->BoolTy.getAsOpaquePtr(); + case eBasicTypeHalf: + return ast->HalfTy.getAsOpaquePtr(); + case eBasicTypeFloat: + return ast->FloatTy.getAsOpaquePtr(); + case eBasicTypeDouble: + return ast->DoubleTy.getAsOpaquePtr(); + case eBasicTypeLongDouble: + return ast->LongDoubleTy.getAsOpaquePtr(); + case eBasicTypeFloatComplex: + return ast->FloatComplexTy.getAsOpaquePtr(); + case eBasicTypeDoubleComplex: + return ast->DoubleComplexTy.getAsOpaquePtr(); + case eBasicTypeLongDoubleComplex: + return ast->LongDoubleComplexTy.getAsOpaquePtr(); + case eBasicTypeObjCID: + return ast->getObjCIdType().getAsOpaquePtr(); + case eBasicTypeObjCClass: + return ast->getObjCClassType().getAsOpaquePtr(); + case eBasicTypeObjCSel: + return ast->getObjCSelType().getAsOpaquePtr(); + case eBasicTypeNullPtr: + return ast->NullPtrTy.getAsOpaquePtr(); + default: + return nullptr; + } +} + #pragma mark Function Types FunctionDecl * @@ -1997,31 +1980,17 @@ ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, if (name && name[0]) { - func_decl = FunctionDecl::Create (*ast, - decl_ctx, - SourceLocation(), - SourceLocation(), - DeclarationName (&ast->Idents.get(name)), - GetQualType(function_clang_type), - nullptr, - (clang::StorageClass)storage, - is_inline, - hasWrittenPrototype, - isConstexprSpecified); + func_decl = FunctionDecl::Create( + *ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(&ast->Idents.get(name)), + ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline, + hasWrittenPrototype, isConstexprSpecified); } else { - func_decl = FunctionDecl::Create (*ast, - decl_ctx, - SourceLocation(), - SourceLocation(), - DeclarationName (), - GetQualType(function_clang_type), - nullptr, - (clang::StorageClass)storage, - is_inline, - hasWrittenPrototype, - isConstexprSpecified); + func_decl = + FunctionDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(), + ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, + is_inline, hasWrittenPrototype, isConstexprSpecified); } if (func_decl) decl_ctx->addDecl (func_decl); @@ -2041,10 +2010,33 @@ ClangASTContext::CreateFunctionType (ASTContext *ast, bool is_variadic, unsigned type_quals) { - assert (ast != nullptr); + if (ast == nullptr) + return CompilerType(); // invalid AST + + if (!result_type || !ClangUtil::IsClangType(result_type)) + return CompilerType(); // invalid return type + std::vector<QualType> qual_type_args; + if (num_args > 0 && args == nullptr) + return CompilerType(); // invalid argument array passed in + + // Verify that all arguments are valid and the right type for (unsigned i=0; i<num_args; ++i) - qual_type_args.push_back (GetQualType(args[i])); + { + if (args[i]) + { + // Make sure we have a clang type in args[i] and not a type from another + // language whose name might match + const bool is_clang_type = ClangUtil::IsClangType(args[i]); + lldbassert(is_clang_type); + if (is_clang_type) + qual_type_args.push_back(ClangUtil::GetQualType(args[i])); + else + return CompilerType(); // invalid argument type (must be a clang type) + } + else + return CompilerType(); // invalid argument type (empty) + } // TODO: Detect calling convention in DWARF? FunctionProtoType::ExtProtoInfo proto_info; @@ -2053,9 +2045,7 @@ ClangASTContext::CreateFunctionType (ASTContext *ast, proto_info.TypeQuals = type_quals; proto_info.RefQualifier = RQ_None; - return CompilerType (ast, ast->getFunctionType (GetQualType(result_type), - qual_type_args, - proto_info)); + return CompilerType(ast, ast->getFunctionType(ClangUtil::GetQualType(result_type), qual_type_args, proto_info)); } ParmVarDecl * @@ -2063,15 +2053,9 @@ ClangASTContext::CreateParameterDeclaration (const char *name, const CompilerTyp { ASTContext *ast = getASTContext(); assert (ast != nullptr); - return ParmVarDecl::Create(*ast, - ast->getTranslationUnitDecl(), - SourceLocation(), - SourceLocation(), - name && name[0] ? &ast->Idents.get(name) : nullptr, - GetQualType(param_type), - nullptr, - (clang::StorageClass)storage, - nullptr); + return ParmVarDecl::Create(*ast, ast->getTranslationUnitDecl(), SourceLocation(), SourceLocation(), + name && name[0] ? &ast->Idents.get(name) : nullptr, ClangUtil::GetQualType(param_type), + nullptr, (clang::StorageClass)storage, nullptr); } void @@ -2081,6 +2065,13 @@ ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl function_decl->setParams (ArrayRef<ParmVarDecl*>(params, num_params)); } +CompilerType +ClangASTContext::CreateBlockPointerType (const CompilerType &function_type) +{ + QualType block_type = m_ast_ap->getBlockPointerType(clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType())); + + return CompilerType (this, block_type.getAsOpaquePtr()); +} #pragma mark Array Types @@ -2096,7 +2087,7 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type, if (is_vector) { - return CompilerType (ast, ast->getExtVectorType(GetQualType(element_type), element_count)); + return CompilerType(ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type), element_count)); } else { @@ -2104,16 +2095,13 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type, llvm::APInt ap_element_count (64, element_count); if (element_count == 0) { - return CompilerType (ast, ast->getIncompleteArrayType (GetQualType(element_type), - ArrayType::Normal, - 0)); + return CompilerType(ast, ast->getIncompleteArrayType(ClangUtil::GetQualType(element_type), + clang::ArrayType::Normal, 0)); } else { - return CompilerType (ast, ast->getConstantArrayType (GetQualType(element_type), - ap_element_count, - ArrayType::Normal, - 0)); + return CompilerType(ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type), + ap_element_count, clang::ArrayType::Normal, 0)); } } } @@ -2121,13 +2109,17 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type, } CompilerType -ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name, - const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields, - bool packed) +ClangASTContext::CreateStructForIdentifier (const ConstString &type_name, + const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields, + bool packed) { CompilerType type; - if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid()) + if (!type_name.IsEmpty() && (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid()) + { + lldbassert("Trying to create a type for an existing name"); return type; + } + type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC); StartTagDeclarationDefinition(type); for (const auto& field : type_fields) @@ -2138,6 +2130,20 @@ ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name, return type; } +CompilerType +ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name, + const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields, + bool packed) +{ + CompilerType type; + if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid()) + return type; + + return CreateStructForIdentifier (type_name, + type_fields, + packed); +} + #pragma mark Enumeration Types CompilerType @@ -2171,8 +2177,8 @@ ClangASTContext::CreateEnumerationType if (enum_decl) { // TODO: check if we should be setting the promotion type too? - enum_decl->setIntegerType(GetQualType(integer_clang_type)); - + enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type)); + enum_decl->setAccess(AS_public); // TODO respect what's in the debug info return CompilerType (ast, ast->getTagDeclType(enum_decl)); @@ -2565,7 +2571,7 @@ ClangASTContext::SetDefaultAccessForRecordFields (clang::RecordDecl* record_decl clang::DeclContext * ClangASTContext::GetDeclContextForType (const CompilerType& type) { - return GetDeclContextForType(GetQualType(type)); + return GetDeclContextForType(ClangUtil::GetQualType(type)); } clang::DeclContext * @@ -2632,8 +2638,8 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool all external_ast_source->CompleteType(cxx_record_decl); if (cxx_record_decl->isCompleteDefinition()) { - cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true); cxx_record_decl->field_begin(); + cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true); } } } @@ -3082,9 +3088,11 @@ ClangASTContext::IsHomogeneousAggregate (lldb::opaque_compiler_type_t type, Comp bool is_hva = false; bool is_hfa = false; clang::QualType base_qual_type; + uint64_t base_bitwidth = 0; for (field_pos = record_decl->field_begin(); field_pos != field_end; ++field_pos) { clang::QualType field_qual_type = field_pos->getType(); + uint64_t field_bitwidth = getASTContext()->getTypeSize (qual_type); if (field_qual_type->isFloatingType()) { if (field_qual_type->isComplexType()) @@ -3105,22 +3113,21 @@ ClangASTContext::IsHomogeneousAggregate (lldb::opaque_compiler_type_t type, Comp } else if (field_qual_type->isVectorType() || field_qual_type->isExtVectorType()) { - const clang::VectorType *array = field_qual_type.getTypePtr()->getAs<clang::VectorType>(); - if (array && array->getNumElements() <= 4) + if (num_fields == 0) { - if (num_fields == 0) - base_qual_type = array->getElementType(); - else - { - if (is_hfa) - return 0; - is_hva = true; - if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr()) - return 0; - } + base_qual_type = field_qual_type; + base_bitwidth = field_bitwidth; } else - return 0; + { + if (is_hfa) + return 0; + is_hva = true; + if (base_bitwidth != field_bitwidth) + return 0; + if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr()) + return 0; + } } else return 0; @@ -3166,7 +3173,7 @@ ClangASTContext::GetFunctionArgumentAtIndex (lldb::opaque_compiler_type_t type, { if (type) { - clang::QualType qual_type (GetCanonicalQualType(type)); + clang::QualType qual_type (GetQualType(type)); const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr()); if (func) { @@ -3216,6 +3223,52 @@ ClangASTContext::IsFunctionPointerType (lldb::opaque_compiler_type_t type) } bool +ClangASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) +{ + if (type) + { + clang::QualType qual_type (GetCanonicalQualType(type)); + + if (qual_type->isBlockPointerType()) + { + if (function_pointer_type_ptr) + { + const clang::BlockPointerType *block_pointer_type = qual_type->getAs<clang::BlockPointerType>(); + QualType pointee_type = block_pointer_type->getPointeeType(); + QualType function_pointer_type = m_ast_ap->getPointerType(pointee_type); + *function_pointer_type_ptr = CompilerType (getASTContext(), function_pointer_type); + } + return true; + } + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + default: + break; + case clang::Type::Typedef: + return IsBlockPointerType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), function_pointer_type_ptr); + case clang::Type::Auto: + return IsBlockPointerType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), function_pointer_type_ptr); + case clang::Type::Elaborated: + return IsBlockPointerType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), function_pointer_type_ptr); + case clang::Type::Paren: + return IsBlockPointerType (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), function_pointer_type_ptr); + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + { + const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); + if (reference_type) + return IsBlockPointerType(reference_type->getPointeeType().getAsOpaquePtr(), function_pointer_type_ptr); + } + break; + } + } + return false; +} + +bool ClangASTContext::IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) { if (!type) @@ -3237,6 +3290,23 @@ ClangASTContext::IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_sign } bool +ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type, bool &is_signed) +{ + if (type) + { + const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type)->getCanonicalTypeInternal()); + + if (enum_type) + { + IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(), is_signed); + return true; + } + } + + return false; +} + +bool ClangASTContext::IsPointerType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type) { if (type) @@ -3466,8 +3536,8 @@ ClangASTContext::IsObjCClassType (const CompilerType& type) { if (type) { - clang::QualType qual_type (GetCanonicalQualType(type)); - + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); + const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type); if (obj_pointer_type) @@ -3479,13 +3549,33 @@ ClangASTContext::IsObjCClassType (const CompilerType& type) bool ClangASTContext::IsObjCObjectOrInterfaceType (const CompilerType& type) { - if (IsClangType(type)) - return GetCanonicalQualType(type)->isObjCObjectOrInterfaceType(); + if (ClangUtil::IsClangType(type)) + return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType(); return false; } bool -ClangASTContext::IsPolymorphicClass (lldb::opaque_compiler_type_t type) +ClangASTContext::IsClassType(lldb::opaque_compiler_type_t type) +{ + if (!type) + return false; + clang::QualType qual_type(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + return (type_class == clang::Type::Record); +} + +bool +ClangASTContext::IsEnumType(lldb::opaque_compiler_type_t type) +{ + if (!type) + return false; + clang::QualType qual_type(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + return (type_class == clang::Type::Enum); +} + +bool +ClangASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) { if (type) { @@ -3539,6 +3629,14 @@ ClangASTContext::IsPossibleDynamicType (lldb::opaque_compiler_type_t type, Compi case clang::Type::ObjCObjectPointer: if (check_objc) { + if (auto objc_pointee_type = qual_type->getPointeeType().getTypePtrOrNull()) + { + if (auto objc_object_type = llvm::dyn_cast_or_null<clang::ObjCObjectType>(objc_pointee_type)) + { + if (objc_object_type->isObjCClass()) + return false; + } + } if (dynamic_pointee_type) dynamic_pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType()); return true; @@ -3696,7 +3794,7 @@ ClangASTContext::GetCXXClassName (const CompilerType& type, std::string &class_n { if (type) { - clang::QualType qual_type (GetCanonicalQualType(type)); + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); if (!qual_type.isNull()) { clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); @@ -3717,8 +3815,8 @@ ClangASTContext::IsCXXClassType (const CompilerType& type) { if (!type) return false; - - clang::QualType qual_type (GetCanonicalQualType(type)); + + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr) return true; return false; @@ -3742,7 +3840,7 @@ ClangASTContext::IsObjCObjectPointerType (const CompilerType& type, CompilerType if (!type) return false; - clang::QualType qual_type (GetCanonicalQualType(type)); + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) { @@ -3770,9 +3868,9 @@ ClangASTContext::GetObjCClassName (const CompilerType& type, std::string &class_ { if (!type) return false; - - clang::QualType qual_type (GetCanonicalQualType(type)); - + + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); + const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); if (object_type) { @@ -3809,7 +3907,6 @@ ClangASTContext::GetTypeName (lldb::opaque_compiler_type_t type) clang::PrintingPolicy printing_policy (getASTContext()->getPrintingPolicy()); clang::QualType qual_type(GetQualType(type)); printing_policy.SuppressTagKeyword = true; - printing_policy.LangOpts.WChar = true; const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>(); if (typedef_type) { @@ -4491,7 +4588,7 @@ ClangASTContext::CreateTypedefType (const CompilerType& type, if (!ast) return CompilerType(); clang::ASTContext* clang_ast = ast->getASTContext(); - clang::QualType qual_type (GetQualType(type)); + clang::QualType qual_type(ClangUtil::GetQualType(type)); clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx); if (decl_ctx == nullptr) @@ -4621,6 +4718,20 @@ ClangASTContext::CreateTypedef (lldb::opaque_compiler_type_t type, const char *t &clang_ast->Idents.get(typedef_name), clang_ast->getTrivialTypeSourceInfo(qual_type)); + clang::TagDecl *tdecl = nullptr; + if (!qual_type.isNull()) + { + if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>()) + tdecl = rt->getDecl(); + if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>()) + tdecl = et->getDecl(); + } + + // Check whether this declaration is an anonymous struct, union, or enum, hidden behind a typedef. If so, we + // try to check whether we have a typedef tag to attach to the original record declaration + if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl()) + tdecl->setTypedefNameForAnonDecl(decl); + decl->setAccess(clang::AS_public); // TODO respect proper access specifier // Get a uniqued clang::QualType for the typedef decl type @@ -4643,18 +4754,6 @@ ClangASTContext::GetTypedefedType (lldb::opaque_compiler_type_t type) return CompilerType(); } -CompilerType -ClangASTContext::RemoveFastQualifiers (const CompilerType& type) -{ - if (IsClangType(type)) - { - clang::QualType qual_type(GetQualType(type)); - qual_type.getQualifiers().removeFastQualifiers(); - return CompilerType (type.GetTypeSystem(), qual_type.getAsOpaquePtr()); - } - return type; -} - //---------------------------------------------------------------------- // Create related types using the current type's AST @@ -4675,8 +4774,16 @@ ClangASTContext::GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContext if (GetCompleteType (type)) { clang::QualType qual_type(GetCanonicalQualType(type)); - switch (qual_type->getTypeClass()) + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) + return getASTContext()->getTypeSize(qual_type); + else + return 0; + break; + case clang::Type::ObjCInterface: case clang::Type::ObjCObject: { @@ -4710,7 +4817,7 @@ ClangASTContext::GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContext } } } - // fallthrough + LLVM_FALLTHROUGH; default: const uint32_t bit_size = getASTContext()->getTypeSize (qual_type); if (bit_size == 0) @@ -4740,97 +4847,127 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count { if (!type) return lldb::eEncodingInvalid; - + count = 1; clang::QualType qual_type(GetCanonicalQualType(type)); - + 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 (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) - { - 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::Half: - 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; - - case clang::BuiltinType::NullPtr: return lldb::eEncodingUint; - - case clang::BuiltinType::Kind::ARCUnbridgedCast: - case clang::BuiltinType::Kind::BoundMember: - case clang::BuiltinType::Kind::BuiltinFn: - case clang::BuiltinType::Kind::Dependent: - case clang::BuiltinType::Kind::OCLClkEvent: - case clang::BuiltinType::Kind::OCLEvent: - case clang::BuiltinType::Kind::OCLImage1d: - case clang::BuiltinType::Kind::OCLImage1dArray: - case clang::BuiltinType::Kind::OCLImage1dBuffer: - case clang::BuiltinType::Kind::OCLImage2d: - case clang::BuiltinType::Kind::OCLImage2dArray: - case clang::BuiltinType::Kind::OCLImage2dArrayDepth: - case clang::BuiltinType::Kind::OCLImage2dArrayMSAA: - case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepth: - case clang::BuiltinType::Kind::OCLImage2dDepth: - case clang::BuiltinType::Kind::OCLImage2dMSAA: - case clang::BuiltinType::Kind::OCLImage2dMSAADepth: - case clang::BuiltinType::Kind::OCLImage3d: - case clang::BuiltinType::Kind::OCLQueue: - case clang::BuiltinType::Kind::OCLNDRange: - case clang::BuiltinType::Kind::OCLReserveID: - case clang::BuiltinType::Kind::OCLSampler: - case clang::BuiltinType::Kind::OMPArraySection: - case clang::BuiltinType::Kind::Overload: - case clang::BuiltinType::Kind::PseudoObject: - case clang::BuiltinType::Kind::UnknownAny: - break; - } + { + 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::Half: + case clang::BuiltinType::Float: + case clang::BuiltinType::Float128: + 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; + + case clang::BuiltinType::NullPtr: + return lldb::eEncodingUint; + + case clang::BuiltinType::Kind::ARCUnbridgedCast: + case clang::BuiltinType::Kind::BoundMember: + case clang::BuiltinType::Kind::BuiltinFn: + case clang::BuiltinType::Kind::Dependent: + case clang::BuiltinType::Kind::OCLClkEvent: + case clang::BuiltinType::Kind::OCLEvent: + case clang::BuiltinType::Kind::OCLImage1dRO: + case clang::BuiltinType::Kind::OCLImage1dWO: + case clang::BuiltinType::Kind::OCLImage1dRW: + case clang::BuiltinType::Kind::OCLImage1dArrayRO: + case clang::BuiltinType::Kind::OCLImage1dArrayWO: + case clang::BuiltinType::Kind::OCLImage1dArrayRW: + case clang::BuiltinType::Kind::OCLImage1dBufferRO: + case clang::BuiltinType::Kind::OCLImage1dBufferWO: + case clang::BuiltinType::Kind::OCLImage1dBufferRW: + case clang::BuiltinType::Kind::OCLImage2dRO: + case clang::BuiltinType::Kind::OCLImage2dWO: + case clang::BuiltinType::Kind::OCLImage2dRW: + case clang::BuiltinType::Kind::OCLImage2dArrayRO: + case clang::BuiltinType::Kind::OCLImage2dArrayWO: + case clang::BuiltinType::Kind::OCLImage2dArrayRW: + case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO: + case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO: + case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW: + case clang::BuiltinType::Kind::OCLImage2dDepthRO: + case clang::BuiltinType::Kind::OCLImage2dDepthWO: + case clang::BuiltinType::Kind::OCLImage2dDepthRW: + case clang::BuiltinType::Kind::OCLImage2dMSAARO: + case clang::BuiltinType::Kind::OCLImage2dMSAAWO: + case clang::BuiltinType::Kind::OCLImage2dMSAARW: + case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO: + case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO: + case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW: + case clang::BuiltinType::Kind::OCLImage3dRO: + case clang::BuiltinType::Kind::OCLImage3dWO: + case clang::BuiltinType::Kind::OCLImage3dRW: + case clang::BuiltinType::Kind::OCLQueue: + case clang::BuiltinType::Kind::OCLNDRange: + case clang::BuiltinType::Kind::OCLReserveID: + case clang::BuiltinType::Kind::OCLSampler: + case clang::BuiltinType::Kind::OMPArraySection: + case clang::BuiltinType::Kind::Overload: + case clang::BuiltinType::Kind::PseudoObject: + case clang::BuiltinType::Kind::UnknownAny: + 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 @@ -4857,7 +4994,7 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count count = 2; return encoding; } - + case clang::Type::ObjCInterface: break; case clang::Type::Record: break; case clang::Type::Enum: return lldb::eEncodingSint; @@ -4866,13 +5003,13 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count case clang::Type::Auto: return CompilerType(getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetEncoding(count); - + case clang::Type::Elaborated: return CompilerType(getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count); - + case clang::Type::Paren: return CompilerType(getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetEncoding(count); - + case clang::Type::DependentSizedArray: case clang::Type::DependentSizedExtVector: case clang::Type::UnresolvedUsing: @@ -4885,7 +5022,7 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count case clang::Type::DependentTemplateSpecialization: case clang::Type::PackExpansion: case clang::Type::ObjCObject: - + case clang::Type::TypeOfExpr: case clang::Type::TypeOf: case clang::Type::Decltype: @@ -4894,7 +5031,7 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count case clang::Type::Adjusted: case clang::Type::Pipe: break; - + // pointer type decayed from an array or function type. case clang::Type::Decayed: break; @@ -5213,7 +5350,7 @@ ClangASTContext::GetNumChildren (lldb::opaque_compiler_type_t type, bool omit_em CompilerType ClangASTContext::GetBuiltinTypeByName (const ConstString &name) { - return GetBasicType (GetBasicTypeEnumeration (name)); + return GetBasicType(GetBasicTypeEnumeration(name)); } lldb::BasicType @@ -5817,7 +5954,8 @@ ClangASTContext::GetVirtualBaseClassAtIndex (lldb::opaque_compiler_type_t type, return GetVirtualBaseClassAtIndex (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), idx, bit_offset_ptr); case clang::Type::Paren: - return GetVirtualBaseClassAtIndex (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx, bit_offset_ptr); + return GetVirtualBaseClassAtIndex(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx, + bit_offset_ptr); default: break; @@ -5848,12 +5986,24 @@ ClangASTContext::GetNumPointeeChildren (clang::QualType type) 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::OCLImage1dRO: + case clang::BuiltinType::OCLImage1dWO: + case clang::BuiltinType::OCLImage1dRW: + case clang::BuiltinType::OCLImage1dArrayRO: + case clang::BuiltinType::OCLImage1dArrayWO: + case clang::BuiltinType::OCLImage1dArrayRW: + case clang::BuiltinType::OCLImage1dBufferRO: + case clang::BuiltinType::OCLImage1dBufferWO: + case clang::BuiltinType::OCLImage1dBufferRW: + case clang::BuiltinType::OCLImage2dRO: + case clang::BuiltinType::OCLImage2dWO: + case clang::BuiltinType::OCLImage2dRW: + case clang::BuiltinType::OCLImage2dArrayRO: + case clang::BuiltinType::OCLImage2dArrayWO: + case clang::BuiltinType::OCLImage2dArrayRW: + case clang::BuiltinType::OCLImage3dRO: + case clang::BuiltinType::OCLImage3dWO: + case clang::BuiltinType::OCLImage3dRW: case clang::BuiltinType::OCLSampler: return 0; case clang::BuiltinType::Bool: @@ -6070,8 +6220,9 @@ ClangASTContext::GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type, { clang::CharUnits base_offset_offset = itanium_vtable_ctx->getVirtualBaseOffsetOffset(cxx_record_decl, base_class_decl); const lldb::addr_t base_offset_addr = vtable_ptr + base_offset_offset.getQuantity(); - const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err); - if (base_offset != UINT32_MAX) + const uint32_t base_offset_size = process->GetAddressByteSize(); + const uint64_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, base_offset_size, UINT32_MAX, err); + if (base_offset < UINT32_MAX) { handled = true; bit_offset = base_offset * 8; @@ -6123,12 +6274,20 @@ ClangASTContext::GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type, CompilerType field_clang_type (getASTContext(), field->getType()); assert(field_idx < record_layout.getFieldCount()); child_byte_size = field_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); + const uint32_t child_bit_size = child_byte_size * 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 (getASTContext(), *field, child_bitfield_bit_size)) - child_bitfield_bit_offset = bit_offset % 8; + { + child_bitfield_bit_offset = bit_offset % child_bit_size; + const uint32_t child_bit_offset = bit_offset - child_bitfield_bit_offset; + child_byte_offset = child_bit_offset / 8; + } + else + { + child_byte_offset = bit_offset / 8; + } return field_clang_type; } @@ -7216,7 +7375,7 @@ CompilerType ClangASTContext::GetTypeForFormatters (void* type) { if (type) - return RemoveFastQualifiers(CompilerType(this, type)); + return ClangUtil::RemoveFastQualifiers(CompilerType(this, type)); return CompilerType(); } @@ -7439,7 +7598,7 @@ IsOperator (const char *name, clang::OverloadedOperatorKind &op_kind) clang::EnumDecl * ClangASTContext::GetAsEnumDecl (const CompilerType& type) { - const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type)); + const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type)); if (enutype) return enutype->getDecl(); return NULL; @@ -7448,7 +7607,7 @@ ClangASTContext::GetAsEnumDecl (const CompilerType& type) clang::RecordDecl * ClangASTContext::GetAsRecordDecl (const CompilerType& type) { - const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(GetCanonicalQualType(type)); + const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type)); if (record_type) return record_type->getDecl(); return nullptr; @@ -7457,7 +7616,7 @@ ClangASTContext::GetAsRecordDecl (const CompilerType& type) clang::TagDecl * ClangASTContext::GetAsTagDecl (const CompilerType& type) { - clang::QualType qual_type = GetCanonicalQualType(type); + clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type); if (qual_type.isNull()) return nullptr; else @@ -7473,7 +7632,8 @@ ClangASTContext::GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type) clang::ObjCInterfaceDecl * ClangASTContext::GetAsObjCInterfaceDecl (const CompilerType& type) { - const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(GetCanonicalQualType(type)); + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast<clang::ObjCObjectType>(ClangUtil::GetCanonicalQualType(type)); if (objc_class_type) return objc_class_type->getInterface(); return nullptr; @@ -7504,17 +7664,14 @@ ClangASTContext::AddFieldToRecordType (const CompilerType& type, const char *nam clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type); if (record_decl) { - field = clang::FieldDecl::Create (*clang_ast, - record_decl, - clang::SourceLocation(), - clang::SourceLocation(), - name ? &clang_ast->Idents.get(name) : nullptr, // Identifier - GetQualType(field_clang_type), // Field type - nullptr, // TInfo * - bit_width, // BitWidth - false, // Mutable - clang::ICIS_NoInit); // HasInit - + field = clang::FieldDecl::Create(*clang_ast, record_decl, clang::SourceLocation(), clang::SourceLocation(), + name ? &clang_ast->Idents.get(name) : nullptr, // Identifier + ClangUtil::GetQualType(field_clang_type), // Field type + nullptr, // TInfo * + bit_width, // BitWidth + false, // Mutable + clang::ICIS_NoInit); // HasInit + if (!name) { // Determine whether this field corresponds to an anonymous @@ -7549,18 +7706,14 @@ ClangASTContext::AddFieldToRecordType (const CompilerType& type, const char *nam const bool is_synthesized = false; field_clang_type.GetCompleteType(); - - field = clang::ObjCIvarDecl::Create (*clang_ast, - class_interface_decl, - clang::SourceLocation(), - clang::SourceLocation(), - name ? &clang_ast->Idents.get(name) : nullptr, // Identifier - GetQualType(field_clang_type), // Field type - nullptr, // TypeSourceInfo * - ConvertAccessTypeToObjCIvarAccessControl (access), - bit_width, - is_synthesized); - + + field = clang::ObjCIvarDecl::Create( + *clang_ast, class_interface_decl, clang::SourceLocation(), clang::SourceLocation(), + name ? &clang_ast->Idents.get(name) : nullptr, // Identifier + ClangUtil::GetQualType(field_clang_type), // Field type + nullptr, // TypeSourceInfo * + ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, is_synthesized); + if (field) { class_interface_decl->addDecl(field); @@ -7625,8 +7778,7 @@ ClangASTContext::BuildIndirectFields (const CompilerType& type) clang::SourceLocation(), nested_field_decl->getIdentifier(), nested_field_decl->getType(), - chain, - 2); + {chain, 2}); indirect_field->setImplicit(); @@ -7637,7 +7789,7 @@ ClangASTContext::BuildIndirectFields (const CompilerType& type) } else if (clang::IndirectFieldDecl *nested_indirect_field_decl = llvm::dyn_cast<clang::IndirectFieldDecl>(*di)) { - int nested_chain_size = nested_indirect_field_decl->getChainingSize(); + size_t nested_chain_size = nested_indirect_field_decl->getChainingSize(); clang::NamedDecl **chain = new (*ast->getASTContext()) clang::NamedDecl*[nested_chain_size + 1]; chain[0] = *field_pos; @@ -7656,8 +7808,7 @@ ClangASTContext::BuildIndirectFields (const CompilerType& type) clang::SourceLocation(), nested_indirect_field_decl->getIdentifier(), nested_indirect_field_decl->getType(), - chain, - nested_chain_size + 1); + {chain, nested_chain_size + 1}); indirect_field->setImplicit(); @@ -7720,14 +7871,15 @@ ClangASTContext::AddVariableToRecordType (const CompilerType& type, const char * clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type); if (record_decl) { - var_decl = clang::VarDecl::Create (*ast->getASTContext(), // ASTContext & - record_decl, // DeclContext * - clang::SourceLocation(), // clang::SourceLocation StartLoc - clang::SourceLocation(), // clang::SourceLocation IdLoc - name ? &ast->getASTContext()->Idents.get(name) : nullptr, // clang::IdentifierInfo * - GetQualType(var_type), // Variable clang::QualType - nullptr, // TypeSourceInfo * - clang::SC_Static); // StorageClass + var_decl = + clang::VarDecl::Create(*ast->getASTContext(), // ASTContext & + record_decl, // DeclContext * + clang::SourceLocation(), // clang::SourceLocation StartLoc + clang::SourceLocation(), // clang::SourceLocation IdLoc + name ? &ast->getASTContext()->Idents.get(name) : nullptr, // clang::IdentifierInfo * + ClangUtil::GetQualType(var_type), // Variable clang::QualType + nullptr, // TypeSourceInfo * + clang::SC_Static); // StorageClass if (var_decl) { var_decl->setAccess(ClangASTContext::ConvertAccessTypeToAccessSpecifier (access)); @@ -7762,9 +7914,9 @@ ClangASTContext::AddMethodToCXXRecordType (lldb::opaque_compiler_type_t type, co if (cxx_record_decl == nullptr) return nullptr; - - clang::QualType method_qual_type (GetQualType(method_clang_type)); - + + clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type)); + clang::CXXMethodDecl *cxx_method_decl = nullptr; clang::DeclarationName decl_name (&getASTContext()->Idents.get(name)); @@ -8048,17 +8200,16 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type, if (ivar_decl) prop_type_source = clang_ast->getTrivialTypeSourceInfo (ivar_decl->getType()); else - prop_type_source = clang_ast->getTrivialTypeSourceInfo (GetQualType(property_clang_type)); - - clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create (*clang_ast, - class_interface_decl, - clang::SourceLocation(), // Source Location - &clang_ast->Idents.get(property_name), - clang::SourceLocation(), //Source Location for AT - clang::SourceLocation(), //Source location for ( - ivar_decl ? ivar_decl->getType() : ClangASTContext::GetQualType(property_clang_type), - prop_type_source); - + prop_type_source = clang_ast->getTrivialTypeSourceInfo(ClangUtil::GetQualType(property_clang_type)); + + clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create( + *clang_ast, class_interface_decl, + clang::SourceLocation(), // Source Location + &clang_ast->Idents.get(property_name), + clang::SourceLocation(), // Source Location for AT + clang::SourceLocation(), // Source location for ( + ivar_decl ? ivar_decl->getType() : ClangUtil::GetQualType(property_clang_type), prop_type_source); + if (property_decl) { if (metadata) @@ -8113,32 +8264,32 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type, 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)) + if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_nullability) + property_decl->setPropertyAttributes(clang::ObjCPropertyDecl::OBJC_PR_nullability); + if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_null_resettable) + property_decl->setPropertyAttributes(clang::ObjCPropertyDecl::OBJC_PR_null_resettable); + if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) + property_decl->setPropertyAttributes(clang::ObjCPropertyDecl::OBJC_PR_class); + + const bool isInstance = (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) == 0; + + if (!getter_sel.isNull() && + !(isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel) + : class_interface_decl->lookupClassMethod(getter_sel))) { - const bool isInstance = true; const bool isVariadic = false; const bool isSynthesized = false; const bool isImplicitlyDeclared = true; const bool isDefined = false; const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None; const bool HasRelatedResultType = false; - - clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create (*clang_ast, - clang::SourceLocation(), - clang::SourceLocation(), - getter_sel, - GetQualType(property_clang_type_to_access), - nullptr, - class_interface_decl, - isInstance, - isVariadic, - isSynthesized, - isImplicitlyDeclared, - isDefined, - impControl, - HasRelatedResultType); - + + clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create( + *clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel, + ClangUtil::GetQualType(property_clang_type_to_access), nullptr, class_interface_decl, + isInstance, isVariadic, isSynthesized, isImplicitlyDeclared, isDefined, impControl, + HasRelatedResultType); + if (getter && metadata) ClangASTContext::SetMetadata(clang_ast, getter, *metadata); @@ -8149,12 +8300,12 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type, class_interface_decl->addDecl(getter); } } - - if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel)) + + if (!setter_sel.isNull() && + !(isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel) + : class_interface_decl->lookupClassMethod(setter_sel))) { clang::QualType result_type = clang_ast->VoidTy; - - const bool isInstance = true; const bool isVariadic = false; const bool isSynthesized = false; const bool isImplicitlyDeclared = true; @@ -8181,17 +8332,12 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type, ClangASTContext::SetMetadata(clang_ast, setter, *metadata); llvm::SmallVector<clang::ParmVarDecl *, 1> params; - - params.push_back (clang::ParmVarDecl::Create (*clang_ast, - setter, - clang::SourceLocation(), - clang::SourceLocation(), - nullptr, // anonymous - GetQualType(property_clang_type_to_access), - nullptr, - clang::SC_Auto, - nullptr)); - + + params.push_back(clang::ParmVarDecl::Create( + *clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(), + nullptr, // anonymous + ClangUtil::GetQualType(property_clang_type_to_access), nullptr, clang::SC_Auto, nullptr)); + if (setter) { setter->setMethodParams(*clang_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>()); @@ -8222,7 +8368,8 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type, const char *name, // the full symbol name as seen in the symbol table (lldb::opaque_compiler_type_t type, "-[NString stringWithCString:]") const CompilerType &method_clang_type, lldb::AccessType access, - bool is_artificial) + bool is_artificial, + bool is_variadic) { if (!type || !method_clang_type.IsValid()) return nullptr; @@ -8267,9 +8414,9 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type, clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, selector_idents.data()); - - clang::QualType method_qual_type (GetQualType(method_clang_type)); - + + clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type)); + // Populate the method decl with parameter decls const clang::Type *method_type(method_qual_type.getTypePtr()); @@ -8282,7 +8429,6 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type, return nullptr; - bool is_variadic = false; bool is_synthesized = false; bool is_defined = false; clang::ObjCMethodDecl::ImplementationControl imp_control = clang::ObjCMethodDecl::None; @@ -8291,23 +8437,18 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type, if (num_args != num_selectors_with_args) return nullptr; // some debug information is corrupt. We are not going to deal with it. - - clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create (*ast, - clang::SourceLocation(), // beginLoc, - clang::SourceLocation(), // endLoc, - method_selector, - method_function_prototype->getReturnType(), - nullptr, // TypeSourceInfo *ResultTInfo, - ClangASTContext::GetASTContext(ast)->GetDeclContextForType(GetQualType(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*/); - - + + clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create( + *ast, + clang::SourceLocation(), // beginLoc, + clang::SourceLocation(), // endLoc, + method_selector, method_function_prototype->getReturnType(), + nullptr, // TypeSourceInfo *ResultTInfo, + ClangASTContext::GetASTContext(ast)->GetDeclContextForType(ClangUtil::GetQualType(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 == nullptr) return nullptr; @@ -8343,10 +8484,10 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type, bool ClangASTContext::GetHasExternalStorage (const CompilerType &type) { - if (IsClangType(type)) + if (ClangUtil::IsClangType(type)) return false; - clang::QualType qual_type (GetCanonicalQualType(type)); + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) @@ -8474,158 +8615,12 @@ ClangASTContext::SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool } -bool -ClangASTContext::CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer) -{ - if (IsClangType(type)) - { - // TODO: remove external completion BOOL - // CompleteAndFetchChildren should get the Decl out and check for the - - clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type))); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - { - const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL)) - return true; - } - } - break; - - case clang::Type::Enum: - { - clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); - if (enum_decl) - { - if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL)) - return true; - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - { - 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(); - // 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 (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL)) - return true; - } - } - } - break; - - - case clang::Type::Typedef: - return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer); - - case clang::Type::Auto: - return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer); - - case clang::Type::Elaborated: - return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer); - - case clang::Type::Paren: - return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer); - - default: - break; - } - } - return false; -} -bool -ClangASTContext::Import (const CompilerType &type, lldb_private::ClangASTImporter &importer) -{ - if (IsClangType(type)) - { - // TODO: remove external completion BOOL - // CompleteAndFetchChildren should get the Decl out and check for the - - clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type))); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - { - const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL)) - return importer.CompleteAndFetchChildren(qual_type); - } - } - break; - - case clang::Type::Enum: - { - clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); - if (enum_decl) - { - if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL)) - return importer.CompleteAndFetchChildren(qual_type); - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - { - 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(); - // 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 (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL)) - return importer.CompleteAndFetchChildren(qual_type); - } - } - } - break; - - - case clang::Type::Typedef: - return Import (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer); - - case clang::Type::Auto: - return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer); - - case clang::Type::Elaborated: - return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer); - - case clang::Type::Paren: - return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer); - - default: - break; - } - } - return false; -} - - #pragma mark TagDecl bool ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type) { - clang::QualType qual_type (ClangASTContext::GetQualType(type)); + clang::QualType qual_type(ClangUtil::GetQualType(type)); if (!qual_type.isNull()) { const clang::TagType *tag_type = qual_type->getAs<clang::TagType>(); @@ -8656,21 +8651,31 @@ ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type) bool ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type) { - clang::QualType qual_type (ClangASTContext::GetQualType(type)); + clang::QualType qual_type(ClangUtil::GetQualType(type)); if (!qual_type.isNull()) { - clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - - if (cxx_record_decl) + // Make sure we use the same methodology as ClangASTContext::StartTagDeclarationDefinition() + // as to how we start/end the definition. Previously we were calling + const clang::TagType *tag_type = qual_type->getAs<clang::TagType>(); + if (tag_type) { - if (!cxx_record_decl->isCompleteDefinition()) - cxx_record_decl->completeDefinition(); - cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); - cxx_record_decl->setHasExternalLexicalStorage (false); - cxx_record_decl->setHasExternalVisibleStorage (false); - return true; + clang::TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) + { + clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(tag_decl); + + if (cxx_record_decl) + { + if (!cxx_record_decl->isCompleteDefinition()) + cxx_record_decl->completeDefinition(); + cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); + cxx_record_decl->setHasExternalLexicalStorage (false); + cxx_record_decl->setHasExternalVisibleStorage (false); + return true; + } + } } - + const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>(); if (enutype) @@ -8687,24 +8692,28 @@ ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type) clang::ASTContext *ast = lldb_ast->getASTContext(); /// TODO This really needs to be fixed. - - unsigned NumPositiveBits = 1; - unsigned NumNegativeBits = 0; - - clang::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)) + + QualType integer_type(enum_decl->getIntegerType()); + if (!integer_type.isNull()) { - if (enum_decl->getIntegerType()->isSignedIntegerType()) - promotion_qual_type = ast->IntTy; + unsigned NumPositiveBits = 1; + unsigned NumNegativeBits = 0; + + clang::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 = ast->UnsignedIntTy; + promotion_qual_type = enum_decl->getIntegerType(); + + enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); } - else - promotion_qual_type = enum_decl->getIntegerType(); - - enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); } return true; } @@ -8736,15 +8745,11 @@ ClangASTContext::AddEnumerationValueToEnumerationType (lldb::opaque_compiler_typ { llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed); enum_llvm_apsint = enum_value; - clang::EnumConstantDecl *enumerator_decl = - clang::EnumConstantDecl::Create (*getASTContext(), - enutype->getDecl(), - clang::SourceLocation(), - name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier - GetQualType(enumerator_clang_type), - nullptr, - enum_llvm_apsint); - + clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create( + *getASTContext(), enutype->getDecl(), clang::SourceLocation(), + name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier + ClangUtil::GetQualType(enumerator_clang_type), nullptr, enum_llvm_apsint); + if (enumerator_decl) { enutype->getDecl()->addDecl(enumerator_decl); @@ -8787,9 +8792,9 @@ ClangASTContext::CreateMemberPointerType (const CompilerType& type, const Compil ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); if (!ast) return CompilerType(); - return CompilerType (ast->getASTContext(), - ast->getASTContext()->getMemberPointerType (GetQualType(pointee_type), - GetQualType(type).getTypePtr())); + return CompilerType(ast->getASTContext(), + ast->getASTContext()->getMemberPointerType(ClangUtil::GetQualType(pointee_type), + ClangUtil::GetQualType(type).getTypePtr())); } return CompilerType(); } @@ -8816,18 +8821,10 @@ ClangASTContext::ConvertStringToFloatValue (lldb::opaque_compiler_type_t type, c 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); + Scalar scalar = ap_float.bitcastToAPInt().zextOrTrunc(llvm::NextPowerOf2(byte_size) * 8); + lldb_private::Error get_data_error; + if (scalar.GetAsMemoryData(dst, byte_size, lldb_private::endian::InlHostByteOrder(), get_data_error)) return byte_size; - } } } } @@ -9281,6 +9278,7 @@ ClangASTContext::DumpTypeValue (lldb::opaque_compiler_type_t type, Stream *s, return true; } // format was not enum, just fall through and dump the value as requested.... + LLVM_FALLTHROUGH; default: // We are down to a scalar type that we just need to display. @@ -9519,9 +9517,9 @@ ClangASTContext::DumpTypeDescription (lldb::opaque_compiler_type_t type, Stream void ClangASTContext::DumpTypeName (const CompilerType &type) { - if (IsClangType(type)) + if (ClangUtil::IsClangType(type)) { - clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type))); + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) @@ -9633,15 +9631,21 @@ ClangASTContext::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDec } } - DWARFASTParser * -ClangASTContext::GetDWARFParser () +ClangASTContext::GetDWARFParser() { if (!m_dwarf_ast_parser_ap) m_dwarf_ast_parser_ap.reset(new DWARFASTParserClang(*this)); return m_dwarf_ast_parser_ap.get(); } +PDBASTParser * +ClangASTContext::GetPDBParser() +{ + if (!m_pdb_ast_parser_ap) + m_pdb_ast_parser_ap.reset(new PDBASTParser(*this)); + return m_pdb_ast_parser_ap.get(); +} bool ClangASTContext::LayoutRecordType(void *baton, @@ -9654,30 +9658,13 @@ ClangASTContext::LayoutRecordType(void *baton, { ClangASTContext *ast = (ClangASTContext *)baton; DWARFASTParserClang *dwarf_ast_parser = (DWARFASTParserClang *)ast->GetDWARFParser(); - return dwarf_ast_parser->LayoutRecordType(record_decl, bit_size, alignment, field_offsets, base_offsets, vbase_offsets); + return dwarf_ast_parser->GetClangASTImporter().LayoutRecordType(record_decl, bit_size, alignment, field_offsets, + base_offsets, vbase_offsets); } //---------------------------------------------------------------------- // CompilerDecl override functions //---------------------------------------------------------------------- -lldb::VariableSP -ClangASTContext::DeclGetVariable (void *opaque_decl) -{ - if (llvm::dyn_cast<clang::VarDecl>((clang::Decl *)opaque_decl)) - { - auto decl_search_it = m_decl_objects.find(opaque_decl); - if (decl_search_it != m_decl_objects.end()) - return std::static_pointer_cast<Variable>(decl_search_it->second); - } - return VariableSP(); -} - -void -ClangASTContext::DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) -{ - if (m_decl_objects.find(opaque_decl) == m_decl_objects.end()) - m_decl_objects.insert(std::make_pair(opaque_decl, object)); -} ConstString ClangASTContext::DeclGetName (void *opaque_decl) @@ -9750,7 +9737,7 @@ ClangASTContext::DeclGetFunctionNumArguments(void *opaque_decl) if (clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>((clang::Decl*)opaque_decl)) return func_decl->param_size(); if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl)) - return objc_method->param_size(); + return objc_method->param_size(); else return 0; } @@ -9764,7 +9751,7 @@ ClangASTContext::DeclGetFunctionArgumentType (void *opaque_decl, size_t idx) { ParmVarDecl *var_decl = func_decl->getParamDecl(idx); if (var_decl) - return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr()); + return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr()); } } else if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl)) @@ -9780,7 +9767,9 @@ ClangASTContext::DeclGetFunctionArgumentType (void *opaque_decl, size_t idx) //---------------------------------------------------------------------- std::vector<CompilerDecl> -ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name) +ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, + ConstString name, + const bool ignore_using_decls) { std::vector<CompilerDecl> found_decls; if (opaque_decl_ctx) @@ -9804,12 +9793,16 @@ ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString na { if (clang::UsingDirectiveDecl *ud = llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) { + if (ignore_using_decls) + continue; clang::DeclContext *from = ud->getCommonAncestor(); if (searched.find(ud->getNominatedNamespace()) == searched.end()) search_queue.insert(std::make_pair(from, ud->getNominatedNamespace())); } else if (clang::UsingDecl *ud = llvm::dyn_cast<clang::UsingDecl>(child)) { + if (ignore_using_decls) + continue; for (clang::UsingShadowDecl *usd : ud->shadows()) { clang::Decl *target = usd->getTargetDecl(); @@ -9902,6 +9895,15 @@ ClangASTContext::CountDeclLevels (clang::DeclContext *frame_decl_ctx, { if (searched.find(it->second) != searched.end()) continue; + + // Currently DWARF has one shared translation unit for all Decls at top level, so this + // would erroneously find using statements anywhere. So don't look at the top-level + // translation unit. + // TODO fix this and add a testcase that depends on it. + + if (llvm::isa<clang::TranslationUnitDecl>(it->second)) + continue; + searched.insert(it->second); symbol_file->ParseDeclsForContext(CompilerDeclContext(this, it->second)); |