Open6
nccc: Clangの -dump-ast=json から各種定義を抽出したい

というわけで各種オブジェクトを抽出していく。(JSONだと読みづらいので以下YAMLに一旦変換している)
ASTからはマクロは抽出できないため、残った
- C関数
- C型(typedef)
- struct
- union
- enum
がターゲットになる。
prev

基本構造
全てのASTノードは id
kind
を持つ。root の kind
は TranslationUnitDecl
となり、その中の inner
配列が個々の宣言となる。
定義には loc
オブジェクトが付き、これを使って定義位置を取得できる。
例えば、定義されている関数名を列挙したければ、 FunctionDecl
をkindとして持つノードの name
を列挙することになる。
- id: '0x21e7f6efe58'
kind: FunctionDecl
loc:
offset: 6937
file: e:/repos/em2native-tests/_build/Android@armeabi-v7a/_yfrm_headers/SDL2\SDL_platform.h
line: 265
col: 38
tokLen: 15
includedFrom:
file: e:/repos/em2native-tests/_build/Android@armeabi-v7a/_yfrm_headers/SDL2\SDL_config.h
range:
begin:
offset: 6900
col: 1
tokLen: 6
includedFrom:
file: e:/repos/em2native-tests/_build/Android@armeabi-v7a/_yfrm_headers/SDL2\SDL_config.h
end:
offset: 6958
col: 59
tokLen: 1
includedFrom:
file: e:/repos/em2native-tests/_build/Android@armeabi-v7a/_yfrm_headers/SDL2\SDL_config.h
name: SDL_GetPlatform
mangledName: SDL_GetPlatform
type:
qualType: const char *(void)
storageClass: extern
inner: (略)

関数
まず簡単なケースということで関数の抽出をする。関数を表現するASTノードは
kind: FunctionDecl
kind: FunctionProtoType
の2つとなる。 FunctionDecl
が通常の意味の関数定義で、 FunctionProtoType
は関数型の表現に使われる。
- id: '0x21e7facc180'
kind: FunctionDecl
name: SDL_WasInit
mangledName: SDL_WasInit
type:
qualType: Uint32 (Uint32)
storageClass: extern
inner:
- id: '0x21e7facc0a8'
kind: ParmVarDecl
name: flags
type:
desugaredQualType: unsigned int
qualType: Uint32
typeAliasDeclId: '0x21e7f95c5d0'
- id: '0x21e7facc230'
kind: VisibilityAttr
visibility: default
関数の型と引数
関数の型は qualType
フィールドに 文字列で 保持される。これは別途パースしないといけない。ただし基本的には 戻り型 (引数型, 引数型, ...)
となっているが引数の型は ParamVarDecl
に含まれるのでパースする必要はない。
- id: '0x21e7f8a45d0'
kind: FunctionDecl
name: qsort
mangledName: qsort
type:
qualType: void (void *, size_t, size_t, __compar_fn_t)
inner:
- id: '0x21e7f8a42f8'
kind: ParmVarDecl
name: __base
type:
qualType: void *
- id: '0x21e7f8a4378'
kind: ParmVarDecl
name: __nmemb
type:
desugaredQualType: unsigned long
qualType: size_t
typeAliasDeclId: '0x21e7f7f5320'
- id: '0x21e7f8a43f8'
kind: ParmVarDecl
name: __size
type:
desugaredQualType: unsigned long
qualType: size_t
typeAliasDeclId: '0x21e7f7f5320'
- id: '0x21e7f8a4478'
kind: ParmVarDecl
name: _compar
type:
desugaredQualType: int (*)(const void *, const void *)
qualType: __compar_fn_t
typeAliasDeclId: '0x21e7f87cc18'
ここで型 __compar_fn_t
は
- id: '0x21e7f87cc18'
kind: TypedefDecl
isReferenced: true
name: __compar_fn_t
type:
qualType: int (*)(const void *, const void *)
inner:
- id: '0x21e7f87cba0'
kind: PointerType
type:
qualType: int (*)(const void *, const void *)
inner:
- id: '0x21e7f87cb40'
kind: ParenType
type:
qualType: int (const void *, const void *)
inner:
- id: '0x21e7f87cb00'
kind: FunctionProtoType
type:
qualType: int (const void *, const void *)
cc: cdecl
inner:
- id: '0x21e7f6ef040'
kind: BuiltinType
type:
qualType: int
- id: '0x21e7f878140'
kind: PointerType
type:
qualType: const void *
inner:
- id: '0x21e7f6eefa1'
kind: QualType
type:
qualType: const void
qualifiers: const
inner:
- id: '0x21e7f6eefa0'
kind: BuiltinType
type:
qualType: void
- id: '0x21e7f878140'
kind: PointerType
type:
qualType: const void *
inner:
- id: '0x21e7f6eefa1'
kind: QualType
type:
qualType: const void
qualifiers: const
inner:
- id: '0x21e7f6eefa0'
kind: BuiltinType
type:
qualType: void

struct / union
これらはRecordとして纏めて扱われる。
kind: RecordDecl
kind: RecordType
宣言は RecordDecl
ノードで行われ、そのinnerの FieldDecl
で個々のフィールドが宣言される。struct/unionの区別は tagUsed
フィールドで指定される。
- id: '0x21e7fa08900'
kind: RecordDecl
name: SDL_Color
tagUsed: struct
completeDefinition: true
inner:
- id: '0x21e7fa089b0'
kind: FieldDecl
name: r
type:
desugaredQualType: unsigned char
qualType: Uint8
typeAliasDeclId: '0x21e7f95c1d0'
- id: '0x21e7fa08a18'
kind: FieldDecl
name: g
type:
desugaredQualType: unsigned char
qualType: Uint8
typeAliasDeclId: '0x21e7f95c1d0'
- id: '0x21e7fa08a80'
kind: FieldDecl
name: b
type:
desugaredQualType: unsigned char
qualType: Uint8
typeAliasDeclId: '0x21e7f95c1d0'
- id: '0x21e7fa08ae8'
kind: FieldDecl
name: a
type:
desugaredQualType: unsigned char
qualType: Uint8
typeAliasDeclId: '0x21e7f95c1d0'

enum
enum
は2種のノードで構成される。
kind: EnumConstantDecl
kind: EnumDecl
... 定数定義が入っている場合は。。? クラスがある場合は。。?
- id: '0x21e7fac5850'
kind: EnumDecl
inner:
- id: '0x21e7fac5910'
kind: EnumConstantDecl
name: ShapeModeDefault
type:
qualType: int
- id: '0x21e7fac5990'
kind: EnumConstantDecl
name: ShapeModeBinarizeAlpha
type:
qualType: int
inner:
- id: '0x21e7fac5a10'
kind: EnumConstantDecl
name: ShapeModeReverseBinarizeAlpha
type:
qualType: int
- id: '0x21e7fac5a90'
kind: EnumConstantDecl
name: ShapeModeColorKey
type:
qualType: int

typedef
typedefは TypedefDecl
→ ElaboratedType
で表現される。
- id: '0x21e7fac5b58'
kind: TypedefDecl
isReferenced: true
name: WindowShapeMode
type:
desugaredQualType: WindowShapeMode
qualType: enum WindowShapeMode
inner:
- id: '0x21e7fac5af0'
kind: ElaboratedType
type:
qualType: enum WindowShapeMode
ownedTagDecl:
id: '0x21e7fac5850'
kind: EnumDecl
name: ''
inner:
- id: '0x21e7fac58f0'
kind: EnumType
type:
qualType: WindowShapeMode
decl:
id: '0x21e7fac5850'
kind: EnumDecl
name: ''