diff options
-rw-r--r-- | clang/include/clang-c/Index.h | 10 | ||||
-rw-r--r-- | clang/include/clang/Frontend/ASTUnit.h | 16 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 17 | ||||
-rw-r--r-- | clang/test/Parser/skip-function-bodies.h | 3 | ||||
-rw-r--r-- | clang/test/Parser/skip-function-bodies.mm | 13 | ||||
-rw-r--r-- | clang/tools/c-index-test/c-index-test.c | 2 | ||||
-rw-r--r-- | clang/tools/libclang/CIndex.cpp | 8 |
7 files changed, 59 insertions, 10 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 3fee13a40b4..ff14d6e729a 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -1324,7 +1324,15 @@ enum CXTranslationUnit_Flags { /** * 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 }; /** diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index af67dd1aedc..35cacee57f7 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -81,6 +81,9 @@ class FileSystem; } // namespace vfs +/// \brief Enumerates the available scopes for skipping function bodies. +enum class SkipFunctionBodiesScope { None, Preamble, PreambleAndMainFile }; + /// Utility class for loading a ASTContext from an AST file. class ASTUnit { public: @@ -348,6 +351,9 @@ private: /// inconsistent state, and is not safe to free. unsigned UnsafeToFree : 1; + /// \brief Enumerator specifying the scope for skipping function bodies. + SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None; + /// Cache any "global" code-completion results, so that we can avoid /// recomputing them with each completion. void CacheCodeCompletionResults(); @@ -363,7 +369,7 @@ private: std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble( std::shared_ptr<PCHContainerOperations> PCHContainerOps, - const CompilerInvocation &PreambleInvocationIn, + CompilerInvocation &PreambleInvocationIn, IntrusiveRefCntPtr<vfs::FileSystem> VFS, bool AllowRebuild = true, unsigned MaxLines = 0); void RealizeTopLevelDeclsFromPreamble(); @@ -801,9 +807,11 @@ public: 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 SkipFunctionBodies = + 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); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 9b672d97551..2214d827455 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1271,7 +1271,7 @@ makeStandaloneDiagnostic(const LangOptions &LangOpts, std::unique_ptr<llvm::MemoryBuffer> ASTUnit::getMainBufferWithPrecompiledPreamble( std::shared_ptr<PCHContainerOperations> PCHContainerOps, - const CompilerInvocation &PreambleInvocationIn, + CompilerInvocation &PreambleInvocationIn, IntrusiveRefCntPtr<vfs::FileSystem> VFS, bool AllowRebuild, unsigned MaxLines) { auto MainFilePath = @@ -1338,9 +1338,18 @@ ASTUnit::getMainBufferWithPrecompiledPreamble( SimpleTimer PreambleTimer(WantTiming); PreambleTimer.setOutput("Precompiling preamble"); + const bool PreviousSkipFunctionBodies = + PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies; + if (SkipFunctionBodies == 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; @@ -1691,7 +1700,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName, unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind, bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion, - bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies, + bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies, bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization, llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST, IntrusiveRefCntPtr<vfs::FileSystem> VFS) { @@ -1724,7 +1733,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine( // Override the resources path. CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; - CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies; + CI->getFrontendOpts().SkipFunctionBodies = + SkipFunctionBodies == SkipFunctionBodiesScope::PreambleAndMainFile; if (ModuleFormat) CI->getHeaderSearchOpts().ModuleFormat = ModuleFormat.getValue(); @@ -1750,6 +1760,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( = IncludeBriefCommentsInCodeCompletion; AST->UserFilesAreVolatile = UserFilesAreVolatile; AST->Invocation = CI; + AST->SkipFunctionBodies = SkipFunctionBodies; if (ForSerialization) AST->WriterData.reset(new ASTWriterData(*AST->PCMCache)); // Zero out now to ease cleanup during crash recovery. diff --git a/clang/test/Parser/skip-function-bodies.h b/clang/test/Parser/skip-function-bodies.h new file mode 100644 index 00000000000..2d1a4c009ca --- /dev/null +++ b/clang/test/Parser/skip-function-bodies.h @@ -0,0 +1,3 @@ +int header1(int t) { + return t; +} diff --git a/clang/test/Parser/skip-function-bodies.mm b/clang/test/Parser/skip-function-bodies.mm index e5b7b2adf83..646730ee6c7 100644 --- a/clang/test/Parser/skip-function-bodies.mm +++ b/clang/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 @@ void J() { 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 @@ void J() { // 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-PREAMBLE %s +// CHECK-PREAMBLE: skip-function-bodies.h:1:5: FunctionDecl=header1:1:5 Extent=[1:1 - 1:19] +// CHECK-PREAMBLE-NOT: skip-function-bodies.h:2:3: ReturnStmt= Extent=[2:3 - 2:11] +// CHECK-PREAMBLE: skip-function-bodies.mm:8:12: StructDecl=C:8:12 (Definition) Extent=[8:5 - 10:6] +// CHECK-PREAMBLE: skip-function-bodies.mm:9:12: CXXMethod=d:9:12 (Definition) Extent=[9:7 - 9:18] diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index d57ac4f9f6c..e86a20b55b6 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -82,6 +82,8 @@ static unsigned getDefaultParsingOptions() { 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; } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index c348506545d..32f6ca994bb 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -3380,9 +3380,15 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename, = options & CXTranslationUnit_CacheCompletionResults; bool IncludeBriefCommentsInCodeCompletion = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; - bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies; bool SingleFileParse = options & CXTranslationUnit_SingleFileParse; bool ForSerialization = options & CXTranslationUnit_ForSerialization; + SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None; + if (options & CXTranslationUnit_SkipFunctionBodies) { + SkipFunctionBodies = + (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble) + ? SkipFunctionBodiesScope::Preamble + : SkipFunctionBodiesScope::PreambleAndMainFile; + } // Configure the diagnostics. IntrusiveRefCntPtr<DiagnosticsEngine> |