From: Adrian Prantl Date: Fri, 2 Oct 2015 00:27:08 +0000 (+0000) Subject: dsymutil: Also ignore the ByteSize when building the DeclContext cache for X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bc01088257ad46b5c34712954edd2c4a2acce7ad;p=oota-llvm.git dsymutil: Also ignore the ByteSize when building the DeclContext cache for clang modules. Forward decls of ObjC interfaces don't have a bytesize. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249110 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/dsymutil/Inputs/modules/1.o b/test/tools/dsymutil/Inputs/modules/1.o index e7a52931b9f..eca930c905c 100644 Binary files a/test/tools/dsymutil/Inputs/modules/1.o and b/test/tools/dsymutil/Inputs/modules/1.o differ diff --git a/test/tools/dsymutil/Inputs/modules/Bar.pcm b/test/tools/dsymutil/Inputs/modules/Bar.pcm index bd77ec55826..f3c0d07f2c5 100644 Binary files a/test/tools/dsymutil/Inputs/modules/Bar.pcm and b/test/tools/dsymutil/Inputs/modules/Bar.pcm differ diff --git a/test/tools/dsymutil/Inputs/modules/Foo.pcm b/test/tools/dsymutil/Inputs/modules/Foo.pcm index a715bfaa7f2..4a39a06c24d 100644 Binary files a/test/tools/dsymutil/Inputs/modules/Foo.pcm and b/test/tools/dsymutil/Inputs/modules/Foo.pcm differ diff --git a/test/tools/dsymutil/X86/modules.m b/test/tools/dsymutil/X86/modules.m index 63d628baa5a..b392c30d062 100644 --- a/test/tools/dsymutil/X86/modules.m +++ b/test/tools/dsymutil/X86/modules.m @@ -8,7 +8,7 @@ header "Bar.h" export * } - EOF +EOF clang -D BAR_H -E -o Bar.h modules.m clang -D FOO_H -E -o Foo.h modules.m clang -cc1 -emit-obj -fmodules -fmodule-map-file=modules.modulemap \ @@ -58,10 +58,16 @@ struct PruneMeNot; // CHECK-NEXT: DW_AT_name{{.*}}"Foo" // CHECK-NOT: DW_TAG // CHECK: DW_TAG_typedef + @import Bar; typedef struct Bar Bar; struct S {}; +@interface Foo { + int ivar; +} +@end + // --------------------------------------------------------------------- #else // --------------------------------------------------------------------- @@ -75,6 +81,10 @@ struct S {}; // CHECK: DW_TAG_typedef // CHECK-NOT: DW_TAG // CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BAR]]) +// CHECK: 0x0[[INTERFACE:.*]]: DW_TAG_structure_type +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name{{.*}}"Foo" + // // CHECK: DW_TAG_imported_declaration // CHECK-NOT: DW_TAG @@ -82,9 +92,21 @@ struct S {}; // // CHECK: DW_TAG_subprogram // CHECK: DW_AT_name {{.*}}"main" +// +// CHECK: DW_TAG_variable +// CHECK: DW_TAG_variable +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name{{.*}}"foo" +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_type {{.*}}{0x{{0*}}[[PTR:.*]]} +// +// CHECK: 0x{{0*}}[[PTR]]: DW_TAG_pointer_type +// CHECK-NEXT DW_AT_type [DW_FORM_ref_addr] {0x{{0*}}[[INTERFACE]]) + @import Foo; int main(int argc, char **argv) { Bar bar; + Foo *foo = 0; bar.value = 42; return bar.value; } diff --git a/tools/dsymutil/DwarfLinker.cpp b/tools/dsymutil/DwarfLinker.cpp index 8489189cc16..c877264a067 100644 --- a/tools/dsymutil/DwarfLinker.cpp +++ b/tools/dsymutil/DwarfLinker.cpp @@ -166,13 +166,14 @@ public: /// required strings will be interned in \a StringPool. /// \returns The child DeclContext along with one bit that is set if /// this context is invalid. - /// FIXME: the invalid bit along the return value is to emulate some - /// dsymutil-classic functionality. See the fucntion definition for - /// a more thorough discussion of its use. + /// An invalid context means it shouldn't be considered for uniquing, but its + /// not returning null, because some children of that context might be + /// uniquing candidates. FIXME: The invalid bit along the return value is to + /// emulate some dsymutil-classic functionality. PointerIntPair getChildDeclContext(DeclContext &Context, const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &Unit, - NonRelocatableStringpool &StringPool); + NonRelocatableStringpool &StringPool, bool InClangModule); DeclContext &getRoot() { return Root; } }; @@ -1535,18 +1536,9 @@ bool DeclContext::setLastSeenDIE(CompileUnit &U, return true; } -/// Get the child context of \a Context corresponding to \a DIE. -/// -/// \returns the child context or null if we shouldn't track children -/// contexts. It also returns an additional bit meaning 'invalid'. An -/// invalid context means it shouldn't be considered for uniquing, but -/// its not returning null, because some children of that context -/// might be uniquing candidates. -/// FIXME: this is for dsymutil-classic compatibility, I don't think -/// it buys us much. PointerIntPair DeclContextTree::getChildDeclContext( DeclContext &Context, const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &U, - NonRelocatableStringpool &StringPool) { + NonRelocatableStringpool &StringPool, bool InClangModule) { unsigned Tag = DIE->getTag(); // FIXME: dsymutil-classic compat: We should bail out here if we @@ -1612,50 +1604,52 @@ PointerIntPair DeclContextTree::getChildDeclContext( std::string File; unsigned Line = 0; - unsigned ByteSize = 0; - - // Gather some discriminating data about the DeclContext we will be - // creating: File, line number and byte size. This shouldn't be - // necessary, because the ODR is just about names, but given that we - // do some approximations with overloaded functions and anonymous - // namespaces, use these additional data points to make the process - // safer. This is disabled for clang modules, because forward - // declarations of module-defined types do not have a file and line. - ByteSize = DIE->getAttributeValueAsUnsignedConstant( - &U.getOrigUnit(), dwarf::DW_AT_byte_size, UINT64_MAX); - if (!U.isClangModule() && (Tag != dwarf::DW_TAG_namespace || !Name)) { - if (unsigned FileNum = DIE->getAttributeValueAsUnsignedConstant( - &U.getOrigUnit(), dwarf::DW_AT_decl_file, 0)) { - if (const auto *LT = U.getOrigUnit().getContext().getLineTableForUnit( - &U.getOrigUnit())) { - // FIXME: dsymutil-classic compatibility. I'd rather not - // unique anything in anonymous namespaces, but if we do, then - // verify that the file and line correspond. - if (!Name && Tag == dwarf::DW_TAG_namespace) - FileNum = 1; - - // FIXME: Passing U.getOrigUnit().getCompilationDir() - // instead of "" would allow more uniquing, but for now, do - // it this way to match dsymutil-classic. - if (LT->getFileNameByIndex( - FileNum, "", - DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, - File)) { - Line = DIE->getAttributeValueAsUnsignedConstant( - &U.getOrigUnit(), dwarf::DW_AT_decl_line, 0); + unsigned ByteSize = UINT32_MAX; + + if (!InClangModule) { + // Gather some discriminating data about the DeclContext we will be + // creating: File, line number and byte size. This shouldn't be + // necessary, because the ODR is just about names, but given that we + // do some approximations with overloaded functions and anonymous + // namespaces, use these additional data points to make the process + // safer. This is disabled for clang modules, because forward + // declarations of module-defined types do not have a file and line. + ByteSize = DIE->getAttributeValueAsUnsignedConstant( + &U.getOrigUnit(), dwarf::DW_AT_byte_size, UINT64_MAX); + if (Tag != dwarf::DW_TAG_namespace || !Name) { + if (unsigned FileNum = DIE->getAttributeValueAsUnsignedConstant( + &U.getOrigUnit(), dwarf::DW_AT_decl_file, 0)) { + if (const auto *LT = U.getOrigUnit().getContext().getLineTableForUnit( + &U.getOrigUnit())) { + // FIXME: dsymutil-classic compatibility. I'd rather not + // unique anything in anonymous namespaces, but if we do, then + // verify that the file and line correspond. + if (!Name && Tag == dwarf::DW_TAG_namespace) + FileNum = 1; + + // FIXME: Passing U.getOrigUnit().getCompilationDir() + // instead of "" would allow more uniquing, but for now, do + // it this way to match dsymutil-classic. + if (LT->getFileNameByIndex( + FileNum, "", + DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, + File)) { + Line = DIE->getAttributeValueAsUnsignedConstant( + &U.getOrigUnit(), dwarf::DW_AT_decl_line, 0); #ifdef HAVE_REALPATH - // Cache the resolved paths, because calling realpath is expansive. - if (const char *ResolvedPath = U.getResolvedPath(FileNum)) { - File = ResolvedPath; - } else { - char RealPath[PATH_MAX + 1]; - RealPath[PATH_MAX] = 0; - if (::realpath(File.c_str(), RealPath)) - File = RealPath; - U.setResolvedPath(FileNum, File); - } + // Cache the resolved paths, because calling realpath is expansive. + if (const char *ResolvedPath = U.getResolvedPath(FileNum)) { + File = ResolvedPath; + } else { + char RealPath[PATH_MAX + 1]; + RealPath[PATH_MAX] = 0; + if (::realpath(File.c_str(), RealPath)) + File = RealPath; + U.setResolvedPath(FileNum, File); + } #endif - FileRef = StringPool.internString(File); + FileRef = StringPool.internString(File); + } } } } @@ -1787,10 +1781,11 @@ static bool analyzeContextInfo(const DWARFDebugInfoEntryMinimal *DIE, } Info.ParentIdx = ParentIdx; - if (CU.hasODR() || CU.isClangModule() || InImportedModule) { + bool InClangModule = CU.isClangModule() || InImportedModule; + if (CU.hasODR() || InClangModule) { if (CurrentDeclContext) { - auto PtrInvalidPair = Contexts.getChildDeclContext(*CurrentDeclContext, - DIE, CU, StringPool); + auto PtrInvalidPair = Contexts.getChildDeclContext( + *CurrentDeclContext, DIE, CU, StringPool, InClangModule); CurrentDeclContext = PtrInvalidPair.getPointer(); Info.Ctxt = PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer();