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 などのマクロがあるとうまく動作しないもよう。
| 固定リンク
最近のコメント