Skip to content

Commit ae79ebe

Browse files
nishithshah2211Nishith Shah
authored andcommitted
Pass LangOpts from CompilerInstance to DependencyScanningWorker
This commit fixes #88896 by passing LangOpts from the CompilerInstance to DependencyScanningWorker so that the original LangOpts are preserved/respected. This makes for more accurate parsing/lexing when certain language versions or features specific to versions are to be used.
1 parent d4ff961 commit ae79ebe

File tree

8 files changed

+47
-27
lines changed

8 files changed

+47
-27
lines changed

clang/include/clang/Lex/DependencyDirectivesScanner.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
1818
#define LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
1919

20+
#include "clang/Basic/LangOptions.h"
2021
#include "clang/Basic/SourceLocation.h"
2122
#include "llvm/ADT/ArrayRef.h"
2223

@@ -117,7 +118,7 @@ struct Directive {
117118
bool scanSourceForDependencyDirectives(
118119
StringRef Input, SmallVectorImpl<dependency_directives_scan::Token> &Tokens,
119120
SmallVectorImpl<dependency_directives_scan::Directive> &Directives,
120-
DiagnosticsEngine *Diags = nullptr,
121+
const LangOptions &LangOpts, DiagnosticsEngine *Diags = nullptr,
121122
SourceLocation InputSourceLoc = SourceLocation());
122123

123124
/// Print the previously scanned dependency directives as minimized source text.

clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ class DependencyScanningWorkerFilesystem
363363
///
364364
/// Returns true if the directive tokens are populated for this file entry,
365365
/// false if not (i.e. this entry is not a file or its scan fails).
366-
bool ensureDirectiveTokensArePopulated(EntryRef Entry);
366+
bool ensureDirectiveTokensArePopulated(EntryRef Entry,
367+
const LangOptions &LangOpts);
367368

368369
/// Check whether \p Path exists. By default checks cached result of \c
369370
/// status(), and falls back on FS if unable to do so.

clang/lib/Frontend/FrontendActions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,8 +1168,8 @@ void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() {
11681168
llvm::SmallVector<dependency_directives_scan::Token, 16> Tokens;
11691169
llvm::SmallVector<dependency_directives_scan::Directive, 32> Directives;
11701170
if (scanSourceForDependencyDirectives(
1171-
FromFile.getBuffer(), Tokens, Directives, &CI.getDiagnostics(),
1172-
SM.getLocForStartOfFile(SM.getMainFileID()))) {
1171+
FromFile.getBuffer(), Tokens, Directives, CI.getLangOpts(),
1172+
&CI.getDiagnostics(), SM.getLocForStartOfFile(SM.getMainFileID()))) {
11731173
assert(CI.getDiagnostics().hasErrorOccurred() &&
11741174
"no errors reported for failure");
11751175

clang/lib/Lex/DependencyDirectivesScanner.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,17 @@ struct DirectiveWithTokens {
6262
struct Scanner {
6363
Scanner(StringRef Input,
6464
SmallVectorImpl<dependency_directives_scan::Token> &Tokens,
65-
DiagnosticsEngine *Diags, SourceLocation InputSourceLoc)
65+
DiagnosticsEngine *Diags, SourceLocation InputSourceLoc,
66+
const LangOptions &LangOpts)
6667
: Input(Input), Tokens(Tokens), Diags(Diags),
67-
InputSourceLoc(InputSourceLoc), LangOpts(getLangOptsForDepScanning()),
68-
TheLexer(InputSourceLoc, LangOpts, Input.begin(), Input.begin(),
68+
InputSourceLoc(InputSourceLoc),
69+
LangOpts(getLangOptsForDepScanning(LangOpts)),
70+
TheLexer(InputSourceLoc, this->LangOpts, Input.begin(), Input.begin(),
6971
Input.end()) {}
7072

71-
static LangOptions getLangOptsForDepScanning() {
72-
LangOptions LangOpts;
73+
static LangOptions
74+
getLangOptsForDepScanning(const LangOptions &invocationLangOpts) {
75+
LangOptions LangOpts(invocationLangOpts);
7376
// Set the lexer to use 'tok::at' for '@', instead of 'tok::unknown'.
7477
LangOpts.ObjC = true;
7578
LangOpts.LineComment = true;
@@ -700,7 +703,7 @@ bool Scanner::lex_Pragma(const char *&First, const char *const End) {
700703
SmallVector<dependency_directives_scan::Token> DiscardTokens;
701704
const char *Begin = Buffer.c_str();
702705
Scanner PragmaScanner{StringRef(Begin, Buffer.size()), DiscardTokens, Diags,
703-
InputSourceLoc};
706+
InputSourceLoc, LangOptions()};
704707

705708
PragmaScanner.TheLexer.setParsingPreprocessorDirective(true);
706709
if (PragmaScanner.lexPragma(Begin, Buffer.end()))
@@ -950,9 +953,10 @@ bool Scanner::scan(SmallVectorImpl<Directive> &Directives) {
950953

951954
bool clang::scanSourceForDependencyDirectives(
952955
StringRef Input, SmallVectorImpl<dependency_directives_scan::Token> &Tokens,
953-
SmallVectorImpl<Directive> &Directives, DiagnosticsEngine *Diags,
954-
SourceLocation InputSourceLoc) {
955-
return Scanner(Input, Tokens, Diags, InputSourceLoc).scan(Directives);
956+
SmallVectorImpl<Directive> &Directives, const LangOptions &LangOpts,
957+
DiagnosticsEngine *Diags, SourceLocation InputSourceLoc) {
958+
return Scanner(Input, Tokens, Diags, InputSourceLoc, LangOpts)
959+
.scan(Directives);
956960
}
957961

958962
void clang::printDependencyDirectivesAsSource(

clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ DependencyScanningWorkerFilesystem::readFile(StringRef Filename) {
4242
}
4343

4444
bool DependencyScanningWorkerFilesystem::ensureDirectiveTokensArePopulated(
45-
EntryRef Ref) {
45+
EntryRef Ref, const LangOptions &LangOpts) {
4646
auto &Entry = Ref.Entry;
4747

4848
if (Entry.isError() || Entry.isDirectory())
@@ -66,7 +66,7 @@ bool DependencyScanningWorkerFilesystem::ensureDirectiveTokensArePopulated(
6666
// dependencies.
6767
if (scanSourceForDependencyDirectives(Contents->Original->getBuffer(),
6868
Contents->DepDirectiveTokens,
69-
Directives)) {
69+
Directives, LangOpts)) {
7070
Contents->DepDirectiveTokens.clear();
7171
// FIXME: Propagate the diagnostic if desired by the client.
7272
Contents->DepDirectives.store(new std::optional<DependencyDirectivesTy>());

clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,12 @@ class DependencyScanningAction : public tooling::ToolAction {
366366
// Use the dependency scanning optimized file system if requested to do so.
367367
if (DepFS)
368368
ScanInstance.getPreprocessorOpts().DependencyDirectivesForFile =
369-
[LocalDepFS = DepFS](FileEntryRef File)
369+
[LocalDepFS = DepFS,
370+
&LangOpts = ScanInstance.getLangOpts()](FileEntryRef File)
370371
-> std::optional<ArrayRef<dependency_directives_scan::Directive>> {
371372
if (llvm::ErrorOr<EntryRef> Entry =
372373
LocalDepFS->getOrCreateFileSystemEntry(File.getName()))
373-
if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry))
374+
if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry, LangOpts))
374375
return Entry->getDirectiveTokens();
375376
return std::nullopt;
376377
};

clang/unittests/Lex/DependencyDirectivesScannerTest.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ using namespace clang::dependency_directives_scan;
1717
static bool minimizeSourceToDependencyDirectives(
1818
StringRef Input, SmallVectorImpl<char> &Out,
1919
SmallVectorImpl<dependency_directives_scan::Token> &Tokens,
20-
SmallVectorImpl<Directive> &Directives) {
20+
SmallVectorImpl<Directive> &Directives, const LangOptions &LangOpts) {
2121
Out.clear();
2222
Tokens.clear();
2323
Directives.clear();
24-
if (scanSourceForDependencyDirectives(Input, Tokens, Directives))
24+
if (scanSourceForDependencyDirectives(Input, Tokens, Directives, LangOpts))
2525
return true;
2626

2727
raw_svector_ostream OS(Out);
@@ -38,7 +38,9 @@ static bool minimizeSourceToDependencyDirectives(StringRef Input,
3838
SmallVectorImpl<char> &Out) {
3939
SmallVector<dependency_directives_scan::Token, 16> Tokens;
4040
SmallVector<Directive, 32> Directives;
41-
return minimizeSourceToDependencyDirectives(Input, Out, Tokens, Directives);
41+
LangOptions LangOpts;
42+
return minimizeSourceToDependencyDirectives(Input, Out, Tokens, Directives,
43+
LangOpts);
4244
}
4345

4446
namespace {
@@ -47,16 +49,19 @@ TEST(MinimizeSourceToDependencyDirectivesTest, Empty) {
4749
SmallVector<char, 128> Out;
4850
SmallVector<dependency_directives_scan::Token, 4> Tokens;
4951
SmallVector<Directive, 4> Directives;
52+
LangOptions LangOpts;
5053

5154
ASSERT_FALSE(
52-
minimizeSourceToDependencyDirectives("", Out, Tokens, Directives));
55+
minimizeSourceToDependencyDirectives("", Out, Tokens, Directives,
56+
LangOpts));
5357
EXPECT_TRUE(Out.empty());
5458
EXPECT_TRUE(Tokens.empty());
5559
ASSERT_EQ(1u, Directives.size());
5660
ASSERT_EQ(pp_eof, Directives.back().Kind);
5761

5862
ASSERT_FALSE(minimizeSourceToDependencyDirectives("abc def\nxyz", Out, Tokens,
59-
Directives));
63+
Directives,
64+
LangOpts));
6065
EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
6166
EXPECT_TRUE(Tokens.empty());
6267
ASSERT_EQ(2u, Directives.size());
@@ -68,6 +73,7 @@ TEST(MinimizeSourceToDependencyDirectivesTest, AllTokens) {
6873
SmallVector<char, 128> Out;
6974
SmallVector<dependency_directives_scan::Token, 4> Tokens;
7075
SmallVector<Directive, 4> Directives;
76+
LangOptions LangOpts;
7177

7278
ASSERT_FALSE(
7379
minimizeSourceToDependencyDirectives("#define A\n"
@@ -92,7 +98,7 @@ TEST(MinimizeSourceToDependencyDirectivesTest, AllTokens) {
9298
"export module m;\n"
9399
"import m;\n"
94100
"#pragma clang system_header\n",
95-
Out, Tokens, Directives));
101+
Out, Tokens, Directives, LangOpts));
96102
EXPECT_EQ(pp_define, Directives[0].Kind);
97103
EXPECT_EQ(pp_undef, Directives[1].Kind);
98104
EXPECT_EQ(pp_endif, Directives[2].Kind);
@@ -145,9 +151,11 @@ TEST(MinimizeSourceToDependencyDirectivesTest, Define) {
145151
SmallVector<char, 128> Out;
146152
SmallVector<dependency_directives_scan::Token, 4> Tokens;
147153
SmallVector<Directive, 4> Directives;
154+
LangOptions LangOpts;
148155

149156
ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO", Out,
150-
Tokens, Directives));
157+
Tokens, Directives,
158+
LangOpts));
151159
EXPECT_STREQ("#define MACRO\n", Out.data());
152160
ASSERT_EQ(4u, Tokens.size());
153161
ASSERT_EQ(2u, Directives.size());
@@ -838,6 +846,7 @@ TEST(MinimizeSourceToDependencyDirectivesTest, PragmaOnce) {
838846
SmallVector<char, 128> Out;
839847
SmallVector<dependency_directives_scan::Token, 4> Tokens;
840848
SmallVector<Directive, 4> Directives;
849+
LangOptions LangOpts;
841850

842851
StringRef Source = R"(// comment
843852
#pragma once
@@ -846,7 +855,8 @@ TEST(MinimizeSourceToDependencyDirectivesTest, PragmaOnce) {
846855
_Pragma("once")
847856
)";
848857
ASSERT_FALSE(
849-
minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
858+
minimizeSourceToDependencyDirectives(Source, Out, Tokens,
859+
Directives, LangOpts));
850860
EXPECT_STREQ("#pragma once\n#include <test.h>\n_Pragma(\"once\")\n",
851861
Out.data());
852862
ASSERT_EQ(Directives.size(), 4u);
@@ -926,6 +936,7 @@ TEST(MinimizeSourceToDependencyDirectivesTest, CxxModules) {
926936
SmallVector<char, 128> Out;
927937
SmallVector<dependency_directives_scan::Token, 4> Tokens;
928938
SmallVector<Directive, 4> Directives;
939+
LangOptions LangOpts;
929940

930941
StringRef Source = R"(
931942
module;
@@ -955,7 +966,8 @@ ort \
955966
}
956967
)";
957968
ASSERT_FALSE(
958-
minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
969+
minimizeSourceToDependencyDirectives(Source, Out, Tokens,
970+
Directives, LangOpts));
959971
EXPECT_STREQ("#include \"textual-header.h\"\nexport module m;"
960972
"exp\\\nort import:l[[rename]];"
961973
"import<<=3;import a b d e d e f e;"

clang/unittests/Lex/PPDependencyDirectivesTest.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,15 @@ TEST_F(PPDependencyDirectivesTest, MacroGuard) {
104104
SmallVector<dependency_directives_scan::Directive> Directives;
105105
};
106106
SmallVector<std::unique_ptr<DepDirectives>> DepDirectivesObjects;
107+
LangOptions LangOpts;
107108

108109
auto getDependencyDirectives = [&](FileEntryRef File)
109110
-> std::optional<ArrayRef<dependency_directives_scan::Directive>> {
110111
DepDirectivesObjects.push_back(std::make_unique<DepDirectives>());
111112
StringRef Input = (*FileMgr.getBufferForFile(File))->getBuffer();
112113
bool Err = scanSourceForDependencyDirectives(
113114
Input, DepDirectivesObjects.back()->Tokens,
114-
DepDirectivesObjects.back()->Directives);
115+
DepDirectivesObjects.back()->Directives, LangOpts);
115116
EXPECT_FALSE(Err);
116117
return llvm::ArrayRef(DepDirectivesObjects.back()->Directives);
117118
};

0 commit comments

Comments
 (0)