//
// main.swift
// swiftstudy
//
// Created by GitArtOS on 2021/1/19.
//
import Foundation
print("Hello, World!")
class SHTest {
var name = "hello"
var size = 10.5
var height = 13.4
}
let test1 = SHTest()
1. 编译器介绍
swift
的编译器是swiftc
1.1 编译历程
SwiftCode源码
->通过词法分析、语法分析(-dump-parse
)->生成AST抽象语法树(-dump-ast
)->通过SILGen生成未优化代码量巨大的RawSIL文件(-emit-silgen
)->再拿到优化后更简洁的Canonical SIL(-emit-sil
)->通过IRGen生成IR(-emit-ir
)->最终生成二进制代码
输入swiftc -h
可以看到如下:
OVERVIEW: Swift compiler
USAGE: swiftc
MODES:
-dump-ast Parse and type-check input file(s) and dump AST(s)
-dump-parse Parse input file(s) and dump AST(s)
-dump-pcm Dump debugging information about a precompiled Clang module
-dump-scope-maps <expanded-or-list-of-line:column>
Parse and type-check input file(s) and dump the scope map(s)
-dump-type-info Output YAML dump of fixed-size types from all imported modules
-dump-type-refinement-contexts
Type-check input file(s) and dump type refinement contexts(s)
-emit-assembly Emit assembly file(s) (-S)
-emit-bc Emit LLVM BC file(s)
-emit-executable Emit a linked executable
-emit-imported-modules Emit a list of the imported modules
-emit-ir Emit LLVM IR file(s)
-emit-library Emit a linked library
-emit-object Emit object file(s) (-c)
-emit-pcm Emit a precompiled Clang module from a module map
-emit-sibgen Emit serialized AST + raw SIL file(s)
-emit-sib Emit serialized AST + canonical SIL file(s)
-emit-silgen Emit raw SIL file(s)
-emit-sil Emit canonical SIL file(s)
-index-file Produce index data for a source file
-parse Parse input file(s)
-print-ast Parse and type-check input file(s) and pretty print AST(s)
-resolve-imports Parse and resolve imports in input file(s)
-typecheck Parse and type-check input file(s)
OPTIONS:
-api-diff-data-dir <path>
Load platform and version specific API migration data files from <path>. Ignored if -api-diff-data-file is specified.
-api-diff-data-file <path>
API migration data is from <path>
-application-extension Restrict code to those available for App Extensions
-assert-config <value> Specify the assert_configuration replacement. Possible values are Debug, Release, Unchecked, DisableReplacement.
-avoid-emit-module-source-info
don't emit Swift source info file
-color-diagnostics Print diagnostics in color
-continue-building-after-errors
Continue building, even after errors are encountered
-debug-info-format=<value>
Specify the debug info format type to either 'dwarf' or 'codeview'
-debug-info-store-invocation
Emit the compiler invocation in the debug info.
-debug-prefix-map <value>
Remap source paths in debug info
-disable-astscope-lookup
Disable ASTScope-based unqualified name lookup
-disable-autolinking-runtime-compatibility-dynamic-replacements
Do not use autolinking for the dynamic replacement runtime compatibility library
-disable-autolinking-runtime-compatibility
Do not use autolinking for runtime compatibility libraries
-disable-migrator-fixits
Disable the Migrator phase which automatically applies fix-its
-disable-only-one-dependency-file
Disables incremental build optimization that only produces one dependencies file
-disable-parser-lookup Disable parser lookup & use ast scope lookup only (experimental)
-driver-compare-incremental-schemes-path <path>
Path to use for machine-readable comparision
-driver-compare-incremental-schemes
Print a simple message comparing dependencies with source ranges (w/ fallback)
-driver-time-compilation
Prints the total time it took to execute all compilation tasks
-dump-migration-states-dir <path>
Dump the input text, output text, and states for migration to <path>
-dump-usr Dump USR for each declaration reference
-D <value> Marks a conditional compilation flag as true
-embed-bitcode-marker Embed placeholder LLVM IR data as a marker
-embed-bitcode Embed LLVM IR bitcode as data
-emit-dependencies Emit basic Make-compatible dependencies files
-emit-loaded-module-trace-path <path>
Emit the loaded module trace JSON to <path>
-emit-loaded-module-trace
Emit a JSON file containing information about what modules were loaded
-emit-module-interface-path <path>
Output module interface file to <path>
-emit-module-interface Output module interface file
-emit-module-path <path>
Emit an importable module to <path>
-emit-module-source-info-path <path>
Output module source info file to <path>
-emit-module Emit an importable module
-emit-objc-header-path <path>
Emit an Objective-C header file to <path>
-emit-objc-header Emit an Objective-C header file
-emit-tbd-path <path> Emit the TBD file to <path>
-emit-tbd Emit a TBD file
-enable-astscope-lookup Enable ASTScope-based unqualified name lookup
-enable-experimental-concise-pound-file
Enable experimental concise '#file' identifier and '#filePath' alternative
-enable-experimental-differentiable-programming
Enable experimental differentiable programming features
-enable-library-evolution
Build the module to allow binary-compatible library evolution
-enable-only-one-dependency-file
Enables incremental build optimization that only produces one dependencies file
-enable-source-range-dependencies
Try using source range information
-enforce-exclusivity=<enforcement>
Enforce law of exclusivity
-fixit-all Apply all fixits from diagnostics without any filtering
-framework <value> Specifies a framework which should be linked against
-Fsystem <value> Add directory to system framework search path
-F <value> Add directory to framework search path
-gdwarf-types Emit full DWARF type info.
-gline-tables-only Emit minimal debug info for backtraces only
-gnone Don't emit debug info
-g Emit debug info. This is the preferred setting for debugging with LLDB.
-help Display available options
-import-underlying-module
Implicitly imports the Objective-C half of a module
-index-file-path <path> Produce index data for file <path>
-index-ignore-system-modules
Avoid indexing system modules
-index-store-path <path>
Store indexing data to <path>
-I <value> Add directory to the import search path
-j <n> Number of commands to execute in parallel
-libc <value> libc runtime library to use
-L <value> Add directory to library link search path
-l<value> Specifies a library which should be linked against
-migrate-keep-objc-visibility
When migrating, add '@objc' to declarations that would've been implicitly visible in Swift 3
-migrator-update-sdk Does nothing. Temporary compatibility flag for Xcode.
-migrator-update-swift Does nothing. Temporary compatibility flag for Xcode.
-module-cache-path <value>
Specifies the Clang module cache path
-module-link-name <value>
Library to link against when using this module
-module-name <value> Name of the module to build
-no-color-diagnostics Do not print diagnostics in color
-nostdimport Don't search the standard library import path for modules
-num-threads <n> Enable multi-threading and specify number of threads
-Onone Compile without any optimization
-Osize Compile with optimizations and target small code size
-Ounchecked Compile with optimizations and remove runtime safety checks
-output-file-map <path> A file which specifies the location of outputs
-O Compile with optimizations
-o <file> Write output to <file>
-parse-as-library Parse the input file(s) as libraries, not scripts
-parse-sil Parse the input file as SIL code, not Swift source
-parseable-output Emit textual output in a parseable format
-print-target-info Print target information for the given target <triple>, such as x86_64-apple-macos10.9
-profile-coverage-mapping
Generate coverage data for use with profiled execution counts
-profile-generate Generate instrumented code to collect execution counts
-profile-use=<profdata> Supply a profdata file to enable profile-guided optimization
-remove-runtime-asserts Remove runtime safety checks.
-require-explicit-availability-target <target>
Suggest fix-its adding @available(<target>, *) to public declarations without availability
-require-explicit-availability
Require explicit availability on public declarations
-Rpass-missed=<value> Report missed transformations by optimization passes whose name matches the given POSIX regular expression
-Rpass=<value> Report performed transformations by optimization passes whose name matches the given POSIX regular expression
-runtime-compatibility-version <value>
Link compatibility library for Swift runtime version, or 'none'
-sanitize-coverage=<type>
Specify the type of coverage instrumentation for Sanitizers and additional options separated by commas
-sanitize-recover=<check>
Specify which sanitizer runtime checks (see -sanitize=) will generate instrumentation that allows error recovery. Listed checks should be comma separated. Default behavior is to not allow error recovery.
-sanitize=<check> Turn on runtime checks for erroneous behavior.
-save-optimization-record-path <value>
Specify the file name of any generated YAML optimization record
-save-optimization-record
Generate a YAML optimization record file
-save-temps Save intermediate compilation results
-sdk <sdk> Compile against <sdk>
-serialize-diagnostics Serialize diagnostics in a binary format
-static-executable Statically link the executable
-static-stdlib Statically link the Swift standard library
-static Make this module statically linkable and make the output of -emit-library a static library.
-suppress-warnings Suppress all warnings
-swift-version <vers> Interpret input according to a specific Swift language version number
-target-cpu <value> Generate code for a particular CPU variant
-target-variant <value> Generate code that may run on a particular variant of the deployment target
-target <triple> Generate code for the given target <triple>, such as x86_64-apple-macos10.9
-tools-directory <directory>
Look for external executables (ld, clang, binutils) in <directory>
-track-system-dependencies
Track system dependencies while emitting Make-style dependencies
-use-ld=<value> Specifies the linker to be used
-verify-debug-info Verify the binary representation of debug output.
-version Print version information and exit
-vfsoverlay <value> Add directory to VFS overlay file
-v Show commands to run and use verbose output
-warn-implicit-overrides
Warn about implicit overrides of protocol members
-warn-swift3-objc-inference-complete
Warn about deprecated @objc inference in Swift 3 for every declaration that will no longer be inferred as @objc in Swift 4
-warn-swift3-objc-inference-minimal
Warn about deprecated @objc inference in Swift 3 based on direct uses of the Objective-C entrypoint
-warnings-as-errors Treat warnings as errors
-whole-module-optimization
Optimize input files together instead of individually
-working-directory <path>
Resolve file paths relative to the specified directory
-Xcc <arg> Pass <arg> to the C/C++/Objective-C compiler
-Xlinker <value> Specifies an option which should be passed to the linker
SEE ALSO: swift build, swift run, swift package, swift test
其中主要的命令是:
-dump-ast 语法和类型检查,打印AST语法树
-dump-parse 语法检查,打印AST语法树
-dump-pcm 转储有关预编译Clang模块的调试信息
-dump-scope-maps <expanded-or-list-of-line:column> Parse and type-check input file(s) and dump the scope map(s)
-dump-type-info Output YAML dump of fixed-size types from all imported modules
-dump-type-refinement-contexts Type-check input file(s) and dump type refinement contexts(s)
-emit-assembly 输出汇编文件 (-S)
-emit-bc 输出一个LLVM的BC文件
-emit-executable 输出一个可执行文件
-emit-imported-modules 展示导入的模块列表
-emit-ir 展示IR中间代码
-emit-library 输出一个dylib动态库
-emit-object 输出一个.o机器文件
-emit-pcm 从模块映射中输出预编译Clang模块
-emit-sibgen 输出一个.sib的原始SIL文件
-emit-sib 输出一个.sib的标准SIL文件
-emit-silgen 展示原始SIL文件
-emit-sil 展示标准的SIL文件
-index-file 为源文件生成索引数据
-parse 解析文件
-print-ast 解析文件并打印(漂亮/简洁的)语法树
-resolve-imports 解析import导入的文件
-typecheck 检查文件类型
1.2 通过词法分析、语法分析 swiftc -dump-parse main.swift
➜ swiftstudy swiftc -dump-parse main.swift
(source_file "main.swift"
(import_decl range=[main.swift:8:1 - line:8:8] 'Foundation')
(top_level_code_decl range=[main.swift:10:1 - line:10:22]
(brace_stmt range=[main.swift:10:1 - line:10:22]
(call_expr type='<null>' arg_labels=_:
(unresolved_decl_ref_expr type='<null>' name=print function_ref=unapplied)
(paren_expr type='<null>'
(string_literal_expr type='<null>' encoding=utf8 value="Hello, World!" builtin_initializer=**NULL** initializer=**NULL**)))))
(class_decl range=[main.swift:12:1 - line:16:1] "SHTest"
(pattern_binding_decl range=[main.swift:13:5 - line:13:16]
(pattern_named 'name')
Original init:
(string_literal_expr type='<null>' encoding=utf8 value="hello" builtin_initializer=**NULL** initializer=**NULL**)
Processed init:
(string_literal_expr type='<null>' encoding=utf8 value="hello" builtin_initializer=**NULL** initializer=**NULL**))
(var_decl range=[main.swift:13:9 - line:13:9] "name" type='<null type>' readImpl=stored writeImpl=stored readWriteImpl=stored)
(pattern_binding_decl range=[main.swift:14:5 - line:14:16]
(pattern_named 'size')
Original init:
(float_literal_expr type='<null>' value=10.5 builtin_initializer=**NULL** initializer=**NULL**)
Processed init:
(float_literal_expr type='<null>' value=10.5 builtin_initializer=**NULL** initializer=**NULL**))
(var_decl range=[main.swift:14:9 - line:14:9] "size" type='<null type>' readImpl=stored writeImpl=stored readWriteImpl=stored)
(pattern_binding_decl range=[main.swift:15:5 - line:15:18]
(pattern_named 'height')
Original init:
(float_literal_expr type='<null>' value=13.4 builtin_initializer=**NULL** initializer=**NULL**)
Processed init:
(float_literal_expr type='<null>' value=13.4 builtin_initializer=**NULL** initializer=**NULL**))
(var_decl range=[main.swift:15:9 - line:15:9] "height" type='<null type>' readImpl=stored writeImpl=stored readWriteImpl=stored))
(top_level_code_decl range=[main.swift:18:1 - line:18:20]
(brace_stmt implicit range=[main.swift:18:1 - line:18:20]
(pattern_binding_decl range=[main.swift:18:1 - line:18:20]
(pattern_named 'test1')
Original init:
(call_expr type='<null>' arg_labels=
(unresolved_decl_ref_expr type='<null>' name=SHTest function_ref=unapplied)
(tuple_expr type='()' location=main.swift:18:19 range=[main.swift:18:19 - line:18:20]))
Processed init:
(call_expr type='<null>' arg_labels=
(unresolved_decl_ref_expr type='<null>' name=SHTest function_ref=unapplied)
(tuple_expr type='()' location=main.swift:18:19 range=[main.swift:18:19 - line:18:20])))
))
(var_decl range=[main.swift:18:5 - line:18:5] "test1" type='<null type>' let readImpl=stored immutable))
1.3 生成AST抽象语法树(-dump-ast
)
➜ swiftstudy swiftc -dump-ast main.swift
(source_file "main.swift"
(import_decl range=[main.swift:8:1 - line:8:8] 'Foundation')
(top_level_code_decl range=[main.swift:10:1 - line:10:22]
(brace_stmt range=[main.swift:10:1 - line:10:22]
(call_expr type='()' location=main.swift:10:1 range=[main.swift:10:1 - line:10:22] nothrow arg_labels=_:
(declref_expr type='(Any..., String, String) -> ()' location=main.swift:10:1 range=[main.swift:10:1 - line:10:1] decl=Swift.(file).print(_:separator:terminator:) function_ref=single)
(tuple_expr implicit type='(Any..., separator: String, terminator: String)' location=main.swift:10:6 range=[main.swift:10:6 - line:10:22] names='',separator,terminator
(vararg_expansion_expr implicit type='[Any]' location=main.swift:10:7 range=[main.swift:10:7 - line:10:7]
(array_expr implicit type='[Any]' location=main.swift:10:7 range=[main.swift:10:7 - line:10:7] initializer=**NULL**
(erasure_expr implicit type='Any' location=main.swift:10:7 range=[main.swift:10:7 - line:10:7]
(string_literal_expr type='String' location=main.swift:10:7 range=[main.swift:10:7 - line:10:7] encoding=utf8 value="Hello, World!" builtin_initializer=Swift.(file).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer=**NULL**))))
(default_argument_expr implicit type='String' location=main.swift:10:6 range=[main.swift:10:6 - line:10:6] default_args_owner=Swift.(file).print(_:separator:terminator:) param=1)
(default_argument_expr implicit type='String' location=main.swift:10:6 range=[main.swift:10:6 - line:10:6] default_args_owner=Swift.(file).print(_:separator:terminator:) param=2)))))
(class_decl range=[main.swift:12:1 - line:16:1] "SHTest" interface type='SHTest.Type' access=internal non-resilient
(pattern_binding_decl range=[main.swift:13:5 - line:13:16]
(pattern_named type='String' 'name')
Original init:
(string_literal_expr type='String' location=main.swift:13:16 range=[main.swift:13:16 - line:13:16] encoding=utf8 value="hello" builtin_initializer=Swift.(file).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer=**NULL**)
Processed init:
(string_literal_expr type='String' location=main.swift:13:16 range=[main.swift:13:16 - line:13:16] encoding=utf8 value="hello" builtin_initializer=Swift.(file).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer=**NULL**))
(var_decl range=[main.swift:13:9 - line:13:9] "name" type='String' interface type='String' access=internal readImpl=stored writeImpl=stored readWriteImpl=stored
(accessor_decl implicit range=[main.swift:13:9 - line:13:9] 'anonname=0x7f80ee150a90' interface type='(SHTest) -> () -> String' access=internal get_for=name
(parameter "self" type='SHTest' interface type='SHTest')
(parameter_list)
(brace_stmt implicit range=[main.swift:13:9 - line:13:9]
(return_stmt implicit
(member_ref_expr implicit type='String' decl=main.(file).SHTest.name@main.swift:13:9 direct_to_storage
(declref_expr implicit type='SHTest' decl=main.(file).SHTest.<anonymous>.self@main.swift:13:9 function_ref=unapplied)))))
(accessor_decl implicit range=[main.swift:13:9 - line:13:9] 'anonname=0x7f80ee150cc0' interface type='(SHTest) -> (String) -> ()' access=internal set_for=name
(parameter "self" type='SHTest' interface type='SHTest')
(parameter_list
(parameter "value" type='String' interface type='String') range=[main.swift:13:9 - line:13:9])
(brace_stmt implicit range=[main.swift:13:9 - line:13:9]
(assign_expr implicit type='()'
(member_ref_expr implicit type='@lvalue String' decl=main.(file).SHTest.name@main.swift:13:9 direct_to_storage
(declref_expr implicit type='SHTest' decl=main.(file).SHTest.<anonymous>.self@main.swift:13:9 function_ref=unapplied))
(declref_expr implicit type='String' decl=main.(file).SHTest.<anonymous>.value@main.swift:13:9 function_ref=unapplied))))
(accessor_decl implicit range=[main.swift:13:9 - line:13:9] 'anonname=0x7f80ee150e20' interface type='(SHTest) -> () -> ()' access=internal _modify_for=name
(parameter "self" type='SHTest' interface type='SHTest')
(parameter_list)
(brace_stmt implicit range=[main.swift:13:9 - line:13:9]
(yield_stmt implicit range=[main.swift:13:9 - line:13:9]
(inout_expr implicit type='inout String'
(member_ref_expr implicit type='@lvalue String' decl=main.(file).SHTest.name@main.swift:13:9 direct_to_impl
(declref_expr implicit type='SHTest' decl=main.(file).SHTest.<anonymous>.self@main.swift:13:9 function_ref=unapplied)))))))
(pattern_binding_decl range=[main.swift:14:5 - line:14:16]
(pattern_named type='Double' 'size')
Original init:
(float_literal_expr type='Double' location=main.swift:14:16 range=[main.swift:14:16 - line:14:16] value=10.5 builtin_initializer=Swift.(file).Double extension.init(_builtinFloatLiteral:) initializer=**NULL** builtin_type='Builtin.FPIEEE80')
Processed init:
(float_literal_expr type='Double' location=main.swift:14:16 range=[main.swift:14:16 - line:14:16] value=10.5 builtin_initializer=Swift.(file).Double extension.init(_builtinFloatLiteral:) initializer=**NULL** builtin_type='Builtin.FPIEEE80'))
(var_decl range=[main.swift:14:9 - line:14:9] "size" type='Double' interface type='Double' access=internal readImpl=stored writeImpl=stored readWriteImpl=stored
(accessor_decl implicit range=[main.swift:14:9 - line:14:9] 'anonname=0x7f80ee151f90' interface type='(SHTest) -> () -> Double' access=internal get_for=size
(parameter "self" type='SHTest' interface type='SHTest')
(parameter_list)
(brace_stmt implicit range=[main.swift:14:9 - line:14:9]
(return_stmt implicit
(member_ref_expr implicit type='Double' decl=main.(file).SHTest.size@main.swift:14:9 direct_to_storage
(declref_expr implicit type='SHTest' decl=main.(file).SHTest.<anonymous>.self@main.swift:14:9 function_ref=unapplied)))))
(accessor_decl implicit range=[main.swift:14:9 - line:14:9] 'anonname=0x7f80ee1521c0' interface type='(SHTest) -> (Double) -> ()' access=internal set_for=size
(parameter "self" type='SHTest' interface type='SHTest')
(parameter_list
(parameter "value" type='Double' interface type='Double') range=[main.swift:14:9 - line:14:9])
(brace_stmt implicit range=[main.swift:14:9 - line:14:9]
(assign_expr implicit type='()'
(member_ref_expr implicit type='@lvalue Double' decl=main.(file).SHTest.size@main.swift:14:9 direct_to_storage
(declref_expr implicit type='SHTest' decl=main.(file).SHTest.<anonymous>.self@main.swift:14:9 function_ref=unapplied))
(declref_expr implicit type='Double' decl=main.(file).SHTest.<anonymous>.value@main.swift:14:9 function_ref=unapplied))))
(accessor_decl implicit range=[main.swift:14:9 - line:14:9] 'anonname=0x7f80ee152320' interface type='(SHTest) -> () -> ()' access=internal _modify_for=size
(parameter "self" type='SHTest' interface type='SHTest')
(parameter_list)
(brace_stmt implicit range=[main.swift:14:9 - line:14:9]
(yield_stmt implicit range=[main.swift:14:9 - line:14:9]
(inout_expr implicit type='inout Double'
(member_ref_expr implicit type='@lvalue Double' decl=main.(file).SHTest.size@main.swift:14:9 direct_to_impl
(declref_expr implicit type='SHTest' decl=main.(file).SHTest.<anonymous>.self@main.swift:14:9 function_ref=unapplied)))))))
(pattern_binding_decl range=[main.swift:15:5 - line:15:18]
(pattern_named type='Double' 'height')
Original init:
(float_literal_expr type='Double' location=main.swift:15:18 range=[main.swift:15:18 - line:15:18] value=13.4 builtin_initializer=Swift.(file).Double extension.init(_builtinFloatLiteral:) initializer=**NULL** builtin_type='Builtin.FPIEEE80')
Processed init:
(float_literal_expr type='Double' location=main.swift:15:18 range=[main.swift:15:18 - line:15:18] value=13.4 builtin_initializer=Swift.(file).Double extension.init(_builtinFloatLiteral:) initializer=**NULL** builtin_type='Builtin.FPIEEE80'))
(var_decl range=[main.swift:15:9 - line:15:9] "height" type='Double' interface type='Double' access=internal readImpl=stored writeImpl=stored readWriteImpl=stored
(accessor_decl implicit range=[main.swift:15:9 - line:15:9] 'anonname=0x7f80ef021260' interface type='(SHTest) -> () -> Double' access=internal get_for=height
(parameter "self" type='SHTest' interface type='SHTest')
(parameter_list)
(brace_stmt implicit range=[main.swift:15:9 - line:15:9]
(return_stmt implicit
(member_ref_expr implicit type='Double' decl=main.(file).SHTest.height@main.swift:15:9 direct_to_storage
(declref_expr implicit type='SHTest' decl=main.(file).SHTest.<anonymous>.self@main.swift:15:9 function_ref=unapplied)))))
(accessor_decl implicit range=[main.swift:15:9 - line:15:9] 'anonname=0x7f80ef021438' interface type='(SHTest) -> (Double) -> ()' access=internal set_for=height
(parameter "self" type='SHTest' interface type='SHTest')
(parameter_list
(parameter "value" type='Double' interface type='Double') range=[main.swift:15:9 - line:15:9])
(brace_stmt implicit range=[main.swift:15:9 - line:15:9]
(assign_expr implicit type='()'
(member_ref_expr implicit type='@lvalue Double' decl=main.(file).SHTest.height@main.swift:15:9 direct_to_storage
(declref_expr implicit type='SHTest' decl=main.(file).SHTest.<anonymous>.self@main.swift:15:9 function_ref=unapplied))
(declref_expr implicit type='Double' decl=main.(file).SHTest.<anonymous>.value@main.swift:15:9 function_ref=unapplied))))
(accessor_decl implicit range=[main.swift:15:9 - line:15:9] 'anonname=0x7f80ef021528' interface type='(SHTest) -> () -> ()' access=internal _modify_for=height
(parameter "self" type='SHTest' interface type='SHTest')
(parameter_list)
(brace_stmt implicit range=[main.swift:15:9 - line:15:9]
(yield_stmt implicit range=[main.swift:15:9 - line:15:9]
(inout_expr implicit type='inout Double'
(member_ref_expr implicit type='@lvalue Double' decl=main.(file).SHTest.height@main.swift:15:9 direct_to_impl
(declref_expr implicit type='SHTest' decl=main.(file).SHTest.<anonymous>.self@main.swift:15:9 function_ref=unapplied)))))))
(destructor_decl implicit range=[main.swift:12:7 - line:12:7] "deinit" interface type='(SHTest) -> () -> ()' access=internal
(parameter "self")
(parameter_list)
(brace_stmt implicit range=[main.swift:12:7 - line:12:7]))
(constructor_decl implicit range=[main.swift:12:7 - line:12:7] "init()" interface type='(SHTest.Type) -> () -> SHTest' access=internal designated
(parameter "self")
(parameter_list)
(brace_stmt implicit range=[main.swift:12:7 - line:12:7]
(return_stmt range=[main.swift:12:7 - line:12:7]))))
(top_level_code_decl range=[main.swift:18:1 - line:18:20]
(brace_stmt implicit range=[main.swift:18:1 - line:18:20]
(pattern_binding_decl range=[main.swift:18:1 - line:18:20]
(pattern_named type='SHTest' 'test1')
Original init:
(call_expr type='SHTest' location=main.swift:18:13 range=[main.swift:18:13 - line:18:20] nothrow arg_labels=
(constructor_ref_call_expr type='() -> SHTest' location=main.swift:18:13 range=[main.swift:18:13 - line:18:13] nothrow
(declref_expr implicit type='(SHTest.Type) -> () -> SHTest' location=main.swift:18:13 range=[main.swift:18:13 - line:18:13] decl=main.(file).SHTest.init()@main.swift:12:7 function_ref=single)
(type_expr type='SHTest.Type' location=main.swift:18:13 range=[main.swift:18:13 - line:18:13] typerepr='SHTest'))
(tuple_expr type='()' location=main.swift:18:19 range=[main.swift:18:19 - line:18:20]))
Processed init:
(call_expr type='SHTest' location=main.swift:18:13 range=[main.swift:18:13 - line:18:20] nothrow arg_labels=
(constructor_ref_call_expr type='() -> SHTest' location=main.swift:18:13 range=[main.swift:18:13 - line:18:13] nothrow
(declref_expr implicit type='(SHTest.Type) -> () -> SHTest' location=main.swift:18:13 range=[main.swift:18:13 - line:18:13] decl=main.(file).SHTest.init()@main.swift:12:7 function_ref=single)
(type_expr type='SHTest.Type' location=main.swift:18:13 range=[main.swift:18:13 - line:18:13] typerepr='SHTest'))
(tuple_expr type='()' location=main.swift:18:19 range=[main.swift:18:19 - line:18:20])))
))
(var_decl range=[main.swift:18:5 - line:18:5] "test1" type='SHTest' interface type='SHTest' access=internal let readImpl=stored immutable))
1.4通过SILGen生成未优化代码量巨大的RawSIL文件(-emit-silgen
)
1.5 再拿到优化后更简洁的Canonical SIL(-emit-sil
)
➜ swiftstudy swiftc -emit-sil main.swift
sil_stage canonical
import Builtin
import Swift
import SwiftShims
import Foundation
class SHTest {
@_hasStorage @_hasInitialValue var name: String { get set }
@_hasStorage @_hasInitialValue var size: Double { get set }
@_hasStorage @_hasInitialValue var height: Double { get set }
@objc deinit
init()
}
@_hasStorage @_hasInitialValue let test1: SHTest { get }
// test1
sil_global hidden [let] @$s4main5test1AA6SHTestCvp : $SHTest
// main
sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
%2 = integer_literal $Builtin.Word, 1 // user: %4
// function_ref _allocateUninitializedArray<A>(_:)
%3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
%4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // users: %6, %5
%5 = tuple_extract %4 : $(Array<Any>, Builtin.RawPointer), 0 // users: %24, %21
%6 = tuple_extract %4 : $(Array<Any>, Builtin.RawPointer), 1 // user: %7
%7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
%8 = string_literal utf8 "Hello, World!" // user: %13
%9 = integer_literal $Builtin.Word, 13 // user: %13
%10 = integer_literal $Builtin.Int1, -1 // user: %13
%11 = metatype $@thin String.Type // user: %13
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
%12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
%13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
%14 = init_existential_addr %7 : $*Any, $String // user: %15
store %13 to %14 : $*String // id: %15
// function_ref default argument 1 of print(_:separator:terminator:)
%16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
%17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
// function_ref default argument 2 of print(_:separator:terminator:)
%18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
%19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
// function_ref print(_:separator:terminator:)
%20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () // user: %21
%21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> ()
release_value %19 : $String // id: %22
release_value %17 : $String // id: %23
release_value %5 : $Array<Any> // id: %24
alloc_global @$s4main5test1AA6SHTestCvp // id: %25
%26 = global_addr @$s4main5test1AA6SHTestCvp : $*SHTest // user: %30
%27 = metatype $@thick SHTest.Type // user: %29
// function_ref SHTest.__allocating_init()
%28 = function_ref @$s4main6SHTestCACycfC : $@convention(method) (@thick SHTest.Type) -> @owned SHTest // user: %29
%29 = apply %28(%27) : $@convention(method) (@thick SHTest.Type) -> @owned SHTest // user: %30
store %29 to %26 : $*SHTest // id: %30
%31 = integer_literal $Builtin.Int32, 0 // user: %32
%32 = struct $Int32 (%31 : $Builtin.Int32) // user: %33
return %32 : $Int32 // id: %33
} // end sil function 'main'
// _allocateUninitializedArray<A>(_:)
sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
// String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
// default argument 1 of print(_:separator:terminator:)
sil shared_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String {
bb0:
%0 = string_literal utf8 " " // user: %5
%1 = integer_literal $Builtin.Word, 1 // user: %5
%2 = integer_literal $Builtin.Int1, -1 // user: %5
%3 = metatype $@thin String.Type // user: %5
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %5
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %6
return %5 : $String // id: %6
} // end sil function '$ss5print_9separator10terminatoryypd_S2StFfA0_'
// default argument 2 of print(_:separator:terminator:)
sil shared_external [serialized] @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String {
bb0:
%0 = string_literal utf8 "\n" // user: %5
%1 = integer_literal $Builtin.Word, 1 // user: %5
%2 = integer_literal $Builtin.Int1, -1 // user: %5
%3 = metatype $@thin String.Type // user: %5
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %5
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %6
return %5 : $String // id: %6
} // end sil function '$ss5print_9separator10terminatoryypd_S2StFfA1_'
// print(_:separator:terminator:)
sil @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> ()
// variable initialization expression of SHTest.name
sil hidden [transparent] @$s4main6SHTestC4nameSSvpfi : $@convention(thin) () -> @owned String {
bb0:
%0 = string_literal utf8 "hello" // user: %5
%1 = integer_literal $Builtin.Word, 5 // user: %5
%2 = integer_literal $Builtin.Int1, -1 // user: %5
%3 = metatype $@thin String.Type // user: %5
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %5
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %6
return %5 : $String // id: %6
} // end sil function '$s4main6SHTestC4nameSSvpfi'
// SHTest.name.getter
sil hidden [transparent] @$s4main6SHTestC4nameSSvg : $@convention(method) (@guaranteed SHTest) -> @owned String {
// %0 // users: %2, %1
bb0(%0 : $SHTest):
debug_value %0 : $SHTest, let, name "self", argno 1 // id: %1
%2 = ref_element_addr %0 : $SHTest, #SHTest.name // user: %3
%3 = begin_access [read] [dynamic] %2 : $*String // users: %4, %6
%4 = load %3 : $*String // users: %7, %5
retain_value %4 : $String // id: %5
end_access %3 : $*String // id: %6
return %4 : $String // id: %7
} // end sil function '$s4main6SHTestC4nameSSvg'
// SHTest.name.setter
sil hidden [transparent] @$s4main6SHTestC4nameSSvs : $@convention(method) (@owned String, @guaranteed SHTest) -> () {
// %0 // users: %11, %8, %4, %2
// %1 // users: %5, %3
bb0(%0 : $String, %1 : $SHTest):
debug_value %0 : $String, let, name "value", argno 1 // id: %2
debug_value %1 : $SHTest, let, name "self", argno 2 // id: %3
retain_value %0 : $String // id: %4
%5 = ref_element_addr %1 : $SHTest, #SHTest.name // user: %6
%6 = begin_access [modify] [dynamic] %5 : $*String // users: %8, %7, %10
%7 = load %6 : $*String // user: %9
store %0 to %6 : $*String // id: %8
release_value %7 : $String // id: %9
end_access %6 : $*String // id: %10
release_value %0 : $String // id: %11
%12 = tuple () // user: %13
return %12 : $() // id: %13
} // end sil function '$s4main6SHTestC4nameSSvs'
// SHTest.name.modify
sil hidden [transparent] @$s4main6SHTestC4nameSSvM : $@yield_once @convention(method) (@guaranteed SHTest) -> @yields @inout String {
// %0 // users: %2, %1
bb0(%0 : $SHTest):
debug_value %0 : $SHTest, let, name "self", argno 1 // id: %1
%2 = ref_element_addr %0 : $SHTest, #SHTest.name // user: %3
%3 = begin_access [modify] [dynamic] %2 : $*String // users: %5, %8, %4
yield %3 : $*String, resume bb1, unwind bb2 // id: %4
bb1: // Preds: bb0
end_access %3 : $*String // id: %5
%6 = tuple () // user: %7
return %6 : $() // id: %7
bb2: // Preds: bb0
end_access %3 : $*String // id: %8
unwind // id: %9
} // end sil function '$s4main6SHTestC4nameSSvM'
// variable initialization expression of SHTest.size
sil hidden [transparent] @$s4main6SHTestC4sizeSdvpfi : $@convention(thin) () -> Double {
bb0:
%0 = float_literal $Builtin.FPIEEE64, 0x4025000000000000 // 10.5 // user: %1
%1 = struct $Double (%0 : $Builtin.FPIEEE64) // user: %2
return %1 : $Double // id: %2
} // end sil function '$s4main6SHTestC4sizeSdvpfi'
// Double.init(_builtinFloatLiteral:)
sil public_external [transparent] [serialized] @$sSd20_builtinFloatLiteralSdBf80__tcfC : $@convention(method) (Builtin.FPIEEE80, @thin Double.Type) -> Double {
// %0 // user: %2
bb0(%0 : $Builtin.FPIEEE80, %1 : $@thin Double.Type):
%2 = builtin "fptrunc_FPIEEE80_FPIEEE64"(%0 : $Builtin.FPIEEE80) : $Builtin.FPIEEE64 // user: %3
%3 = struct $Double (%2 : $Builtin.FPIEEE64) // user: %4
return %3 : $Double // id: %4
} // end sil function '$sSd20_builtinFloatLiteralSdBf80__tcfC'
// SHTest.size.getter
sil hidden [transparent] @$s4main6SHTestC4sizeSdvg : $@convention(method) (@guaranteed SHTest) -> Double {
// %0 // users: %2, %1
bb0(%0 : $SHTest):
debug_value %0 : $SHTest, let, name "self", argno 1 // id: %1
%2 = ref_element_addr %0 : $SHTest, #SHTest.size // user: %3
%3 = begin_access [read] [dynamic] %2 : $*Double // users: %4, %5
%4 = load %3 : $*Double // user: %6
end_access %3 : $*Double // id: %5
return %4 : $Double // id: %6
} // end sil function '$s4main6SHTestC4sizeSdvg'
// SHTest.size.setter
sil hidden [transparent] @$s4main6SHTestC4sizeSdvs : $@convention(method) (Double, @guaranteed SHTest) -> () {
// %0 // users: %6, %2
// %1 // users: %4, %3
bb0(%0 : $Double, %1 : $SHTest):
debug_value %0 : $Double, let, name "value", argno 1 // id: %2
debug_value %1 : $SHTest, let, name "self", argno 2 // id: %3
%4 = ref_element_addr %1 : $SHTest, #SHTest.size // user: %5
%5 = begin_access [modify] [dynamic] %4 : $*Double // users: %6, %7
store %0 to %5 : $*Double // id: %6
end_access %5 : $*Double // id: %7
%8 = tuple () // user: %9
return %8 : $() // id: %9
} // end sil function '$s4main6SHTestC4sizeSdvs'
// SHTest.size.modify
sil hidden [transparent] @$s4main6SHTestC4sizeSdvM : $@yield_once @convention(method) (@guaranteed SHTest) -> @yields @inout Double {
// %0 // users: %2, %1
bb0(%0 : $SHTest):
debug_value %0 : $SHTest, let, name "self", argno 1 // id: %1
%2 = ref_element_addr %0 : $SHTest, #SHTest.size // user: %3
%3 = begin_access [modify] [dynamic] %2 : $*Double // users: %5, %8, %4
yield %3 : $*Double, resume bb1, unwind bb2 // id: %4
bb1: // Preds: bb0
end_access %3 : $*Double // id: %5
%6 = tuple () // user: %7
return %6 : $() // id: %7
bb2: // Preds: bb0
end_access %3 : $*Double // id: %8
unwind // id: %9
} // end sil function '$s4main6SHTestC4sizeSdvM'
// variable initialization expression of SHTest.height
sil hidden [transparent] @$s4main6SHTestC6heightSdvpfi : $@convention(thin) () -> Double {
bb0:
%0 = float_literal $Builtin.FPIEEE64, 0x402ACCCCCCCCCCCD // 13.4 // user: %1
%1 = struct $Double (%0 : $Builtin.FPIEEE64) // user: %2
return %1 : $Double // id: %2
} // end sil function '$s4main6SHTestC6heightSdvpfi'
// SHTest.height.getter
sil hidden [transparent] @$s4main6SHTestC6heightSdvg : $@convention(method) (@guaranteed SHTest) -> Double {
// %0 // users: %2, %1
bb0(%0 : $SHTest):
debug_value %0 : $SHTest, let, name "self", argno 1 // id: %1
%2 = ref_element_addr %0 : $SHTest, #SHTest.height // user: %3
%3 = begin_access [read] [dynamic] %2 : $*Double // users: %4, %5
%4 = load %3 : $*Double // user: %6
end_access %3 : $*Double // id: %5
return %4 : $Double // id: %6
} // end sil function '$s4main6SHTestC6heightSdvg'
// SHTest.height.setter
sil hidden [transparent] @$s4main6SHTestC6heightSdvs : $@convention(method) (Double, @guaranteed SHTest) -> () {
// %0 // users: %6, %2
// %1 // users: %4, %3
bb0(%0 : $Double, %1 : $SHTest):
debug_value %0 : $Double, let, name "value", argno 1 // id: %2
debug_value %1 : $SHTest, let, name "self", argno 2 // id: %3
%4 = ref_element_addr %1 : $SHTest, #SHTest.height // user: %5
%5 = begin_access [modify] [dynamic] %4 : $*Double // users: %6, %7
store %0 to %5 : $*Double // id: %6
end_access %5 : $*Double // id: %7
%8 = tuple () // user: %9
return %8 : $() // id: %9
} // end sil function '$s4main6SHTestC6heightSdvs'
// SHTest.height.modify
sil hidden [transparent] @$s4main6SHTestC6heightSdvM : $@yield_once @convention(method) (@guaranteed SHTest) -> @yields @inout Double {
// %0 // users: %2, %1
bb0(%0 : $SHTest):
debug_value %0 : $SHTest, let, name "self", argno 1 // id: %1
%2 = ref_element_addr %0 : $SHTest, #SHTest.height // user: %3
%3 = begin_access [modify] [dynamic] %2 : $*Double // users: %5, %8, %4
yield %3 : $*Double, resume bb1, unwind bb2 // id: %4
bb1: // Preds: bb0
end_access %3 : $*Double // id: %5
%6 = tuple () // user: %7
return %6 : $() // id: %7
bb2: // Preds: bb0
end_access %3 : $*Double // id: %8
unwind // id: %9
} // end sil function '$s4main6SHTestC6heightSdvM'
// SHTest.deinit
sil hidden @$s4main6SHTestCfd : $@convention(method) (@guaranteed SHTest) -> @owned Builtin.NativeObject {
// %0 // users: %4, %2, %1
bb0(%0 : $SHTest):
debug_value %0 : $SHTest, let, name "self", argno 1 // id: %1
%2 = ref_element_addr %0 : $SHTest, #SHTest.name // user: %3
destroy_addr %2 : $*String // id: %3
%4 = unchecked_ref_cast %0 : $SHTest to $Builtin.NativeObject // user: %5
return %4 : $Builtin.NativeObject // id: %5
} // end sil function '$s4main6SHTestCfd'
// SHTest.__deallocating_deinit
sil hidden @$s4main6SHTestCfD : $@convention(method) (@owned SHTest) -> () {
// %0 // users: %3, %1
bb0(%0 : $SHTest):
debug_value %0 : $SHTest, let, name "self", argno 1 // id: %1
// function_ref SHTest.deinit
%2 = function_ref @$s4main6SHTestCfd : $@convention(method) (@guaranteed SHTest) -> @owned Builtin.NativeObject // user: %3
%3 = apply %2(%0) : $@convention(method) (@guaranteed SHTest) -> @owned Builtin.NativeObject // user: %4
%4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $SHTest // user: %5
dealloc_ref %4 : $SHTest // id: %5
%6 = tuple () // user: %7
return %6 : $() // id: %7
} // end sil function '$s4main6SHTestCfD'
// SHTest.__allocating_init()
sil hidden [exact_self_class] @$s4main6SHTestCACycfC : $@convention(method) (@thick SHTest.Type) -> @owned SHTest {
bb0(%0 : $@thick SHTest.Type):
%1 = alloc_ref $SHTest // user: %3
// function_ref SHTest.init()
%2 = function_ref @$s4main6SHTestCACycfc : $@convention(method) (@owned SHTest) -> @owned SHTest // user: %3
%3 = apply %2(%1) : $@convention(method) (@owned SHTest) -> @owned SHTest // user: %4
return %3 : $SHTest // id: %4
} // end sil function '$s4main6SHTestCACycfC'
// SHTest.init()
sil hidden @$s4main6SHTestCACycfc : $@convention(method) (@owned SHTest) -> @owned SHTest {
// %0 // users: %24, %20, %14, %8, %1
bb0(%0 : $SHTest):
debug_value %0 : $SHTest, let, name "self", argno 1 // id: %1
%2 = string_literal utf8 "hello" // user: %7
%3 = integer_literal $Builtin.Word, 5 // user: %7
%4 = integer_literal $Builtin.Int1, -1 // user: %7
%5 = metatype $@thin String.Type // user: %7
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
%6 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %7
%7 = apply %6(%2, %3, %4, %5) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %10
%8 = ref_element_addr %0 : $SHTest, #SHTest.name // user: %9
%9 = begin_access [modify] [dynamic] %8 : $*String // users: %10, %11
store %7 to %9 : $*String // id: %10
end_access %9 : $*String // id: %11
%12 = float_literal $Builtin.FPIEEE64, 0x4025000000000000 // 10.5 // user: %13
%13 = struct $Double (%12 : $Builtin.FPIEEE64) // user: %16
%14 = ref_element_addr %0 : $SHTest, #SHTest.size // user: %15
%15 = begin_access [modify] [dynamic] %14 : $*Double // users: %16, %17
store %13 to %15 : $*Double // id: %16
end_access %15 : $*Double // id: %17
%18 = float_literal $Builtin.FPIEEE64, 0x402ACCCCCCCCCCCD // 13.4 // user: %19
%19 = struct $Double (%18 : $Builtin.FPIEEE64) // user: %22
%20 = ref_element_addr %0 : $SHTest, #SHTest.height // user: %21
%21 = begin_access [modify] [dynamic] %20 : $*Double // users: %22, %23
store %19 to %21 : $*Double // id: %22
end_access %21 : $*Double // id: %23
return %0 : $SHTest // id: %24
} // end sil function '$s4main6SHTestCACycfc'
sil_vtable SHTest {
#SHTest.name!getter.1: (SHTest) -> () -> String : @$s4main6SHTestC4nameSSvg // SHTest.name.getter
#SHTest.name!setter.1: (SHTest) -> (String) -> () : @$s4main6SHTestC4nameSSvs // SHTest.name.setter
#SHTest.name!modify.1: (SHTest) -> () -> () : @$s4main6SHTestC4nameSSvM // SHTest.name.modify
#SHTest.size!getter.1: (SHTest) -> () -> Double : @$s4main6SHTestC4sizeSdvg // SHTest.size.getter
#SHTest.size!setter.1: (SHTest) -> (Double) -> () : @$s4main6SHTestC4sizeSdvs // SHTest.size.setter
#SHTest.size!modify.1: (SHTest) -> () -> () : @$s4main6SHTestC4sizeSdvM // SHTest.size.modify
#SHTest.height!getter.1: (SHTest) -> () -> Double : @$s4main6SHTestC6heightSdvg // SHTest.height.getter
#SHTest.height!setter.1: (SHTest) -> (Double) -> () : @$s4main6SHTestC6heightSdvs // SHTest.height.setter
#SHTest.height!modify.1: (SHTest) -> () -> () : @$s4main6SHTestC6heightSdvM // SHTest.height.modify
#SHTest.init!allocator.1: (SHTest.Type) -> () -> SHTest : @$s4main6SHTestCACycfC // SHTest.__allocating_init()
#SHTest.deinit!deallocator.1: @$s4main6SHTestCfD // SHTest.__deallocating_deinit
}
######1.5.1
我们来看这段
class SHTest {
@_hasStorage @_hasInitialValue var name: String { get set }
@_hasStorage @_hasInitialValue var size: Double { get set }
@_hasStorage @_hasInitialValue var height: Double { get set }
@objc deinit
init()
}
@_hasStorage @_hasInitialValue let test1: SHTest { get }
// test1
sil_global hidden [let] @$s4main5test1AA6SHTestCvp : $SHTest
通过xcrun
命令还原混写后的字符串:
xcrun swift-demangle s4main5test1AA6SHTestCvp
可以得到:
$s4main5test1AA6SHTestCvp ---> main.test1 : main.SHTest
1.5.2 main
// main
sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
%2 = integer_literal $Builtin.Word, 1 // user: %4
// function_ref _allocateUninitializedArray<A>(_:)
%3 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %4
%4 = apply %3<Any>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // users: %6, %5
%5 = tuple_extract %4 : $(Array<Any>, Builtin.RawPointer), 0 // users: %24, %21
%6 = tuple_extract %4 : $(Array<Any>, Builtin.RawPointer), 1 // user: %7
%7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Any // user: %14
%8 = string_literal utf8 "Hello, World!" // user: %13
%9 = integer_literal $Builtin.Word, 13 // user: %13
%10 = integer_literal $Builtin.Int1, -1 // user: %13
%11 = metatype $@thin String.Type // user: %13
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
%12 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %13
%13 = apply %12(%8, %9, %10, %11) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %15
%14 = init_existential_addr %7 : $*Any, $String // user: %15
store %13 to %14 : $*String // id: %15
// function_ref default argument 1 of print(_:separator:terminator:)
%16 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %17
%17 = apply %16() : $@convention(thin) () -> @owned String // users: %23, %21
// function_ref default argument 2 of print(_:separator:terminator:)
%18 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %19
%19 = apply %18() : $@convention(thin) () -> @owned String // users: %22, %21
// function_ref print(_:separator:terminator:)
%20 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () // user: %21
%21 = apply %20(%5, %17, %19) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> ()
release_value %19 : $String // id: %22
release_value %17 : $String // id: %23
release_value %5 : $Array<Any> // id: %24
alloc_global @$s4main5test1AA6SHTestCvp // id: %25
%26 = global_addr @$s4main5test1AA6SHTestCvp : $*SHTest // user: %30
%27 = metatype $@thick SHTest.Type // user: %29
// function_ref SHTest.__allocating_init()
%28 = function_ref @$s4main6SHTestCACycfC : $@convention(method) (@thick SHTest.Type) -> @owned SHTest // user: %29
%29 = apply %28(%27) : $@convention(method) (@thick SHTest.Type) -> @owned SHTest // user: %30
store %29 to %26 : $*SHTest // id: %30
%31 = integer_literal $Builtin.Int32, 0 // user: %32
%32 = struct $Int32 (%31 : $Builtin.Int32) // user: %33
return %32 : $Int32 // id: %33
} // end sil function 'main'
1.6通过IRGen生成IR(-emit-ir
)
1.7最终生成二进制代码
看下汇编代码 swiftc -emit-assembly main.swift
......
globl _$s4main6SHTestC4nameSSvgTq
.private_extern _$s4main6SHTestC4nameSSvgTq
.alt_entry _$s4main6SHTestC4nameSSvgTq
.set _$s4main6SHTestC4nameSSvgTq, _$s4main6SHTestCMn+52
.globl _$s4main6SHTestC4nameSSvsTq
.private_extern _$s4main6SHTestC4nameSSvsTq
.alt_entry _$s4main6SHTestC4nameSSvsTq
.set _$s4main6SHTestC4nameSSvsTq, _$s4main6SHTestCMn+60
.globl _$s4main6SHTestC4nameSSvMTq
.private_extern _$s4main6SHTestC4nameSSvMTq
.alt_entry _$s4main6SHTestC4nameSSvMTq
.set _$s4main6SHTestC4nameSSvMTq, _$s4main6SHTestCMn+68
.globl _$s4main6SHTestC4sizeSdvgTq
.private_extern _$s4main6SHTestC4sizeSdvgTq
.alt_entry _$s4main6SHTestC4sizeSdvgTq
.set _$s4main6SHTestC4sizeSdvgTq, _$s4main6SHTestCMn+76
.globl _$s4main6SHTestC4sizeSdvsTq
.private_extern _$s4main6SHTestC4sizeSdvsTq
.alt_entry _$s4main6SHTestC4sizeSdvsTq
.set _$s4main6SHTestC4sizeSdvsTq, _$s4main6SHTestCMn+84
.globl _$s4main6SHTestC4sizeSdvMTq
.private_extern _$s4main6SHTestC4sizeSdvMTq
.alt_entry _$s4main6SHTestC4sizeSdvMTq
.set _$s4main6SHTestC4sizeSdvMTq, _$s4main6SHTestCMn+92
.globl _$s4main6SHTestC6heightSdvgTq
.private_extern _$s4main6SHTestC6heightSdvgTq
.alt_entry _$s4main6SHTestC6heightSdvgTq
.set _$s4main6SHTestC6heightSdvgTq, _$s4main6SHTestCMn+100
.globl _$s4main6SHTestC6heightSdvsTq
.private_extern _$s4main6SHTestC6heightSdvsTq
.alt_entry _$s4main6SHTestC6heightSdvsTq
.set _$s4main6SHTestC6heightSdvsTq, _$s4main6SHTestCMn+108
.globl _$s4main6SHTestC6heightSdvMTq
.private_extern _$s4main6SHTestC6heightSdvMTq
.alt_entry _$s4main6SHTestC6heightSdvMTq
.set _$s4main6SHTestC6heightSdvMTq, _$s4main6SHTestCMn+116
.globl _$s4main6SHTestCACycfCTq
.private_extern _$s4main6SHTestCACycfCTq
.alt_entry _$s4main6SHTestCACycfCTq
.set _$s4main6SHTestCACycfCTq, _$s4main6SHTestCMn+124
.globl _$s4main6SHTestCN
.private_extern _$s4main6SHTestCN
.alt_entry _$s4main6SHTestCN
.set _$s4main6SHTestCN, _$s4main6SHTestCMf+16
.subsections_via_symbols
网友评论