/* 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: llvm-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: llvm-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_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_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: 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: 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"