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:
parent
0ed0740c7e
commit
42562c38f5
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue