Keine Beschreibung

expected_test.go 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package demangle
  5. import (
  6. "bufio"
  7. "flag"
  8. "fmt"
  9. "os"
  10. "strings"
  11. "testing"
  12. )
  13. var verbose = flag.Bool("verbose", false, "print each demangle-expected symbol")
  14. const filename = "testdata/demangle-expected"
  15. // A list of exceptions from demangle-expected that we do not handle
  16. // the same as the standard demangler. We keep a list of exceptions
  17. // so that we can use an exact copy of the file. These exceptions are
  18. // all based on different handling of a substitution that refers to a
  19. // template parameter. The standard demangler seems to have a bug in
  20. // which template it uses when a reference or rvalue-reference refers
  21. // to a substitution that resolves to a template parameter.
  22. var exceptions = map[string]bool{
  23. "_ZSt7forwardIRN1x14refobjiteratorINS0_3refINS0_4mime30multipart_section_processorObjIZ15get_body_parserIZZN14mime_processor21make_section_iteratorERKNS2_INS3_10sectionObjENS0_10ptrrefBaseEEEbENKUlvE_clEvEUlSB_bE_ZZNS6_21make_section_iteratorESB_bENKSC_clEvEUlSB_E0_ENS1_INS2_INS0_20outputrefiteratorObjIiEES8_EEEERKSsSB_OT_OT0_EUlmE_NS3_32make_multipart_default_discarderISP_EEEES8_EEEEEOT_RNSt16remove_referenceISW_E4typeE": true,
  24. "_ZN3mdr16in_cached_threadIRZNK4cudr6GPUSet17parallel_for_eachIZN5tns3d20shape_representation7compute7GPUImpl7executeERKNS_1AINS_7ptr_refIKjEELl3ELl3ENS_8c_strideILl1ELl0EEEEERKNS8_INS9_IjEELl4ELl1ESD_EEEUliRKNS1_7ContextERNS7_5StateEE_JSt6vectorISO_SaISO_EEEEEvOT_DpRT0_EUlSP_E_JSt17reference_wrapperISO_EEEENS_12ScopedFutureIDTclfp_spcl7forwardISW_Efp0_EEEEESV_DpOSW_": true,
  25. "_ZNSt9_Any_data9_M_accessIPZN3sel8Selector6SetObjI3FooJPKcMS4_FviEEEEvRT_DpT0_EUlvE_EESA_v": true,
  26. "_ZNSt9_Any_data9_M_accessIPZN13ThreadManager7newTaskIRSt5_BindIFSt7_Mem_fnIM5DiaryFivEEPS5_EEIEEESt6futureINSt9result_ofIFT_DpT0_EE4typeEEOSF_DpOSG_EUlvE_EERSF_v": true,
  27. "_ZNSt9_Any_data9_M_accessIPZN6cereal18polymorphic_detail15getInputBindingINS1_16JSONInputArchiveEEENS1_6detail15InputBindingMapIT_E11SerializersERS7_jEUlPvRSt10unique_ptrIvNS5_12EmptyDeleterIvEEEE0_EESA_v": true,
  28. "_ZNSt9_Any_data9_M_accessIPZ4postISt8functionIFvvEEEvOT_EUlvE_EERS5_v": true,
  29. }
  30. // For simplicity, this test reads an exact copy of
  31. // libiberty/testsuite/demangle-expected from GCC. See that file for
  32. // the syntax. We ignore all tests that are not --format=gnu-v3 or
  33. // --format=auto with a string starting with _Z.
  34. func TestExpected(t *testing.T) {
  35. f, err := os.Open(filename)
  36. if err != nil {
  37. t.Fatal(err)
  38. }
  39. scanner := bufio.NewScanner(f)
  40. lineno := 1
  41. for {
  42. format, got := getOptLine(t, scanner, &lineno)
  43. if !got {
  44. break
  45. }
  46. report := lineno
  47. input := getLine(t, scanner, &lineno)
  48. expect := getLine(t, scanner, &lineno)
  49. testNoParams := false
  50. skip := false
  51. if len(format) > 0 && format[0] == '-' {
  52. for _, arg := range strings.Fields(format) {
  53. switch arg {
  54. case "--format=gnu-v3":
  55. case "--format=auto":
  56. if !strings.HasPrefix(input, "_Z") {
  57. skip = true
  58. }
  59. case "--no-params":
  60. testNoParams = true
  61. case "--ret-postfix", "--ret-drop":
  62. skip = true
  63. case "--is-v3-ctor", "--is-v3-dtor":
  64. skip = true
  65. default:
  66. if !strings.HasPrefix(arg, "--format=") {
  67. t.Errorf("%s:%d: unrecognized argument %s", filename, report, arg)
  68. }
  69. skip = true
  70. }
  71. }
  72. }
  73. // The libiberty testsuite passes DMGL_TYPES to
  74. // demangle type names, but that doesn't seem useful
  75. // and we don't support it.
  76. if !strings.HasPrefix(input, "_Z") && !strings.HasPrefix(input, "_GLOBAL_") {
  77. skip = true
  78. }
  79. var expectNoParams string
  80. if testNoParams {
  81. expectNoParams = getLine(t, scanner, &lineno)
  82. }
  83. if skip {
  84. continue
  85. }
  86. oneTest(t, report, input, expect, true)
  87. if testNoParams {
  88. oneTest(t, report, input, expectNoParams, false)
  89. }
  90. }
  91. if err := scanner.Err(); err != nil {
  92. t.Error(err)
  93. }
  94. }
  95. // oneTest tests one entry from demangle-expected.
  96. func oneTest(t *testing.T, report int, input, expect string, params bool) {
  97. if *verbose {
  98. fmt.Println(input)
  99. }
  100. exception := exceptions[input]
  101. var s string
  102. var err error
  103. if params {
  104. s, err = ToString(input)
  105. } else {
  106. s, err = ToString(input, NoParams)
  107. }
  108. if err != nil {
  109. if exception {
  110. t.Logf("%s:%d: ignore expected difference: got %q, expected %q", filename, report, err, expect)
  111. return
  112. }
  113. if err != ErrNotMangledName {
  114. if input == expect {
  115. return
  116. }
  117. t.Errorf("%s:%d: %v", filename, report, err)
  118. return
  119. }
  120. s = input
  121. }
  122. if s != expect {
  123. if exception {
  124. t.Logf("%s:%d: ignore expected difference: got %q, expected %q", filename, report, s, expect)
  125. } else {
  126. var a AST
  127. if params {
  128. a, err = ToAST(input)
  129. } else {
  130. a, err = ToAST(input, NoParams)
  131. }
  132. if err != nil {
  133. t.Logf("ToAST error: %v", err)
  134. } else {
  135. t.Logf("\n%#v", a)
  136. }
  137. t.Errorf("%s:%d: params: %t: got %q, expected %q", filename, report, params, s, expect)
  138. }
  139. } else if exception && params {
  140. t.Errorf("%s:%d: unexpected success (input listed in exceptions)", filename, report)
  141. }
  142. }
  143. // getLine reads a line from demangle-expected.
  144. func getLine(t *testing.T, scanner *bufio.Scanner, lineno *int) string {
  145. s, got := getOptLine(t, scanner, lineno)
  146. if !got {
  147. t.Fatalf("%s:%d: unexpected EOF", filename, *lineno)
  148. }
  149. return s
  150. }
  151. // getOptLine reads an optional line from demangle-expected, returning
  152. // false at EOF. It skips comment lines and updates *lineno.
  153. func getOptLine(t *testing.T, scanner *bufio.Scanner, lineno *int) (string, bool) {
  154. for {
  155. if !scanner.Scan() {
  156. return "", false
  157. }
  158. *lineno++
  159. line := scanner.Text()
  160. if !strings.HasPrefix(line, "#") {
  161. return line, true
  162. }
  163. }
  164. }