1. ClangãŸãã¯clang-cïŒ
clangéçºè ã顧客ã«2çš®é¡ã®APIãæäŸãããšããäºå®ããå§ããå¿ èŠããããŸãã 1ã€ç®ã¯å®å šã«ãããžãã£ããã§ããã...æœåšçã«äžå®å®ã§ãïŒããŒãžã§ã³ã«ãã£ãŠç°ãªãå¯èœæ§ããããšããæå³ã§ïŒã 2çªç®ã¯å®å®ããŠããããšãä¿èšŒãããŠããŸããã...çŽç²ã«ãsyishnoeãã§ãã ç¶æ³ã«å¿ããŠããŸãã¯clangã«åºã¥ããŠéçºããã補åã®ããŒãºã«åºã¥ããŠãã©ã¡ããåªå ããããéžæããå¿ èŠããããŸãã
1.1 clang-c API
clangãœãŒã¹ããªãŒã§ã¯ããã®ã©ã€ãã©ãªã®å®è£ ã¯toolsãã©ã³ãã«ãããŸãïŒclangã³ã¢ã®å®è£ èªäœã¯libã«ãããŸãïŒã ãã®ã©ã€ãã©ãªã¯ãåçã«ããŒããããã¢ãžã¥ãŒã«ã«ã³ã³ãã€ã«ããããã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯ã¯ã©ã€ã¢ã³ãã«å€ãã®ä¿èšŒãæäŸããŸãã
- å®å®æ§ãšäžäœäºææ§ã ã¯ã©ã€ã¢ã³ãã¯ãäœããèœã¡ãããããã«æªãããšã«åéãåæ¢ããããšãæããããšãªããç¬èªã®ã³ãŒãã®ããã«ãclangã®ããããŒãžã§ã³ããå¥ã®ããŒãžã§ã³ã«å®å šã«åãæ¿ããããšãã§ããŸãã
- å®è¡æã«ã䜿çšãããclangå®è£ ã®æ©èœã決å®ãããããã«é©å¿ããå¯èœæ§ããããŸãã
- é«ããã©ãŒã«ããã¬ã©ã³ã¹-clangã«ãŒãã«ã®èŽåœçãªãšã©ãŒã¯ãã¯ã©ã€ã¢ã³ãã¯ã©ãã·ã¥ã«ã€ãªãããŸããã
- éãã¢ã¯ãã£ããã£ïŒè§£æãªã©ïŒã®ç¬èªã®ãããŒå¶åŸ¡ã
- ã³ã³ãã€ã©ãšAPIã®ãã¹ãŠã®æ©èœã¯ãåçã«ããŒãããã1ã€ã®ã©ã€ãã©ãªã®åœ¢åŒã§ã¢ã»ã³ãã«ããããããããã³ããšã³ãèªäœãã³ã³ãã€ã«ããå¿ èŠã¯ãããŸããã
ãã ããèšèŒãããŠããç¹å žãå©çšããã«ã¯æ¯æããå¿ èŠã§ãã ãããã£ãŠãclang-c APIã«ã¯æ¬¡ã®äžé£ã®æ¬ ç¹ããããŸãã
- ãããã«å ¥ãã®è¹ããã¿ãŒã³ã«åŸã£ãŠèšèšããŸãã ãã®APIã®ã¯ã©ã€ã¢ã³ãã察話ãããšã³ãã£ãã£ã¯ãæ¬è³ªçã«clang APIã«ãã£ãŠæäŸãããå ã®ã¯ã©ã¹ã®ã©ãããŒã§ãã
- ïŒçµæãšããŠïŒæåã®ãªãœãŒã¹ç®¡çã C ++ã³ãŒããã䟿å©ã«äœ¿çšããã«ã¯ãRAIIãæäŸããã©ãããŒãäœæããå¿ èŠããããŸãã
- éåžžã«ãçããã€ã³ã¿ãŒãã§ãŒã¹ã ã¯ã©ã€ã¢ã³ãã«ã¯ãã«ãŒãã«ãšå¯Ÿè©±ããããã®Cã¡ãœãããšã¿ã€ãã®å°ããªã»ãããæäŸãããŸãã
- ïŒçµæãšããŠïŒæ©èœã®ããªã貧匱ãªã»ããã clang APIã«ãã£ãŠæäŸãããããŒã«ã®å€ãã¯ãã¯ã©ã€ã¢ã³ããåã«å©çšã§ããªãããç°¡ç¥åããã圢åŒã§æäŸãããŸãã
æ¢åã®ããã©ã¹ãã®ã»ãããã¯ã©ã€ã¢ã³ãã³ãŒãã«äžå¯æ¬ ãªå Žåã«ããã®APIãªãã·ã§ã³ã䜿çšããããšã¯çã«ããªã£ãŠããŸãã ãŸãããŸãã¯ãçæãã¯ããã»ã©åºæ¬çã§ã¯ãããŸããã ãã®APIã¯ããœãŒã¹ããã¹ãïŒASTã®åœ¢åŒãšãœãŒã¹ããã¹ãå ã®åç¹å®ã®ããŒã¯ã³ã®ã»ãã³ãã£ãã¯ããŒãã®åœ¢åŒã®äž¡æ¹ïŒããã»ãã³ãã£ãã¯æ å ±ãæœåºããã®ã«éåžžã«é©ããŠããŸããã¿ã¹ã¯ã ãããã£ãŠãããŸããŸãªçš®é¡ã®ã¹ã¿ã³ãã¢ãã³ã®ãã©ã³ã¹ã¬ãŒã¿ãã¡ã¿æ å ±ãžã§ãã¬ãŒã¿ãéçã¢ãã©ã€ã¶ãã³ãŒãæ€èšŒãªã©ã«é©ããŠããŸãã
ãŸãããã®APIã¯ãããé«ãããã©ãŒãã³ã¹ãå¿ èŠãªã¿ã¹ã¯ããŸãã¯ã³ã³ãã€ã©ã³ã¢ãšã®ããç·å¯ãªçžäºäœçšã«ããŸãé©ããŠããŸããã
1.2 clang API
ãã®ããŒãžã§ã³ã®APIã¯ãæ¬è³ªçã«ã³ã³ãã€ã©ã³ã¢èªäœã®ã€ã³ã¿ãŒãã§ã€ã¹ã§ãã ãã®APIã¯çŽç²ã«C ++ã§ãããclangã«ãŒãã«ã®ãã¹ãŠã®æ©èœãžã®å¹ åºãã¢ã¯ã»ã¹ãæäŸããŸãã ãã®å©ç¹ã¯æ¬¡ã®ãšããã§ãã
- æ¢ã«è¿°ã¹ãããã«ãã³ã³ãã€ã©ã®ãã¹ãŠã®æ©èœãžã®çŽæ¥ãã€äŸ¿å©ãªã¢ã¯ã»ã¹ã
- 䟿å©ãªïŒå°ãªããšãclang-cãšæ¯èŒããŠïŒã€ã³ã¿ãŒãã§ãŒã¹ã
- å€æ°ã®ããŸããŸãªã«ã¹ã¿ãã€ãºã
- ãããã«é«ãããã©ãŒãã³ã¹ïŒclang-cãšæ¯èŒïŒã
ãããŠããã®çµæã®äžéšãšããŠããã¡ãªããïŒ
- ã«ãŒãã«å éšã§çºçããå¯èœæ§ã®ããã¯ã©ãã·ã¥ã«ããã¯ã©ã€ã¢ã³ãã®äžå®ã
- ã€ã³ã¿ãŒãã§ã€ã¹ã®äžäœäºææ§ãä¿èšŒãããŠããŸããã
- éçã©ã€ãã©ãªã®åœ¢åŒã§é ä¿¡ã ã¯ã©ã€ã¢ã³ãã¯ã«ãŒãã«ã«çŽæ¥ãªã³ã¯ããããã«åŒ·å¶ããããã®çµæãæ§æã®ããã«clangãšllvmãåéããŸãã
- ãåé·æ§ãã ïŒclang-c APIãšæ¯èŒããŠïŒå€ãã®ãœãŒã¹ã³ãŒãã·ããªãªã§ãããå€ããååŸãããŸãã
- ãã¹ãŠãææžåãããŠããããã§ã¯ãããŸããã
- llvm APIãšã®é«åºŠãªæ¥ç¶æ§ã llvmããªããšãclangã䜿çšã§ããŸããã ææ ¢ããå¿ èŠããããŸãã
æ¬ ç¹ãã©ãã»ã©éèŠã§ãããããããå©ç¹ãäžåããã©ãã-ç¶æ³ã決å®ããå¿ èŠããããŸãã ç§ã®æèŠã§ã¯ãclangã䜿çšãããã®ãªãã·ã§ã³ã¯ã©ãã§ãéžæããå¿ èŠããããè¯å¥œãªããã©ãŒãã³ã¹ãŸãã¯clang-cã§å©çšã§ããªãç¹å®ã®æ©èœãžã®ã¢ã¯ã»ã¹ãå¿ èŠã§ãã ç¹ã«ãIDEã®ãªã³ã¶ãã©ã€ããŒãµãŒãšããŠclangã䜿çšããå Žåããã®ç¹å®ã®APIããªã¢ã³ãã䜿çšããããšã¯çã«ããªã£ãŠããŸãã
2.ã¯ããã«ããŸãã¯ãœãŒã¹ããã¹ãã®è§£æ
ãããŠããªãããã®clangãå¿ èŠãªã®ã§ããããïŒ å®éãéçºè ãé¢å¿ã®ããæ å ±ããœãŒã¹ã³ãŒãããæœåºãããããã€ãã³ãŒãã«å€æãããããããã«ãœãŒã¹ã³ãŒãã解æããããšã¯ãclangããã³ããšã³ãã®äž»ãªã¿ã¹ã¯ã§ãã ãã®åé¡ã解決ããããã«ãclangã¯è±å¯ãªæ©äŒãæäŸããŸãã ããããããŸãã«ãè±ãã§ãã ç§ãæåã«clangã®äŸã®1ã€ãéãããšããç§ã¯å°ãé©ããããšãèªããªããã°ãªããŸãã-ããã§è¡ãããæäœã¯ããã®éåžžã«æ§æ解æãã©ã®ããã«èŠããã¹ããã«ã€ããŠã®çŽæçãªã¢ã€ãã¢ãšäžèŽããªãã£ããããé»éè¡ã®é åããç§ã«ã¯æããŸããã æçµçã«ããã¹ãŠãéåžžã«è«ççã§ããããšãå€æããŸããããã³ãã³ãã©ã€ã³åŒæ°ãèšè¿°ããæååã®é åãæž¡ãããšã«ãã£ãŠè§£æãªãã·ã§ã³ãèšå®ããããšã¯ããŸã ç§ã«ãšã£ãŠãããã£ããã§ãã
2.1 clang-cã䜿çšãã解æ
ç§ã®clangã®ç¥èãããã®APIã«åºã¥ããŠæ§ç¯ãããäŸããå§ãŸãå Žåãããã»ã©é©ãã¯ãããŸããã å®éããã¡ã€ã«ã®è§£æã¯2ã€ã®åŒã³åºãã§è¡ãããŸãã æåã¯CXIndexãªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãäœæãã2çªç®ã¯ãœãŒã¹ããã¹ãã®å®éã®åæãšASTã®æ§ç¯ãéå§ããŸãã ãœãŒã¹ã³ãŒãã§ã¯æ¬¡ã®ããã«ãªããŸãã
#include <iostream> #include <clang-c/Index.h> int main (int argc, char** argv) { CXIndex index = clang_createIndex ( false, // excludeDeclarationFromPCH true // displayDiagnostics ); CXTranslationUnit unit = clang_parseTranslationUnit ( index, // CIdx "main.cpp", // source_filename argv + 1 , // command_line_args argc - 1 , // num_command_line_args 0, // unsave_files 0, // num_unsaved_files CXTranslationUnit_None // options ); if (unit != 0 ) std::cout << "Translation unit successfully created" << std::endl; else std::cout << "Translation unit was not created" << std::endl; clang_disposeTranslationUnit(unit); clang_disposeIndex(index); }
æåã®ã¡ãœããïŒ clang_createIndex ïŒã¯ã翻蚳åäœïŒ CXTranslationUnit ïŒã®ã€ã³ã¹ã¿ã³ã¹ãäœæããã³è§£æãããã³ã³ããã¹ããäœæããŸãã 2ã€ã®ãã©ã¡ãŒã¿ãŒãå¿ èŠã§ãã æåã®ïŒ excludeDeclarationsFromPCH ïŒã¯ãçµæã®ASTã®ã¯ããŒã«äžã«ããªã³ã³ãã€ã«æžã¿ããããŒããèªã¿åãããåºåã®å¯èŠæ§ãå¶åŸ¡ããŸãã å€ã1ã®å Žåããã®ãããªåºåã¯æçµASTããé€å€ãããŸãã 2çªç®ã®ãã©ã¡ãŒã¿ãŒïŒ displayDiagnostics ïŒã¯ãã³ã³ãœãŒã«ãžã®ãããŒããã£ã¹ãäžã«åä¿¡ãã蚺æã®åºåãå¶åŸ¡ããŸãã
2çªç®ã®ã¡ãœããïŒ clang_parseTranslationUnit ïŒã¯ããœãŒã¹ãã¡ã€ã«èªäœã解æããŸãã ãã®ã¡ãœããã«ã¯ã次ã®ãã©ã¡ãŒã¿ãŒããããŸãã
- CIdxã¯ã clang_createIndexãåŒã³åºããŠäœæãããã³ã³ããã¹ããžã®ãã€ã³ã¿ãŒã§ãã
- source_filename-解æãããã¡ã€ã«ãžã®ãã¹ã
- command_line_args-ã³ã³ãã€ã©ãªãã·ã§ã³ã«å€æãããã³ãã³ãã©ã€ã³åŒæ°ã
- num_command_line_args-åã®ãã©ã¡ãŒã¿ãŒãšããŠæž¡ãããã³ãã³ãã©ã€ã³ã®åŒæ°ã®æ°ã
- unsaved_files-å®éã®å 容ããã£ã¹ã¯ã§ã¯ãªãã¡ã¢ãªã«ãããã¡ã€ã«ã®ã³ã¬ã¯ã·ã§ã³ã
- num_unsaved_files-èšé²ãããŠããªããã¡ã€ã«ã®ã³ã¬ã¯ã·ã§ã³å ã®èŠçŽ ã®æ°ã
- options-è¿œå ã®è§£æãªãã·ã§ã³ã
ã芧ã®ãšããããã¹ãŠã®ããŒãµãŒæ§æã¯ãããŒãµãŒã®ã³ãã³ãã©ã€ã³åŒæ°ãããã¹ã圢åŒã§æž¡ãããšã«ãã£ãŠè¡ãããŸãã unsaved_filesãã©ã¡ãŒã¿ãŒã¯ ããšãã£ã¿ãŒãŸãã¯IDEããã®clangã¹ã¯ãªããã§åœ¹ç«ã¡ãŸãã ããã䜿çšãããšããŠãŒã¶ãŒã«ãã£ãŠå€æŽãããããŸã ãã£ã¹ã¯ã«ä¿åãããŠããªããã¡ã€ã«ãããŒãµãŒã«è»¢éã§ããŸãã ããã¯ããã¡ã€ã«åããã®ã³ã³ãã³ããããã³ã³ã³ãã³ãã®ãµã€ãºïŒãã€ãåäœïŒãå«ãCXUnsavedFileåã®æ§é äœã®ã³ã¬ã¯ã·ã§ã³ã§ãã ååãšå 容ã¯Cã©ã€ã³ãšããŠæå®ããããµã€ãºã¯ç¬Šå·ãªãæŽæ°ãšããŠæå®ãããŸãã
æåŸã®ãã©ã¡ãŒã¿ãŒïŒ options ïŒã¯ã次ã®ãã©ã°ã®ã»ããã§ãã
- CXTranslationUnit_None-ããã§ã¯ãã¹ãŠãæããã§ãã ç¹å¥ãªè§£æãªãã·ã§ã³ã¯èšå®ãããŠããŸããã
- CXTranslationUnit_DetailedPreprocessingRecord-ãã®ãªãã·ã§ã³ãèšå®ãããšããœãŒã¹ããã¹ãã§ããªããã»ããµã䜿çšãããæ¹æ³ãšå Žæã«é¢ãã詳现æ å ±ãããŒãµãŒãçæããå¿ èŠãããããšã瀺ããŸãã ããã¥ã¡ã³ãã«ç€ºãããŠããããã«ããã£ãã«äœ¿çšãããªããªãã·ã§ã³ã¯å€§éã®ã¡ã¢ãªãæ¶è²»ãããã®ãããªæ å ±ãæ¬åœã«å¿ èŠãªå Žåã«ã®ã¿ã€ã³ã¹ããŒã«ãã䟡å€ããããŸãã
- CXTranslationUnit_Incomplete-ãã®ãªãã·ã§ã³ãèšå®ãããšã äžå®å šãª ïŒ äžå®å šãª ïŒç¿»èš³åäœãåŠçãããŠããããšã瀺ããŸãã ããšãã°ãããããŒãã¡ã€ã«ã ãã®å Žåã翻蚳è ã¯ããããŒããã£ã¹ããçµäºããåã«ã€ã³ã¹ã¿ã³ã¹åããå¿ èŠããããã¿ãŒã³ãã€ã³ã¹ã¿ã³ã¹åããããšããŸããã
- CXTranslationUnit_PrecompiledPreamble-ãã®ãªãã·ã§ã³ãèšå®ãããšã翻蚳ãŠãããã®å é ã«å«ãŸãããã¹ãŠã®ããããŒãã¡ã€ã«ã«å¯ŸããŠãããŒãµãŒãããªã³ã³ãã€ã«æžã¿ããããŒãèªåçã«äœæããå¿ èŠãããããšã瀺ããŸãã ãã®ãªãã·ã§ã³ã¯ããã¡ã€ã«ãé »ç¹ã«å解æãããå ŽåïŒclang_reparseTranslationUnitã¡ãœããã䜿çšïŒã«äŸ¿å©ã§ããã次ã®ã»ã¯ã·ã§ã³ã§èª¬æããç¬èªã®ç¹æ§ããããŸãã
- CXTranslationUnit_CacheCompletionResults-ãã®ãªãã·ã§ã³ãèšå®ãããšããã®åŸã®åå解æåŸã«ãã³ãŒãè£å®ã®çµæã®äžéšãä¿åããããšããäºå®ã«ã€ãªãããŸãã
- CXTranslationUnit_SkipFunctionBodies-ãã®ãªãã·ã§ã³ãèšå®ãããšãå€æããã»ã¹äžã«é¢æ°ãšã¡ãœããã®æ¬äœãåŠçãããªããšããäºå®ã«ã€ãªãããŸãã ç¹å®ã®ãã£ã©ã¯ã¿ãŒã®ã¢ããŠã³ã¹ãå®çŸ©ããã°ããæ€çŽ¢ããã®ã«äŸ¿å©ã§ãã
ãã©ã°ã¯ãã|ãæäœã䜿çšããŠçµåã§ããŸãã
æåŸã®2ã€ã®ã¡ãœããïŒ clang_disposeTranslationUnitããã³clang_disposeIndex ïŒã¯ã翻蚳åäœãšã³ã³ããã¹ããèšè¿°ãã以åã«äœæããããã³ãã«ãåé€ããŸãã
ãã®ãµã³ãã«ã³ãŒããæ£åžžã«ãã«ãããã«ã¯ãlibclangã©ã€ãã©ãªãæ¥ç¶ããã ãã§ãã
2.1 clang APIã䜿çšãã解æ
clang APIã䜿çšããåæ§ã®ïŒæ©èœïŒã³ãŒãã¯æ¬¡ã®ãšããã§ãã
#include <vector> #include <iostream> #include <clang/Basic/Diagnostic.h> #include <clang/Frontend/DiagnosticOptions.h> #include <clang/Frontend/CompilerInstance.h> #include <clang/Frontend/CompilerInvocation.h> #include <clang/Frontend/Utils.h> #include <clang/Frontend/ASTUnit.h> int main(int argc, char ** argv) { using namespace clang ; using namespace llvm ; // Initialize compiler options list std::vector< const char *> args; for (int n = 1; n < argc; ++ n) args.push_back(argv[n]); args.push_back("main_clang.cpp" ); const char** opts = &args.front(); int opts_num = args.size(); // Create and setup diagnostic consumer DiagnosticOptions diagOpts; IntrusiveRefCntPtr< DiagnosticsEngine> diags(CompilerInstance::createDiagnostics( diagOpts, // Opts opts_num, // Argc opts, // Argv 0, // Client true, // ShouldOwnClient false // ShouldCloneClient )); // Create compiler invocation IntrusiveRefCntPtr< CompilerInvocation> compInvoke = clang::createInvocationFromCommandLine( makeArrayRef(opts, opts + opts_num), // Args diags // Diags ); if (!compInvoke) { std::cout << "Can't create compiler invocation for given args" ; return -1; } // Parse file clang::ASTUnit *tu = ASTUnit ::LoadFromCompilerInvocation( compInvoke.getPtr(), // CI diags, // Diags false, // OnlyLocalDecls true, // CaptureDiagnostics false, // PrecompilePreamble TU_Complete, // TUKind false // CacheCodeCompletionResults ); if (tu == 0 ) std::cout << "Translation unit was not created" ; else std::cout << "Translation unit successfully created" ; return 0; }
ããã«å€ãã®æåããããã¢ã»ã³ããªã«ã¯ã clangLexãclangBasicãclangASTãclangSerializationãclangEditãclangAnalysisãclangFrontendãclangSemaãclangDriverãclangParseãLLVMCoreãLLVMMC ãããã³LLVMSupportã®ã»ãããå¿ èŠã§ãã Windowsã§ãã«ãããå Žåã¯ãadvapi32ãšshell32ãè¿œå ããå¿ èŠããããŸãã ãã ããåºåã¯ãäžå¿ èŠãªå€éšäŸåé¢ä¿ã®ãªãå®è¡å¯èœã¢ãžã¥ãŒã«ã«ãªããŸãã
äžèšã®ã³ãŒãã¯4ã€ã®éšåã«åããããšãã§ããŸãã
- ã³ã³ãã€ã©ãŒã®ã³ãã³ãè¡ãã©ã¡ãŒã¿ãŒã®ã³ã¬ã¯ã·ã§ã³ã®åœ¢æã ãã®ããŒãžã§ã³ã®APIã§ã¯ã解æããå¿ èŠããããã¡ã€ã«ãžã®ãã¹ãã³ã¬ã¯ã·ã§ã³ã®èŠçŽ ã®1ã€ãšããŠéä¿¡ãããããããã®å ŽåãargvãšargcãçŽæ¥æž¡ãããšã¯ã§ããŸããã
- 蚺æãšã³ãžã³ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã ãã®ã¯ã©ã¹ã®ãªããžã§ã¯ãã¯ããœãŒã¹ããã¹ãã®è§£æããã»ã¹ã§ããŒãµãŒãçæã§ãããã¹ãŠã®ãšã©ãŒã¡ãã»ãŒãžãèŠåãããã³ãã®ä»ã®èšºæãåéããã³ä¿åããŸãã
- ã³ã³ãã€ã©ãŒåŒã³åºãã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã
- å®éã«ãœãŒã¹ããã¹ãã解æããŸãã
ã³ãã³ãã©ã€ã³åŒæ°ã®ã³ã¬ã¯ã·ã§ã³ãæ§ç¯ãã
äžèšã§æžããããã«ãclangãæäœããããã®ãªãã·ã§ã³ã¯ã察å¿ããã¯ã©ã¹ã¯ã©ã¹ã«ãããã®èšå®ãèšè¿°ããæååã®ã³ã¬ã¯ã·ã§ã³ãæž¡ãããšã§èšå®ãããŸãã æååã¯ãã€ã³ã¿ã®é åãšããŠæž¡ãããäžéãã¯ãã«ã䜿çšããŠãããè¡ãã®ãæã䟿å©ã§ãã ãã®å Žåãä»»æã®æ°ã®å€éšããåãåã£ãåŒæ°ã«è¿œå ã§ããŸãã ç¹ã«ã解æãããã¡ã€ã«ã®ååã
蚺æãšã³ãžã³ã®äœæ
DEã®äœæã¯ããœãŒã¹ããã¹ãã®è§£æããã»ã¹ã§çæãããããŒãµãŒclangããããŸããŸãªèšºææ å ±ãåä¿¡ããããã«å¿ èŠã§ãã 衚瀺ããããšã©ãŒã®æ倧æ°ã衚瀺ãããšã©ãŒ/èŠåãªã©ã®ãã©ã¡ãŒã¿ãŒãDEã¯ã³ãã³ãã©ã€ã³ããååŸãã2çªç®ãš3çªç®ã®ãã©ã¡ãŒã¿ãŒã«ãã£ãŠéä¿¡ãããŸãã æåŸã®3ã€ã®ãã©ã¡ãŒã¿ãŒã¯ãã蚺æã¯ã©ã€ã¢ã³ããã説æããŠããŸãã ããã¯ããŠãŒã¶ãŒclangã«åºæã®æ¹æ³ã§ããã«åŠçããããã«DEãããŒãµãŒã¡ãã»ãŒãžãïŒçºçæã«ïŒéãç¹å¥ãªã¯ã©ã¹ã§ãã DEã¯ã¯ã©ã€ã¢ã³ãã®åç¶æéãå¶åŸ¡ãããã転éããããªããžã§ã¯ãã®ã¯ããŒã³ãæäœãããã§ããŸãã ããã«ãããããŸããŸãªã¯ã©ã€ã¢ã³ãå®è£ ã·ããªãªã䜿çšã§ããŸã-éç/èªåãªããžã§ã¯ãã®åœ¢åŒãããŒãäžã®ãªããžã§ã¯ãã®åœ¢åŒãclang APIãæäœããã¡ãœãããæã€ã¯ã©ã¹ã®äžéšãªã©
ã³ã³ãã€ã©ãŒåŒã³åºãã®äœæ
å®éããã®ã¹ãããã§ã¯ã解æãå®è¡ãããã³ã³ããã¹ããäœæãããŸãã 転éãããã³ãã³ãã©ã€ã³ã®ãã¹ãŠã®ãã©ã¡ãŒã¿ãŒãç°å¢å€æ°ãåæãããå éšã€ã³ãã©ã¹ãã©ã¯ãã£å šäœãïŒãããã®ãã©ã¡ãŒã¿ãŒã«åŸã£ãŠïŒäœæããã蚺æãšã³ãžã³ãæ¥ç¶ãããŸãã ãã®åŸãclangã¯æåŸã®ãã©ã¡ãŒã¿ãŒãšããŠæž¡ããããã¡ã€ã«ã解æããæºåãå®å šã«æŽããŸãã
ãœãŒã¹ããã¹ãã®è§£æ
ããã¯ãclangã¯ã©ã¹ã®éçã¡ãœããã®1ã€ã§ããASTUnitãåŒã³åºãããšã§å®è¡ãããŸãã ãã®ãããªæ¹æ³ã¯ããã€ããããããŸããŸãªã·ããªãªã«åãããŠåŒ·åãããŠããŸãã ãã®äŸã¯ãå¯èœãªãªãã·ã§ã³ã®1ã€ã瀺ããŠããŸãã ãã®å Žåãã³ã³ãã€ã©ãŒåŒã³åºãã€ã³ã¹ã¿ã³ã¹ã¯ããŒãµãŒïŒããŒãµãŒã¯åŸã§åé€ããŸãïŒïŒã蚺æãšã³ãžã³ã€ã³ã¹ã¿ã³ã¹ïŒãã®ããŒãµãŒã¯èªåçã«åé€ãããŸããïŒãããã³ããŒãµãŒã®åäœãå¶åŸ¡ããããã€ãã®ãã©ã¡ãŒã¿ãŒã«æž¡ãããŸãã
- OnlyLocalDecls-解æããã翻蚳åäœããã®å®£èšã®ã¿ãæçµASTã«å«ãŸããŸãã PCHããã³æ·»ä»ããããŒãã¡ã€ã«ããã®å®£èšã¯é€å€ãããŸãã
- CaptureDiagnostic-蚺æã®åéæ¹æ³ãå¶åŸ¡ããŸãã ãã®ãã©ã¡ãŒã¿ãŒãšããŠfalseãæž¡ãããå Žåãåéããããã¹ãŠã®èšºæã¯ã蚺æãšã³ãžã³ã®äœææã«æå®ããã蚺æã¯ã©ã€ã¢ã³ãã«æž¡ãããŸãã ãã以å€ã®å Žåã蚺æã¯ASTUnitã®å éšæ§é ã«ä¿åãããŸãã
- PrecompilePreamble-åè¿°ã®ããã«ããã®ãªãã·ã§ã³ãæå¹ã«ãããšãããŒãµãŒã¯ãœãŒã¹ããã¹ãã«å«ãŸãããã¹ãŠã®ããããŒã«å¯ŸããŠPCHãèªåçã«äœæããŸãã ã¯ããããã§ãã ç¹°ãè¿ã解æã«åœ¹ç«ã¡ãŸãã ããããå€æããããã«ãããã€ãã®éåžžã«æ¥œããç¬éã¯ãããŸããã ãŸããå®éã«ã¯ãçµæã®ASTUnitã€ã³ã¹ã¿ã³ã¹ã«å¯ŸããŠASTUnit :: Reparseã¡ãœãããæåã«åŒã³åºããããšãã«PCHãäœæãããŸãã 第äºã«ãïŒifdef-guardsãå«ãããããŒãã¡ã€ã«ã解æãããå Žåãæ²ããããªãäœãäœæãããŸããã
- TUKind-翻蚳åäœã®ã¿ã€ãã ããã§ã¯æ¬¡ã®ãªãã·ã§ã³ãå¯èœã§ãã
- TU_Complete-å®å šã«å®æãã翻蚳åäœã解æãããŸãã ãã®å ŽåããœãŒã¹ããã¹ãã§äœ¿çšããããã³ãã¬ãŒãã®ãã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ãæçµASTã«é 眮ãããŸãã
- TU_Prefix- ã翻蚳åäœã®ãã¬ãã£ãã¯ã¹ãã解æãããŸãããã®å ŽåããœãŒã¹ããã¹ãã¯å®å šãšã¯èŠãªãããŸããã
- TU_Module-äžéšã®ãã¢ãžã¥ãŒã«ãã解æãããŸãã ããã¯äœã§ãã-ããã¥ã¡ã³ãã¯ãµã€ã¬ã³ãã§ãã
- CacheCodeCompletionResults-解æäžã«ã³ãŒãè£å®çµæããã£ãã·ã¥ãããŸãã åŸç¶ã®ã³ãŒãå®äºèŠæ±ã«æ¬åœã«åœ¹ç«ã¡ãŸãã
3.ãªãã·ã§ã³ã»ããã®å°ããªã³ã
ç§ã®æåã®å®éšïŒå®£èšãæœåºããããã®ããããŒãã¡ã€ã«ã®è§£æã§ããïŒã§ã¯ã解æãå€ãã®ãšã©ãŒã§çµäºããçç±ãé·ãéç解ããŠããŸããã§ããã æçµçã«ããã¹ãŠãéåžžã«ã·ã³ãã«ã§ããããšãå€æããŸããã ãã®ããã圹ç«ã€ãªãã·ã§ã³ïŒ
- -x language-解æãããã¡ã€ã«ã®ç¹å®ã®ã¿ã€ããæå®ããŸãã åæ§ã®gccã³ã³ãã€ã©ãªãã·ã§ã³ãšäºææ§ããããŸãã
- -std = standard-ãœãŒã¹ããã¹ãã察å¿ããæšæºãæå®ããŸãã gccã³ã³ãã€ã©ãªãã·ã§ã³ãšäºææ§ããããŸãã
- -ferror-limit = N-解æãå®äºãããŸã§ã®ãšã©ãŒã®æ倧æ°ãNã«èšå®ããŸãã ãšã©ãŒãå®å šã«ç¡èŠããŠãã¡ã€ã«ã解æããå ŽåãNã¯0ã«çãããªããã°ãªããŸããã
- -include <prefix-file> -ã¡ã€ã³ãã¡ã€ã«ã解æããåã«è§£æãããã¡ã€ã«ïŒéåžžã¯ããããŒïŒãæå®ããŸãã äžè¬ã«ããã®ãªãã·ã§ã³ã¯å ã PCHããããŒãå«ããããšãç®çãšããŠããŸããããã¡ã€ã«ã解æãããšããããšãã°ããŸããŸãªãã¯ããå®çŸ©ããã®ã«åœ¹ç«ã¡ãŸãã
ããã«é¢ããŠãclang APIã®æåã®ç¥èã¯å®å šã§ãããšèããããšãã§ããŸãã clang-c APIã®è©³çŽ°ã«ã€ããŠã¯ãå ¬åŒã®clang Webãµã€ãclang.llvm.org/doxygen/group__CINDEX.htmlãã芧ãã ããã
ãã㧠ãclang APIã¯ã©ã¹ã®éå±€å šäœã«æ £ããããšãã§ããŸãã æ®å¿µãªãããããã¥ã¡ã³ãã¯ã¢ããã¹ããªãŒã ã®clangããèªåçã«çæããããããããã¥ã¡ã³ããšå ±ã«Webãµã€ãã§èª¬æãããŠããé¢æ°ã®ã·ã°ããã£ããã®ã»ãããªã©ã¯ãç¹å®ã®ãªãªãŒã¹ã§æ瀺ãããŠãããã®ãšç°ãªãå ŽåããããŸãã
次ã®èšäºã§ã¯ãclangã§äœæãããASTãã宣èšããªãŒãååŸããæ¹æ³ã«ã€ããŠèª¬æããŸãã