18
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

clangでASTをdumpする

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参照。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
18
Help us understand the problem. What are the problem?