summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2018-05-16 15:06:55 +0200
committerNikolai Kosjar <nikolai.kosjar@qt.io>2018-05-17 07:08:58 +0000
commitcbe51a943adebe43cfd8f20a190670a1d6a0e908 (patch)
tree4a9ddc355d6d194b791f648711d1c6af0e33c221
parent0e790628055f8e1edbc4a1176e3cc064cf544a2b (diff)
[backported/clang-7][libclang] Allow skipping function bodies in preamble only
-------------------------------------------------------------------------- * https://reviews.llvm.org/D45815 * Speed ups parse/reparse significantly but on the other hand does not issue any more diagnostics from template functions from headers. -------------------------------------------------------------------------- As an addition to CXTranslationUnit_SkipFunctionBodies, provide the new option CXTranslationUnit_LimitSkipFunctionBodiesToPreamble, which constraints the skipping of functions bodies to the preamble only. Function bodies in the main file are not affected if this option is set. Skipping function bodies only in the preamble is what clangd already does and the introduced flag implements it for libclang clients. Change-Id: I092a2d78d1e59a9e546d317ee2f18c98cdc7dcdb Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
-rw-r--r--include/clang-c/Index.h11
-rw-r--r--include/clang/Frontend/ASTUnit.h16
-rw-r--r--lib/Frontend/ASTUnit.cpp17
-rw-r--r--test/Parser/skip-function-bodies.h3
-rw-r--r--test/Parser/skip-function-bodies.mm13
-rw-r--r--tools/c-index-test/c-index-test.c2
-rw-r--r--tools/libclang/CIndex.cpp8
7 files changed, 60 insertions, 10 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 0179058944..d06c82a4db 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -35,6 +35,7 @@
#define CINDEX_VERSION_MINOR 45
#define CINDEX_VERSION_HAS_ISINVALIDECL_BACKPORTED
#define CINDEX_VERSION_HAS_PRETTYDECL_BACKPORTED
+#define CINDEX_VERSION_HAS_LIMITSKIPFUNCTIONBODIESTOPREAMBLE_BACKPORTED
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -1319,7 +1320,15 @@ enum CXTranslationUnit_Flags {
/**
* \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,
};
/**
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 5d04dcd191..09aeab5b6f 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -66,6 +66,9 @@ namespace vfs {
class FileSystem;
}
+/// \brief Enumerates the available scopes for skipping function bodies.
+enum class SkipFunctionBodiesScope { None, Preamble, PreambleAndMainFile };
+
/// \brief Utility class for loading a ASTContext from an AST file.
///
class ASTUnit {
@@ -335,6 +338,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;
+
/// \brief Cache any "global" code-completion results, so that we can avoid
/// recomputing them with each completion.
void CacheCodeCompletionResults();
@@ -353,7 +359,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();
@@ -782,9 +788,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/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 1160df15a9..84598fa4d5 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -1223,7 +1223,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) {
@@ -1290,9 +1290,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;
@@ -1646,7 +1655,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) {
@@ -1680,7 +1689,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();
@@ -1708,6 +1718,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
AST->StoredDiagnostics.swap(StoredDiagnostics);
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/test/Parser/skip-function-bodies.h b/test/Parser/skip-function-bodies.h
new file mode 100644
index 0000000000..2d1a4c009c
--- /dev/null
+++ b/test/Parser/skip-function-bodies.h
@@ -0,0 +1,3 @@
+int header1(int t) {
+ return t;
+}
diff --git a/test/Parser/skip-function-bodies.mm b/test/Parser/skip-function-bodies.mm
index e5b7b2adf8..646730ee6c 100644
--- a/test/Parser/skip-function-bodies.mm
+++ b/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/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index e9902efffb..bcc42ad994 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/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/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 8d288b5dd5..884206d9d1 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -3376,9 +3376,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>