« ack の MacPorts が公式から p5-app-ack として提供されている | トップページ | RubyKaigi のチケットを入手し損ねたわけだが »

2008.06.05

clang という LLVM フロントエンド

objc-lang ML に流れてた etoile の Compiler Fun 経由で LLVM の新しいコンパイラインターフェイス clang ていうものあることを知る。日本語の情報だと、マイコミの「GCCに匹敵するコンパイラ?! LLVM - BSDCan2008」が最近のBSDCan2008での発表を中心に紹介していてよさげ。

個人的に興味あるのは、Objective-C のサポートと IDE との協調のためにいろいろ用意している(これから?)らしいこと。Objective-C はマイナー言語であるために、Apple が提供する Xcode 以外の開発ツールではサポートがビミョウなことが多い。せめて ctags くらいは使えてほしいもの。まだドキュメント読んでいるところだけど、なんとかなりそうな感じ。

また、便利かはわからないけれど、おもしろい機能があったので紹介。clang には rewrite という機能があって、コードを操作することができる。そのサンプルとして、Objective-C のコードを C にするという -rewrite-objc というオプションがある。

たとえば

 #import "ECTAppController.h"
 #import "ECTValueTransformers.h"
 
 // 省略
 
 @implementation ECTAppController
 
 + (void)initialize
 {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   [self setupDefaults];
   [self registerTransformers];
   [pool release];
 }
 
 - (void)applicationDidFinishLaunching:(id)sender
 {
   NSNotificationCenter * center;
   center = [NSNotificationCenter defaultCenter];
   [center addObserver:self selector:@selector(syncDefaults:)
     name:NSUserDefaultsDidChangeNotification object:nil];
 }
 
 // save defaults in .plist immediately
 - (void)syncDefaults:(id)sender
 {
   [[NSUserDefaults standardUserDefaults] synchronize];
 }
 
 @end

 struct objc_selector; struct objc_class;
 #ifndef OBJC_SUPER
 // 省略
 #endif
 static __NSConstantStringImpl __NSConstantStringImpl_ECTAppController_m_0 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"CFBundleName",12};
 static __NSConstantStringImpl __NSConstantStringImpl_ECTAppController_m_1 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"CFBundleExecutable",18};
 
 #include "ECTAppController.h"
 #include "ECTValueTransformers.h"
 
 // 省略
 
 // @implementation ECTAppController
 
 
 static void _C_ECTAppController_initialize(id self, SEL _cmd) {
   NSAutoreleasePool * pool = ((id (*)(id, SEL))(void *)objc_msgSend)((id)((id (*)(id, SEL))(void *)objc_msgSend)(objc_getClass("NSAutoreleasePool"), sel_registerName("alloc")), sel_registerName("init"));
   ((void (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("setupDefaults"));
   ((void (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("registerTransformers"));
   ((void (*)(id, SEL))(void *)objc_msgSend)((id)pool, sel_registerName("release"));
 }
 
 
 static void _I_ECTAppController_applicationDidFinishLaunching_(struct ECTAppController * self, SEL _cmd, id sender) {
   NSNotificationCenter * center;
   center = ((id (*)(id, SEL))(void *)objc_msgSend)(objc_getClass("NSNotificationCenter"), sel_registerName("defaultCenter"));
   ((void (*)(id, SEL, id, SEL, NSString *, id))(void *)objc_msgSend)((id)center, sel_registerName("addObserver:selector:name:object:"), (id)self, sel_registerName("syncDefaults:"), (NSString *)NSUserDefaultsDidChangeNotification, (id)((void *)0));
 }
 
 // save defaults in .plist immediately
 
 static void _I_ECTAppController_syncDefaults_(struct ECTAppController * self, SEL _cmd, id sender) {
   ((BOOL (*)(id, SEL))(void *)objc_msgSend)((id)((NSUserDefaults *(*)(id, SEL))(void *)objc_msgSend)(objc_getClass("NSUserDefaults"), sel_registerName("standardUserDefaults")), sel_registerName("synchronize"));
 }
 
 // @end
 
 // 省略

という、C のコードに変換されて出力される(拡張子はなぜか .cpp)。NSAssert() や NS_DURING などのマクロがあるとうまく動作しないもよう。

|

« ack の MacPorts が公式から p5-app-ack として提供されている | トップページ | RubyKaigi のチケットを入手し損ねたわけだが »