int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; CompilerInstance ci; ci.createDiagnostics(0,NULL); TargetOptions to; to.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); ci.getPreprocessorOpts().UsePredefines = false; MyASTConsumer *astConsumer = new MyASTConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); const FileEntry *pFile = ci.getFileManager().getFile("test.c"); ci.getSourceManager().createMainFileID(pFile); ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); clang::ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext()); ci.getDiagnosticClient().EndSourceFile(); return 0; }
int main() { CompilerInstance ci; ci.createDiagnostics(0,NULL); TargetOptions to; to.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); ci.setTarget(pti); ci.getHeaderSearchOpts().AddPath( StringRef("../usr/lib/clang/3.0/include"), frontend::Angled, false, false, false ); ci.getHeaderSearchOpts().AddPath( StringRef("support"), frontend::Quoted, true, false, false ); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); PrintFunctionsConsumer *astConsumer = new PrintFunctionsConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); const FileEntry *pFile = ci.getFileManager().getFile("julia.h"); ci.getSourceManager().createMainFileID(pFile); ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); clang::ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext()); ci.getDiagnosticClient().EndSourceFile(); return 0; }
int main(int argc, char *argv[]) { if (argc != 2) { llvm::errs() << "Usage: rewritersample <filename>\n"; return 1; } // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance TheCompInst; TheCompInst.createDiagnostics(); LangOptions &lo = TheCompInst.getLangOpts(); lo.CPlusPlus = 1; // Initialize target info with the default triple for our platform. auto TO = std::make_shared<TargetOptions>(); TO->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO); TheCompInst.setTarget(TI); TheCompInst.createFileManager(); FileManager &FileMgr = TheCompInst.getFileManager(); TheCompInst.createSourceManager(FileMgr); SourceManager &SourceMgr = TheCompInst.getSourceManager(); TheCompInst.createPreprocessor(TU_Module); TheCompInst.createASTContext(); // A Rewriter helps us manage the code rewriting task. Rewriter TheRewriter; TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts()); // Set the main file handled by the source manager to the input file. const FileEntry *FileIn = FileMgr.getFile(argv[1]); SourceMgr.setMainFileID( SourceMgr.createFileID(FileIn, SourceLocation(), SrcMgr::C_User)); TheCompInst.getDiagnosticClient().BeginSourceFile( TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor()); // Create an AST consumer instance which is going to get called by // ParseAST. MyASTConsumer TheConsumer(TheRewriter); // Parse the file to AST, registering our consumer as the AST consumer. ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext()); // At this point the rewriter's buffer should be full with the rewritten // file contents. const RewriteBuffer *RewriteBuf = TheRewriter.getRewriteBufferFor(SourceMgr.getMainFileID()); llvm::outs() << std::string(RewriteBuf->begin(), RewriteBuf->end()); return 0; }
int main(int argc, char *argv[]) { if (argc != 2) { llvm::errs() << "Usage: rewritersample <filename>\n"; return 1; } // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance ci; ci.createDiagnostics(0, 0); // Initialize target info with the default triple for our platform. TargetOptions TO; TO.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo( ci.getDiagnostics(), TO); ci.setTarget(TI); ci.createFileManager(); FileManager &fm = ci.getFileManager(); ci.createSourceManager(fm); SourceManager &SourceMgr = ci.getSourceManager(); ci.createPreprocessor(); ci.createASTContext(); // A Rewriter helps us manage the code rewriting task. Rewriter rw; rw.setSourceMgr(SourceMgr, ci.getLangOpts()); // Set the main file handled by the source manager to the input file. const FileEntry *fi = fm.getFile(argv[1]); SourceMgr.createMainFileID(fi); ci.getDiagnosticClient().BeginSourceFile( ci.getLangOpts(), &ci.getPreprocessor()); // Create an AST consumer instance which is going to get called by // ParseAST. MyASTConsumer astc(rw); // Parse the file to AST, registering our consumer as the AST consumer. ParseAST(ci.getPreprocessor(), &astc, ci.getASTContext()); // At this point the rewriter's buffer should be full with the rewritten // file contents. const RewriteBuffer *rwb = rw.getRewriteBufferFor(SourceMgr.getMainFileID()); llvm::outs() << string(rwb->begin(), rwb->end()); return 0; }
int main(int argc, char *argv[]) { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; using clang::ASTConsumer; using clang::DiagnosticOptions; using clang::TextDiagnosticPrinter; CompilerInstance CI; DiagnosticOptions diagnosticOptions; TextDiagnosticPrinter *pTextDiagnosticPrinter = new TextDiagnosticPrinter( llvm::outs(), diagnosticOptions, true); CI.createDiagnostics(0, NULL, pTextDiagnosticPrinter); TargetOptions targetOptions; targetOptions.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pTargetInfo = TargetInfo::CreateTargetInfo( CI.getDiagnostics(), targetOptions); CI.setTarget(pTargetInfo); CI.createFileManager(); CI.createSourceManager(CI.getFileManager()); CI.createPreprocessor(); CI.getPreprocessorOpts().UsePredefines = false; ASTConsumer *astConsumer = new ASTConsumer(); CI.setASTConsumer(astConsumer); CI.createASTContext(); CI.createSema(clang::TU_Complete, NULL); const FileEntry *pFile = CI.getFileManager().getFile(argv[1]); CI.getSourceManager().createMainFileID(pFile); CI.getASTContext().BuiltinInfo.InitializeBuiltins( CI.getPreprocessor().getIdentifierTable(), CI.getLangOpts()); CI.getDiagnosticClient().BeginSourceFile( CI.getLangOpts(), &(CI.getPreprocessor())); clang::ParseAST(CI.getSema()); CI.getDiagnosticClient().EndSourceFile(); return 0; }
void checkVariables(string filename, vector<Issue>& lineIssues){ // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance TheCompInst; TheCompInst.createDiagnostics(); CompilerInvocation TheCompInv; LangOptions &lo = TheCompInst.getLangOpts(); lo.CPlusPlus = 1; lo.Bool = 1; lo.WChar = 1; lo.NoBuiltin = 0; // Initialize target info with the default triple for our platform. auto TO = std::make_shared<TargetOptions>(); TO->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO); TheCompInst.setTarget(TI); TheCompInst.createFileManager(); FileManager &FileMgr = TheCompInst.getFileManager(); TheCompInst.createSourceManager(FileMgr); SourceManager &SourceMgr = TheCompInst.getSourceManager(); TheCompInst.createPreprocessor(TU_Module); Preprocessor& pp = TheCompInst.getPreprocessor(); pp.getBuiltinInfo().InitializeBuiltins(pp.getIdentifierTable(), lo); //pp.getLangOpts().NoBuiltin); TheCompInst.createASTContext(); // Set the main file handled by the source manager to the input file. const FileEntry *FileIn = FileMgr.getFile(filename); SourceMgr.setMainFileID( SourceMgr.createFileID(FileIn, SourceLocation(), SrcMgr::C_User)); TheCompInst.getDiagnosticClient().BeginSourceFile( TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor()); MyASTConsumer consm{lineIssues, SourceMgr}; ParseAST(TheCompInst.getPreprocessor(), &consm, TheCompInst.getASTContext()); }
int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; using clang::Token; using clang::ASTContext; using clang::ASTConsumer; using clang::Parser; using clang::DiagnosticOptions; using clang::TextDiagnosticPrinter; CompilerInstance ci; DiagnosticOptions diagnosticOptions; ci.createDiagnostics(); llvm::IntrusiveRefCntPtr<TargetOptions> pto( new TargetOptions()); pto->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto.getPtr()); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); #ifdef CLANG_3_5 ci.createPreprocessor(clang::TU_Complete); #else ci.createPreprocessor(); #endif ci.getPreprocessorOpts().UsePredefines = false; ASTConsumer *astConsumer = new ASTConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); ci.createSema(clang::TU_Complete, NULL); const FileEntry *pFile = ci.getFileManager().getFile("test.c"); ci.getSourceManager().createMainFileID(pFile); clang::ParseAST(ci.getSema()); ci.getASTContext().Idents.PrintStats(); return 0; }
int main(int argc, const char *argv[]) { struct stat sb; if (argc != 2) { std::cout << "Usage: ./PrintFunctionInfo <filename>" << std::endl; exit(1); } if (stat(argv[1], &sb) == -1) { perror(argv[1]); exit(EXIT_FAILURE); } CompilerInstance ci; ci.createDiagnostics(0,NULL); TargetOptions to; to.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); ci.getPreprocessorOpts().UsePredefines = false; FunctionLocConsumer *astConsumer = new FunctionLocConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); const FileEntry *pFile = ci.getFileManager().getFile(argv[1]); ci.getSourceManager().createMainFileID(pFile); ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext()); ci.getDiagnosticClient().EndSourceFile(); return 0; }
int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; using clang::Token; using clang::ASTContext; using clang::ASTConsumer; using clang::Parser; CompilerInstance ci; ci.createDiagnostics(0,NULL); TargetOptions to; to.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); ci.getPreprocessorOpts().UsePredefines = false; ASTConsumer *astConsumer = new ASTConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); ci.createSema(clang::TU_Complete, NULL); const FileEntry *pFile = ci.getFileManager().getFile("test.c"); ci.getSourceManager().createMainFileID(pFile); ci.getPreprocessor().EnterMainSourceFile(); ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); Parser parser(ci.getPreprocessor(), ci.getSema(), false /*skipFunctionBodies*/); parser.ParseTranslationUnit(); ci.getDiagnosticClient().EndSourceFile(); ci.getASTContext().Idents.PrintStats(); return 0; }
int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; using clang::Token; using clang::ASTContext; using clang::ASTConsumer; using clang::Parser; using clang::DiagnosticOptions; using clang::TextDiagnosticPrinter; CompilerInstance ci; DiagnosticOptions diagnosticOptions; ci.createDiagnostics(); std::shared_ptr<clang::TargetOptions> pto = std::make_shared<clang::TargetOptions>(); pto->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(clang::TU_Complete); ci.getPreprocessorOpts().UsePredefines = false; ci.setASTConsumer(llvm::make_unique<ASTConsumer>()); ci.createASTContext(); ci.createSema(clang::TU_Complete, NULL); const FileEntry *pFile = ci.getFileManager().getFile("test.c"); ci.getSourceManager().setMainFileID( ci.getSourceManager().createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); clang::ParseAST(ci.getSema()); ci.getASTContext().Idents.PrintStats(); return 0; }
bool FrontendAction::BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename, bool IsAST) { assert(!Instance && "Already processing a source file!"); assert(!Filename.empty() && "Unexpected empty filename!"); setCurrentFile(Filename); setCompilerInstance(&CI); // AST files follow a very different path, since they share objects via the // AST unit. if (IsAST) { assert(!usesPreprocessorOnly() && "Attempt to pass AST file to preprocessor only action!"); assert(hasASTSupport() && "This action does not have AST support!"); llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics()); std::string Error; ASTUnit *AST = ASTUnit::LoadFromPCHFile(Filename, Diags); if (!AST) goto failure; setCurrentFile(Filename, AST); // Set the shared objects, these are reset when we finish processing the // file, otherwise the CompilerInstance will happily destroy them. CI.setFileManager(&AST->getFileManager()); CI.setSourceManager(&AST->getSourceManager()); CI.setPreprocessor(&AST->getPreprocessor()); CI.setASTContext(&AST->getASTContext()); // Initialize the action. if (!BeginSourceFileAction(CI, Filename)) goto failure; /// Create the AST consumer. CI.setASTConsumer(CreateASTConsumer(CI, Filename)); if (!CI.hasASTConsumer()) goto failure; return true; } // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), &CI.getPreprocessor()); // Initialize the action. if (!BeginSourceFileAction(CI, Filename)) goto failure; /// Create the AST context and consumer unless this is a preprocessor only /// action. if (!usesPreprocessorOnly()) { CI.createASTContext(); CI.setASTConsumer(CreateASTConsumer(CI, Filename)); if (!CI.hasASTConsumer()) goto failure; /// Use PCH? if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { assert(hasPCHSupport() && "This action does not have PCH support!"); CI.createPCHExternalASTSource( CI.getPreprocessorOpts().ImplicitPCHInclude); if (!CI.getASTContext().getExternalSource()) goto failure; } } // Initialize builtin info as long as we aren't using an external AST // source. if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { Preprocessor &PP = CI.getPreprocessor(); PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), PP.getLangOptions().NoBuiltin); } return true; // If we failed, reset state since the client will not end up calling the // matching EndSourceFile(). failure: if (isCurrentFileAST()) { CI.takeASTContext(); CI.takePreprocessor(); CI.takeSourceManager(); CI.takeFileManager(); } CI.getDiagnosticClient().EndSourceFile(); setCurrentFile(""); setCompilerInstance(0); return false; }
bool FrontendAction::BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input) { assert(!Instance && "Already processing a source file!"); assert(!Input.isEmpty() && "Unexpected empty filename!"); setCurrentInput(Input); setCompilerInstance(&CI); StringRef InputFile = Input.getFile(); bool HasBegunSourceFile = false; if (!BeginInvocation(CI)) goto failure; // AST files follow a very different path, since they share objects via the // AST unit. if (Input.getKind() == IK_AST) { assert(!usesPreprocessorOnly() && "Attempt to pass AST file to preprocessor only action!"); assert(hasASTFileSupport() && "This action does not have AST file support!"); IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( InputFile, CI.getPCHContainerReader(), Diags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs); if (!AST) goto failure; // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); HasBegunSourceFile = true; // Set the shared objects, these are reset when we finish processing the // file, otherwise the CompilerInstance will happily destroy them. CI.setFileManager(&AST->getFileManager()); CI.setSourceManager(&AST->getSourceManager()); CI.setPreprocessor(AST->getPreprocessorPtr()); CI.setASTContext(&AST->getASTContext()); setCurrentInput(Input, std::move(AST)); // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; // Create the AST consumer. CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile)); if (!CI.hasASTConsumer()) goto failure; return true; } if (!CI.hasVirtualFileSystem()) { if (IntrusiveRefCntPtr<vfs::FileSystem> VFS = createVFSFromCompilerInvocation(CI.getInvocation(), CI.getDiagnostics())) CI.setVirtualFileSystem(VFS); else goto failure; } // Set up the file and source managers, if needed. if (!CI.hasFileManager()) CI.createFileManager(); if (!CI.hasSourceManager()) CI.createSourceManager(CI.getFileManager()); // IR files bypass the rest of initialization. if (Input.getKind() == IK_LLVM_IR) { assert(hasIRSupport() && "This action does not have IR file support!"); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); HasBegunSourceFile = true; // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; // Initialize the main file entry. if (!CI.InitializeSourceManager(CurrentInput)) goto failure; return true; } // If the implicit PCH include is actually a directory, rather than // a single file, search for a suitable PCH file in that directory. if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { FileManager &FileMgr = CI.getFileManager(); PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); StringRef PCHInclude = PPOpts.ImplicitPCHInclude; std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath(); if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) { std::error_code EC; SmallString<128> DirNative; llvm::sys::path::native(PCHDir->getName(), DirNative); bool Found = false; vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { // Check whether this is an acceptable AST file. if (ASTReader::isAcceptableASTFile( Dir->getName(), FileMgr, CI.getPCHContainerReader(), CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(), SpecificModuleCachePath)) { PPOpts.ImplicitPCHInclude = Dir->getName(); Found = true; break; } } if (!Found) { CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude; goto failure; } } } // Set up the preprocessor if needed. When parsing model files the // preprocessor of the original source is reused. if (!isModelParsingAction()) CI.createPreprocessor(getTranslationUnitKind()); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), &CI.getPreprocessor()); HasBegunSourceFile = true; // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; // Initialize the main file entry. It is important that this occurs after // BeginSourceFileAction, which may change CurrentInput during module builds. if (!CI.InitializeSourceManager(CurrentInput)) goto failure; // Create the AST context and consumer unless this is a preprocessor only // action. if (!usesPreprocessorOnly()) { // Parsing a model file should reuse the existing ASTContext. if (!isModelParsingAction()) CI.createASTContext(); std::unique_ptr<ASTConsumer> Consumer = CreateWrappedASTConsumer(CI, InputFile); if (!Consumer) goto failure; // FIXME: should not overwrite ASTMutationListener when parsing model files? if (!isModelParsingAction()) CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { // Convert headers to PCH and chain them. IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader; source = createChainedIncludesSource(CI, FinalReader); if (!source) goto failure; CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get())); CI.getASTContext().setExternalSource(source); } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { // Use PCH. assert(hasPCHSupport() && "This action does not have PCH support!"); ASTDeserializationListener *DeserialListener = Consumer->GetASTDeserializationListener(); bool DeleteDeserialListener = false; if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) { DeserialListener = new DeserializedDeclsDumper(DeserialListener, DeleteDeserialListener); DeleteDeserialListener = true; } if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) { DeserialListener = new DeserializedDeclsChecker( CI.getASTContext(), CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, DeserialListener, DeleteDeserialListener); DeleteDeserialListener = true; } CI.createPCHExternalASTSource( CI.getPreprocessorOpts().ImplicitPCHInclude, CI.getPreprocessorOpts().DisablePCHValidation, CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener, DeleteDeserialListener); if (!CI.getASTContext().getExternalSource()) goto failure; } CI.setASTConsumer(std::move(Consumer)); if (!CI.hasASTConsumer()) goto failure; } // Initialize built-in info as long as we aren't using an external AST // source. if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { Preprocessor &PP = CI.getPreprocessor(); // If modules are enabled, create the module manager before creating // any builtins, so that all declarations know that they might be // extended by an external source. if (CI.getLangOpts().Modules) CI.createModuleManager(); PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), PP.getLangOpts()); } else { // FIXME: If this is a problem, recover from it by creating a multiplex // source. assert((!CI.getLangOpts().Modules || CI.getModuleManager()) && "modules enabled but created an external source that " "doesn't support modules"); } // If we were asked to load any module map files, do so now. for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) { if (auto *File = CI.getFileManager().getFile(Filename)) CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile( File, /*IsSystem*/false); else CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename; } // If we were asked to load any module files, do so now. for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) if (!CI.loadModuleFile(ModuleFile)) goto failure; // If there is a layout overrides file, attach an external AST source that // provides the layouts from that file. if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { IntrusiveRefCntPtr<ExternalASTSource> Override(new LayoutOverrideSource( CI.getFrontendOpts().OverrideRecordLayoutsFile)); CI.getASTContext().setExternalSource(Override); } return true; // If we failed, reset state since the client will not end up calling the // matching EndSourceFile(). failure: if (isCurrentFileAST()) { CI.setASTContext(nullptr); CI.setPreprocessor(nullptr); CI.setSourceManager(nullptr); CI.setFileManager(nullptr); } if (HasBegunSourceFile) CI.getDiagnosticClient().EndSourceFile(); CI.clearOutputFiles(/*EraseFiles=*/true); setCurrentInput(FrontendInputFile()); setCompilerInstance(nullptr); return false; }
bool FrontendAction::BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename, InputKind InputKind) { assert(!Instance && "Already processing a source file!"); assert(!Filename.empty() && "Unexpected empty filename!"); setCurrentFile(Filename, InputKind); setCompilerInstance(&CI); if (!BeginInvocation(CI)) goto failure; // AST files follow a very different path, since they share objects via the // AST unit. if (InputKind == IK_AST) { assert(!usesPreprocessorOnly() && "Attempt to pass AST file to preprocessor only action!"); assert(hasASTFileSupport() && "This action does not have AST file support!"); llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics()); std::string Error; ASTUnit *AST = ASTUnit::LoadFromASTFile(Filename, Diags, CI.getFileSystemOpts()); if (!AST) goto failure; setCurrentFile(Filename, InputKind, AST); // Set the shared objects, these are reset when we finish processing the // file, otherwise the CompilerInstance will happily destroy them. CI.setFileManager(&AST->getFileManager()); CI.setSourceManager(&AST->getSourceManager()); CI.setPreprocessor(&AST->getPreprocessor()); CI.setASTContext(&AST->getASTContext()); // Initialize the action. if (!BeginSourceFileAction(CI, Filename)) goto failure; /// Create the AST consumer. CI.setASTConsumer(CreateWrappedASTConsumer(CI, Filename)); if (!CI.hasASTConsumer()) goto failure; return true; } // Set up the file and source managers, if needed. if (!CI.hasFileManager()) CI.createFileManager(); if (!CI.hasSourceManager()) CI.createSourceManager(CI.getFileManager()); // IR files bypass the rest of initialization. if (InputKind == IK_LLVM_IR) { assert(hasIRSupport() && "This action does not have IR file support!"); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); // Initialize the action. if (!BeginSourceFileAction(CI, Filename)) goto failure; return true; } // Set up the preprocessor. CI.createPreprocessor(); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), &CI.getPreprocessor()); // Initialize the action. if (!BeginSourceFileAction(CI, Filename)) goto failure; /// Create the AST context and consumer unless this is a preprocessor only /// action. if (!usesPreprocessorOnly()) { CI.createASTContext(); llvm::OwningPtr<ASTConsumer> Consumer( CreateWrappedASTConsumer(CI, Filename)); if (!Consumer) goto failure; CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { // Convert headers to PCH and chain them. llvm::OwningPtr<ExternalASTSource> source; source.reset(ChainedIncludesSource::create(CI)); if (!source) goto failure; CI.getASTContext().setExternalSource(source); } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { // Use PCH. assert(hasPCHSupport() && "This action does not have PCH support!"); ASTDeserializationListener *DeserialListener = CI.getInvocation().getFrontendOpts().ChainedPCH ? Consumer->GetASTDeserializationListener() : 0; if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) DeserialListener = new DeserializedDeclsDumper(DeserialListener); if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(), CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, DeserialListener); CI.createPCHExternalASTSource( CI.getPreprocessorOpts().ImplicitPCHInclude, CI.getPreprocessorOpts().DisablePCHValidation, CI.getPreprocessorOpts().DisableStatCache, DeserialListener); if (!CI.getASTContext().getExternalSource()) goto failure; } CI.setASTConsumer(Consumer.take()); if (!CI.hasASTConsumer()) goto failure; } // Initialize builtin info as long as we aren't using an external AST // source. if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { Preprocessor &PP = CI.getPreprocessor(); PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), PP.getLangOptions()); } return true; // If we failed, reset state since the client will not end up calling the // matching EndSourceFile(). failure: if (isCurrentFileAST()) { CI.setASTContext(0); CI.setPreprocessor(0); CI.setSourceManager(0); CI.setFileManager(0); } CI.getDiagnosticClient().EndSourceFile(); setCurrentFile("", IK_None); setCompilerInstance(0); return false; }
//使用的格式: ./checkMemory 被测试文件名 -- int main(int argc,const char **argv) { //----此块基本一样 start---- struct stat sb; //set compilerinstance for rewriter std::string fileName(argv[1]); if (stat(fileName.c_str(), &sb) == -1){ perror(fileName.c_str()); exit(EXIT_FAILURE); } CompilerInstance compiler; DiagnosticOptions diagnosticOptions; compiler.createDiagnostics(); //invocation可以传递任何flag给preprocessor CompilerInvocation *Invocation = new CompilerInvocation; CompilerInvocation::CreateFromArgs(*Invocation, argv + 1, argv + argc-1,compiler.getDiagnostics()); compiler.setInvocation(Invocation); //建立TargetOptions和TargetInfo,并设置好Target // Set default target triple llvm::IntrusiveRefCntPtr<TargetOptions> pto( new TargetOptions()); pto->Triple = llvm::sys::getDefaultTargetTriple(); llvm::IntrusiveRefCntPtr<TargetInfo> pti(TargetInfo::CreateTargetInfo(compiler.getDiagnostics(), pto.getPtr())); compiler.setTarget(pti.getPtr()); //FileManager,SourceManager 以及heaDREearch的Options的设置 compiler.createFileManager(); compiler.createSourceManager(compiler.getFileManager()); HeaderSearchOptions &headerSearchOptions = compiler.getHeaderSearchOpts(); headerSearchOptions.AddPath("/usr/include/c++", clang::frontend::Angled, false, false); headerSearchOptions.AddPath("/usr/local/lib/clang/3.5.0/include", clang::frontend::Angled, false, false); headerSearchOptions.AddPath("/usr/include/i386-linux-gnu", clang::frontend::Angled, false, false); headerSearchOptions.AddPath("/usr/include", clang::frontend::Angled, false, false); /* headerSearchOptions.AddPath("/usr/include", clang::frontend::Angled, false, false); */ //langOptions设置,要传给rewriter LangOptions langOpts; langOpts.GNUMode = 1; langOpts.CXXExceptions = 1; langOpts.RTTI = 1; langOpts.Bool = 1; langOpts.CPlusPlus = 1; Invocation->setLangDefaults(langOpts, clang::IK_CXX,clang::LangStandard::lang_cxx0x); //create PP compiler.createPreprocessor();//(TU_Complete);// compiler.getPreprocessorOpts().UsePredefines = false; //createASTContext compiler.createASTContext(); //set the sourceManager for rewriter rewrite.setSourceMgr(compiler.getSourceManager(), compiler.getLangOpts()); //插装文件入口 const FileEntry *pFile = compiler.getFileManager().getFile(fileName); compiler.getSourceManager().createMainFileID(pFile); compiler.getDiagnosticClient().BeginSourceFile(compiler.getLangOpts(),&compiler.getPreprocessor()); MyASTConsumer astConsumer(rewrite); //将.c转成_out.c // Convert <file>.c to <file_out>.c std::string outName (fileName); /*size_t ext = outName.rfind("."); //根据有没有找到‘。’来决定在哪里加入_out if (ext == std::string::npos) ext = outName.length(); outName.insert(ext, "_out"); */ outName.insert(outName.length(),"_out"); llvm::errs() << "Output to: " << outName << "\n"; std::string OutErrorInfo; //新建输入到新文件的流 llvm::raw_fd_ostream outFile(outName.c_str(), OutErrorInfo);//,llvm::sys::fs::F_None);//版本问题////// //----此块基本一样 end---- if (OutErrorInfo.empty()){ // Parse the AST //用PP,astConsumer,ASTContext来解释AST ParseAST(compiler.getPreprocessor(), &astConsumer, compiler.getASTContext()); compiler.getDiagnosticClient().EndSourceFile(); //建立ClangTool CommonOptionsParser OptionsParser(argc, argv);//, MyToolCategory); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); //开始匹配 MallocVarPrinter mallocVarPrinter; MatchFinder mallocVarFinder; mallocVarFinder.addMatcher(MallocVarMatcher, &mallocVarPrinter); Tool.run(newFrontendActionFactory(&mallocVarFinder)); MallocPrinter mallocPrinter; MatchFinder mallocFinder; mallocFinder.addMatcher(MallocMatcher, &mallocPrinter); Tool.run(newFrontendActionFactory(&mallocFinder)); FreeVarPrinter freeVarPrinter; MatchFinder freeVarFinder; freeVarFinder.addMatcher(FreeVarMatcher, &freeVarPrinter); Tool.run(newFrontendActionFactory(&freeVarFinder)); FreePrinter freePrinter; MatchFinder freeFinder; freeFinder.addMatcher(FreeMatcher, &freePrinter); Tool.run(newFrontendActionFactory(&freeFinder)); const RewriteBuffer *RewriteBuf =rewrite.getRewriteBufferFor(compiler.getSourceManager().getMainFileID()); if(RewriteBuf != NULL){ #ifdef DEBUG llvm::errs() << " RewriteBuf not NULL \n"; //在文件头加上改头文件,防止没有 stdlib,stdio 而不能使用printf和exit函数 #endif outFile << "#include\"plugHead.h\"\n"; outFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); }else{ #ifdef DEBUG llvm::errs() << " RewriteBuf is NULL \n"; #endif outFile << "#include\"plugHead.h\"\n"; std::ifstream infile(fileName.c_str()); if(!infile){ llvm::errs() << " fail to open the input file!\n"; exit(-1); } std::string str_in; while(std::getline(infile,str_in)){ outFile << str_in <<"\n"; } } outFile.close(); #ifdef DEBUG std::string checkStructErrorInfo; std::string checkStructFileName = "checkStruct.txt"; //新建输入到新文件的流,将已经找到的malloc过的结构体信息写入文件,供另一个处理程序读取 llvm::raw_fd_ostream csFile(checkStructFileName.c_str(),checkStructErrorInfo);//,llvm::sys::fs::F_None); if (checkStructErrorInfo.empty()){ for(unsigned int i=0;i<cpVec.size();++i){ csFile << cpVec[i].name << " " << cpVec[i].row << " " << cpVec[i].col << " " << cpVec[i].declName << " " << cpVec[i].declRow << " " << cpVec[i].declCol << "\n" ; } } csFile.close(); for(unsigned int i=0;i<cpVec.size();++i){ llvm::errs()<<cpVec[i].name<<"|"<<cpVec[i].declName<<":"<<cpVec[i].declRow<<":"<<cpVec[i].declCol<<"\n"; } #endif } else{ llvm::errs() << "Cannot open " << outName << " for writing\n"; } return 0; }
int main(int argc, char *argv[]) { #if 0 vector<string> args; args.push_back("tool-executable"); for (int i = 1; i < argc; ++i) { args.push_back(argv[i]); } parse_with_tool(args); return 0; #endif string user_defines; for (int i = 1; i < argc; ++i) { if (argv[i][0] == '-' && argv[i][1] == 'D') { user_defines += "#define "; char *def = argv[i]+2; char* eq_pos = strchr(def, '='); if (eq_pos) { user_defines += string(def, eq_pos - def); user_defines += " "; user_defines += string(def+1); } else { user_defines += string(def); } user_defines += "\n"; } } if (argc < 2) { llvm::errs() << "Usage: mkapi filename [-Ddefine1 -Ddefine2...]\n"; return 1; } string file(argv[1]); // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance TheCompInst; TheCompInst.createDiagnostics(0, true); //() for clang3.3, (0,0) for clang3.2 // Initialize target info with the default triple for our platform. TargetOptions *TO = new TargetOptions(); //TODO: why on stack crash when dtor called TO->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo( TheCompInst.getDiagnostics(), TO); TheCompInst.setTarget(TI); TheCompInst.createFileManager(); FileManager &FileMgr = TheCompInst.getFileManager(); TheCompInst.createSourceManager(FileMgr); SourceManager &SourceMgr = TheCompInst.getSourceManager(); TheCompInst.createPreprocessor(); TheCompInst.createASTContext(); if (!user_defines.empty()) { clang::Preprocessor &PP = TheCompInst.getPreprocessor(); PP.setPredefines(PP.getPredefines() + user_defines); } //cout << "predefines: " << TheCompInst.getPreprocessor().getPredefines() << endl; // A Rewriter helps us manage the code rewriting task. Rewriter TheRewriter; TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts()); // Set the main file handled by the source manager to the input file. const FileEntry *FileIn = FileMgr.getFile(file); SourceMgr.createMainFileID(FileIn); TheCompInst.getDiagnosticClient().BeginSourceFile( TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor()); // Create an AST consumer instance which is going to get called by // ParseAST. MkApiASTConsumer TheConsumer(TheRewriter); // Parse the file to AST, registering our consumer as the AST consumer. ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext() , clang::TU_Complete); // At this point the rewriter's buffer should be full with the rewritten // file contents. #if 0 const RewriteBuffer *RewriteBuf = TheRewriter.getRewriteBufferFor(SourceMgr.getMainFileID()); llvm::outs() << string(RewriteBuf->begin(), RewriteBuf->end()); #endif std::vector<func_info> fi = TheConsumer.GetFuncInfo(); stringstream stream; for (std::vector<func_info>::const_iterator it = fi.begin(); it != fi.end(); ++it) { std::vector<std::string> params = (*it).argv; stream << "DEFINE_DLLAPI_ARG(" << params.size() << ", " << (*it).return_type << ", " << (*it).name; for (int i = 0; i < params.size(); ++i) { stream << ", " << params[i]; } stream << ")" << endl; } cout << stream.str() << endl; return 0; }
bool FrontendAction::BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &RealInput) { FrontendInputFile Input(RealInput); assert(!Instance && "Already processing a source file!"); assert(!Input.isEmpty() && "Unexpected empty filename!"); setCurrentInput(Input); setCompilerInstance(&CI); StringRef InputFile = Input.getFile(); bool HasBegunSourceFile = false; bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled && usesPreprocessorOnly(); if (!BeginInvocation(CI)) goto failure; // If we're replaying the build of an AST file, import it and set up // the initial state from its build. if (ReplayASTFile) { IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); // The AST unit populates its own diagnostics engine rather than ours. IntrusiveRefCntPtr<DiagnosticsEngine> ASTDiags( new DiagnosticsEngine(Diags->getDiagnosticIDs(), &Diags->getDiagnosticOptions())); ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false); std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( InputFile, CI.getPCHContainerReader(), ASTUnit::LoadPreprocessorOnly, ASTDiags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs); if (!AST) goto failure; // Options relating to how we treat the input (but not what we do with it) // are inherited from the AST unit. CI.getHeaderSearchOpts() = AST->getHeaderSearchOpts(); CI.getPreprocessorOpts() = AST->getPreprocessorOpts(); CI.getLangOpts() = AST->getLangOpts(); // Set the shared objects, these are reset when we finish processing the // file, otherwise the CompilerInstance will happily destroy them. CI.setFileManager(&AST->getFileManager()); CI.createSourceManager(CI.getFileManager()); CI.getSourceManager().initializeForReplay(AST->getSourceManager()); // Preload all the module files loaded transitively by the AST unit. Also // load all module map files that were parsed as part of building the AST // unit. if (auto ASTReader = AST->getASTReader()) { auto &MM = ASTReader->getModuleManager(); auto &PrimaryModule = MM.getPrimaryModule(); for (ModuleFile &MF : MM) if (&MF != &PrimaryModule) CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName); ASTReader->visitTopLevelModuleMaps(PrimaryModule, [&](const FileEntry *FE) { CI.getFrontendOpts().ModuleMapFiles.push_back(FE->getName()); }); } // Set up the input file for replay purposes. auto Kind = AST->getInputKind(); if (Kind.getFormat() == InputKind::ModuleMap) { Module *ASTModule = AST->getPreprocessor().getHeaderSearchInfo().lookupModule( AST->getLangOpts().CurrentModule, /*AllowSearch*/ false); assert(ASTModule && "module file does not define its own module"); Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind); } else { auto &SM = CI.getSourceManager(); FileID ID = SM.getMainFileID(); if (auto *File = SM.getFileEntryForID(ID)) Input = FrontendInputFile(File->getName(), Kind); else Input = FrontendInputFile(SM.getBuffer(ID), Kind); } setCurrentInput(Input, std::move(AST)); } // AST files follow a very different path, since they share objects via the // AST unit. if (Input.getKind().getFormat() == InputKind::Precompiled) { assert(!usesPreprocessorOnly() && "this case was handled above"); assert(hasASTFileSupport() && "This action does not have AST file support!"); IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( InputFile, CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs); if (!AST) goto failure; // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); HasBegunSourceFile = true; // Set the shared objects, these are reset when we finish processing the // file, otherwise the CompilerInstance will happily destroy them. CI.setFileManager(&AST->getFileManager()); CI.setSourceManager(&AST->getSourceManager()); CI.setPreprocessor(AST->getPreprocessorPtr()); Preprocessor &PP = CI.getPreprocessor(); PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), PP.getLangOpts()); CI.setASTContext(&AST->getASTContext()); setCurrentInput(Input, std::move(AST)); // Initialize the action. if (!BeginSourceFileAction(CI)) goto failure; // Create the AST consumer. CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile)); if (!CI.hasASTConsumer()) goto failure; return true; } // Set up the file and source managers, if needed. if (!CI.hasFileManager()) { if (!CI.createFileManager()) { goto failure; } } if (!CI.hasSourceManager()) CI.createSourceManager(CI.getFileManager()); // Set up embedding for any specified files. Do this before we load any // source files, including the primary module map for the compilation. for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) { if (const auto *FE = CI.getFileManager().getFile(F, /*openFile*/true)) CI.getSourceManager().setFileIsTransient(FE); else CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F; } if (CI.getFrontendOpts().ModulesEmbedAllFiles) CI.getSourceManager().setAllFilesAreTransient(true); // IR files bypass the rest of initialization. if (Input.getKind().getLanguage() == InputKind::LLVM_IR) { assert(hasIRSupport() && "This action does not have IR file support!"); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); HasBegunSourceFile = true; // Initialize the action. if (!BeginSourceFileAction(CI)) goto failure; // Initialize the main file entry. if (!CI.InitializeSourceManager(CurrentInput)) goto failure; return true; } // If the implicit PCH include is actually a directory, rather than // a single file, search for a suitable PCH file in that directory. if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { FileManager &FileMgr = CI.getFileManager(); PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); StringRef PCHInclude = PPOpts.ImplicitPCHInclude; std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath(); if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) { std::error_code EC; SmallString<128> DirNative; llvm::sys::path::native(PCHDir->getName(), DirNative); bool Found = false; vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { // Check whether this is an acceptable AST file. if (ASTReader::isAcceptableASTFile( Dir->getName(), FileMgr, CI.getPCHContainerReader(), CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(), SpecificModuleCachePath)) { PPOpts.ImplicitPCHInclude = Dir->getName(); Found = true; break; } } if (!Found) { CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude; goto failure; } } } // Set up the preprocessor if needed. When parsing model files the // preprocessor of the original source is reused. if (!isModelParsingAction()) CI.createPreprocessor(getTranslationUnitKind()); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), &CI.getPreprocessor()); HasBegunSourceFile = true; // Initialize the main file entry. if (!CI.InitializeSourceManager(Input)) goto failure; // For module map files, we first parse the module map and synthesize a // "<module-includes>" buffer before more conventional processing. if (Input.getKind().getFormat() == InputKind::ModuleMap) { CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap); std::string PresumedModuleMapFile; unsigned OffsetToContents; if (loadModuleMapForModuleBuild(CI, Input.isSystem(), Input.isPreprocessed(), PresumedModuleMapFile, OffsetToContents)) goto failure; auto *CurrentModule = prepareToBuildModule(CI, Input.getFile()); if (!CurrentModule) goto failure; CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile; if (OffsetToContents) // If the module contents are in the same file, skip to them. CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true); else { // Otherwise, convert the module description to a suitable input buffer. auto Buffer = getInputBufferForModule(CI, CurrentModule); if (!Buffer) goto failure; // Reinitialize the main file entry to refer to the new input. auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User; auto &SourceMgr = CI.getSourceManager(); auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind); assert(BufferID.isValid() && "couldn't creaate module buffer ID"); SourceMgr.setMainFileID(BufferID); } } // Initialize the action. if (!BeginSourceFileAction(CI)) goto failure; // If we were asked to load any module map files, do so now. for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) { if (auto *File = CI.getFileManager().getFile(Filename)) CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile( File, /*IsSystem*/false); else CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename; } // Add a module declaration scope so that modules from -fmodule-map-file // arguments may shadow modules found implicitly in search paths. CI.getPreprocessor() .getHeaderSearchInfo() .getModuleMap() .finishModuleDeclarationScope(); // Create the AST context and consumer unless this is a preprocessor only // action. if (!usesPreprocessorOnly()) { // Parsing a model file should reuse the existing ASTContext. if (!isModelParsingAction()) CI.createASTContext(); // For preprocessed files, check if the first line specifies the original // source file name with a linemarker. std::string PresumedInputFile = InputFile; if (Input.isPreprocessed()) ReadOriginalFileName(CI, PresumedInputFile); std::unique_ptr<ASTConsumer> Consumer = CreateWrappedASTConsumer(CI, PresumedInputFile); if (!Consumer) goto failure; // FIXME: should not overwrite ASTMutationListener when parsing model files? if (!isModelParsingAction()) CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { // Convert headers to PCH and chain them. IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader; source = createChainedIncludesSource(CI, FinalReader); if (!source) goto failure; CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get())); CI.getASTContext().setExternalSource(source); } else if (CI.getLangOpts().Modules || !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { // Use PCM or PCH. assert(hasPCHSupport() && "This action does not have PCH support!"); ASTDeserializationListener *DeserialListener = Consumer->GetASTDeserializationListener(); bool DeleteDeserialListener = false; if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) { DeserialListener = new DeserializedDeclsDumper(DeserialListener, DeleteDeserialListener); DeleteDeserialListener = true; } if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) { DeserialListener = new DeserializedDeclsChecker( CI.getASTContext(), CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, DeserialListener, DeleteDeserialListener); DeleteDeserialListener = true; } if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { CI.createPCHExternalASTSource( CI.getPreprocessorOpts().ImplicitPCHInclude, CI.getPreprocessorOpts().DisablePCHValidation, CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener, DeleteDeserialListener); if (!CI.getASTContext().getExternalSource()) goto failure; } // If modules are enabled, create the module manager before creating // any builtins, so that all declarations know that they might be // extended by an external source. if (CI.getLangOpts().Modules || !CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { CI.createModuleManager(); CI.getModuleManager()->setDeserializationListener(DeserialListener, DeleteDeserialListener); } } CI.setASTConsumer(std::move(Consumer)); if (!CI.hasASTConsumer()) goto failure; } // Initialize built-in info as long as we aren't using an external AST // source. if (CI.getLangOpts().Modules || !CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { Preprocessor &PP = CI.getPreprocessor(); PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), PP.getLangOpts()); } else { // FIXME: If this is a problem, recover from it by creating a multiplex // source. assert((!CI.getLangOpts().Modules || CI.getModuleManager()) && "modules enabled but created an external source that " "doesn't support modules"); } // If we were asked to load any module files, do so now. for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) if (!CI.loadModuleFile(ModuleFile)) goto failure; // If there is a layout overrides file, attach an external AST source that // provides the layouts from that file. if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { IntrusiveRefCntPtr<ExternalASTSource> Override(new LayoutOverrideSource( CI.getFrontendOpts().OverrideRecordLayoutsFile)); CI.getASTContext().setExternalSource(Override); } return true; // If we failed, reset state since the client will not end up calling the // matching EndSourceFile(). failure: if (HasBegunSourceFile) CI.getDiagnosticClient().EndSourceFile(); CI.clearOutputFiles(/*EraseFiles=*/true); CI.getLangOpts().setCompilingModule(LangOptions::CMK_None); setCurrentInput(FrontendInputFile()); setCompilerInstance(nullptr); return false; }
bool FrontendAction::BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input) { assert(!Instance && "Already processing a source file!"); assert(!Input.isEmpty() && "Unexpected empty filename!"); setCurrentInput(Input); setCompilerInstance(&CI); StringRef InputFile = Input.getFile(); bool HasBegunSourceFile = false; if (!BeginInvocation(CI)) goto failure; // AST files follow a very different path, since they share objects via the // AST unit. if (Input.getKind() == IK_AST) { assert(!usesPreprocessorOnly() && "Attempt to pass AST file to preprocessor only action!"); assert(hasASTFileSupport() && "This action does not have AST file support!"); IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); ASTUnit *AST = ASTUnit::LoadFromASTFile(InputFile, Diags, CI.getFileSystemOpts()); if (!AST) goto failure; setCurrentInput(Input, AST); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); HasBegunSourceFile = true; // Set the shared objects, these are reset when we finish processing the // file, otherwise the CompilerInstance will happily destroy them. CI.setFileManager(&AST->getFileManager()); CI.setSourceManager(&AST->getSourceManager()); CI.setPreprocessor(&AST->getPreprocessor()); CI.setASTContext(&AST->getASTContext()); // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; // Create the AST consumer. CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile)); if (!CI.hasASTConsumer()) goto failure; return true; } // Set up the file and source managers, if needed. if (!CI.hasFileManager()) CI.createFileManager(); if (!CI.hasSourceManager()) CI.createSourceManager(CI.getFileManager()); // IR files bypass the rest of initialization. if (Input.getKind() == IK_LLVM_IR) { assert(hasIRSupport() && "This action does not have IR file support!"); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); HasBegunSourceFile = true; // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; return true; } // If the implicit PCH include is actually a directory, rather than // a single file, search for a suitable PCH file in that directory. if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { FileManager &FileMgr = CI.getFileManager(); PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); StringRef PCHInclude = PPOpts.ImplicitPCHInclude; if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) { llvm::error_code EC; SmallString<128> DirNative; llvm::sys::path::native(PCHDir->getName(), DirNative); bool Found = false; for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { // Check whether this is an acceptable AST file. if (ASTReader::isAcceptableASTFile(Dir->path(), FileMgr, CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts())) { PPOpts.ImplicitPCHInclude = Dir->path(); Found = true; break; } } if (!Found) { CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude; return true; } } } // Set up the preprocessor. CI.createPreprocessor(); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), &CI.getPreprocessor()); HasBegunSourceFile = true; // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; // Create the AST context and consumer unless this is a preprocessor only // action. if (!usesPreprocessorOnly()) { CI.createASTContext(); OwningPtr<ASTConsumer> Consumer( CreateWrappedASTConsumer(CI, InputFile)); if (!Consumer) goto failure; CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { // Convert headers to PCH and chain them. OwningPtr<ExternalASTSource> source; source.reset(ChainedIncludesSource::create(CI)); if (!source) goto failure; CI.setModuleManager(static_cast<ASTReader*>( &static_cast<ChainedIncludesSource*>(source.get())->getFinalReader())); CI.getASTContext().setExternalSource(source); } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { // Use PCH. assert(hasPCHSupport() && "This action does not have PCH support!"); ASTDeserializationListener *DeserialListener = Consumer->GetASTDeserializationListener(); if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) DeserialListener = new DeserializedDeclsDumper(DeserialListener); if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(), CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, DeserialListener); CI.createPCHExternalASTSource( CI.getPreprocessorOpts().ImplicitPCHInclude, CI.getPreprocessorOpts().DisablePCHValidation, CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener); if (!CI.getASTContext().getExternalSource()) goto failure; } CI.setASTConsumer(Consumer.take()); if (!CI.hasASTConsumer()) goto failure; } // Initialize built-in info as long as we aren't using an external AST // source. if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { Preprocessor &PP = CI.getPreprocessor(); PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), PP.getLangOpts()); } // If there is a layout overrides file, attach an external AST source that // provides the layouts from that file. if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { OwningPtr<ExternalASTSource> Override(new LayoutOverrideSource( CI.getFrontendOpts().OverrideRecordLayoutsFile)); CI.getASTContext().setExternalSource(Override); } return true; // If we failed, reset state since the client will not end up calling the // matching EndSourceFile(). failure: if (isCurrentFileAST()) { CI.setASTContext(0); CI.setPreprocessor(0); CI.setSourceManager(0); CI.setFileManager(0); } if (HasBegunSourceFile) CI.getDiagnosticClient().EndSourceFile(); CI.clearOutputFiles(/*EraseFiles=*/true); setCurrentInput(FrontendInputFile()); setCompilerInstance(0); return false; }
int main(int argc, char *argv[]) { if (argc != 2) { llvm::errs() << "Usage: kcov-branch-identify <filename>\n"; return 1; } // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance TheCompInst; // Diagnostics manage problems and issues in compile TheCompInst.createDiagnostics(NULL, false); // Set target platform options // Initialize target info with the default triple for our platform. TargetOptions *TO = new TargetOptions(); TO->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO); TheCompInst.setTarget(TI); // FileManager supports for file system lookup, file system caching, and directory search management. TheCompInst.createFileManager(); FileManager &FileMgr = TheCompInst.getFileManager(); // SourceManager handles loading and caching of source files into memory. TheCompInst.createSourceManager(FileMgr); SourceManager &SourceMgr = TheCompInst.getSourceManager(); //global var m_srcmgr //m_srcmgr = &SourceMgr; // Prreprocessor runs within a single source file TheCompInst.createPreprocessor(); // ASTContext holds long-lived AST nodes (such as types and decls) . TheCompInst.createASTContext(); // Enable HeaderSearch option llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> hso( new HeaderSearchOptions()); HeaderSearch headerSearch(hso, TheCompInst.getFileManager(), TheCompInst.getDiagnostics(), TheCompInst.getLangOpts(), TI); // <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. /* $ gcc -xc -E -v - .. /usr/local/include /usr/lib/gcc/x86_64-linux-gnu/4.4.5/include /usr/lib/gcc/x86_64-linux-gnu/4.4.5/include-fixed /usr/include End of search list. */ const char *include_paths[] = {"/usr/local/include", "/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include", "/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include-fixed", "/usr/include"}; for (int i=0; i<4; i++) hso->AddPath(include_paths[i], clang::frontend::Angled, false, false); // </Warning!!> -- End of Platform Specific Code InitializePreprocessor(TheCompInst.getPreprocessor(), TheCompInst.getPreprocessorOpts(), *hso, TheCompInst.getFrontendOpts()); // A Rewriter helps us manage the code rewriting task. Rewriter TheRewriter; TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts()); // Set the main file handled by the source manager to the input file. const FileEntry *FileIn = FileMgr.getFile(argv[1]); SourceMgr.createMainFileID(FileIn); // Inform Diagnostics that processing of a source file is beginning. TheCompInst.getDiagnosticClient().BeginSourceFile(TheCompInst.getLangOpts(),&TheCompInst.getPreprocessor()); // Create an AST consumer instance which is going to get called by ParseAST. MyASTConsumer TheConsumer(SourceMgr); // Parse the file to AST, registering our consumer as the AST consumer. ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext()); TheConsumer.printBranchNum(); return 0; }
int main(int argc, char *argv[] ) { type_for_quoting[ "void" ] = 1; type_for_quoting[ "bool" ] = 1; type_for_quoting[ "char" ] = 1; type_for_quoting[ "wchar_t" ] = 1; type_for_quoting[ "short" ] = 1; type_for_quoting[ "long" ] = 1; type_for_quoting[ "size_t" ] = 1; type_for_quoting[ "int8_t" ] = 1; type_for_quoting[ "int16_t" ] = 1; type_for_quoting[ "int32_t" ] = 1; type_for_quoting[ "int64_t" ] = 1; type_for_quoting[ "uint8_t" ] = 1; type_for_quoting[ "uint16_t" ] = 1; type_for_quoting[ "uint32_t" ] = 1; type_for_quoting[ "uint64_t" ] = 1; type_substitutions[ "_Bool" ] = "bool"; size_t i; cl::ParseCommandLineOptions( argc, argv, "ClangDao: Clang-based automatic binding tool for Dao." ); if (!ignored_arguments.empty()) { errs() << "Ignoring the following arguments:"; copy(ignored_arguments.begin(), ignored_arguments.end(), std::ostream_iterator<std::string>(std::cerr, " ")); } CompilerInstance compiler; CDaoModule module( & compiler, main_input_file ); compiler.createDiagnostics(); //compiler.getInvocation().setLangDefaults(IK_CXX); //compiler.getInvocation().setLangDefaults(IK_ObjC); CompilerInvocation::CreateFromArgs( compiler.getInvocation(), argv + 1, argv + argc, compiler.getDiagnostics() ); std::shared_ptr<TargetOptions> taropts( new TargetOptions( compiler.getTargetOpts() ) ); compiler.setTarget( TargetInfo::CreateTargetInfo( compiler.getDiagnostics(), taropts ) ); compiler.createFileManager(); compiler.createSourceManager(compiler.getFileManager()); compiler.createPreprocessor( TU_Complete ); compiler.createASTContext(); std::unique_ptr<ASTConsumer> astConsumer( new CDaoASTConsumer( & compiler, & module ) ); compiler.setASTConsumer( std::move(astConsumer) ); //XXX compiler.createSema(false, NULL); //compiler.createSema(TU_Module, NULL); compiler.createSema(TU_Prefix, NULL); Preprocessor & pp = compiler.getPreprocessor(); //outs()<<pp.getPredefines()<<"\n"; string builtinDefines = pp.getPredefines(); #if 1 ClangDao_RemoveDefine( builtinDefines, "#define __APPLE_CC__" ); ClangDao_RemoveDefine( builtinDefines, "#define __APPLE__" ); ClangDao_RemoveDefine( builtinDefines, "#define __MACH__" ); ClangDao_RemoveDefine( builtinDefines, "#define __ENVIRONMENT_MAC_OS_X" ); ClangDao_RemoveDefine( builtinDefines, "#define OBJC_" ); #endif //outs()<<builtinDefines<<"\n"; std::unique_ptr<PPCallbacks> ppCallbacks( new CDaoPPCallbacks( & compiler, & module ) ); pp.setPredefines( builtinDefines + "\n" + predefines + "\n#define __CLANGDAO__\n" ); pp.addPPCallbacks( std::move( ppCallbacks ) ); InputKind ik = FrontendOptions::getInputKindForExtension( main_input_file ); compiler.InitializeSourceManager( FrontendInputFile( main_input_file, ik ) ); compiler.getDiagnosticClient().BeginSourceFile( compiler.getLangOpts(), & pp ); ParseAST( pp, &compiler.getASTConsumer(), compiler.getASTContext() ); compiler.getDiagnosticClient().EndSourceFile(); return module.Generate( output_dir ); }