nik updated this revision to Diff 144303. nik added a comment. Reduction to skip-in-preamble-only functionality.
Repository: rC Clang https://reviews.llvm.org/D45815 Files: include/clang-c/Index.h include/clang/Frontend/ASTUnit.h lib/Frontend/ASTUnit.cpp test/Parser/skip-function-bodies.h test/Parser/skip-function-bodies.mm tools/c-index-test/c-index-test.c tools/libclang/CIndex.cpp unittests/Frontend/PCHPreambleTest.cpp
Index: unittests/Frontend/PCHPreambleTest.cpp =================================================================== --- unittests/Frontend/PCHPreambleTest.cpp +++ unittests/Frontend/PCHPreambleTest.cpp @@ -103,7 +103,9 @@ } bool ReparseAST(const std::unique_ptr<ASTUnit> &AST) { - bool reparseFailed = AST->Reparse(PCHContainerOpts, GetRemappedFiles(), VFS); + bool reparseFailed = + AST->Reparse(PCHContainerOpts, GetRemappedFiles(), + ASTUnit::SkipFunctionBodiesScope::None, VFS); return !reparseFailed; } Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -3346,6 +3346,19 @@ Options); } +static ASTUnit::SkipFunctionBodiesScope +skipFunctionBodiesScopeFromParseOptions(unsigned options) { + ASTUnit::SkipFunctionBodiesScope SkipFunctionBodiesScp = + ASTUnit::SkipFunctionBodiesScope::None; + if (options & CXTranslationUnit_SkipFunctionBodies) { + SkipFunctionBodiesScp = + (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble) + ? ASTUnit::SkipFunctionBodiesScope::Preamble + : ASTUnit::SkipFunctionBodiesScope::MainFileAndPreamble; + } + return SkipFunctionBodiesScp; +} + static CXErrorCode clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename, const char *const *command_line_args, @@ -3376,9 +3389,10 @@ = options & CXTranslationUnit_CacheCompletionResults; bool IncludeBriefCommentsInCodeCompletion = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; - bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies; bool SingleFileParse = options & CXTranslationUnit_SingleFileParse; bool ForSerialization = options & CXTranslationUnit_ForSerialization; + ASTUnit::SkipFunctionBodiesScope SkipFunctionBodiesScp = + skipFunctionBodiesScopeFromParseOptions(options); // Configure the diagnostics. IntrusiveRefCntPtr<DiagnosticsEngine> @@ -3467,7 +3481,7 @@ /*CaptureDiagnostics=*/true, *RemappedFiles.get(), /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses, TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion, - /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse, + /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodiesScp, SingleFileParse, /*UserFilesAreVolatile=*/true, ForSerialization, CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(), &ErrUnit)); @@ -4054,8 +4068,9 @@ RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release())); } - if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(), - *RemappedFiles.get())) + if (!CXXUnit->Reparse( + CXXIdx->getPCHContainerOperations(), *RemappedFiles.get(), + skipFunctionBodiesScopeFromParseOptions(TU->ParsingOptions))) return CXError_Success; if (isASTReadError(CXXUnit)) return CXError_ASTReadError; Index: tools/c-index-test/c-index-test.c =================================================================== --- tools/c-index-test/c-index-test.c +++ tools/c-index-test/c-index-test.c @@ -82,6 +82,8 @@ options |= CXTranslationUnit_CreatePreambleOnFirstParse; if (getenv("CINDEXTEST_KEEP_GOING")) options |= CXTranslationUnit_KeepGoing; + if (getenv("CINDEXTEST_LIMIT_SKIP_FUNCTION_BODIES_TO_PREAMBLE")) + options |= CXTranslationUnit_LimitSkipFunctionBodiesToPreamble; return options; } Index: test/Parser/skip-function-bodies.mm =================================================================== --- test/Parser/skip-function-bodies.mm +++ test/Parser/skip-function-bodies.mm @@ -1,4 +1,4 @@ -// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s | FileCheck %s +#include "skip-function-bodies.h" class A { class B {}; @@ -27,6 +27,7 @@ class K {}; } +// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s | FileCheck %s // CHECK: skip-function-bodies.mm:3:7: ClassDecl=A:3:7 (Definition) Extent=[3:1 - 14:2] // CHECK: skip-function-bodies.mm:4:9: ClassDecl=B:4:9 (Definition) Extent=[4:3 - 4:13] // CHECK: skip-function-bodies.mm:6:1: CXXAccessSpecifier=:6:1 (Definition) Extent=[6:1 - 6:8] @@ -43,3 +44,13 @@ // CHECK-NOT: skip-function-bodies.mm:21:11: TypeRef=class A:3:7 Extent=[21:11 - 21:12] // CHECK: skip-function-bodies.mm:26:6: FunctionDecl=J:26:6 Extent=[26:1 - 26:9] // CHECK-NOT: skip-function-bodies.mm:27:9: ClassDecl=K:27:9 (Definition) Extent=[27:3 - 27:13] + +// RUN: env CINDEXTEST_EDITING=1 \ +// RUN: CINDEXTEST_CREATE_PREAMBLE_ON_FIRST_PARSE=1 \ +// RUN: CINDEXTEST_SKIP_FUNCTION_BODIES=1 \ +// RUN: CINDEXTEST_LIMIT_SKIP_FUNCTION_BODIES_TO_PREAMBLE=1 \ +// RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix=CHECK-PREAMBLE1 %s +// CHECK-PREAMBLE1: skip-function-bodies.h:1:5: FunctionDecl=header1:1:5 Extent=[1:1 - 1:19] +// CHECK-PREAMBLE1-NOT: skip-function-bodies.h:2:3: ReturnStmt= Extent=[2:3 - 2:11] +// CHECK-PREAMBLE1: skip-function-bodies.mm:8:12: StructDecl=C:8:12 (Definition) Extent=[8:5 - 10:6] +// CHECK-PREAMBLE1: skip-function-bodies.mm:9:12: CXXMethod=d:9:12 (Definition) Extent=[9:7 - 9:18] Index: test/Parser/skip-function-bodies.h =================================================================== --- /dev/null +++ test/Parser/skip-function-bodies.h @@ -0,0 +1,3 @@ +int header1(int t) { + return t; +} Index: lib/Frontend/ASTUnit.cpp =================================================================== --- lib/Frontend/ASTUnit.cpp +++ lib/Frontend/ASTUnit.cpp @@ -1271,8 +1271,9 @@ std::unique_ptr<llvm::MemoryBuffer> ASTUnit::getMainBufferWithPrecompiledPreamble( std::shared_ptr<PCHContainerOperations> PCHContainerOps, - const CompilerInvocation &PreambleInvocationIn, - IntrusiveRefCntPtr<vfs::FileSystem> VFS, bool AllowRebuild, + CompilerInvocation &PreambleInvocationIn, + IntrusiveRefCntPtr<vfs::FileSystem> VFS, + SkipFunctionBodiesScope SkipFunctionBodiesScp, bool AllowRebuild, unsigned MaxLines) { auto MainFilePath = PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile(); @@ -1338,9 +1339,18 @@ SimpleTimer PreambleTimer(WantTiming); PreambleTimer.setOutput("Precompiling preamble"); + const bool PreviousSkipFunctionBodies = + PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies; + if (SkipFunctionBodiesScp == SkipFunctionBodiesScope::Preamble) + PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = true; + llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build( PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS, PCHContainerOps, /*StoreInMemory=*/false, Callbacks); + + PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = + PreviousSkipFunctionBodies; + if (NewPreamble) { Preamble = std::move(*NewPreamble); PreambleRebuildCounter = 1; @@ -1615,6 +1625,7 @@ bool ASTUnit::LoadFromCompilerInvocation( std::shared_ptr<PCHContainerOperations> PCHContainerOps, unsigned PrecompilePreambleAfterNParses, + SkipFunctionBodiesScope SkipFunctionBodiesScp, IntrusiveRefCntPtr<vfs::FileSystem> VFS) { if (!Invocation) return true; @@ -1630,8 +1641,8 @@ std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer; if (PrecompilePreambleAfterNParses > 0) { PreambleRebuildCounter = PrecompilePreambleAfterNParses; - OverrideMainBuffer = - getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS); + OverrideMainBuffer = getMainBufferWithPrecompiledPreamble( + PCHContainerOps, *Invocation, VFS, SkipFunctionBodiesScp); getDiagnostics().Reset(); ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); } @@ -1678,6 +1689,7 @@ if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps), PrecompilePreambleAfterNParses, + SkipFunctionBodiesScope::None, AST->FileMgr->getVirtualFileSystem())) return nullptr; return AST; @@ -1691,8 +1703,9 @@ ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName, unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind, bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion, - bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies, - bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization, + bool AllowPCHWithCompilerErrors, + SkipFunctionBodiesScope SkipFunctionBodiesScp, bool SingleFileParse, + bool UserFilesAreVolatile, bool ForSerialization, llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST, IntrusiveRefCntPtr<vfs::FileSystem> VFS) { assert(Diags.get() && "no DiagnosticsEngine was provided"); @@ -1724,7 +1737,8 @@ // Override the resources path. CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; - CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies; + CI->getFrontendOpts().SkipFunctionBodies = + SkipFunctionBodiesScp == SkipFunctionBodiesScope::MainFileAndPreamble; if (ModuleFormat) CI->getHeaderSearchOpts().ModuleFormat = ModuleFormat.getValue(); @@ -1762,6 +1776,7 @@ if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps), PrecompilePreambleAfterNParses, + SkipFunctionBodiesScp, VFS)) { // Some error occurred, if caller wants to examine diagnostics, pass it the // ASTUnit. @@ -1777,6 +1792,7 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, ArrayRef<RemappedFile> RemappedFiles, + SkipFunctionBodiesScope SkipFunctionBodiesScp, IntrusiveRefCntPtr<vfs::FileSystem> VFS) { if (!Invocation) return true; @@ -1806,8 +1822,8 @@ // build a precompiled preamble, do so now. std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer; if (Preamble || PreambleRebuildCounter > 0) - OverrideMainBuffer = - getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS); + OverrideMainBuffer = getMainBufferWithPrecompiledPreamble( + PCHContainerOps, *Invocation, VFS, SkipFunctionBodiesScp); // Clear out the diagnostics state. FileMgr.reset(); @@ -2203,7 +2219,8 @@ llvm::sys::fs::UniqueID MainID = MainStatus->getUniqueID(); if (CompleteFileID == MainID && Line > 1) OverrideMainBuffer = getMainBufferWithPrecompiledPreamble( - PCHContainerOps, Inv, VFS, false, Line - 1); + PCHContainerOps, Inv, VFS, SkipFunctionBodiesScope::None, false, + Line - 1); } } } Index: include/clang/Frontend/ASTUnit.h =================================================================== --- include/clang/Frontend/ASTUnit.h +++ include/clang/Frontend/ASTUnit.h @@ -101,6 +101,8 @@ std::vector<StandaloneFixIt> FixIts; }; + enum class SkipFunctionBodiesScope { None, MainFileAndPreamble, Preamble }; + private: std::shared_ptr<LangOptions> LangOpts; IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; @@ -363,9 +365,11 @@ std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble( std::shared_ptr<PCHContainerOperations> PCHContainerOps, - const CompilerInvocation &PreambleInvocationIn, - IntrusiveRefCntPtr<vfs::FileSystem> VFS, bool AllowRebuild = true, - unsigned MaxLines = 0); + CompilerInvocation &PreambleInvocationIn, + IntrusiveRefCntPtr<vfs::FileSystem> VFS, + SkipFunctionBodiesScope SkipFunctionBodiesScp = + SkipFunctionBodiesScope::None, + bool AllowRebuild = true, unsigned MaxLines = 0); void RealizeTopLevelDeclsFromPreamble(); /// \brief Transfers ownership of the objects (like SourceManager) from @@ -693,6 +697,7 @@ bool LoadFromCompilerInvocation( std::shared_ptr<PCHContainerOperations> PCHContainerOps, unsigned PrecompilePreambleAfterNParses, + SkipFunctionBodiesScope SkipFunctionBodiesScp, IntrusiveRefCntPtr<vfs::FileSystem> VFS); public: @@ -801,9 +806,11 @@ TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, bool IncludeBriefCommentsInCodeCompletion = false, - bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false, - bool SingleFileParse = false, - bool UserFilesAreVolatile = false, bool ForSerialization = false, + bool AllowPCHWithCompilerErrors = false, + SkipFunctionBodiesScope SkipFunctionBodiesScp = + SkipFunctionBodiesScope::None, + bool SingleFileParse = false, bool UserFilesAreVolatile = false, + bool ForSerialization = false, llvm::Optional<StringRef> ModuleFormat = llvm::None, std::unique_ptr<ASTUnit> *ErrAST = nullptr, IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr); @@ -821,6 +828,8 @@ /// contain any translation-unit information, false otherwise. bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, ArrayRef<RemappedFile> RemappedFiles = None, + SkipFunctionBodiesScope SkipFunctionBodiesScp = + SkipFunctionBodiesScope::None, IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr); /// \brief Free data that will be re-generated on the next parse. Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -1324,7 +1324,15 @@ /** * \brief Sets the preprocessor in a mode for parsing a single file only. */ - CXTranslationUnit_SingleFileParse = 0x400 + CXTranslationUnit_SingleFileParse = 0x400, + + /** + * \brief Used in combination with CXTranslationUnit_SkipFunctionBodies to + * constrain the skipping of function bodies to the preamble. + * + * The function bodies of the main file are not skipped. + */ + CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800, }; /**
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits