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"
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<DeclContext *, 1>
|
||||
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<DeclContext *, 1> 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<DeclContext *, 1> DeclContextTree::getChildDeclContext(
|
|||
|
||||
std::string File;
|
||||
unsigned Line = 0;
|
||||
unsigned ByteSize = 0;
|
||||
unsigned ByteSize = UINT32_MAX;
|
||||
|
||||
// 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;
|
||||
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);
|
||||
// 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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue