std::vector<ASTMemoryUsage> TranslationUnitManager::GetMemoryUsageForProjectFile(ProjectFile* file) { ASTUnit* tu = GetASTUnitForProjectFile(file); std::vector<ASTMemoryUsage> usages; if (tu) { //AST Context ASTContext& ctx = tu->getASTContext(); usages.emplace_back(AST_Nodes, ctx.getASTAllocatedMemory()); usages.emplace_back(AST_Identifiers, ctx.Idents.getAllocator().getTotalMemory()); usages.emplace_back(AST_Selectors, ctx.Selectors.getTotalMemory()); usages.emplace_back(AST_SideTables, ctx.getSideTableAllocatedMemory()); //Source Manager usages.emplace_back(SM_ContentCache, ctx.getSourceManager().getContentCacheSize()); const SourceManager::MemoryBufferSizes& srcBufs = tu->getSourceManager().getMemoryBufferSizes(); usages.emplace_back(SM_Malloc, srcBufs.malloc_bytes); usages.emplace_back(SM_Mmap, srcBufs.mmap_bytes); usages.emplace_back(SM_DataStructures, tu->getSourceManager().getDataStructureSizes()); // Preprocessor Preprocessor& PP = tu->getPreprocessor(); usages.emplace_back(PP_Total, PP.getTotalMemory()); usages.emplace_back(PP_HeaderSearch, PP.getHeaderSearchInfo().getTotalMemory()); if (PP.getPreprocessorOpts().DetailedRecord) usages.emplace_back(ASTMemoryUsage(PP_PreprocessingRecord, PP.getPreprocessingRecord()->getTotalMemory())); } return usages; }
static bool findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor, const FileEntry *File, CXCursorAndRangeVisitor Visitor) { if (Cursor.kind != CXCursor_MacroDefinition && Cursor.kind != CXCursor_MacroExpansion) return false; ASTUnit *Unit = cxtu::getASTUnit(TU); SourceManager &SM = Unit->getSourceManager(); FileID FID = SM.translateFile(File); const IdentifierInfo *Macro = 0; if (Cursor.kind == CXCursor_MacroDefinition) Macro = getCursorMacroDefinition(Cursor)->getName(); else Macro = getCursorMacroExpansion(Cursor).getName(); if (!Macro) return false; FindFileMacroRefVisitData data(*Unit, File, Macro, Visitor); SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID)); CursorVisitor FindMacroRefsVisitor(TU, findFileMacroRefVisit, &data, /*VisitPreprocessorLast=*/false, /*VisitIncludedEntities=*/false, Range); return FindMacroRefsVisitor.visitPreprocessedEntitiesInRegion(); }
static void getInclusions(const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsigned, bool*) const, unsigned n, CXTranslationUnit TU, CXInclusionVisitor CB, CXClientData clientData) { ASTUnit *CXXUnit = cxtu::getASTUnit(TU); SourceManager &SM = CXXUnit->getSourceManager(); ASTContext &Ctx = CXXUnit->getASTContext(); SmallVector<CXSourceLocation, 10> InclusionStack; const bool HasPreamble = SM.getPreambleFileID().isValid(); for (unsigned i = 0 ; i < n ; ++i) { bool Invalid = false; const SrcMgr::SLocEntry &SL = (SM.*Getter)(i, &Invalid); if (!SL.isFile() || Invalid) continue; const SrcMgr::FileInfo &FI = SL.getFile(); if (!FI.getContentCache()->OrigEntry) continue; // If this is the main file, and there is a preamble, skip this SLoc. The // inclusions of the preamble already showed it. SourceLocation L = FI.getIncludeLoc(); if (HasPreamble && CXXUnit->isInMainFileID(L)) continue; // Build the inclusion stack. InclusionStack.clear(); while (L.isValid()) { PresumedLoc PLoc = SM.getPresumedLoc(L); InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L)); L = PLoc.isValid()? PLoc.getIncludeLoc() : SourceLocation(); } // If there is a preamble, the last entry is the "inclusion" of that // preamble into the main file, which has the bogus entry of main.c:1:1 if (HasPreamble && !InclusionStack.empty()) InclusionStack.pop_back(); // Callback to the client. // FIXME: We should have a function to construct CXFiles. CB(static_cast<CXFile>( const_cast<FileEntry *>(FI.getContentCache()->OrigEntry)), InclusionStack.data(), InclusionStack.size(), clientData); } }
CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU, bool checkIfChanged) { ASTUnit *AU = static_cast<ASTUnit *>(TU->TUData); if (TU->Diagnostics && checkIfChanged) { // In normal use, ASTUnit's diagnostics should not change unless we reparse. // Currently they can only change by using the internal testing flag // '-error-on-deserialized-decl' which will error during deserialization of // a declaration. What will happen is: // // -c-index-test gets a CXTranslationUnit // -checks the diagnostics, the diagnostics set is lazily created, // no errors are reported // -later does an operation, like annotation of tokens, that triggers // -error-on-deserialized-decl, that will emit a diagnostic error, // that ASTUnit will catch and add to its stored diagnostics vector. // -c-index-test wants to check whether an error occurred after performing // the operation but can only query the lazily created set. // // We check here if a new diagnostic was appended since the last time the // diagnostic set was created, in which case we reset it. CXDiagnosticSetImpl * Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics); if (AU->stored_diag_size() != Set->getNumDiagnostics()) { // Diagnostics in the ASTUnit were updated, reset the associated // diagnostics. delete Set; TU->Diagnostics = 0; } } if (!TU->Diagnostics) { CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl(); TU->Diagnostics = Set; DiagnosticOptions DOpts; CXDiagnosticRenderer Renderer(AU->getSourceManager(), AU->getASTContext().getLangOpts(), DOpts, Set); for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(), ei = AU->stored_diag_end(); it != ei; ++it) { Renderer.emitStoredDiagnostic(*it); } } return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics); }
void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB, CXClientData clientData) { ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); SourceManager &SM = CXXUnit->getSourceManager(); ASTContext &Ctx = CXXUnit->getASTContext(); llvm::SmallVector<CXSourceLocation, 10> InclusionStack; unsigned i = SM.sloc_loaded_entry_size(); unsigned n = SM.sloc_entry_size(); // In the case where all the SLocEntries are in an external source, traverse // those SLocEntries as well. This is the case where we are looking // at the inclusion stack of an AST/PCH file. if (i >= n) i = 0; for ( ; i < n ; ++i) { const SrcMgr::SLocEntry &SL = SM.getSLocEntry(i); if (!SL.isFile()) continue; const SrcMgr::FileInfo &FI = SL.getFile(); if (!FI.getContentCache()->Entry) continue; // Build the inclusion stack. SourceLocation L = FI.getIncludeLoc(); InclusionStack.clear(); while (L.isValid()) { PresumedLoc PLoc = SM.getPresumedLoc(L); InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L)); L = PLoc.getIncludeLoc(); } // Callback to the client. // FIXME: We should have a function to construct CXFiles. CB((CXFile) FI.getContentCache()->Entry, InclusionStack.data(), InclusionStack.size(), clientData); } }
static bool findIncludesInFile(CXTranslationUnit TU, const FileEntry *File, CXCursorAndRangeVisitor Visitor) { assert(TU && File && Visitor.visit); ASTUnit *Unit = cxtu::getASTUnit(TU); SourceManager &SM = Unit->getSourceManager(); FileID FID = SM.translateFile(File); FindFileIncludesVisitor IncludesVisitor(*Unit, File, Visitor); SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID)); CursorVisitor InclusionCursorsVisitor(TU, FindFileIncludesVisitor::visit, &IncludesVisitor, /*VisitPreprocessorLast=*/false, /*VisitIncludedEntities=*/false, Range); return InclusionCursorsVisitor.visitPreprocessedEntitiesInRegion(); }
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; }
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 MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { unsigned MatchCount = 0; for (llvm::ArrayRef<ASTUnit *>::iterator I = QS.ASTs.begin(), E = QS.ASTs.end(); I != E; ++I) { ASTUnit *AST = *I; MatchFinder Finder; std::vector<BoundNodes> Matches; DynTypedMatcher MaybeBoundMatcher = Matcher; if (QS.BindRoot) { llvm::Optional<DynTypedMatcher> M = Matcher.tryBind("root"); if (M) MaybeBoundMatcher = *M; } CollectBoundNodes Collect(Matches); if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) { OS << "Not a valid top-level matcher.\n"; return false; } Finder.matchAST(AST->getASTContext()); for (std::vector<BoundNodes>::iterator MI = Matches.begin(), ME = Matches.end(); MI != ME; ++MI) { OS << "\nMatch #" << ++MatchCount << ":\n\n"; for (BoundNodes::IDToNodeMap::const_iterator BI = MI->getMap().begin(), BE = MI->getMap().end(); BI != BE; ++BI) { switch (QS.OutKind) { case OK_Diag: { clang::SourceRange R = BI->second.getSourceRange(); if (R.isValid()) { TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(), &AST->getDiagnostics().getDiagnosticOptions()); TD.emitDiagnostic( R.getBegin(), DiagnosticsEngine::Note, "\"" + BI->first + "\" binds here", ArrayRef<CharSourceRange>(CharSourceRange::getTokenRange(R)), ArrayRef<FixItHint>(), &AST->getSourceManager()); } break; } case OK_Print: { OS << "Binding for \"" << BI->first << "\":\n"; BI->second.print(OS, AST->getASTContext().getPrintingPolicy()); OS << "\n"; break; } case OK_Dump: { OS << "Binding for \"" << BI->first << "\":\n"; BI->second.dump(OS, AST->getSourceManager()); OS << "\n"; break; } } } if (MI->getMap().empty()) OS << "No bindings.\n"; } } OS << MatchCount << (MatchCount == 1 ? " match.\n" : " matches.\n"); return true; }
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; }