You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.8 KiB

  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 ssa
  5. // This file defines the BuilderMode type and its command-line flag.
  6. import (
  7. "bytes"
  8. "fmt"
  9. )
  10. // BuilderMode is a bitmask of options for diagnostics and checking.
  11. //
  12. // *BuilderMode satisfies the flag.Value interface. Example:
  13. //
  14. // var mode = ssa.BuilderMode(0)
  15. // func init() { flag.Var(&mode, "build", ssa.BuilderModeDoc) }
  16. //
  17. type BuilderMode uint
  18. const (
  19. PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout
  20. PrintFunctions // Print function SSA code to stdout
  21. LogSource // Log source locations as SSA builder progresses
  22. SanityCheckFunctions // Perform sanity checking of function bodies
  23. NaiveForm // Build naïve SSA form: don't replace local loads/stores with registers
  24. BuildSerially // Build packages serially, not in parallel.
  25. GlobalDebug // Enable debug info for all packages
  26. BareInits // Build init functions without guards or calls to dependent inits
  27. )
  28. const BuilderModeDoc = `Options controlling the SSA builder.
  29. The value is a sequence of zero or more of these letters:
  30. C perform sanity [C]hecking of the SSA form.
  31. D include [D]ebug info for every function.
  32. P print [P]ackage inventory.
  33. F print [F]unction SSA code.
  34. S log [S]ource locations as SSA builder progresses.
  35. L build distinct packages seria[L]ly instead of in parallel.
  36. N build [N]aive SSA form: don't replace local loads/stores with registers.
  37. I build bare [I]nit functions: no init guards or calls to dependent inits.
  38. `
  39. func (m BuilderMode) String() string {
  40. var buf bytes.Buffer
  41. if m&GlobalDebug != 0 {
  42. buf.WriteByte('D')
  43. }
  44. if m&PrintPackages != 0 {
  45. buf.WriteByte('P')
  46. }
  47. if m&PrintFunctions != 0 {
  48. buf.WriteByte('F')
  49. }
  50. if m&LogSource != 0 {
  51. buf.WriteByte('S')
  52. }
  53. if m&SanityCheckFunctions != 0 {
  54. buf.WriteByte('C')
  55. }
  56. if m&NaiveForm != 0 {
  57. buf.WriteByte('N')
  58. }
  59. if m&BuildSerially != 0 {
  60. buf.WriteByte('L')
  61. }
  62. return buf.String()
  63. }
  64. // Set parses the flag characters in s and updates *m.
  65. func (m *BuilderMode) Set(s string) error {
  66. var mode BuilderMode
  67. for _, c := range s {
  68. switch c {
  69. case 'D':
  70. mode |= GlobalDebug
  71. case 'P':
  72. mode |= PrintPackages
  73. case 'F':
  74. mode |= PrintFunctions
  75. case 'S':
  76. mode |= LogSource | BuildSerially
  77. case 'C':
  78. mode |= SanityCheckFunctions
  79. case 'N':
  80. mode |= NaiveForm
  81. case 'L':
  82. mode |= BuildSerially
  83. default:
  84. return fmt.Errorf("unknown BuilderMode option: %q", c)
  85. }
  86. }
  87. *m = mode
  88. return nil
  89. }
  90. // Get returns m.
  91. func (m BuilderMode) Get() interface{} { return m }