/* Compile with:
cat >modules.modulemap <<EOF
module Foo {
header "Foo.h"
export *
}
module Bar {
header "Bar.h"
export *
}
EOF
clang -D BAR_H -E -o Bar.h modules.m
clang -D FOO_H -E -o Foo.h modules.m
clang -D ODR_VIOLATION_C -E -o odr_violation.c modules.m
clang -c -fmodules -fmodule-map-file=modules.modulemap \
-g -gmodules -fmodules-cache-path=. \
-Xclang -fdisable-module-hash modules.m -o 1.o
clang -c -g odr_violation.c -o 2.o
*/
// RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/modules \
// RUN: -y %p/dummy-debug-map.map -o - \
// RUN: | llvm-dwarfdump -v --debug-info - | FileCheck %s
// RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/modules -y \
// RUN: %p/dummy-debug-map.map -o %t 2>&1 | FileCheck --check-prefix=WARN %s
// WARN-NOT: warning: hash mismatch
// ---------------------------------------------------------------------
#ifdef BAR_H
// ---------------------------------------------------------------------
// CHECK: DW_TAG_compile_unit
// CHECK-NOT: DW_AT_GNU_dwo_id
// CHECK-NOT: DW_TAG
// CHECK: DW_TAG_module
// CHECK-NEXT: DW_AT_name{{.*}}"Bar"
// CHECK: 0x0[[BAR:.*]]: DW_TAG_structure_type
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_name {{.*}}"Bar"
// CHECK-NOT: DW_TAG
// CHECK: DW_TAG_member
// CHECK: DW_AT_name {{.*}}"value"
// CHECK: DW_TAG_structure_type
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_name {{.*}}"PruneMeNot"
struct Bar {
int value;
};
struct PruneMeNot;
#else
// ---------------------------------------------------------------------
#ifdef FOO_H
// ---------------------------------------------------------------------
// CHECK: DW_TAG_compile_unit
// CHECK-NOT: DW_AT_GNU_dwo_id
// CHECK-NOT: DW_TAG
// CHECK: 0x0[[FOO:.*]]: DW_TAG_module
// CHECK-NEXT: DW_AT_name{{.*}}"Foo"
// CHECK-NOT: DW_TAG
// CHECK: 0x0[[BARTD:.*]]: DW_TAG_typedef
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BAR]]
// CHECK: DW_TAG_structure_type
// CHECK-NEXT: DW_AT_name{{.*}}"S"
// CHECK-NOT: DW_TAG
// CHECK: 0x0[[INTERFACE:.*]]: DW_TAG_structure_type
// CHECK-NEXT: DW_AT_name{{.*}}"Foo"
@import Bar;
typedef struct Bar Bar;
struct S {};
@interface Foo {
int ivar;
}
@end
#else
// ---------------------------------------------------------------------
#ifdef ODR_VIOLATION_C
// ---------------------------------------------------------------------
struct Bar {
int i;
};
typedef struct Bar Bar;
Bar odr_violation = { 42 };
// ---------------------------------------------------------------------
#else
// ---------------------------------------------------------------------
// CHECK: DW_TAG_compile_unit
// CHECK-NOT: DW_AT_GNU_dwo_id
// CHECK: DW_AT_low_pc
// CHECK-NOT: DW_TAG_module
// CHECK-NOT: DW_TAG_typedef
//
// CHECK: DW_TAG_imported_declaration
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_import [DW_FORM_ref_addr] (0x{{0*}}[[FOO]]
//
// CHECK: DW_TAG_subprogram
// CHECK: DW_AT_name {{.*}}"main"
//
// CHECK: DW_TAG_variable
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_name{{.*}}"bar"
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BARTD]]
// 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]]
extern int odr_violation;
@import Foo;
int main(int argc, char **argv) {
Bar bar;
Foo *foo = 0;
bar.value = odr_violation;
return bar.value;
}
#endif
#endif
#endif
// CHECK: DW_TAG_compile_unit
// CHECK-NOT: DW_AT_GNU_dwo_id
// CHECK: DW_AT_name {{.*}}"odr_violation.c"
// CHECK: DW_TAG_variable
// CHECK: DW_AT_name {{.*}}"odr_violation"
// CHECK: DW_AT_type [DW_FORM_ref4] ({{.*}}{0x{{0*}}[[BAR2:.*]]}
// CHECK: 0x{{0*}}[[BAR2]]: DW_TAG_typedef
// CHECK: DW_AT_type [DW_FORM_ref4] ({{.*}}{0x{{0*}}[[BAR3:.*]]}
// CHECK: DW_AT_name {{.*}}"Bar"
// CHECK: 0x{{0*}}[[BAR3]]: DW_TAG_structure_type
// CHECK-NEXT: DW_AT_name {{.*}}"Bar"