nik updated this revision to Diff 143738.
nik marked 2 inline comments as done.
nik added a comment.
Herald added a subscriber: eraman.
Addressed inline comments.
Repository:
rC Clang
https://reviews.llvm.org/D45815
Files:
include/clang-c/Index.h
include/clang/Frontend/ASTUnit.h
include/clang/Frontend/FrontendOptions.h
include/clang/Frontend/SkipFunctionBodies.h
include/clang/Parse/ParseAST.h
include/clang/Parse/Parser.h
lib/Frontend/ASTUnit.cpp
lib/Parse/ParseAST.cpp
lib/Parse/ParseCXXInlineMethods.cpp
lib/Parse/ParseObjc.cpp
lib/Parse/Parser.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
tools/libclang/Indexing.cpp
unittests/CodeGen/BufferSourceTest.cpp
unittests/CodeGen/CodeGenExternalTest.cpp
unittests/CodeGen/IncrementalProcessingTest.cpp
unittests/CodeGen/TBAAMetadataTest.cpp
unittests/Frontend/PCHPreambleTest.cpp
unittests/Lex/PPCallbacksTest.cpp
unittests/Tooling/ToolingTest.cpp
Index: unittests/Tooling/ToolingTest.cpp
===================================================================
--- unittests/Tooling/ToolingTest.cpp
+++ unittests/Tooling/ToolingTest.cpp
@@ -250,7 +250,7 @@
struct SkipBodyAction : public clang::ASTFrontendAction {
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
StringRef) override {
- Compiler.getFrontendOpts().SkipFunctionBodies = true;
+ Compiler.getFrontendOpts().SkipFunctionBodies = SkipFunctionBodiesKind::All;
return llvm::make_unique<SkipBodyConsumer>();
}
};
Index: unittests/Lex/PPCallbacksTest.cpp
===================================================================
--- unittests/Lex/PPCallbacksTest.cpp
+++ unittests/Lex/PPCallbacksTest.cpp
@@ -201,7 +201,7 @@
ASTConsumer Consumer;
Sema S(PP, Context, Consumer);
- Parser P(PP, S, false);
+ Parser P(PP, S, SkipFunctionBodiesKind::None);
PragmaOpenCLExtensionCallbacks* Callbacks = new PragmaOpenCLExtensionCallbacks;
PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
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::SkipFunctionBodiesOptions(), VFS);
return !reparseFailed;
}
Index: unittests/CodeGen/TBAAMetadataTest.cpp
===================================================================
--- unittests/CodeGen/TBAAMetadataTest.cpp
+++ unittests/CodeGen/TBAAMetadataTest.cpp
@@ -73,7 +73,7 @@
}
const BasicBlock *compile() {
- clang::ParseAST(compiler.getSema(), false, false);
+ clang::ParseAST(compiler.getSema(), false, clang::SkipFunctionBodiesKind::None);
M = CG->GetModule();
// Do not expect more than one function definition.
Index: unittests/CodeGen/IncrementalProcessingTest.cpp
===================================================================
--- unittests/CodeGen/IncrementalProcessingTest.cpp
+++ unittests/CodeGen/IncrementalProcessingTest.cpp
@@ -143,7 +143,7 @@
Sema& S = compiler.getSema();
std::unique_ptr<Parser> ParseOP(new Parser(S.getPreprocessor(), S,
- /*SkipFunctionBodies*/ false));
+ SkipFunctionBodiesKind::None));
Parser &P = *ParseOP.get();
std::array<std::unique_ptr<llvm::Module>, 3> M;
Index: unittests/CodeGen/CodeGenExternalTest.cpp
===================================================================
--- unittests/CodeGen/CodeGenExternalTest.cpp
+++ unittests/CodeGen/CodeGenExternalTest.cpp
@@ -294,7 +294,7 @@
sm.setMainFileID(sm.createFileID(
llvm::MemoryBuffer::getMemBuffer(TestProgram), clang::SrcMgr::C_User));
- clang::ParseAST(compiler.getSema(), false, false);
+ clang::ParseAST(compiler.getSema(), false, clang::SkipFunctionBodiesKind::None);
ASSERT_TRUE(test_codegen_fns_ran);
}
Index: unittests/CodeGen/BufferSourceTest.cpp
===================================================================
--- unittests/CodeGen/BufferSourceTest.cpp
+++ unittests/CodeGen/BufferSourceTest.cpp
@@ -74,7 +74,7 @@
sm.setMainFileID(sm.createFileID(
llvm::MemoryBuffer::getMemBuffer(TestProgram), clang::SrcMgr::C_User));
- clang::ParseAST(compiler.getSema(), false, false);
+ clang::ParseAST(compiler.getSema(), false, clang::SkipFunctionBodiesKind::None);
}
} // end anonymous namespace
Index: tools/libclang/Indexing.cpp
===================================================================
--- tools/libclang/Indexing.cpp
+++ tools/libclang/Indexing.cpp
@@ -540,7 +540,7 @@
bool SkipBodies = (index_options & CXIndexOpt_SkipParsedBodiesInSession) &&
CInvok->getLangOpts()->CPlusPlus;
if (SkipBodies)
- CInvok->getFrontendOpts().SkipFunctionBodies = true;
+ CInvok->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodiesKind::All;
auto DataConsumer =
std::make_shared<CXIndexDataConsumer>(client_data, CB, index_options,
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -3346,6 +3346,20 @@
Options);
}
+static ASTUnit::SkipFunctionBodiesOptions
+skipFunctionBodiesOptionsFromParseOptions(unsigned options) {
+ ASTUnit::SkipFunctionBodiesOptions SkipFunctionBodiesOpts;
+ if (options & CXTranslationUnit_SkipFunctionBodies) {
+ if (options & CXTranslationUnit_LimitSkipFunctionBodiesToNonTemplates)
+ SkipFunctionBodiesOpts.LimitToNonTemplateFunctions = true;
+ SkipFunctionBodiesOpts.Scope =
+ (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
+ ? ASTUnit::SkipFunctionBodiesOptions::Preamble
+ : ASTUnit::SkipFunctionBodiesOptions::MainFileAndPreamble;
+ }
+ return SkipFunctionBodiesOpts;
+}
+
static CXErrorCode
clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
const char *const *command_line_args,
@@ -3376,9 +3390,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::SkipFunctionBodiesOptions SkipFunctionBodiesOpts =
+ skipFunctionBodiesOptionsFromParseOptions(options);
// Configure the diagnostics.
IntrusiveRefCntPtr<DiagnosticsEngine>
@@ -3467,7 +3482,7 @@
/*CaptureDiagnostics=*/true, *RemappedFiles.get(),
/*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
- /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
+ /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodiesOpts, SingleFileParse,
/*UserFilesAreVolatile=*/true, ForSerialization,
CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
&ErrUnit));
@@ -4055,7 +4070,8 @@
}
if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
- *RemappedFiles.get()))
+ *RemappedFiles.get(),
+ skipFunctionBodiesOptionsFromParseOptions(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,10 @@
options |= CXTranslationUnit_CreatePreambleOnFirstParse;
if (getenv("CINDEXTEST_KEEP_GOING"))
options |= CXTranslationUnit_KeepGoing;
+ if (getenv("CINDEXTEST_LIMIT_SKIP_FUNCTION_BODIES_TO_PREAMBLE"))
+ options |= CXTranslationUnit_LimitSkipFunctionBodiesToPreamble;
+ if (getenv("CINDEXTEST_LIMIT_SKIP_FUNCTION_BODIES_TO_NON_TEMPLATES"))
+ options |= CXTranslationUnit_LimitSkipFunctionBodiesToNonTemplates;
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,12 @@
class K {};
}
+template <typename T>
+T g(T t) {
+ return t;
+}
+
+// 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 +49,48 @@
// 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]
+// CHECK: skip-function-bodies.mm:31:3: FunctionTemplate=g:31:3 Extent=[30:1 - 31:9]
+// CHECK: skip-function-bodies.mm:30:20: TemplateTypeParameter=T:30:20 (Definition) Extent=[30:11 - 30:21] [access=public]
+// CHECK: skip-function-bodies.mm:31:1: TypeRef=T:30:20 Extent=[31:1 - 31:2]
+// CHECK: skip-function-bodies.mm:31:7: ParmDecl=t:31:7 (Definition) Extent=[31:5 - 31:8]
+// CHECK: skip-function-bodies.mm:31:5: TypeRef=T:30:20 Extent=[31:5 - 31:6]
+// CHECK-NOT: skip-function-bodies.mm:31:10: CompoundStmt= Extent=[31:10 - 33:2]
+// CHECK-NOT: skip-function-bodies.mm:32:3: ReturnStmt= Extent=[32:3 - 32:11]
+// CHECK-NOT: skip-function-bodies.mm:32:10: DeclRefExpr=t:31:7 Extent=[32:10 - 32:11]
+
+// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 \
+// RUN: CINDEXTEST_LIMIT_SKIP_FUNCTION_BODIES_TO_NON_TEMPLATES=1 \
+// RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix=CHECK-TEMPLATES %s
+// CHECK-TEMPLATES-NOT: skip-function-bodies.mm:8:12: StructDecl=C:8:12 (Definition) Extent=[8:5 - 10:6]
+// CHECK-TEMPLATES-NOT: skip-function-bodies.mm:9:12: CXXMethod=d:9:12 (Definition) Extent=[9:7 - 9:18]
+// CHECK-TEMPLATES: skip-function-bodies.mm:31:3: FunctionTemplate=g:31:3 (Definition) Extent=[30:1 - 33:2]
+// CHECK-TEMPLATES: skip-function-bodies.mm:30:20: TemplateTypeParameter=T:30:20 (Definition) Extent=[30:11 - 30:21] [access=public]
+// CHECK-TEMPLATES: skip-function-bodies.mm:31:1: TypeRef=T:30:20 Extent=[31:1 - 31:2]
+// CHECK-TEMPLATES: skip-function-bodies.mm:31:7: ParmDecl=t:31:7 (Definition) Extent=[31:5 - 31:8]
+// CHECK-TEMPLATES: skip-function-bodies.mm:31:5: TypeRef=T:30:20 Extent=[31:5 - 31:6]
+// CHECK-TEMPLATES: skip-function-bodies.mm:31:10: CompoundStmt= Extent=[31:10 - 33:2]
+// CHECK-TEMPLATES: skip-function-bodies.mm:32:3: ReturnStmt= Extent=[32:3 - 32:11]
+// CHECK-TEMPLATES: skip-function-bodies.mm:32:10: DeclRefExpr=t:31:7 Extent=[32:10 - 32:11]
+
+// 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]
+
+// 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: CINDEXTEST_LIMIT_SKIP_FUNCTION_BODIES_TO_NON_TEMPLATES=1 \
+// RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix=CHECK-PREAMBLE2 %s
+// CHECK-PREAMBLE2: skip-function-bodies.h:1:5: FunctionDecl=header1:1:5 Extent=[1:1 - 1:19]
+// CHECK-PREAMBLE2-NOT: skip-function-bodies.h:2:3: ReturnStmt= Extent=[2:3 - 2:11]
+// CHECK-PREAMBLE2: skip-function-bodies.h:6:3: FunctionTemplate=header2:6:3 (Definition) Extent=[5:1 - 8:2]
+// CHECK-PREAMBLE2: skip-function-bodies.h:7:3: ReturnStmt= Extent=[7:3 - 7:11]
+// CHECK-PREAMBLE2: skip-function-bodies.mm:8:12: StructDecl=C:8:12 (Definition) Extent=[8:5 - 10:6]
+// CHECK-PREAMBLE2: 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,8 @@
+int header1(int t) {
+ return t;
+}
+
+template <typename T>
+T header2(T t) {
+ return t;
+}
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp
+++ lib/Parse/Parser.cpp
@@ -47,12 +47,17 @@
return Ident__except;
}
-Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
- : PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
- GreaterThanIsOperator(true), ColonIsSacred(false),
- InMessageExpression(false), TemplateParameterDepth(0),
- ParsingInObjCContainer(false) {
- SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
+Parser::Parser(Preprocessor &pp, Sema &actions,
+ SkipFunctionBodiesKind skipFunctionBodies)
+ : PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
+ GreaterThanIsOperator(true), ColonIsSacred(false),
+ InMessageExpression(false), TemplateParameterDepth(0),
+ ParsingInObjCContainer(false) {
+
+ if (pp.isCodeCompletionEnabled())
+ SkipFunctionBodies = SkipFunctionBodiesKind::All;
+ else
+ SkipFunctionBodies = skipFunctionBodies;
Tok.startToken();
Tok.setKind(tok::eof);
Actions.CurScope = nullptr;
@@ -1100,6 +1105,19 @@
}
}
+ bool ShouldSkipFunctionBody = false;
+ switch (SkipFunctionBodies) {
+ case SkipFunctionBodiesKind::All:
+ ShouldSkipFunctionBody = true;
+ break;
+ case SkipFunctionBodiesKind::AllExceptTemplates:
+ ShouldSkipFunctionBody = TemplateInfo.Kind != ParsedTemplateInfo::Template;
+ break;
+ case SkipFunctionBodiesKind::None:
+ default:
+ ShouldSkipFunctionBody = false;
+ }
+
// In delayed template parsing mode, for function template we consume the
// tokens and store them for late parsing at the end of the translation unit.
if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) &&
@@ -1117,7 +1135,7 @@
D.complete(DP);
D.getMutableDeclSpec().abort();
- if (SkipFunctionBodies && (!DP || Actions.canSkipFunctionBody(DP)) &&
+ if (ShouldSkipFunctionBody && (!DP || Actions.canSkipFunctionBody(DP)) &&
trySkippingFunctionBody()) {
BodyScope.Exit();
return Actions.ActOnSkippedFunctionBody(DP);
@@ -1217,7 +1235,7 @@
return Res;
}
- if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) &&
+ if (ShouldSkipFunctionBody && (!Res || Actions.canSkipFunctionBody(Res)) &&
trySkippingFunctionBody()) {
BodyScope.Exit();
Actions.ActOnSkippedFunctionBody(Res);
Index: lib/Parse/ParseObjc.cpp
===================================================================
--- lib/Parse/ParseObjc.cpp
+++ lib/Parse/ParseObjc.cpp
@@ -2634,7 +2634,8 @@
/// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them
/// for later parsing.
void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
- if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
+ if (SkipFunctionBodies != SkipFunctionBodiesKind::None &&
+ (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
trySkippingFunctionBody()) {
Actions.ActOnSkippedFunctionBody(MDecl);
return;
Index: lib/Parse/ParseCXXInlineMethods.cpp
===================================================================
--- lib/Parse/ParseCXXInlineMethods.cpp
+++ lib/Parse/ParseCXXInlineMethods.cpp
@@ -101,8 +101,8 @@
return FnD;
}
- if (SkipFunctionBodies && (!FnD || Actions.canSkipFunctionBody(FnD)) &&
- trySkippingFunctionBody()) {
+ if (SkipFunctionBodies != SkipFunctionBodiesKind::None &&
+ (!FnD || Actions.canSkipFunctionBody(FnD)) && trySkippingFunctionBody()) {
Actions.ActOnSkippedFunctionBody(FnD);
return FnD;
}
Index: lib/Parse/ParseAST.cpp
===================================================================
--- lib/Parse/ParseAST.cpp
+++ lib/Parse/ParseAST.cpp
@@ -100,7 +100,7 @@
ASTContext &Ctx, bool PrintStats,
TranslationUnitKind TUKind,
CodeCompleteConsumer *CompletionConsumer,
- bool SkipFunctionBodies) {
+ SkipFunctionBodiesKind SkipFunctionBodies) {
std::unique_ptr<Sema> S(
new Sema(PP, Ctx, *Consumer, TUKind, CompletionConsumer));
@@ -111,7 +111,8 @@
ParseAST(*S.get(), PrintStats, SkipFunctionBodies);
}
-void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
+void clang::ParseAST(Sema &S, bool PrintStats,
+ SkipFunctionBodiesKind SkipFunctionBodies) {
// Collect global stats on Decls/Stmts (until we have a module streamer).
if (PrintStats) {
Decl::EnableStatistics();
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,
+ SkipFunctionBodiesOptions SkipFunctionBodiesOpts, bool AllowRebuild,
unsigned MaxLines) {
auto MainFilePath =
PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
@@ -1338,9 +1339,22 @@
SimpleTimer PreambleTimer(WantTiming);
PreambleTimer.setOutput("Precompiling preamble");
+ const SkipFunctionBodiesKind PreviousSkipFunctionBodies =
+ PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies;
+ if (SkipFunctionBodiesOpts.Scope == SkipFunctionBodiesOptions::Preamble) {
+ PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies =
+ SkipFunctionBodiesOpts.LimitToNonTemplateFunctions
+ ? SkipFunctionBodiesKind::AllExceptTemplates
+ : SkipFunctionBodiesKind::All;
+ }
+
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 +1629,7 @@
bool ASTUnit::LoadFromCompilerInvocation(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
unsigned PrecompilePreambleAfterNParses,
+ SkipFunctionBodiesOptions SkipFunctionBodiesOpts,
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
if (!Invocation)
return true;
@@ -1630,8 +1645,8 @@
std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
if (PrecompilePreambleAfterNParses > 0) {
PreambleRebuildCounter = PrecompilePreambleAfterNParses;
- OverrideMainBuffer =
- getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
+ OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
+ PCHContainerOps, *Invocation, VFS, SkipFunctionBodiesOpts);
getDiagnostics().Reset();
ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
}
@@ -1678,6 +1693,7 @@
if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
PrecompilePreambleAfterNParses,
+ SkipFunctionBodiesOptions(),
AST->FileMgr->getVirtualFileSystem()))
return nullptr;
return AST;
@@ -1691,8 +1707,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,
+ SkipFunctionBodiesOptions SkipFunctionBodiesOpts, 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 +1741,14 @@
// Override the resources path.
CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
- CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies;
+ if (SkipFunctionBodiesOpts.Scope == SkipFunctionBodiesOptions::MainFileAndPreamble) {
+ CI->getFrontendOpts().SkipFunctionBodies =
+ SkipFunctionBodiesOpts.LimitToNonTemplateFunctions
+ ? SkipFunctionBodiesKind::AllExceptTemplates
+ : SkipFunctionBodiesKind::All;
+ } else {
+ CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodiesKind::None;
+ }
if (ModuleFormat)
CI->getHeaderSearchOpts().ModuleFormat = ModuleFormat.getValue();
@@ -1762,6 +1786,7 @@
if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
PrecompilePreambleAfterNParses,
+ SkipFunctionBodiesOpts,
VFS)) {
// Some error occurred, if caller wants to examine diagnostics, pass it the
// ASTUnit.
@@ -1777,6 +1802,7 @@
bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
ArrayRef<RemappedFile> RemappedFiles,
+ SkipFunctionBodiesOptions SkipFunBodiesOpts,
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
if (!Invocation)
return true;
@@ -1806,8 +1832,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, SkipFunBodiesOpts);
// Clear out the diagnostics state.
FileMgr.reset();
@@ -2203,7 +2229,8 @@
llvm::sys::fs::UniqueID MainID = MainStatus->getUniqueID();
if (CompleteFileID == MainID && Line > 1)
OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
- PCHContainerOps, Inv, VFS, false, Line - 1);
+ PCHContainerOps, Inv, VFS, SkipFunctionBodiesOptions(), false,
+ Line - 1);
}
}
}
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h
+++ include/clang/Parse/Parser.h
@@ -18,6 +18,7 @@
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/OperatorPrecedence.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Frontend/SkipFunctionBodies.h"
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DeclSpec.h"
@@ -261,15 +262,16 @@
///
/// This option can be used, for example, to speed up searches for
/// declarations/definitions when indexing.
- bool SkipFunctionBodies;
+ SkipFunctionBodiesKind SkipFunctionBodies;
/// The location of the expression statement that is being parsed right now.
/// Used to determine if an expression that is being parsed is a statement or
/// just a regular sub-expression.
SourceLocation ExprStatementTokLoc;
public:
- Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
+ Parser(Preprocessor &PP, Sema &Actions,
+ SkipFunctionBodiesKind SkipFunctionBodies);
~Parser() override;
const LangOptions &getLangOpts() const { return PP.getLangOpts(); }
Index: include/clang/Parse/ParseAST.h
===================================================================
--- include/clang/Parse/ParseAST.h
+++ include/clang/Parse/ParseAST.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_PARSE_PARSEAST_H
#include "clang/Basic/LangOptions.h"
+#include "clang/Frontend/SkipFunctionBodies.h"
namespace clang {
class Preprocessor;
@@ -36,16 +37,17 @@
/// \param SkipFunctionBodies Whether to skip parsing of function bodies.
/// This option can be used, for example, to speed up searches for
/// declarations/definitions when indexing.
- void ParseAST(Preprocessor &pp, ASTConsumer *C,
- ASTContext &Ctx, bool PrintStats = false,
- TranslationUnitKind TUKind = TU_Complete,
- CodeCompleteConsumer *CompletionConsumer = nullptr,
- bool SkipFunctionBodies = false);
+ void ParseAST(
+ Preprocessor &pp, ASTConsumer *C, ASTContext &Ctx,
+ bool PrintStats = false, TranslationUnitKind TUKind = TU_Complete,
+ CodeCompleteConsumer *CompletionConsumer = nullptr,
+ SkipFunctionBodiesKind SkipFunctionBodies = SkipFunctionBodiesKind::None);
/// \brief Parse the main file known to the preprocessor, producing an
/// abstract syntax tree.
- void ParseAST(Sema &S, bool PrintStats = false,
- bool SkipFunctionBodies = false);
+ void ParseAST(
+ Sema &S, bool PrintStats = false,
+ SkipFunctionBodiesKind SkipFunctionBodies = SkipFunctionBodiesKind::None);
} // end namespace clang
Index: include/clang/Frontend/SkipFunctionBodies.h
===================================================================
--- /dev/null
+++ include/clang/Frontend/SkipFunctionBodies.h
@@ -0,0 +1,25 @@
+//===--- FrontendOptions.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_SKIPFUNCTIONBODIES_H
+#define LLVM_CLANG_FRONTEND_SKIPFUNCTIONBODIES_H
+
+namespace clang {
+
+/// Skip over function bodies to speed up parsing in cases you do not need
+/// them (e.g. with code completion).
+enum class SkipFunctionBodiesKind {
+ None,
+ All,
+ AllExceptTemplates,
+};
+
+} // end namespace clang
+
+#endif
Index: include/clang/Frontend/FrontendOptions.h
===================================================================
--- include/clang/Frontend/FrontendOptions.h
+++ include/clang/Frontend/FrontendOptions.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
#include "clang/Frontend/CommandLineSourceLoc.h"
+#include "clang/Frontend/SkipFunctionBodies.h"
#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Sema/CodeCompleteOptions.h"
#include "llvm/ADT/StringRef.h"
@@ -274,10 +275,6 @@
/// Emit ARC errors even if the migrator can fix them.
unsigned ARCMTMigrateEmitARCErrors : 1;
- /// Skip over function bodies to speed up parsing in cases you do not need
- /// them (e.g. with code completion).
- unsigned SkipFunctionBodies : 1;
-
/// Whether we can use the global module index if available.
unsigned UseGlobalModuleIndex : 1;
@@ -302,6 +299,8 @@
/// Whether timestamps should be written to the produced PCH file.
unsigned IncludeTimestamps : 1;
+ SkipFunctionBodiesKind SkipFunctionBodies;
+
CodeCompleteOptions CodeCompleteOpts;
enum {
@@ -444,10 +443,11 @@
ShowStats(false), ShowTimers(false), ShowVersion(false),
FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
- SkipFunctionBodies(false), UseGlobalModuleIndex(true),
- GenerateGlobalModuleIndex(true), ASTDumpDecls(false),
- ASTDumpLookups(false), BuildingImplicitModule(false),
- ModulesEmbedAllFiles(false), IncludeTimestamps(true) {}
+ UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true),
+ ASTDumpDecls(false), ASTDumpLookups(false),
+ BuildingImplicitModule(false), ModulesEmbedAllFiles(false),
+ IncludeTimestamps(true),
+ SkipFunctionBodies(SkipFunctionBodiesKind::None) {}
/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return InputKind::C.
Index: include/clang/Frontend/ASTUnit.h
===================================================================
--- include/clang/Frontend/ASTUnit.h
+++ include/clang/Frontend/ASTUnit.h
@@ -101,6 +101,12 @@
std::vector<StandaloneFixIt> FixIts;
};
+ struct SkipFunctionBodiesOptions {
+ SkipFunctionBodiesOptions() {}
+ enum { None, MainFileAndPreamble, Preamble } Scope = None;
+ bool LimitToNonTemplateFunctions = false;
+ };
+
private:
std::shared_ptr<LangOptions> LangOpts;
IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
@@ -363,9 +369,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,
+ SkipFunctionBodiesOptions SkipFunctionBodiesOpts =
+ SkipFunctionBodiesOptions(),
+ bool AllowRebuild = true, unsigned MaxLines = 0);
void RealizeTopLevelDeclsFromPreamble();
/// \brief Transfers ownership of the objects (like SourceManager) from
@@ -693,6 +701,7 @@
bool LoadFromCompilerInvocation(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
unsigned PrecompilePreambleAfterNParses,
+ SkipFunctionBodiesOptions SkipFunctionBodiesOpts,
IntrusiveRefCntPtr<vfs::FileSystem> VFS);
public:
@@ -801,9 +810,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,
+ SkipFunctionBodiesOptions SkipFunctionBodiesOpts =
+ SkipFunctionBodiesOptions(),
+ 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 +832,8 @@
/// contain any translation-unit information, false otherwise.
bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
ArrayRef<RemappedFile> RemappedFiles = None,
+ SkipFunctionBodiesOptions SkipFunctionBodiesOpts =
+ SkipFunctionBodiesOptions(),
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,24 @@
/**
* \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,
+
+ /**
+ * \brief Used in combination with CXTranslationUnit_SkipFunctionBodies to
+ * exclude template function bodies from being skipped.
+ *
+ * Parsing template function bodies allows diagnostics for wrong/incomplete
+ * template instantiations.
+ */
+ CXTranslationUnit_LimitSkipFunctionBodiesToNonTemplates = 0x1000,
};
/**
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits