Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-3773] Class definition not included when running -emit-sil #46358

Closed
ahoppen opened this issue Jan 28, 2017 · 18 comments
Closed

[SR-3773] Class definition not included when running -emit-sil #46358

ahoppen opened this issue Jan 28, 2017 · 18 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself good first issue Good for newcomers

Comments

@ahoppen
Copy link
Contributor

ahoppen commented Jan 28, 2017

Previous ID SR-3773
Radar None
Original Reporter @ahoppen
Type Bug
Status Resolved
Resolution Done
Environment

swift-DEVELOPMENT-SNAPSHOT-2017-01-27-a

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, StarterBug
Assignee None
Priority Medium

md5: 33a0544be27949ad4e2a8cc6c6d09653

Issue Description:

Running swiftc -emit-sil on the following file generates a SIL file that is missing the class definition, i.e. the bit that looks like Swift code without function bodies:

class Foo {
  func bar() {
  }
}

The resulting SIL file is:

sil_stage canonical

import Builtin
import Swift
import SwiftShims

sil_scope 1 {  parent @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 }

// main
sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
  %2 = integer_literal $Builtin.Int32, 0, scope 1 // user: %3
  %3 = struct $Int32 (%2 : $Builtin.Int32), scope 1 // user: %4
  return %3 : $Int32, scope 1                     // id: %4
} // end sil function 'main'

sil_scope 2 { loc "/Users/Alex/Desktop/test.swift":2:8 parent @_TFC1a3Foo3barfT_T_ : $@convention(method) (@guaranteed Foo) -> () }
sil_scope 3 { loc "/Users/Alex/Desktop/test.swift":4:3 parent 2 }

// Foo.bar() -> ()
sil hidden @_TFC1a3Foo3barfT_T_ : $@convention(method) (@guaranteed Foo) -> () {
// %0                                             // user: %1
bb0(%0 : $Foo):
  debug_value %0 : $Foo, let, name "self", argno 1, loc "/Users/Alex/Desktop/test.swift":2:8, scope 2 // id: %1
  %2 = tuple (), loc "/Users/Alex/Desktop/test.swift":4:3, scope 3 // user: %3
  return %2 : $(), loc "/Users/Alex/Desktop/test.swift":4:3, scope 3 // id: %3
} // end sil function '_TFC1a3Foo3barfT_T_'

sil_scope 4 { loc "/Users/Alex/Desktop/test.swift":1:7 parent @_TFC1a3FooD : $@convention(method) (@owned Foo) -> () }

// Foo.__deallocating_deinit
sil hidden @_TFC1a3FooD : $@convention(method) (@owned Foo) -> () {
// %0                                             // users: %3, %1
bb0(%0 : $Foo):
  debug_value %0 : $Foo, let, name "self", argno 1, loc "/Users/Alex/Desktop/test.swift":1:7, scope 4 // id: %1
  // function_ref Foo.deinit
  %2 = function_ref @_TFC1a3Food : $@convention(method) (@guaranteed Foo) -> @owned Builtin.NativeObject, scope 4 // user: %3
  %3 = apply %2(%0) : $@convention(method) (@guaranteed Foo) -> @owned Builtin.NativeObject, scope 4 // user: %4
  %4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $Foo, scope 4 // user: %5
  dealloc_ref %4 : $Foo, scope 4                  // id: %5
  %6 = tuple (), scope 4                          // user: %7
  return %6 : $(), scope 4                        // id: %7
} // end sil function '_TFC1a3FooD'

sil_scope 5 { loc "/Users/Alex/Desktop/test.swift":1:7 parent @_TFC1a3Food : $@convention(method) (@guaranteed Foo) -> @owned Builtin.NativeObject }
sil_scope 6 { loc "/Users/Alex/Desktop/test.swift":1:7 parent 5 }

// Foo.deinit
sil hidden @_TFC1a3Food : $@convention(method) (@guaranteed Foo) -> @owned Builtin.NativeObject {
// %0                                             // users: %2, %1
bb0(%0 : $Foo):
  debug_value %0 : $Foo, let, name "self", argno 1, loc "/Users/Alex/Desktop/test.swift":1:7, scope 5 // id: %1
  %2 = unchecked_ref_cast %0 : $Foo to $Builtin.NativeObject, scope 6 // user: %3
  return %2 : $Builtin.NativeObject, scope 6      // id: %3
} // end sil function '_TFC1a3Food'

sil_scope 7 { loc "/Users/Alex/Desktop/test.swift":1:7 parent @_TFC1a3FoocfT_S0_ : $@convention(method) (@owned Foo) -> @owned Foo }
sil_scope 8 {  parent 7 }

// Foo.init() -> Foo
sil hidden @_TFC1a3FoocfT_S0_ : $@convention(method) (@owned Foo) -> @owned Foo {
// %0                                             // users: %2, %1
bb0(%0 : $Foo):
  debug_value %0 : $Foo, let, name "self", loc "/Users/Alex/Desktop/test.swift":1:7, scope 7 // id: %1
  return %0 : $Foo, loc "/Users/Alex/Desktop/test.swift":1:7, scope 8 // id: %2
} // end sil function '_TFC1a3FoocfT_S0_'

sil_scope 9 { loc "/Users/Alex/Desktop/test.swift":1:7 parent @_TFC1a3FooCfT_S0_ : $@convention(method) (@thick Foo.Type) -> @owned Foo }

// Foo.__allocating_init() -> Foo
sil hidden @_TFC1a3FooCfT_S0_ : $@convention(method) (@thick Foo.Type) -> @owned Foo {
bb0(%0 : $@thick Foo.Type):
  %1 = alloc_ref $Foo, scope 9                    // user: %3
  // function_ref Foo.init() -> Foo
  %2 = function_ref @_TFC1a3FoocfT_S0_ : $@convention(method) (@owned Foo) -> @owned Foo, scope 9 // user: %3
  %3 = apply %2(%1) : $@convention(method) (@owned Foo) -> @owned Foo, scope 9 // user: %4
  return %3 : $Foo, scope 9                       // id: %4
} // end sil function '_TFC1a3FooCfT_S0_'

sil_vtable Foo {
  #Foo.bar!1: _TFC1a3Foo3barfT_T_   // Foo.bar() -> ()
  #Foo.deinit!deallocator: _TFC1a3FooD  // Foo.__deallocating_deinit
  #Foo.init!initializer.1: _TFC1a3FoocfT_S0_    // Foo.init() -> Foo
}

This can't be parsed using the -parse-sil command line flag and fails with a bunch of errors like:

/Users/Alex/Desktop/a.sil:8:44: error: use of undeclared type 'Foo'
sil_global hidden [let] @_Tv1a1xVS_3Foo : $Foo

Adding the -frontend flag to the swiftc call resolves the issue.

@slavapestov
Copy link
Member

Try adding the -primary-file flag. I believe this behavior might be intentional.

@ahoppen
Copy link
Contributor Author

ahoppen commented Jan 30, 2017

FWIW, adding -primary-file, i.e. running

@slavapestov
Copy link
Member

Maybe @jckarter has some ideas.

@jckarter
Copy link
Member

I haven't touched the SIL printer in a while. It was never particularly thorough about printing needed decls, though.

@ahoppen
Copy link
Contributor Author

ahoppen commented Jan 30, 2017

Would it be expected, though, for the printer to print the class definition?

@jckarter
Copy link
Member

Yeah, printed SIL ought to be parsable, and parsing it requires the declarations it references.

@belkadan
Copy link
Contributor

Emitted SIL files deliberately don't print declarations if there might be more than one file in the project, because we have no way to represent that in a single file. The short-term thing to do might just be to print the declarations from the current file, since we do (?) support a SIL -primary-file input and .swift files for other inputs. Even that's not quite correct for 'private', though, which currently mangles symbol names based on the name of the current file. I'm okay with partial improvements in this area, though.

@jckarter
Copy link
Member

Alex noted that -primary-file didn't seem to address the issue in this case. Maybe we could introduce a sil_file construct for SIL files to let us represent a body of SIL generated from multi-file Swift source.

@belkadan
Copy link
Contributor

I think you need to not use -primary-file today.

@ahoppen
Copy link
Contributor Author

ahoppen commented Jan 31, 2017

I just played around with the flags a little more and the class definition is correctly included if you add the -frontend flag and don't use -primary-file. Seems a bit of an oddity but I'd understand if that was desired behaviour for some reason.

@swift-ci
Copy link
Collaborator

Comment by David Sweeris (JIRA)

Is this still considered a bug?

@jckarter
Copy link
Member

Yes. In principle the output of -emit-sil ought to be parsable by passing it back into swiftc as a *.sil file.

@ahoppen
Copy link
Contributor Author

ahoppen commented Mar 18, 2017

The issue associated with this ticket is resolved for me since the class definitions are printed for the -frontend -emit-sil compiler flags. The other configurations I tried should, however, print class definitions as well.

A short summary of what different combinations do right now:

Compiler flags Class definitions printed
-emit-sil No
-frontend -emit-sil Yes
-emit-sil -primary-file Invalid command options combination (seems alright to me)
-frontend -emit-sil -primary-file No

@slavapestov
Copy link
Member

-primary-file is a frontend-only flag.

Basically 'swift -emit-silgen foo.swift' is equivalent to 'swift -frontend -primary-file -emit-silgen foo.swift'.

@ahoppen
Copy link
Contributor Author

ahoppen commented Mar 22, 2017

OK, I guess then it boils down to that the class definitions should when the -primary-file flag is present

@belkadan
Copy link
Contributor

Specifically, the class definitions from the current file, I suppose.

@swift-ci
Copy link
Collaborator

Comment by Bartosz Polaczyk (JIRA)

Can you please check PR-14595?

@swift-ci
Copy link
Collaborator

Comment by Bartosz Polaczyk (JIRA)

Merged 14595

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

5 participants