From bc01088257ad46b5c34712954edd2c4a2acce7ad Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 2 Oct 2015 00:27:08 +0000 Subject: [PATCH] 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 --- test/tools/dsymutil/Inputs/modules/1.o | Bin 2392 -> 2444 bytes test/tools/dsymutil/Inputs/modules/Bar.pcm | Bin 25636 -> 25636 bytes test/tools/dsymutil/Inputs/modules/Foo.pcm | Bin 25464 -> 26060 bytes test/tools/dsymutil/X86/modules.m | 24 ++++- tools/dsymutil/DwarfLinker.cpp | 113 ++++++++++----------- 5 files changed, 77 insertions(+), 60 deletions(-) diff --git a/test/tools/dsymutil/Inputs/modules/1.o b/test/tools/dsymutil/Inputs/modules/1.o index e7a52931b9f83c7b521e7ff4819e568de87dff34..eca930c905c47c7dd176d4cd9d1c558858739577 100644 GIT binary patch delta 830 zcmZWo&ubG=5T3WYFZ-*mSyM-nj$8dXBk8%1TmHx7WMFdc1&epZnMh5NB6LjSd5ZCJ+U4)v{)mvK{sK~==GPhlky z^NV;?EBH;VT_eUi*0u1DT2jF}ekS#!%FQTs6$3r=xBpQ$ahlX!dYtrF<^IAoJq(^J z^@viR(5x)oK;I|?pHy^7ML(!FQNyZ{wdZUA9$^uej469;{d8uF^H9iqx_B&qsJpLL zdw3^1ckjW>?e1LvK=F7U&&slXYjzeRnd?k}?v(-nX~Cd-!tF`{Byd9p;r{j3qq>3_$(F0xDgcu zogUDN3yV7uL_x&jFX+mZpeu1D?)(X!lev-FUO4Bw-*>*bkGbbj^sVPfO%^QZj6WI+ z$+!}INm7@6X#qTqVe(tay_($CxC=*wlCL!D!U{gzq`ubj3Vs(VZiA!F5x`EiRZL5r91)r08*ewc}dO3|ZY5HzE}SI5rqsYLL+#{*QY7V1`G6 zAOP@p02?w9DM3)BPXh^i!pJtmZ13*yXFGmB=Dr&X>4cvs=yh@0$+!7YjiZ!~Qz#1a z1Eo_uISiJVI7l;_qBGbmrp{3|CLdFFjAVI!GrPRlVNWT$M$%elHdUbv-g!#4<-Z{C z*I2kl$(a)d@73Kr!-S5;U6uBqM^^*L0v~aPf}QcP++6~wQ*3wg61OPWxzyOWfLGkA sXyRM{b`ONvVKvK5R>EG*58H5nL`IZtev7H&QHxsDy< zg~@8Vt||@;42%q5AON92WP<_&Lq`J#N23AVp#IV?TF$>M^u#U4iM z4b1_zTMkSAX|lNDY_);eaz~@}l4k1_&K5fuEvGbFTsdsHr_ll^vZqmc$3f{0&Q=|V zrF)pITbixs9F{)QDE**O`hepDHU|L~Mu8m%C4g2kPOj5a5qT)M{b`ONvVKvK5R>EQ}3}G#MC_Ip2g%yJk(ar(fn@c@Nm~5AeNI z;LA7Qdn3U2t^mkj&ud`MV_ad^O%478GkVRD_Gib!L5;sGy4r^F(?44}_d zelVIGYS_F@PmEO@M<8x~Y@El4Q!>MpO+)C$R?liN2L6*k13_R9H}m9%*p|s2aWR_{ Y;`TA)(mdHTX(mgV=gF+imy&`Q0Xw3RvH$=8 diff --git a/test/tools/dsymutil/Inputs/modules/Foo.pcm b/test/tools/dsymutil/Inputs/modules/Foo.pcm index a715bfaa7f21fb09386dfab1a983b06a5ba4fbd9..4a39a06c24dd94b16cba5c21d94c484df03db7f4 100644 GIT binary patch delta 1712 zcmZ`(eN0deTj=A{}>1u@$9mqRUUw??0i_IEP_c**&e$<4yEUq^leL8{}{^{pKm!tay>$ zp>h~5E4#Powq|+;>52c*!_9OK>3a%2sRWsArjfkEaN4zLA6Mw=7FxsSMozZ?5Txc? zX2$q*OR{Z$cB*V?YrE8**?sn049~LZ;yo>!Q;-PwYPL zv4Yu<>2aTR$(iR<+58^+q}P7aY4sD^sMop_vdw#}$jp08{-DX{%o_@suBq((Ui)~+ zwBRwVcuaxf6-|-E6UiS;z#|DA%SefPuo~kJR*-|8of)SwIrBy^rOQjd%gEFJqzCZo z^vN|AqNNF$)oKI!jkGspBLF*5Ga+y??PR$c&@G}FO9ORP zbdirGI+|R6qsJL-mBVA~0)B6sVL7)yXfUtBD=!<3kGBx^C2zEV~ zNCOANyD>5*K8kt)bzBpH2dL$C0>7dD2m`pQVk|i^_(aj>T(D)h05icCvq}6m6F4Je zcWmz*&e^+X7sl)BmJ@WE6FmH#CRKD3xQ>u75tz73mutI7DXpxlH1t`!8lHh@9JsK& z6NsWW>(Xg#y`N^)7p1z>CCh9w79+r_&nnPwC7{QeV=Eyk%wfB*F+bElHgNFydv^4x zq4iSZdDbYpe5!^up$HK*;xR_BGUg&0M?CT5ZT8)XnL=|*Lb&)5+gDBfyfG?~y^V^L zx3#02rZ-mf5S1thd4gSd*dqXFqCh2<8<}kt_93A)A|VL*iTLK3ap@2QWFvII zwj^LJB4gk=(Wq95QoKoA?Mb{i94y5O+G95KPVfwImqfA5?X&B6vplk3hX0y m7Qt>ef?!Fq>#^jq8cbLYjAE&p5h&~mj5H*Os8&785o`BuuchRQa+U$QJb< z+QOVJ3n{z&K~NH+{)ZY3&Jd$X+5D{igDf#ljY(N%wj~QT@gr!K=(+HkO%qOf?z!i8 z&OP_tb8oZXlFctk%4>}D!j|OuZ5!#GIWfKK_Nn`nqpQ4ys)=MQQ1x~Yt_Nu|@fh=R za+i#AL3#mk;2GJMO=BPZ@c}%1A6F|p#$`EsTE=hp(N_@rdj4CaHbgTI;7U1)cn{|> zM&#@Q?hMf(#IOGkzZ{~UAbwBA&&fp=LbRCo7)^3VPRN)G({BDyaaS0CAQ}iS&+|35 zin_;}swCUU$k`Vh<6~!{!%|&CV|{I16~O+YG3%?X?etbn(>~$vw~F3Re3q#@r8;k$ znsl!a_r+G%lv;t6SiekJ>Oa_4NkDGD7g<4)0Fq*##3v|U~L&1ae7+-c4=+iFR*Hhz7z<()~_=f1KPV#Obp&<{IxzqN~B?8#nr&rVvi zc{~O0(}Q<=A3Z?OcEKtEXbsTuu0Jn8S``aweoc#itckxkbun-8x>vWJ7w)FT=WZXc^W@ zj!R~>(8N$>eu6M;m)<=$o}( z+TXik2-WCqAB`#jQl_mqq352xM+l|CZlxEAW+q`OV(+LN^~g-3gp9Jku7RRkkR_aa zMQ3WCCbuzLBjiXhS`W%5~!KBr0j)kD&qL0R{652}&h=L^RkGKlpsW3R%l<*xysUuv>*qCIq#da2 QL)fyz)D;<}OOc9y0hmfH=l}o! 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(); -- 2.34.1