【WIP】弱参照(docs/weak.rst) 翻訳

出典

https://github.com/apple/swift/blob/3cbabfd196d3be8d01e97cacef71f41e9c594f1d/docs/weak.rst

弱参照

要約:本書では、他の言語での様々な設計を含む弱参照の一般的な概念について説明し、標準ライブラリで利用できるいくつかの新しいコア言語機能とより洗練されたランタイムサポート機能を提案する

警告

このドキュメントはSwift1.0の計画に使用された。最新の状態に保たれておらず、Swiftの現在、または計画されている動作を記述していない

参照グラフ

基本的な用語を解説する

プログラムメモリは

  • ノード
    • オブジェクト
    • (ローカルスコープのような一時的な割り当てをオブジェクトとして扱う)
  • エッジ
    • 参照
    • (必ずしも接続されていない)

上記のような有向グラフとして抽象的に見ることができる

(もちろん、マルチエッジとセルフエッジは許可されている)

これらのエッジのそれぞれにあるレベルの強度を割り当てることができる

最高レベルのstrong、それ以外はweakを呼び出す

全てのオブジェクトは、参照グラフから生じる参照の強さを持つ

これは任意のレベルの強さ、または参照されない特別な値にすることができる

パスの強さはパス内のエッジの最小強度である

パスセットの強さは、セットが空でない場合をのぞいて、全てのパスの最大強度である

この場合、パスは参照されない

一般に、実装はオブジェクトが強参照されている場合には、オブジェクトの割り当てを解除することのみが禁じられている

しかし、何からの形で弱参照されていると、ある種の追加保証が発生する可能性がある

言語の前提条件のセクションを参照して欲しい

サイクルコレクタ環境では、特定のノードにルートとして特別な処理が与えられる

これらのノードは常に強参照される

それ以外の場合、オブジェクトの参照強度はルートからオブジェクトまでの全てのパスの強度になる

非サイクルコレクタ環境では、オブジェクトの参照の強さは、そのオブジェクトの全ての直接参照の強度であり、length=1のパスとみなされる

この環境配慮は言語の保証となることに注意

例え実装がオブジェクト単独のみ参照されることを自明に証明できるとしても、オブジェクトの割り当てを解除することはできない

特定の種類の参照が完全な保証を受けないことは一般的である

例えば、ローカル変数からの強参照は、変数がもはや必要でなくなった

(ただし、正式にスコープを離れる前に)有効性を失う可能性がある

これはGC環境に広がっている、例えばObjective-CでのARC

いくつかのプログラム、特にUIやサーバーのようなイベントドリブンなプログラムでは、概念上の定常状態の間にキャプチャされた静的参照グラフを考慮すると便利

ローカルスコープは静的グラフ内のオブジェクトへの多数の参照を形成するかもしれないが、スコープが無期限に持続する、または大規模な再構築がトリガされない限り、これらの参照は参照グラフに影響を与えないので、参照強度に意味的な重要性はない

言語とライブラリの前例

ここでは既に管理された先例についてのみ議論するつもりである

オブジェクト参照に特別な振る舞いを与えることなく弱参照の種類を作成することは可能である

オブジェクトが割り当てを解除された場合、参照がぶら下がり、その参照がクラッシュしたり、その原因を引き起こす可能性がある

これは例えば(ARCのような環境で)特定の変数の参照カウント操作を挿入したり、(正確なGC環境で)型マップ内のポインタとして変数のframe offsetマッピングしないようにした

このぶら下がりをweakとして呼び出すだろう

Objective-C

Objective-Cのすべてのモードは、synthesizeされたプロパティのメモリ管理を自動化する

GCとARCでは、アクセサは、基本的なivar(もちろんcopy/atomicな保証)のための通常のセマンティクスを使用する

MRCでのアクセサは保持またはコピーされていない限り、弱いセマンティクスを使用する、この場合指示対象に対して+1の参照カウントが維持される

GCとARCでは、__weakで修飾された変数は、参照されたオブジェクトが解放を開始すると直ちにゼロになる

使用上の構文上の違いはない

読み込まれた値が最後に書き込まれたものではなくnilになる可能性がある

読み込みコードがクラッシュする(例えば、ivarアクセス​​)か、または何もしない(メッセージ送信など)

__weakなivarsからロードされた値の特定の用途については、ARCにオプトイン警告がある

GCでは、

  1. スキャンされていないヒープメモリ
  2. オブジェクトポインタ型ではなく、__strongまたは__weakで修飾されていないインスタンス変数にオブジェクトポインタを格納する

上記によって、ダングリング弱参照を構築することもできる

それ以外の場合、オブジェクトは強参照となる
(ローカルスコープからのすべての参照を含む)

ARCでは、__unsafe_unretained修飾子を使用するか、Cポインタ型にポインタ値を橋渡しすることで、ダングリング弱参照を構築することができる

C++

C++ではスマートポインタ(e.g. std::unique_ptr)は通常、ポインタを通常のCポインタとして取得するアクセサを提供することによって弱参照の作成を可能にする(get()を持っていなくても手動でoperator->を呼び出し同じ効果を得ることができる

C++std::shared_ptrは共有ポインタからweakポインタ(std::weak_ptr)を形成することを許可する

weakポインタを直接使用することはできない

参照元が割り当て解除されている場合はnullポインタを生成する)操作を行うか、参照対象が既に存在する場合に例外をスローするweak_ptrを使用してshared_ptrを直接構築することによって、shared_ptrに最初に変換する必要がある(割り当てが解除される)

weak_ptrがまだ有効かどうかを明示的に問い合わせる方法もある、これはキャストの結果を調べるよりも効率的である

Java

Javaは弱参照をダングリングするための機能を提供していない

標準ライブラリは(java.lang.refの)3つのレベルの弱参照を提供する

参照を再配置することはできない(明示的にクリアすることはできるが)

ユーザは値にアクセスする為にget()を呼び出す必要があり、nullを返される可能性がある

これらの参照クラスの興味深い議論は、ここでたくさん行われている

Java ReferenceオブジェクトはオプションのReferenceQueueで構築できる

その場合オブジェクトの到達可能性が変更されると、参照オブジェクトがそのキューに追加される

これにより、構造全体を定期的にスキャンしたり、完全にlazyすることなく、クリアされたsoft referencesの後にデータ構造をクリーンアップすることができる

サブクラス化することによって参照オブジェクトに追加データを追加することができる

リファレンスは強度の順に表示される

SoftReferenceVMがメモリ不足になるまでオブジェクトに保持される一種のquasi-strong参照である

softly-referencedオブジェクトのソフト参照はVMがOutOfMemoryErrorをスローする前にクリアされていることが保証されている

参照は参照キューに追加される前にクリアされる(参照キューはオブジェクトを復活できない)

ソフトリファレンスの目的はmemory-sensitiveなキャッシュを有効にすることだが実際にはmemory-sensitiveなキャッシュはおそらく、「メモリが不足するとすぐに落とす」よりも巧妙な置換戦略を実装したいと考えている

より興味深いのはメモリでガイドされるcircuit-breakerである、非常に大きな構築をする場合はソフト参照で保持して欲しい

構築中に参照がnullになるとただ破棄される、しかしこれはかなり上手くやってもらえるユースケースである

WeakReferenceは一意のキャッシュのようなメモリーに依存しない弱いキャッシュでの使用を意図している

指示対象がより強く参照されている間だけ持続する、参照は参照キューに追加される前にクリアされる (参照キューはオブジェクトを復活できない)

PhantomReferenceは実際にファイナライザ(オブジェクトを復活させる機能を含むいくつかの問題がある)を実際に使用することなく、オブジェクトに余分なファイナライズを加える方法を提供する

ファントム参照は常にその値としてnullを提示するため、参照としては無意味である

ファントム参照は、オブジェクトがファイナライズされた後にエンキューされる

したがって、仮想マシン内のオブジェクトへの参照がまったく存在しない場合がある

しかし、ファントム参照がすべてクリアされるまでオブジェクト自体は割り当てを解除することができない、

またはそれ自体が指示対象にダングリング弱参照を保持することができる
(又はその直接の参照を読み取ることができるかもしれないネイティブコードの便宜のためであると考えている割り当てを解除する)

.NET

.NETのWeakReferenceクラスはJavaのWeakReferenceクラスに似ているが、値に直接アクセスすることはできない

Targetプロパティを使用してアクセスする必要がある

これはnullを返す可能性がある

参照値は別の値に再設定することができる

Targetオブジェクトがファイナライズされるが、実際には割り当てが解除されないようにする弱参照が長く作成されることがある

Python

weakrefは関数オブジェクトのように動作する

特定の値で作成され、再配置することはできない

参照先が収集されている場合、この関数はNoneを返す

弱い参照として値を自動的にプロキシするライブラリ機能がある

プロキシで操作が実行されても参照先が収集されている場合は例外が投げられる

weakrefはコールバック関数で構築することができる

コールバックは弱参照がクリアされた後に呼び出される

しかしそれは弱いrefオブジェクト自体を渡される

Ruby

WeakRefは自動的にオブジェクトのプロキシである

参照がまだいきているかどうかを調べるweakref_aliveメソッドがある

別の操作で例外が投げられる

Rust

筆者が知っている限り、現時点でRustの弱参照のようなものはない

TBD

A managed pointer (@int) is a strong reference subject to GC.

An owning pointer (~int) is a strong reference that cannot be cloned (copying the pointer actually copies the underlying data).

A borrowed pointer (&int) is essentially a dangling weak reference that is subject to static restrictions which ensure that it doesn't actually dangle. It is thus primarily a performance optimization.

A raw pointer (*int) is a dangling weak reference.

Haskell

もちろんHaskellは弱参照を持っている

Weak tはhidden keyと型tの可視値との関連である

doRefWeak theRefIO (Maybe t)である

弱参照は参照先が収集されたときに実行されるoptionalのIO()を使用して構築できる

このファイナライザは何らかの形でkeyと値を参照することができる

それらを復活させることも明示的に許可されている

ユースケース

弱参照のような機能では、潜在的に対処できる多くの問題がある

同じ言語機能で対処すべきであるかどうかは全く異なる

後方参照

Swiftはcycle-collectingでないことを考えると、静的参照グラフの最も重要な使用事例は後方参照である

Rを参照するオブジェクトに(おそらく間接的に)強参照を保持するオブジェクトへの参照Rを含む

例としては、

  • 双方向連結リスト内のpreviousNodeポインタ
  • レンダリングツリー内の「親」ポインタ
  • 一般的なグラフ構造のエッジ

これらは共通のいくつかのプロパティを保持している

  • 強力な参照を使用するには、参照サイクルを分解するための多くの明示的なコードが必要である
  • これらの参照は頻繁にアクセスする可能性があるため、パフォーマンスが重要である
  • これらの参照を構築の直後に有効にすることは必ずしも実現可能ではない
  • 参照先が割り当て解除された後に参照をトラバースすることは、あるものが意図されたよりも長く生きているという調合である可能性が高い。しかしプログラマはクラッシュすることにより根本原因を突き止めるようプログラマに推奨するか、あるいは両方のケースを正しく処理する為の操作を書くだけで、これに対する正しい応答について合理的に異なるかもしれない。最終的にこの選択は哲学に帰結する

キャッシュ

キャッシュが使用可能なすべてのメモリを引き継ぐのを防ぐために、弱いキャッシュが使用される

値の到達可能性に縛られることによってキャッシュはそれらの値が依然として有効であるときに

エントリが誤って期限切れになるのを防ぐ

弱参照を使用することによってキャッシュはシステムがもはや使用されていない値の割り当てを解除することを可能にする

一般に、弱参照を広範囲に使用するデータ構造は、弱参照が収集されたという通知を受け取るために何らかの方法を必要とする

これは値が収集されてもデータ構造内のエントリに大きなオーバーヘッドが発生する可能性があるため

参照が無効にされたという通知を受け取らない弱いデータ構造はこれらのエントリを無期限に累積させるか、

古いエントリを探す構造全体を定期的にスキャンする必要がある

最後の強参照が破棄されたときにその参照先の即時の割り振り解除を可能にする弱参照は、

弱いキャッシュの実装にとって実質的にあまり有用ではない

それは頻繁に何度も検索されるが、各使用が他のものと一時的に乖離しているために、

一般的なアクセスパターン(例えばmemoizing cacheの場合)である

この場合弱参照を単純に使用すると、単にキャッシュにスラッシュが発生してしまう

この問題は非決定論的コレクションを持つ環境では起こりにくい

なぜならエントリがコレクション間で複数のルックアップを処理する可能性が高いからである

弱いデータ構造を実装しているユーザは言語に直接組み込まれているよりも堅牢なシステムよりも、

ゼロ復帰に達するという復活と通知を中心とした柔軟性の高いインフラストラクチャを好む傾向がある

Swiftモデルはメモリスキャナーではなく静的に挿入された操作の周りに構築されているのでこれははるかに実行可能である

TBD External Finalization

TBD

最適化

TBD

プロポーザルの概要

TBD

提案された変数の属性

TBD

@weak

TBD

@unowned

TBD

TBD xxx

TBD

TBD Implementation

TBD

TBD Declaration Attribute or Type Attribute

TBD

TBD weak-Capable Types

TBD

TBD Generic Weak Support

TBD

TBD Proposed Rules for Captures within Closures

TBD

TBD Decorated Capture References

TBD

TBD capture Declarations

TBD

TBD Nested Closures

TBD

TBD Library Directions

TBD

include/swift/Driver コードリーディング(全体)

概要

https://github.com/apple/swift/tree/c309fb2620b030a722741171baee4dfec5017d58/include/swift/Driver

Action.h

Compilation.h

DependencyGraph.h

Driver.h

OutputInfo::Mode

definition desc
StandardCompile 標準コンパイル、複数のFrontend呼び出しを使用する(-primary-fileあり)
SingleCompile 単一のFrontend呼び出しを使用する(-primary-fileなし)
BatchModeCompile 複数のStandardCompileジョブをまとめてパッチ処理する単一プロセス
REPL REPL呼び出し
Immediate 入力をコンパイルして即時実行する

Driver

Driver::DriverKind

引数をパースする方法、許容するOutputInfo::Modeを決定します

definition desc
Interactive swift
Batch swiftc
AutolinkExtract swift-autolink-extract
SwiftFormat swift-format

FrontendUtil.h

Job.h

OutputFileMap.h

ParseableOutput.h

PrettyStackTrace.h

ToolChain.h

Types.def

Types.h

Util.h

include/swift/Frontend コードリーディング(全体)

概要

swift/include/swift/Frontend at 4b727e5813246d4029e7c4269bba317db9b012d3 · apple/swift · GitHub

ArgsToFrontendInputsConverter.h

ArgsToFrontendOptionsConverter.h

ArgsToFrontendOutputsConverter.h

DiagnosticVerifier.h

Frontend.h

CompilerInvocation

CompilerInstance

Invocation

CompilerInvocation Invocation;

SourceMgr

SourceManager SourceMgr;

Diagnostics

DiagnosticEngine Diagnostics{SourceMgr};

Context

std::unique_ptr<ASTContext> Context;

TheSILModule

std::unique_ptr<SILModule> TheSILModule;

DepTracker

DependencyTracker *DepTracker = nullptr;

NameTracker

ReferencedNameTracker *NameTracker = nullptr;

MainModule

ModuleDecl *MainModule = nullptr;

SML

SerializedModuleLoader *SML = nullptr;

InputSourceCodeBufferIDs

std::vector<unsigned> InputSourceCodeBufferIDs;

FrontendInputsAndOutputs.h

FrontendOptions.h

InputFile.h

PrintingDiagnosticConsumer.h

SerializedDiagnosticConsumer.h

lib/Frontend コードリーディング(全体)

概要

swift/lib/Frontend at master · apple/swift · GitHub

ArgsToFrontendInputsConverter.cpp

ArgsToFrontendOptionsConverter.cpp

ArgsToFrontendOutputsConverter.cpp

CompilerInvocation.cpp

DiagnosticVerifier.cpp

Frontend.cpp

CompilerInstance

performSema

void CompilerInstance::performSema()

メモ

  1. CompilerInstanceが保持しているASTContext型のContextのメンバ変数のLoadedModulesというmapにMainModuleを保持させる

  2. 入力モードを確認しSILモードがあればSILのモジュールを作成する

  3. Stdlibモードかを確認しStdlibモジュールを読み込む
  4. xxx shouldImplicityImportSwiftOnoneSupportModule?
  5. REPLかを確認しREPLであればREPL用のファイルを作成し終了
  6. if (MainBufferID != NO_SUCH_BUFFER) addMainFileToModule(implicitImports)
  7. parseAndCheckTypes

FrontendInputsAndOutputs.cpp

FrontendOptions.cpp

PrintingDiagnosticConsumer.cpp

SerializedDiagnosticConsumer.cpp

(discord/swift/2018/03/12/0) Swift IRGenがcoroutineをサポートした件について

概要

  • discord ios dev
    • #swift
    • 2018/03/12
  • Swift IRGenがcoroutineをサポートした

log

omochimetaru - 03/12 12:47

github.com

コルーチンの下回り進んでた


koher - 03/12 01:04

コルーチンって正式な Proposal になってないけど、表面的なシンタックスは別として何かしら導入する方向なのは既定路線ってことなのかな?


omochimetaru - 03/12 01:05

そう見えますね


koher - 03/12 01:06

それは楽しみだ。 Swift 5 は無理かなぁ?


omochimetaru - 03/12 01:07

5はしばらく来なくて4.Xを引っ張る気がする


koher - 03/12 01:08

年 1 回メジャーリリースする方針なわけではないのか。


omochimetaru - 03/12 01:09

リリースサイクル的な話はなかった気がするなあ

apple/swift - include/swift/AST コードリーディング(全体)

概要

swift/include/swift/AST at c309fb2620b030a722741171baee4dfec5017d58 · apple/swift · GitHub

AST.h

FIXME: おそらくアンブレラヘッダー

#ifndef SWIFT_AST_H
#define SWIFT_AST_H

#include "swift/AST/ASTContext.h"
#include "swift/AST/AvailabilitySpec.h"
#include "swift/AST/Builtins.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Module.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/Stmt.h"
#include "swift/AST/Types.h"
#include "swift/AST/TypeRepr.h"

#endif

ASTContext.h

AllocationArena

FIXME: C++のArena Allocationのことを指している?

C ++ Arena Allocation Guide

definition desc
Permanent ASTContextのライフタイムに縛られている永続的なArena
全てのグローバル宣言と型をこのArenaに割り当てる必要がある。
現時点では型変数を含まない型の全てがこのArenaに割り当てられる
ConstraintSolver xxx
型変数を含む型は全てこのArenaに割り当てれる

KnownFoundationEntity

KnownFoundationEntities.defを参照しマクロにより定義を展開

enum class KnownFoundationEntity {
#define FOUNDATION_ENTITY(Name) Name,
#include "swift/AST/KnownFoundationEntities.def"
};

ASTContext

ASTContext(LangOptions &langOpts, SearchPathOptions &SearchPathOpts,
             SourceManager &SourceMgr, DiagnosticEngine &Diags)

ASTMangler.h

ASTNode.h

ASTPrinter.h

ASTScope.h

ASTVisitor.h

ASTWalker.h

AccessScope.h

AnyFunctionRef.h

Attr.def

Swiftで使えるattributeの一覧がマクロを駆使して定義されている

必須マクロ定義

#ifndef DECL_ATTR
#define DECL_ATTR(SPELLING, CLASS, OPTIONS, CODE)
#endif

#ifndef SIMPLE_DECL_ATTR
#define SIMPLE_DECL_ATTR(X, CLASS, OPTIONS, CODE) DECL_ATTR(X, CLASS, OPTIONS, CODE)
#endif

#ifndef DECL_ATTR_ALIAS
#define DECL_ATTR_ALIAS(SPELLING, CLASS)
#endif

#ifndef TYPE_ATTR
#define TYPE_ATTR(X)
#endif

型attribute

attribute
autoclosure
convention
noreturn
noescape
escaping

SIL特有の型attribute

attribute
block_storage
box
dynamic_self
sil_unowned
sil_unmanaged
sil_weak
error
out
in
inout
inout_aliasable
in_guaranteed
in_constant
owned
unowned_inner_pointer
guaranteed
autoreleased
callee_owned
callee_guaranteed
objc_metatype
opened
pseudogeneric
yields
yield_once
yield_many

SILメタタイプの型attribute

attribute
thin
thick

DECL_ATTRスキーマ

  • DECL_ATTR
    • SPELLING
      • attribute名、この定義が実際にSwiftのコードで使える名前となる
    • CLASS
      • attributeに紐付くクラス名、クラス定義は{クラス名}Attrとなる
    • OPTIONS
      • attributeのオプション
        • attributeが表示される宣言
        • 重複が許されるかどうか
        • attributeがdecl修飾子かどうか (@なし)
    • CODE
      • シリアル化に使用される一意のattribute識別子
      • これは決して変更できない

Attr.h

AttrKind.h

Availability.h

AvailabilitySpec.h

Builtins.def

Builtins.h

CanTypeVisitor.h

CaptureInfo.h

ClangModuleLoader.h

ClangNode.h

Comment.h

ConcreteDeclRef.h

DebuggerClient.h

Decl.h

DeclContext.h

DeclNameLoc.h

DeclNodes.def

DefaultArgumentKind.h

DiagnosticEngine.h

DiagnosticsAll.def

DiagnosticsClangImporter.def

DiagnosticsClangImporter.h

DiagnosticsCommon.def

DiagnosticsCommon.h

DiagnosticsDriver.def

DiagnosticsDriver.h

DiagnosticsFrontend.def

DiagnosticsFrontend.h

DiagnosticsIRGen.def

DiagnosticsIRGen.h

DiagnosticsParse.def

DiagnosticsParse.h

DiagnosticsSIL.def

DiagnosticsSIL.h

DiagnosticsSema.def

DiagnosticsSema.h

Expr.h

ExprNodes.def

ForeignErrorConvention.h

FunctionRefKind.h

GenericEnvironment.h

GenericParamKey.h

GenericSignature.h

GenericSignatureBuilder.h

IRGenOptions.h

Identifier.h

Initializer.h

KnownDecls.def

KnownFoundationEntities.def

#ifndef FOUNDATION_ENTITY
#  error define FOUNDATION_ENTITY(Name)
#endif

FOUNDATION_ENTITY(NSArray)
FOUNDATION_ENTITY(NSCopying)
FOUNDATION_ENTITY(NSDictionary)
FOUNDATION_ENTITY(NSError)
FOUNDATION_ENTITY(NSErrorPointer)
FOUNDATION_ENTITY(NSInteger)
FOUNDATION_ENTITY(NSNumber)
FOUNDATION_ENTITY(NSObject)
FOUNDATION_ENTITY(NSRange)
FOUNDATION_ENTITY(NSSet)
FOUNDATION_ENTITY(NSString)
FOUNDATION_ENTITY(NSUInteger)
FOUNDATION_ENTITY(NSURL)
FOUNDATION_ENTITY(NSValue)
FOUNDATION_ENTITY(NSZone)

#undef FOUNDATION_ENTITY

KnownIdentifiers.def

#ifndef IDENTIFIER_WITH_NAME
#  error Must define IDENTIFIER_WITH_NAME(Name, IdStr) before including this x-macro file
#endif

#define IDENTIFIER(name) IDENTIFIER_WITH_NAME(name, #name)
#define IDENTIFIER_(name) IDENTIFIER_WITH_NAME(name, "_" #name)

IDENTIFIER(alloc)
IDENTIFIER(allocWithZone)
IDENTIFIER(allZeros)
IDENTIFIER(Any)
IDENTIFIER(atIndexedSubscript)
IDENTIFIER_(bridgeToObjectiveC)
IDENTIFIER_WITH_NAME(code_, "_code")
IDENTIFIER(CoreGraphics)
IDENTIFIER(CoreMedia)
IDENTIFIER(CGFloat)
IDENTIFIER(CVarArg)
IDENTIFIER(Darwin)
IDENTIFIER(dealloc)
IDENTIFIER(deinit)
IDENTIFIER(Element)
IDENTIFIER(error)
IDENTIFIER(forKeyedSubscript)
IDENTIFIER(Foundation)
IDENTIFIER(fromRaw)
IDENTIFIER(hashValue)
IDENTIFIER(init)
IDENTIFIER(initialize)
IDENTIFIER(initStorage)
IDENTIFIER(initialValue)
IDENTIFIER(Key)
IDENTIFIER(makeIterator)
IDENTIFIER(Iterator)
IDENTIFIER(load)
IDENTIFIER(next)
IDENTIFIER(none)
IDENTIFIER_(nsErrorDomain)
IDENTIFIER(objectAtIndexedSubscript)
IDENTIFIER(objectForKeyedSubscript)
IDENTIFIER(ObjectiveC)
IDENTIFIER_(ObjectiveCType)
IDENTIFIER_(OptionalNilComparisonType)
IDENTIFIER(parameter)
IDENTIFIER(Protocol)
IDENTIFIER(rawValue)
IDENTIFIER(RawValue)
IDENTIFIER(Selector)
IDENTIFIER(self)
IDENTIFIER(Self)
IDENTIFIER(setObject)
IDENTIFIER(simd)
IDENTIFIER(some)
IDENTIFIER(storage)
IDENTIFIER(subscript)
IDENTIFIER(SwiftObject)
IDENTIFIER(toRaw)
IDENTIFIER(Type)
IDENTIFIER(Value)
IDENTIFIER(value)
IDENTIFIER_WITH_NAME(value_, "_value")
IDENTIFIER(with)

// Kinds of layout constraints
IDENTIFIER_WITH_NAME(UnknownLayout, "_UnknownLayout")
IDENTIFIER_WITH_NAME(TrivialLayout, "_Trivial")
IDENTIFIER_WITH_NAME(TrivialAtMostLayout, "_TrivialAtMost")
IDENTIFIER_WITH_NAME(RefCountedObjectLayout, "_RefCountedObject")
IDENTIFIER_WITH_NAME(NativeRefCountedObjectLayout, "_NativeRefCountedObject")

// Operators
IDENTIFIER_WITH_NAME(MatchOperator, "~=")
IDENTIFIER_WITH_NAME(EqualsOperator, "==")

// Precedence groups
IDENTIFIER(AssignmentPrecedence)
IDENTIFIER(CastingPrecedence)
IDENTIFIER(DefaultPrecedence)
IDENTIFIER(FunctionArrowPrecedence)
IDENTIFIER(TernaryPrecedence)

// Builtins and literals
IDENTIFIER_(MaxBuiltinIntegerType)
IDENTIFIER(IntegerLiteralType)
IDENTIFIER(nilLiteral)
IDENTIFIER(integerLiteral)
IDENTIFIER_(builtinIntegerLiteral)
IDENTIFIER_(MaxBuiltinFloatType)
IDENTIFIER(FloatLiteralType)
IDENTIFIER(floatLiteral)
IDENTIFIER_(builtinFloatLiteral)
IDENTIFIER(BooleanLiteralType)
IDENTIFIER_(builtinBooleanLiteral)
IDENTIFIER(booleanLiteral)

IDENTIFIER(ExtendedGraphemeClusterLiteralType)
IDENTIFIER_(builtinExtendedGraphemeClusterLiteral)
IDENTIFIER(extendedGraphemeClusterLiteral)

IDENTIFIER(UnicodeScalarLiteralType)
IDENTIFIER_(builtinUnicodeScalarLiteral)
IDENTIFIER(unicodeScalarLiteral)

IDENTIFIER(stringLiteral)
IDENTIFIER_(builtinUTF16StringLiteral)
IDENTIFIER_(builtinStringLiteral)
IDENTIFIER(StringLiteralType)
IDENTIFIER(stringInterpolation)
IDENTIFIER(stringInterpolationSegment)
IDENTIFIER(arrayLiteral)
IDENTIFIER(dictionaryLiteral)
IDENTIFIER_(getBuiltinLogicValue)
IDENTIFIER(className)

IDENTIFIER_(ErrorType)
IDENTIFIER(Code)
IDENTIFIER_(nsError)

#undef IDENTIFIER
#undef IDENTIFIER_
#undef IDENTIFIER_WITH_NAME

KnownProtocols.def

KnownProtocols.h

KnownStdlibTypes.def

LayoutConstraint.h

LazyResolver.h

LinkLibrary.h

LookupKinds.h

Mangle.h

Module.h

ModuleLoader.h

NameLookup.h

Ownership.h

ParameterList.h

Pattern.h

PatternNodes.def

PlatformKind.h

PlatformKinds.def

PrettyStackTrace.h

PrintOptions.h

ProtocolConformance.h

ProtocolConformanceRef.h

RawComment.h

ReferencedNameTracker.h

Requirement.h

ResilienceExpansion.h

SILLayout.h

SILOptions.h

SearchPathOptions.h

SourceEntityWalker.h

Stmt.h

StmtNodes.def

Substitution.h

SubstitutionList.h

SubstitutionMap.h

Type.h

ForeignLanguage

definition desc
C C言語
ObjectiveC Objective-C

Swiftがブリッジされる可能性のある外部言語

ForeignRepresentableKind

definition desc
None このタイプは外部言語では表現できない
Trivial このタイプは外部言語で自明に表現可能である
Object このタイプは外部言語でオブジェクトとして表現できる
Bridged このタイプはbridgingを介して外部言語で表現することができる
BridgedError このタイプはエラーのbridgingを介して外部言語で表現できる
StaticBridged このタイプは静的なbridgingコードを介してのみ外部言語で表現できる(実行時には使用できない)

特定のタイプを外部言語でどのように表現できるかを説明する

Type

これは型クラスへのポインタを含む単純な値オブジェクト。

This is potentially sugared.

コードベース全体でこれを生のTypeBase代わりに使用して、同等性の比較を無効にする。

これは糖衣的な型では安全でない。

CanType

静的にカノニカルであることが知られているタイプ

これらのいずれかを取得するには、Type->getCanonicalType()を使用する

すべてのCanTypeは 'Type'として使用することができる(単に糖衣を含まない)

Typeから派生している

TypeAlignments.h

TypeCheckerDebugConsumer.h

TypeLoc.h

TypeMatcher.h

TypeMemberVisitor.h

TypeNodes.def

TypeRefinementContext.h

TypeRepr.h

TypeReprNodes.def

TypeVisitor.h

TypeWalker.h

Types.h

TypeKind

メモ:TypeNodes.defをマクロ展開してる

RecursiveTypeProperties::Property

単一のプロパティ

Note that the property polarities should be chosen so that 0 is the correct default value and bitwise-or correctly merges things.

  • プロパティの極性[?property polarities]
definition desc
HasTypeVariable TypeVariableTypeが含まれる
HasArchetype ArchetypeTypeが含まれる
HasTypeParameter GenericTypeParamTypeが含まれる
HasUnresolvedType UnresolvedTypeが含まれる
HasUnboundGeneric バインドされていない[?unbound]ジェネリクス型が含まれるかどうか
IsLValue This type expression contains an LValueType other than as a function input, and can be loaded to convert to an rvalue
HasOpenedExistential 開かれたexistentialなArchetypeTypeを含む
HasDynamicSelf DynamicSelf型が含まれる
HasError エラー型が含まれる
HasDependentMember DependentMemberTypeが含まれる

USRGeneration.h

Witness.h

include/swift/ClangImporter コードリーディング(全体)

概要

swift/include/swift/ClangImporter at 4b727e5813246d4029e7c4269bba317db9b012d3 · apple/swift · GitHub

BuiltinMappedTypes.def

ClangImporter.h

SWIFT_MAX_IMPORTED_SIMD_ELEMENTS

= 4

importしようとしているSIMDベクトル要素の最大数

ClangTypeKind

clang :: Sema :: LookupKindの簡略版定義

definition desc
Typedef
ObjCClass
Tag /// Structs, enums, and unions.
ObjCProtocol

ClangImporter

super class

ClangModuleLoader

friend class

ClangModuleUnit

create

ClangImporter.cpp - ClangImporter::create

 static std::unique_ptr<ClangImporter>
 create(ASTContext &ctx,
        const ClangImporterOptions &importerOpts,
        std::string swiftPCHHash = "",
        DependencyTracker *tracker = nullptr);

指定されたASTContextに適切なClangモジュールをimportできる新しいClangImporterを作成する

params

  • ctx
    • モジュールをimportする対象のASTContext
    • ASTContextのSearchPathOptionsはClangImporterに使用される
  • importerOpts
    • ClangImporterに使用するオプション
  • swiftPCHHash
    • hashはコンパイラの呼び出しによって要求された場合に一意のBridging PCHを作成するために使用される
  • tracker

returns

  • 新しいClangモジュールのimporterを返す
  • エラーが発生した場合はnull(診断あり)を返す

createDependencyCollector

ClangImporterDependencyCollector

ClangImporterの特定の用途に合わせてカスタマイズされた新しいclang::DependencyCollectorを作成する

static std::shared_ptr<clang::DependencyCollector>
createDependencyCollector();

canImportModule

指定した名前のモジュールをimportingしなくてもimportできるかどうか確認する

このチェックが成功したとしてもモジュールが一杯に読み込まれてた場合はエラーが発生する可能性があることに注意

virtual bool canImportModule(std::pair<Identifier, SourceLoc> named) override;

loadModule

指定したモジュールパスを持つモジュールをimportする

ClangモジュールはObjective-C ARCの方言を使用してimportされ、全ての警告は無効になる

virtual ModuleDecl *loadModule(
                      SourceLoc importLoc,
                      ArrayRef<std::pair<Identifier, SourceLoc>> path)
                    override;

lookupValue

与えられた名前に関する宣言を検索する

void lookupValue(DeclName name, VisibleDeclConsumer &consumer);

lookupTypeDecl

型宣言をClangの名前で検索する

void lookupTypeDecl(StringRef clangName, ClangTypeKind kind,
                    llvm::function_ref<void(TypeDecl*)> receiver);

lookupRelatedEntity

related entity kindを使用してClangImporter自体によって合成された宣言を検索し、どの型にするかを決定する

例えば、NS_ERROR_ENUMの合成エラー構造体を見つけるのに使用できる

void lookupRelatedEntity(StringRef clangName, ClangTypeKind kind,
                         StringRef relatedEntityKind,
                         llvm::function_ref<void(TypeDecl*)> receiver);

lookupBridgingHeaderDecls

BridgingHeaderからのテキスト付きの宣言を検索する

void lookupBridgingHeaderDecls(llvm::function_ref<bool(ClangNode)> filter,
                              llvm::function_ref<void(Decl*)> receiver) const;

lookupDeclsFromHeader

特定のヘッダーからの宣言を検索する

ヘッダーはClangモジュールの一部であってもよいし、BridgingHeaderから含まれても良い

bool lookupDeclsFromHeader(StringRef filename,
                           llvm::function_ref<bool(ClangNode)> filter,
                           llvm::function_ref<void(Decl*)> receiver) const;

loadExtensions

与えられたnominal typeにextensionをロードする

void loadExtensions(NominalTypeDecl *nominal, unsigned previousGeneration);

loadObjCMethods

  • classDecl
  • selector
  • isInstanceMethod
  • previousGeneration
  • methods
virtual void loadObjCMethods(
               ClassDecl *classDecl,
               ObjCSelector selector,
               bool isInstanceMethod,
               unsigned previousGeneration,
               llvm::TinyPtrVector<AbstractFunctionDecl *> &methods) override;

addSearchPath

存在してない場合に限り、SearchPathOptsに検索パスを追加する

全てのModuleLoaderを最新の状態に保つための適切な記録を行う

void addSearchPath(StringRef searchPath, bool isFramework, bool isSystem);

importHeader

Objective-Cヘッダーファイルを共有importされたヘッダーのモジュールにimportする

bool importHeader(StringRef header, ModuleDecl *adapter, off_t expectedSize,
                  time_t expectedModTime, StringRef cachedContents,
                  SourceLoc diagLoc);

importBridgingHeader

Objective-Cヘッダーファイルを共有importされたヘッダーのモジュールにimportする

bool importBridgingHeader(StringRef header, ModuleDecl *adapter,
                          SourceLoc diagLoc = {},
                          bool trackParsedSymbols = false,
                          bool implicitImport = false);

getImportedHeaderModule

読み込まれた全てのObjective-Cヘッダーファイルからのimportと宣言を含むモジュールを返す

ModuleDecl *getImportedHeaderModule() const override;

getBridgingHeaderContents

emitBridgingPCH

ClangImporterのCompileInstanceの一時的なレプリカを作成し、Objective-Cヘッダーファイルをレプリカに読み込み、その内容のPCHファイルを出力する。

bool emitBridgingPCH(StringRef headerPath,
                     StringRef outputPCHPath);

canReadPCH

現在のオプションが存在すると仮定して、CompilerInstanceがPCHで正常に読み込める場合はtrueを返す

これはあとで再利用するためにPCHを保持する必要があるかどうかを調べるために使用できる

bool canReadPCH(StringRef PCHFilename);

ClangImporterOptions.h

ClangImporterOptions

ModuleCachePath

ClangImporterが使用するモジュールのキャッシュパス

std::string ModuleCachePath;

ExtraArgs

ClangImporterに渡すべき余分な引数群

std::vector<std::string> ExtraArgs;

OverrideResourceDir

Clangのリソースディレクトリを上書きするためのディレクト

std::string OverrideResourceDir;

TargetCPU

コンパイル対象のCPU

Clangの -mcpu と同等

例えば、-mcpu=cortex-a53、-mcpu=cortex-a57、-mcpu=cortex-a15

std::string IndexStorePath;

IndexStorePath

indexを格納する必要がある場合のパス

std::string IndexStorePath;

BridgingHeader

importされるbridging header、またはPCH

std::string BridgingHeader;

PrecompiledHeaderOutputDir

bridging headerからプリコンパイル済みのヘッダーを自動生成する場合の指定ディレクト

std::string PrecompiledHeaderOutputDir;

Optimization

最適化の設定、通常のimportに関して問題はないがClang IRの生成に影響を与える

std::string Optimization;

PCHDisableValidation

永続的なPCHの検証を無効にする

std::string Optimization;

Modes

definition desc
Normal モジュールをSwiftにimportし、SwiftのコードからIRを生成するためのClangを設定
EmbedBitcode バックエンドのコンパイル用にのみClangを設定

Mode

Clangの初期設定モード、Normalを指定

Modes Mode = Modes::Normal;

DetailedPreprocessingRecord

設定すると、インポート時に多くの情報が保持される

また、オブジェクトファイルの生成にのみ必要な情報は無効にする

bool DetailedPreprocessingRecord = false;

DumpClangDiagnostics

trueの場合、Clangの診断用プリンタを用いてstderrにダンプされSwiftの診断エンジンに渡される

bool DumpClangDiagnostics = false;

ImportForwardDeclarations

trueの場合、前方宣言は可能であれば完全に削除される代わりに使用できない型をimportする

bool ImportForwardDeclarations = false;

InferImportAsMember

メンバの推論システムとしてimportするかどうか

When importing a global, try to infer whether we can import it as a member of some type instead. This includes inits, computed properties, and methods.

bool InferImportAsMember = false;

DisableSwiftBridgeAttr

/// If true ignore the swift bridged attribute.

bool DisableSwiftBridgeAttr = false;

/// When set, don't validate module system headers. If a header is modified /// and this is not set, clang will rebuild the module. bool DisableModulesValidateSystemHeaders = false;

/// When set, don't look for or load adapter modules. bool DisableAdapterModules = false;

/// When set, don't enforce warnings with -Werror. bool DebuggerSupport = false;

ClangModule.h

SIMDMappedTypes.def