From 99cb0224000ece85afb25a596356e70ab0434e3b Mon Sep 17 00:00:00 2001 From: Sean Callanan Date: Tue, 23 Feb 2016 00:51:52 +0000 Subject: [PATCH] Fixed a problem where the DWARF for inline functions was mis-parsed. Inline functions in DWARF have AT_abstract_origin set, but we only handled that if the functions were C++ methods. Inline functions -- C or C++ -- have this also, and as a result they got one FunctionDecl for each inlined instance. When going to construct the locals, this meant that the arguments (which did properly have their abstract origins handled) would get associated with the master FunctionDecl, and the inlined FunctionDecls would all appear to have no locals. This manifested as not being able to look up local variables when stopped in an inline fuunction. We should have had a test for this, but somewhere along the line the relevant test case lost its .py file (or it never had one). This patch fixes this problem and restores the .py file. llvm-svn: 261598 --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 101 +++++++++++------- 1 file changed, 65 insertions(+), 36 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 358febc4b328..ac73cdf3695e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -33,6 +33,7 @@ #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Target/Language.h" +#include "lldb/Utility/LLDBAssert.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "clang/AST/DeclCXX.h" @@ -1515,44 +1516,72 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, if (!type_handled) { - // We just have a function that isn't part of a class - clang::FunctionDecl *function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - type_name_cstr, - clang_type, - storage, - is_inline); - - // if (template_param_infos.GetSize() > 0) - // { - // clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx, - // function_decl, - // type_name_cstr, - // template_param_infos); - // - // CreateFunctionTemplateSpecializationInfo (function_decl, - // func_template_decl, - // template_param_infos); - // } - // Add the decl to our DIE to decl context map - assert (function_decl); - LinkDeclContextToDIE(function_decl, die); - if (!function_param_decls.empty()) - m_ast.SetFunctionParameters (function_decl, - &function_param_decls.front(), - function_param_decls.size()); - - ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); - - if (!object_pointer_name.empty()) + clang::FunctionDecl *function_decl = nullptr; + + if (abstract_origin_die_form.IsValid()) { - metadata.SetObjectPtrName(object_pointer_name.c_str()); - if (log) - log->Printf ("Setting object pointer name: %s on function object %p.", - object_pointer_name.c_str(), - static_cast(function_decl)); + DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(abstract_origin_die_form)); + + SymbolContext sc; + + if (dwarf->ResolveType (abs_die)) + { + function_decl = llvm::dyn_cast_or_null(GetCachedClangDeclContextForDIE(abs_die)); + + if (function_decl) + { + LinkDeclContextToDIE(function_decl, die); + } + } + } + + if (!function_decl) + { + // We just have a function that isn't part of a class + function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, + type_name_cstr, + clang_type, + storage, + is_inline); + + // if (template_param_infos.GetSize() > 0) + // { + // clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx, + // function_decl, + // type_name_cstr, + // template_param_infos); + // + // CreateFunctionTemplateSpecializationInfo (function_decl, + // func_template_decl, + // template_param_infos); + // } + // Add the decl to our DIE to decl context map + + lldbassert (function_decl); + + if (function_decl) + { + LinkDeclContextToDIE(function_decl, die); + + if (!function_param_decls.empty()) + m_ast.SetFunctionParameters (function_decl, + &function_param_decls.front(), + function_param_decls.size()); + + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); + + if (!object_pointer_name.empty()) + { + metadata.SetObjectPtrName(object_pointer_name.c_str()); + if (log) + log->Printf ("Setting object pointer name: %s on function object %p.", + object_pointer_name.c_str(), + static_cast(function_decl)); + } + m_ast.SetMetadata (function_decl, metadata); + } } - m_ast.SetMetadata (function_decl, metadata); } } type_sp.reset( new Type (die.GetID(),