summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2018-05-17 09:24:37 +0000
committerIvan Donchevskii <ivan.donchevskii@qt.io>2018-05-17 09:24:37 +0000
commit6e89528c557fe7e41b2c4946d75d1e5b36f62fd5 (patch)
tree2f8458fec27372b1304faa4349faef6897b602a1
parent270ef5b85c9c0898ef76fee3e4ba5e3e5cb46c29 (diff)
downloadbcm5719-llvm-6e89528c557fe7e41b2c4946d75d1e5b36f62fd5.tar.gz
bcm5719-llvm-6e89528c557fe7e41b2c4946d75d1e5b36f62fd5.zip
[libclang] Allow skipping function bodies in preamble only
Second attempt. Fix line endings and warning. 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. Patch by Nikolai Kosjar. Differential Revision: https://reviews.llvm.org/D45815 llvm-svn: 332587
-rw-r--r--clang/include/clang-c/Index.h10
-rw-r--r--clang/include/clang/Frontend/ASTUnit.h16
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp17
-rw-r--r--clang/test/Parser/skip-function-bodies.h3
-rw-r--r--clang/test/Parser/skip-function-bodies.mm13
-rw-r--r--clang/tools/c-index-test/c-index-test.c2
-rw-r--r--clang/tools/libclang/CIndex.cpp8
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>
OpenPOWER on IntegriCloud