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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits