r370123 - [preprocessor] Add an opportunity to retain excluded conditional blocks
Evgeny Mankov via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 27 15:15:32 PDT 2019
Author: emankov
Date: Tue Aug 27 15:15:32 2019
New Revision: 370123
URL: http://llvm.org/viewvc/llvm-project?rev=370123&view=rev
Log:
[preprocessor] Add an opportunity to retain excluded conditional blocks
It is handy for clang tooling, for instance, in source to source transformation.
Reviewers: vpykhtin (Valery Pykhtin), erichkeane (Erich Keane)
Subscribers: rsmith (Richard Smith), akyrtzi (Argyrios Kyrtzidis)
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66597
Added:
cfe/trunk/test/Index/retain-excluded-conditional-blocks.m
Modified:
cfe/trunk/include/clang-c/Index.h
cfe/trunk/include/clang/Frontend/ASTUnit.h
cfe/trunk/include/clang/Lex/PreprocessorOptions.h
cfe/trunk/lib/Frontend/ASTUnit.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/tools/c-index-test/c-index-test.c
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=370123&r1=370122&r2=370123&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Tue Aug 27 15:15:32 2019
@@ -1356,7 +1356,12 @@ enum CXTranslationUnit_Flags {
* the case where these warnings are not of interest, as for an IDE for
* example, which typically shows only the diagnostics in the main file.
*/
- CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 0x4000
+ CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 0x4000,
+
+ /**
+ * Tells the preprocessor not to skip excluded conditional blocks.
+ */
+ CXTranslationUnit_RetainExcludedConditionalBlocks = 0x8000,
};
/**
Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=370123&r1=370122&r2=370123&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Tue Aug 27 15:15:32 2019
@@ -832,6 +832,7 @@ public:
SkipFunctionBodiesScope::None,
bool SingleFileParse = false, bool UserFilesAreVolatile = false,
bool ForSerialization = false,
+ bool RetainExcludedConditionalBlocks = false,
llvm::Optional<StringRef> ModuleFormat = llvm::None,
std::unique_ptr<ASTUnit> *ErrAST = nullptr,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
Modified: cfe/trunk/include/clang/Lex/PreprocessorOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PreprocessorOptions.h?rev=370123&r1=370122&r2=370123&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/PreprocessorOptions.h (original)
+++ cfe/trunk/include/clang/Lex/PreprocessorOptions.h Tue Aug 27 15:15:32 2019
@@ -142,6 +142,9 @@ public:
/// compiler invocation and its buffers will be reused.
bool RetainRemappedFileBuffers = false;
+ /// When enabled, excluded conditional blocks retain in the main file.
+ bool RetainExcludedConditionalBlocks = false;
+
/// The Objective-C++ ARC standard library that we should support,
/// by providing appropriate definitions to retrofit the standard library
/// with support for lifetime-qualified pointers.
@@ -201,6 +204,7 @@ public:
RetainRemappedFileBuffers = true;
PrecompiledPreambleBytes.first = 0;
PrecompiledPreambleBytes.second = false;
+ RetainExcludedConditionalBlocks = false;
}
};
Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=370123&r1=370122&r2=370123&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Tue Aug 27 15:15:32 2019
@@ -1735,6 +1735,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies,
bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization,
+ bool RetainExcludedConditionalBlocks,
llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
assert(Diags.get() && "no DiagnosticsEngine was provided");
@@ -1762,6 +1763,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
PPOpts.SingleFileParseMode = SingleFileParse;
+ PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
// Override the resources path.
CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=370123&r1=370122&r2=370123&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Tue Aug 27 15:15:32 2019
@@ -2855,6 +2855,9 @@ void Preprocessor::HandleIfdefDirective(
Callbacks->Ifdef(DirectiveTok.getLocation(), MacroNameTok, MD);
}
+ bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
+ getSourceManager().isInMainFile(DirectiveTok.getLocation());
+
// Should we include the stuff contained by this directive?
if (PPOpts->SingleFileParseMode && !MI) {
// In 'single-file-parse mode' undefined identifiers trigger parsing of all
@@ -2862,7 +2865,7 @@ void Preprocessor::HandleIfdefDirective(
CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(),
/*wasskip*/false, /*foundnonskip*/false,
/*foundelse*/false);
- } else if (!MI == isIfndef) {
+ } else if (!MI == isIfndef || RetainExcludedCB) {
// Yes, remember that we are inside a conditional, then lex the next token.
CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(),
/*wasskip*/false, /*foundnonskip*/true,
@@ -2903,13 +2906,16 @@ void Preprocessor::HandleIfDirective(Tok
IfToken.getLocation(), DER.ExprRange,
(ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
+ bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
+ getSourceManager().isInMainFile(IfToken.getLocation());
+
// Should we include the stuff contained by this directive?
if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
// In 'single-file-parse mode' undefined identifiers trigger parsing of all
// the directive blocks.
CurPPLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false,
/*foundnonskip*/false, /*foundelse*/false);
- } else if (ConditionalTrue) {
+ } else if (ConditionalTrue || RetainExcludedCB) {
// Yes, remember that we are inside a conditional, then lex the next token.
CurPPLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false,
/*foundnonskip*/true, /*foundelse*/false);
@@ -2971,7 +2977,10 @@ void Preprocessor::HandleElseDirective(T
if (Callbacks)
Callbacks->Else(Result.getLocation(), CI.IfLoc);
- if (PPOpts->SingleFileParseMode && !CI.FoundNonSkip) {
+ bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
+ getSourceManager().isInMainFile(Result.getLocation());
+
+ if ((PPOpts->SingleFileParseMode && !CI.FoundNonSkip) || RetainExcludedCB) {
// In 'single-file-parse mode' undefined identifiers trigger parsing of all
// the directive blocks.
CurPPLexer->pushConditionalLevel(CI.IfLoc, /*wasskip*/false,
@@ -3013,7 +3022,10 @@ void Preprocessor::HandleElifDirective(T
Callbacks->Elif(ElifToken.getLocation(), ConditionRange,
PPCallbacks::CVK_NotEvaluated, CI.IfLoc);
- if (PPOpts->SingleFileParseMode && !CI.FoundNonSkip) {
+ bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
+ getSourceManager().isInMainFile(ElifToken.getLocation());
+
+ if ((PPOpts->SingleFileParseMode && !CI.FoundNonSkip) || RetainExcludedCB) {
// In 'single-file-parse mode' undefined identifiers trigger parsing of all
// the directive blocks.
CurPPLexer->pushConditionalLevel(ElifToken.getLocation(), /*wasskip*/false,
Added: cfe/trunk/test/Index/retain-excluded-conditional-blocks.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/retain-excluded-conditional-blocks.m?rev=370123&view=auto
==============================================================================
--- cfe/trunk/test/Index/retain-excluded-conditional-blocks.m (added)
+++ cfe/trunk/test/Index/retain-excluded-conditional-blocks.m Tue Aug 27 15:15:32 2019
@@ -0,0 +1,132 @@
+// RUN: c-index-test -retain-excluded-conditional-blocks %s | FileCheck %s
+
+#include <stdint.h>
+
+// CHECK: TypedefDecl=intptr_t
+
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=MyCls
+ at interface MyCls
+// CHECK: [[@LINE+1]]:8: ObjCInstanceMethodDecl=some_meth
+-(void)some_meth;
+ at end
+
+#if 1
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test1
+ at interface Test1 @end
+#else
+// CHECK: [[@LINE+1]]:12:
+ at interface Test2 @end
+#endif
+
+#if 0
+// CHECK: [[@LINE+1]]:12:
+ at interface Test3 @end
+#else
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test4
+ at interface Test4 @end
+#endif
+
+#if SOMETHING_NOT_DEFINED
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test5
+ at interface Test5 @end
+#else
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test6
+ at interface Test6 @end
+#endif
+
+#define SOMETHING_DEFINED 1
+#if SOMETHING_DEFINED
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test7
+ at interface Test7 @end
+#else
+// CHECK: [[@LINE+1]]:12:
+ at interface Test8 @end
+#endif
+
+#if defined(SOMETHING_NOT_DEFINED)
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test9
+ at interface Test9 @end
+#else
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test10
+ at interface Test10 @end
+#endif
+
+#if defined(SOMETHING_DEFINED)
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test11
+ at interface Test11 @end
+#else
+// CHECK: [[@LINE+1]]:12:
+ at interface Test12 @end
+#endif
+
+#if SOMETHING_NOT_DEFINED1
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test13
+ at interface Test13 @end
+#elif SOMETHING_NOT_DEFINED2
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test14
+ at interface Test14 @end
+#else
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test15
+ at interface Test15 @end
+#endif
+
+#ifdef SOMETHING_NOT_DEFINED
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test19
+ at interface Test19 @end
+#else
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test20
+ at interface Test20 @end
+#endif
+
+#ifdef SOMETHING_DEFINED
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test21
+ at interface Test21 @end
+#else
+// CHECK: [[@LINE+1]]:12:
+ at interface Test22 @end
+#endif
+
+#ifndef SOMETHING_NOT_DEFINED
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test23
+ at interface Test23 @end
+#else
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test24
+ at interface Test24 @end
+#endif
+
+#ifndef SOMETHING_DEFINED
+// CHECK: [[@LINE+1]]:12:
+ at interface Test25 @end
+#else
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test26
+ at interface Test26 @end
+#endif
+
+#if 1 < SOMETHING_NOT_DEFINED
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test27
+ at interface Test27 @end
+#else
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test28
+ at interface Test28 @end
+#endif
+
+#if SOMETHING_NOT_DEFINED
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test29
+ at interface Test29 @end
+#endif
+
+#ifdef SOMETHING_NOT_DEFINED
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test30
+ at interface Test30 @end
+#endif
+
+#ifdef SOMETHING_DEFINED
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test31
+ at interface Test31 @end
+#elif !defined(SOMETHING_NOT_DEFINED)
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test32
+ at interface Test32 @end
+#else
+// CHECK: [[@LINE+1]]:12: ObjCInterfaceDecl=Test33
+ at interface Test33 @end
+#endif
Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=370123&r1=370122&r2=370123&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Tue Aug 27 15:15:32 2019
@@ -2181,6 +2181,34 @@ static int perform_single_file_parse(con
return result;
}
+static int perform_file_retain_excluded_cb(const char *filename) {
+ CXIndex Idx;
+ CXTranslationUnit TU;
+ enum CXErrorCode Err;
+ int result;
+
+ Idx = clang_createIndex(/* excludeDeclsFromPCH */1,
+ /* displayDiagnostics=*/1);
+
+ Err = clang_parseTranslationUnit2(Idx, filename,
+ /*command_line_args=*/NULL,
+ /*num_command_line_args=*/0,
+ /*unsaved_files=*/NULL,
+ /*num_unsaved_files=*/0,
+ CXTranslationUnit_RetainExcludedConditionalBlocks, &TU);
+ if (Err != CXError_Success) {
+ fprintf(stderr, "Unable to load translation unit!\n");
+ describeLibclangFailure(Err);
+ clang_disposeIndex(Idx);
+ return 1;
+ }
+
+ result = perform_test_load(Idx, TU, /*filter=*/"all", /*prefix=*/NULL, FilteredPrintingVisitor, /*PostVisit=*/NULL,
+ /*CommentSchemaFile=*/NULL);
+ clang_disposeIndex(Idx);
+ return result;
+}
+
/******************************************************************************/
/* Logic for testing clang_getCursor(). */
/******************************************************************************/
@@ -4849,6 +4877,8 @@ int cindextest_main(int argc, const char
}
else if (argc >= 3 && strcmp(argv[1], "-single-file-parse") == 0)
return perform_single_file_parse(argv[2]);
+ else if (argc >= 3 && strcmp(argv[1], "-retain-excluded-conditional-blocks") == 0)
+ return perform_file_retain_excluded_cb(argv[2]);
else if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0)
return perform_file_scan(argv[2], argv[3],
argc >= 5 ? argv[4] : 0);
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=370123&r1=370122&r2=370123&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Aug 27 15:15:32 2019
@@ -3417,6 +3417,8 @@ clang_parseTranslationUnit_Impl(CXIndex
= options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
bool ForSerialization = options & CXTranslationUnit_ForSerialization;
+ bool RetainExcludedCB = options &
+ CXTranslationUnit_RetainExcludedConditionalBlocks;
SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
if (options & CXTranslationUnit_SkipFunctionBodies) {
SkipFunctionBodies =
@@ -3517,7 +3519,7 @@ clang_parseTranslationUnit_Impl(CXIndex
/*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
/*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
- /*UserFilesAreVolatile=*/true, ForSerialization,
+ /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
&ErrUnit));
More information about the cfe-commits
mailing list