reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
/* Compile with:
   for FILE in `seq 3`; do
     clang -g -c  odr-member-functions.cpp -DFILE$FILE -o odr-member-functions/$FILE.o
   done
 */

// RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/odr-member-functions -y %p/dummy-debug-map.map -o - | llvm-dwarfdump -debug-info - | FileCheck %s

struct S {
  __attribute__((always_inline)) void foo() { bar(); }
  __attribute__((always_inline)) void foo(int i) { if (i) bar(); }
  void bar();

  template<typename T> void baz(T t) {}
};

#ifdef FILE1
void foo() {
  S s;
}

// CHECK: TAG_compile_unit
// CHECK-NOT: {{DW_TAG|NULL}}
// CHECK: AT_name{{.*}}"odr-member-functions.cpp"

// CHECK: 0x[[S:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type
// CHECK-NOT: {{DW_TAG|NULL}}
// CHECK: DW_AT_name{{.*}}"S"
// CHECK-NOT: NULL
// CHECK: 0x[[FOO:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
// CHECK-NEXT: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3fooEv"
// CHECK: NULL
// CHECK: 0x[[FOOI:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
// CHECK-NEXT: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3fooEi"

#elif defined(FILE2)
void foo() {
  S s;
  // Check that the overloaded member functions are resolved correctly
  s.foo();
  s.foo(1);
}

// CHECK: TAG_compile_unit
// CHECK-NOT: DW_TAG
// CHECK: AT_name{{.*}}"odr-member-functions.cpp"

// Normal member functions should be desribed by the type in the first
// CU, thus we should be able to reuse its definition and avoid
// reemiting it.
// CHECK-NOT: DW_TAG_structure_type

// CHECK: 0x[[FOO_SUB:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
// CHECK-NEXT: DW_AT_specification{{.*}}[[FOO]]
// CHECK-NOT: DW_TAG_structure_type
// CHECK: 0x[[FOOI_SUB:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
// CHECK-NEXT: DW_AT_specification{{.*}}[[FOOI]]
// CHECK-NOT: DW_TAG_structure_type

// CHECK: DW_TAG_variable
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_name {{.*}}"s"
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_type {{.*}}[[S]]
// CHECK: DW_TAG_inlined_subroutine
// CHECK-NEXT: DW_AT_abstract_origin{{.*}}[[FOO_SUB]]
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_call_line{{.*}}40
// CHECK: DW_TAG_inlined_subroutine
// CHECK-NEXT: DW_AT_abstract_origin{{.*}}[[FOOI_SUB]]
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_call_line{{.*}}41

#elif defined(FILE3)
void foo() {
  S s;
  s.baz<int>(42);
}

// CHECK: TAG_compile_unit
// CHECK-NOT: DW_TAG
// CHECK: AT_name{{.*}}"odr-member-functions.cpp"

// Template or other implicit members will be included in the type
// only if they are generated. Thus actually creating a new type.
// CHECK: DW_TAG_structure_type

// Skip 'normal' member functions
// CHECK: DW_TAG_subprogram
// CHECK: DW_TAG_subprogram
// CHECK: DW_TAG_subprogram

// This is the 'baz' member
// CHECK: 0x[[BAZ:[0-9a-f]*]]: DW_TAG_subprogram
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_MIPS_linkage_name {{.*}}"_ZN1S3bazIiEEvT_"
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_name {{.*}}"baz<int>"

// Skip foo3
// CHECK: DW_TAG_subprogram

// baz instanciation:
// CHECK: DW_TAG_subprogram
// CHECK-NOT: DW_TAG
// CHECK: DW_AT_specification {{.*}}[[BAZ]] "_ZN1S3bazIiEEvT_"
#else
#error "You must define which file you generate"
#endif