Objective-CのAST(抽象構文木)をdumpするやり方を調べたのでメモ。
以前はxml形式、バイナリ形式で出力ができたらしいが、LLVM version 3.4ではできなかった。
詳細はclang -cc1 --help
を参照。
例として以下のクラスのASTを取得する。
Objective-C
#import <Foundation/Foundation.h>
@interface Spam : NSObject
@property(retain) NSString *ham;
- (instancetype)initWithHam:(NSString *)ham;
@end
Objective-C
#import "Spam.h"
@implementation Spam
- (instancetype)initWithHam:(NSString *)ham{
if (self = [super init]) {
_ham = ham;
}
return self;
}
@end
dumpするコマンド
##シンボル一覧を取得
$ clang -cc1 -ast-list -fblocks -x objective-c Spam.h
###出力結果
__int128_t
__uint128_t
SEL
id
...(省略)...
NSXPCListenerEndpoint::_internal
Spam
Spam::ham
Spam::initWithHam:
ham
##ASTをdump
$ clang -cc1 -ast-dump -fblocks -x objective-c Spam.h
###出力結果
TranslationUnitDecl 0x1028218d0 <<invalid sloc>>
|-TypedefDecl 0x102821dd0 <<invalid sloc>> __int128_t '__int128'
|-TypedefDecl 0x102821e30 <<invalid sloc>> __uint128_t 'unsigned __int128'
|-TypedefDecl 0x102821ec0 <<invalid sloc>> SEL 'SEL *'
|-TypedefDecl 0x102821f90 <<invalid sloc>> id 'id'
|-TypedefDecl 0x102822060 <<invalid sloc>> Class 'Class *'
...(省略)...
| `-ParmVarDecl 0x1053064c0 <col:30> protocol 'Protocol *'
|-ObjCInterfaceDecl 0x105306560 prev 0x105301ad0 <line:194:1, line:198:2> NSXPCListenerEndpoint
| |-super ObjCInterface 0x103181710 'NSObject'
| |-ObjCProtocol 0x1031b2f00 'NSSecureCoding'
| |-AvailabilityAttr 0x1053065d0 </System/Library/Frameworks/CoreFoundation.framework/Headers/CFAvailability.h:95:49, col:81> macosx 10.8 0 0 ""
| |-VisibilityAttr 0x105306660 </System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:259:55, col:75> Default
| `-ObjCIvarDecl 0x105306700 </System/Library/Frameworks/Foundation.framework/Headers/NSXPCConnection.h:196:5, col:11> _internal 'void *' private
`-ObjCInterfaceDecl 0x105306760 <Spam.h:3:1, line:7:2> Spam
|-super ObjCInterface 0x103181710 'NSObject'
|-ObjCPropertyDecl 0x105306870 <line:4:1, col:29> ham 'NSString *' readwrite retain atomic
|-ObjCMethodDecl 0x105306900 <line:6:1, col:44> - initWithHam: 'instancetype':'id'
| `-ParmVarDecl 0x105306990 <col:30, col:41> ham 'NSString *'
|-ObjCMethodDecl 0x1053069f0 <line:4:29> - ham 'NSString *'
`-ObjCMethodDecl 0x105306a80 <col:29> - setHam: 'void'
`-ParmVarDecl 0x105306b10 <col:29> ham 'NSString *'
##ASTをpretty-print
$ clang -cc1 -ast-print -fblocks -x objective-c Spam.h
###出力結果
typedef SEL *SEL;
typedef id id;
typedef Class *Class;
...(省略)...
@interface NSXPCListenerEndpoint : NSObject<NSSecureCoding> {
void * _internal;
}
@end
@interface Spam : NSObject
@property ( readwrite,retain,atomic ) NSString * ham;
- (instancetype) initWithHam:(NSString *)ham;
@end
##特定のシンボルに関連する部分のみ取得
-ast-list
で取得したシンボル名を指定して、そのシンボルに関連する部分のみdumpする。
$ clang -cc1 -ast-dump -fblocks -x objective-c Spam.h -ast-dump-filter Spam
###出力結果
Dumping Spam:
ObjCInterfaceDecl 0x105506760 <Spam.h:3:1, line:7:2> Spam
|-super ObjCInterface 0x102a13110 'NSObject'
|-ObjCPropertyDecl 0x105506870 <line:4:1, col:29> ham 'NSString *' readwrite retain atomic
|-ObjCMethodDecl 0x105506900 <line:6:1, col:44> - initWithHam: 'instancetype':'id'
| `-ParmVarDecl 0x105506990 <col:30, col:41> ham 'NSString *'
|-ObjCMethodDecl 0x1055069f0 <line:4:29> - ham 'NSString *'
`-ObjCMethodDecl 0x105506a80 <col:29> - setHam: 'void'
`-ParmVarDecl 0x105506b10 <col:29> ham 'NSString *'
-ast-dump-filter
は-ast-print
に対しても利用可能。
dump関連のオプションはまだある。詳細はhelp参照。