std::vector<std::string> getLocalizedStringFromFile(std::string filename, std::string triple, std::vector<std::string> includepaths) { clang::DiagnosticOptions diagnosticOptions; clang::TextDiagnosticPrinter *pTextDiagnosticPrinter = new clang::TextDiagnosticPrinter( llvm::outs(), &diagnosticOptions); llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs; clang::DiagnosticsEngine *pDiagnosticsEngine = new clang::DiagnosticsEngine(pDiagIDs, &diagnosticOptions, pTextDiagnosticPrinter); clang::LangOptions languageOptions; clang::FileSystemOptions fileSystemOptions; clang::FileManager fileManager(fileSystemOptions); clang::SourceManager sourceManager( *pDiagnosticsEngine, fileManager); const std::shared_ptr<clang::TargetOptions> targetOptions = std::make_shared<clang::TargetOptions>(); targetOptions->Triple = triple;//"arm-apple-darwin11";//llvm::sys::getDefaultTargetTriple(); clang::TargetInfo *pTargetInfo = clang::TargetInfo::CreateTargetInfo( *pDiagnosticsEngine, targetOptions ); llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> headerSearchOptions(new clang::HeaderSearchOptions()); for(unsigned long i = 0 ; i < includepaths.size(); i++) { headerSearchOptions->AddPath(includepaths.at(i), clang::frontend::Angled, false, false); } clang::HeaderSearch headerSearch(headerSearchOptions, sourceManager, *pDiagnosticsEngine, languageOptions, pTargetInfo); /* headerSearchOptions->AddPath("/usr/share/iPhoneOS5.0.sdk/usr/include/c++/4.2.1/tr1/", clang::frontend::Angled, false, false, false); headerSearchOptions->AddPath("/usr/share/iPhoneOS5.0.sdk/usr/include/c++/4.2.1", clang::frontend::Angled, false, false, false); */ clang::CompilerInstance compInst; llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions> pOpts (new clang::PreprocessorOptions()); clang::Preprocessor preprocessor( pOpts, *pDiagnosticsEngine, languageOptions, sourceManager, headerSearch, compInst); preprocessor.Initialize(*pTargetInfo); clang::FrontendOptions frontendOptions; clang::RawPCHContainerReader Reader; clang::InitializePreprocessor( preprocessor, *pOpts, Reader, frontendOptions); clang::ApplyHeaderSearchOptions( headerSearch,//preprocessor.getHeaderSearchInfo(), *headerSearchOptions,//compInst.getHeaderSearchOpts(), preprocessor.getLangOpts(), preprocessor.getTargetInfo().getTriple()); const clang::FileEntry *pFile = fileManager.getFile(filename); //sourceManager.setMainFileID( sourceManager.createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_System)); sourceManager.setMainFileID( sourceManager.createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); //sourceManager.createMainFileID(pFile); preprocessor.EnterMainSourceFile(); pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor); /* * identifier 'localizedStringForKey' * colon ':' * l_paren '(' * unknown '@' * string_literal '"UIAlertView"' * r_paren ')' * */ int found = 0; std::string trans_str; std::vector<std::string> trans_list; clang::Token token; do { preprocessor.Lex(token); if( pDiagnosticsEngine->hasErrorOccurred()) { break; } // if we meet localizedStringForKey, that means we need record it params. if(token.is(clang::tok::identifier) && token.isNot(clang::tok::raw_identifier)) { const clang::IdentifierInfo *II = token.getIdentifierInfo(); if ( II && (strcmp(II->getName().data(), "localizedStringForKey") == 0)) found = 1; } // only string literal we should handle. if(found == 1 && token.is(clang::tok::string_literal)) { std::string got = preprocessor.getSpelling(token); //here, we got a string with "" got = got.substr(1,got.length()-2); //remove "" trans_str += got; // string may split to multiline, we save them all. } // when match ), that means we got what we need. // push it to vector and wait next found == 1; if(found == 1 && token.is(clang::tok::r_paren) && token.isNot(clang::tok::raw_identifier)) { trans_list.push_back(trans_str); trans_str.clear(); found = 0; } } while( token.isNot(clang::tok::eof)); pTextDiagnosticPrinter->EndSourceFile(); /*for(int i = 0; i < trans_list.size(); i++) std::cout<<trans_list[i]<<std::endl; */ return trans_list; }
int main() { clang::DiagnosticOptions diagnosticOptions; clang::TextDiagnosticPrinter *pTextDiagnosticPrinter = new clang::TextDiagnosticPrinter( llvm::outs(), &diagnosticOptions); llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs; clang::DiagnosticsEngine *pDiagnosticsEngine = new clang::DiagnosticsEngine(pDiagIDs, &diagnosticOptions, pTextDiagnosticPrinter); clang::LangOptions languageOptions; clang::FileSystemOptions fileSystemOptions; clang::FileManager fileManager(fileSystemOptions); clang::SourceManager sourceManager( *pDiagnosticsEngine, fileManager); llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> headerSearchOptions(new clang::HeaderSearchOptions()); // <Warning!!> -- Platform Specific Code lives here // This depends on A) that you're running linux and // B) that you have the same GCC LIBs installed that // I do. // Search through Clang itself for something like this, // go on, you won't find it. The reason why is Clang // has its own versions of std* which are installed under // /usr/local/lib/clang/<version>/include/ // See somewhere around Driver.cpp:77 to see Clang adding // its version of the headers to its include path. headerSearchOptions->AddPath("/usr/include/linux", clang::frontend::Angled, false, false); headerSearchOptions->AddPath("/usr/include/c++/4.4/tr1", clang::frontend::Angled, false, false); headerSearchOptions->AddPath("/usr/include/c++/4.4", clang::frontend::Angled, false, false); // </Warning!!> -- End of Platform Specific Code clang::TargetOptions targetOptions; targetOptions.Triple = llvm::sys::getDefaultTargetTriple(); clang::TargetInfo *pTargetInfo = clang::TargetInfo::CreateTargetInfo( *pDiagnosticsEngine, &targetOptions); llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> hso; clang::HeaderSearch headerSearch(hso, fileManager, *pDiagnosticsEngine, languageOptions, pTargetInfo); clang::CompilerInstance compInst; llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions> pOpts( new clang::PreprocessorOptions()); clang::Preprocessor preprocessor( pOpts, *pDiagnosticsEngine, languageOptions, pTargetInfo, sourceManager, headerSearch, compInst); clang::FrontendOptions frontendOptions; clang::InitializePreprocessor( preprocessor, *pOpts, *headerSearchOptions, frontendOptions); const clang::FileEntry *pFile = fileManager.getFile( "test.c"); sourceManager.createMainFileID(pFile); const clang::TargetInfo &targetInfo = *pTargetInfo; clang::IdentifierTable identifierTable(languageOptions); clang::SelectorTable selectorTable; clang::Builtin::Context builtinContext; builtinContext.InitializeTarget(targetInfo); clang::ASTContext astContext( languageOptions, sourceManager, pTargetInfo, identifierTable, selectorTable, builtinContext, 0 /* size_reserve*/); clang::ASTConsumer astConsumer; clang::Sema sema( preprocessor, astContext, astConsumer); pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor); clang::ParseAST(preprocessor, &astConsumer, astContext); pTextDiagnosticPrinter->EndSourceFile(); identifierTable.PrintStats(); return 0; }