dsymutil: Also ignore the ByteSize when building the DeclContext cache for

clang modules.

Forward decls of ObjC interfaces don't have a bytesize.

llvm-svn: 249110
This commit is contained in:
Adrian Prantl 2015-10-02 00:27:08 +00:00
parent 0ed0740c7e
commit 42562c38f5
5 changed files with 75 additions and 58 deletions

View File

@ -8,7 +8,7 @@
header "Bar.h" header "Bar.h"
export * export *
} }
EOF EOF
clang -D BAR_H -E -o Bar.h modules.m clang -D BAR_H -E -o Bar.h modules.m
clang -D FOO_H -E -o Foo.h modules.m clang -D FOO_H -E -o Foo.h modules.m
clang -cc1 -emit-obj -fmodules -fmodule-map-file=modules.modulemap \ clang -cc1 -emit-obj -fmodules -fmodule-map-file=modules.modulemap \
@ -58,10 +58,16 @@ struct PruneMeNot;
// CHECK-NEXT: DW_AT_name{{.*}}"Foo" // CHECK-NEXT: DW_AT_name{{.*}}"Foo"
// CHECK-NOT: DW_TAG // CHECK-NOT: DW_TAG
// CHECK: DW_TAG_typedef // CHECK: DW_TAG_typedef
@import Bar; @import Bar;
typedef struct Bar Bar; typedef struct Bar Bar;
struct S {}; struct S {};
@interface Foo {
int ivar;
}
@end
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
#else #else
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -75,6 +81,10 @@ struct S {};
// CHECK: DW_TAG_typedef // CHECK: DW_TAG_typedef
// CHECK-NOT: DW_TAG // CHECK-NOT: DW_TAG
// CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BAR]]) // 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: DW_TAG_imported_declaration
// CHECK-NOT: DW_TAG // CHECK-NOT: DW_TAG
@ -82,9 +92,21 @@ struct S {};
// //
// CHECK: DW_TAG_subprogram // CHECK: DW_TAG_subprogram
// CHECK: DW_AT_name {{.*}}"main" // 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; @import Foo;
int main(int argc, char **argv) { int main(int argc, char **argv) {
Bar bar; Bar bar;
Foo *foo = 0;
bar.value = 42; bar.value = 42;
return bar.value; return bar.value;
} }

View File

@ -166,13 +166,14 @@ public:
/// required strings will be interned in \a StringPool. /// required strings will be interned in \a StringPool.
/// \returns The child DeclContext along with one bit that is set if /// \returns The child DeclContext along with one bit that is set if
/// this context is invalid. /// this context is invalid.
/// FIXME: the invalid bit along the return value is to emulate some /// An invalid context means it shouldn't be considered for uniquing, but its
/// dsymutil-classic functionality. See the fucntion definition for /// not returning null, because some children of that context might be
/// a more thorough discussion of its use. /// uniquing candidates. FIXME: The invalid bit along the return value is to
/// emulate some dsymutil-classic functionality.
PointerIntPair<DeclContext *, 1> PointerIntPair<DeclContext *, 1>
getChildDeclContext(DeclContext &Context, getChildDeclContext(DeclContext &Context,
const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &Unit, const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &Unit,
NonRelocatableStringpool &StringPool); NonRelocatableStringpool &StringPool, bool InClangModule);
DeclContext &getRoot() { return Root; } DeclContext &getRoot() { return Root; }
}; };
@ -1535,18 +1536,9 @@ bool DeclContext::setLastSeenDIE(CompileUnit &U,
return true; 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<DeclContext *, 1> DeclContextTree::getChildDeclContext( PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext(
DeclContext &Context, const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &U, DeclContext &Context, const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &U,
NonRelocatableStringpool &StringPool) { NonRelocatableStringpool &StringPool, bool InClangModule) {
unsigned Tag = DIE->getTag(); unsigned Tag = DIE->getTag();
// FIXME: dsymutil-classic compat: We should bail out here if we // FIXME: dsymutil-classic compat: We should bail out here if we
@ -1612,50 +1604,52 @@ PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext(
std::string File; std::string File;
unsigned Line = 0; unsigned Line = 0;
unsigned ByteSize = 0; unsigned ByteSize = UINT32_MAX;
// Gather some discriminating data about the DeclContext we will be if (!InClangModule) {
// creating: File, line number and byte size. This shouldn't be // Gather some discriminating data about the DeclContext we will be
// necessary, because the ODR is just about names, but given that we // creating: File, line number and byte size. This shouldn't be
// do some approximations with overloaded functions and anonymous // necessary, because the ODR is just about names, but given that we
// namespaces, use these additional data points to make the process // do some approximations with overloaded functions and anonymous
// safer. This is disabled for clang modules, because forward // namespaces, use these additional data points to make the process
// declarations of module-defined types do not have a file and line. // safer. This is disabled for clang modules, because forward
ByteSize = DIE->getAttributeValueAsUnsignedConstant( // declarations of module-defined types do not have a file and line.
&U.getOrigUnit(), dwarf::DW_AT_byte_size, UINT64_MAX); ByteSize = DIE->getAttributeValueAsUnsignedConstant(
if (!U.isClangModule() && (Tag != dwarf::DW_TAG_namespace || !Name)) { &U.getOrigUnit(), dwarf::DW_AT_byte_size, UINT64_MAX);
if (unsigned FileNum = DIE->getAttributeValueAsUnsignedConstant( if (Tag != dwarf::DW_TAG_namespace || !Name) {
&U.getOrigUnit(), dwarf::DW_AT_decl_file, 0)) { if (unsigned FileNum = DIE->getAttributeValueAsUnsignedConstant(
if (const auto *LT = U.getOrigUnit().getContext().getLineTableForUnit( &U.getOrigUnit(), dwarf::DW_AT_decl_file, 0)) {
&U.getOrigUnit())) { if (const auto *LT = U.getOrigUnit().getContext().getLineTableForUnit(
// FIXME: dsymutil-classic compatibility. I'd rather not &U.getOrigUnit())) {
// unique anything in anonymous namespaces, but if we do, then // FIXME: dsymutil-classic compatibility. I'd rather not
// verify that the file and line correspond. // unique anything in anonymous namespaces, but if we do, then
if (!Name && Tag == dwarf::DW_TAG_namespace) // verify that the file and line correspond.
FileNum = 1; if (!Name && Tag == dwarf::DW_TAG_namespace)
FileNum = 1;
// FIXME: Passing U.getOrigUnit().getCompilationDir() // FIXME: Passing U.getOrigUnit().getCompilationDir()
// instead of "" would allow more uniquing, but for now, do // instead of "" would allow more uniquing, but for now, do
// it this way to match dsymutil-classic. // it this way to match dsymutil-classic.
if (LT->getFileNameByIndex( if (LT->getFileNameByIndex(
FileNum, "", FileNum, "",
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
File)) { File)) {
Line = DIE->getAttributeValueAsUnsignedConstant( Line = DIE->getAttributeValueAsUnsignedConstant(
&U.getOrigUnit(), dwarf::DW_AT_decl_line, 0); &U.getOrigUnit(), dwarf::DW_AT_decl_line, 0);
#ifdef HAVE_REALPATH #ifdef HAVE_REALPATH
// Cache the resolved paths, because calling realpath is expansive. // Cache the resolved paths, because calling realpath is expansive.
if (const char *ResolvedPath = U.getResolvedPath(FileNum)) { if (const char *ResolvedPath = U.getResolvedPath(FileNum)) {
File = ResolvedPath; File = ResolvedPath;
} else { } else {
char RealPath[PATH_MAX + 1]; char RealPath[PATH_MAX + 1];
RealPath[PATH_MAX] = 0; RealPath[PATH_MAX] = 0;
if (::realpath(File.c_str(), RealPath)) if (::realpath(File.c_str(), RealPath))
File = RealPath; File = RealPath;
U.setResolvedPath(FileNum, File); U.setResolvedPath(FileNum, File);
} }
#endif #endif
FileRef = StringPool.internString(File); FileRef = StringPool.internString(File);
}
} }
} }
} }
@ -1787,10 +1781,11 @@ static bool analyzeContextInfo(const DWARFDebugInfoEntryMinimal *DIE,
} }
Info.ParentIdx = ParentIdx; Info.ParentIdx = ParentIdx;
if (CU.hasODR() || CU.isClangModule() || InImportedModule) { bool InClangModule = CU.isClangModule() || InImportedModule;
if (CU.hasODR() || InClangModule) {
if (CurrentDeclContext) { if (CurrentDeclContext) {
auto PtrInvalidPair = Contexts.getChildDeclContext(*CurrentDeclContext, auto PtrInvalidPair = Contexts.getChildDeclContext(
DIE, CU, StringPool); *CurrentDeclContext, DIE, CU, StringPool, InClangModule);
CurrentDeclContext = PtrInvalidPair.getPointer(); CurrentDeclContext = PtrInvalidPair.getPointer();
Info.Ctxt = Info.Ctxt =
PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer(); PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer();