39 const Prescanner &,
Preprocessor &,
bool isNestedInIncludeDirective);
40 Prescanner(
const Prescanner &) =
delete;
41 Prescanner(Prescanner &&) =
delete;
43 const AllSources &allSources()
const {
return allSources_; }
44 AllSources &allSources() {
return allSources_; }
45 const Messages &messages()
const {
return messages_; }
46 Messages &messages() {
return messages_; }
47 const Preprocessor &preprocessor()
const {
return preprocessor_; }
51 Prescanner &set_preprocessingOnly(
bool yes) {
52 preprocessingOnly_ = yes;
55 Prescanner &set_expandIncludeLines(
bool yes) {
56 expandIncludeLines_ = yes;
59 Prescanner &set_fixedForm(
bool yes) {
63 Prescanner &set_encoding(Encoding code) {
67 Prescanner &set_fixedFormColumnLimit(
int limit) {
68 fixedFormColumnLimit_ = limit;
72 Prescanner &AddCompilerDirectiveSentinel(
const std::string &);
74 void Prescan(ProvenanceRange);
79 bool IsAtEnd()
const {
return nextLine_ >= limit_; }
80 bool IsNextLinePreprocessorDirective()
const;
82 Provenance GetCurrentProvenance()
const {
return GetProvenance(at_); }
84 const char *IsCompilerDirectiveSentinel(
const char *, std::size_t)
const;
85 const char *IsCompilerDirectiveSentinel(
CharBlock)
const;
87 std::optional<std::pair<const char *, const char *>>
88 IsCompilerDirectiveSentinel(
const char *p)
const;
90 template <
typename... A>
Message &Say(A &&...a) {
91 return messages_.Say(std::forward<A>(a)...);
94 template <
typename... A>
95 Message *Warn(common::UsageWarning warning, A &&...a) {
96 return messages_.Warn(
false, features_, warning, std::forward<A>(a)...);
98 template <
typename... A>
99 Message *Warn(common::LanguageFeature feature, A &&...a) {
100 return messages_.Warn(
false, features_, feature, std::forward<A>(a)...);
104 struct LineClassification {
107 ConditionalCompilationDirective,
110 PreprocessorDirective,
115 LineClassification(Kind k, std::size_t po = 0,
const char *s =
nullptr)
116 : kind{k}, payloadOffset{po}, sentinel{s} {}
117 LineClassification(LineClassification &&) =
default;
118 LineClassification &operator=(LineClassification &&) =
default;
120 std::size_t payloadOffset;
121 const char *sentinel;
124 void BeginSourceLine(
const char *at) {
127 tabInCurrentLine_ =
false;
130 void BeginSourceLineAndAdvance() {
131 BeginSourceLine(nextLine_);
135 void BeginStatementAndAdvance() {
136 BeginSourceLineAndAdvance();
137 slashInCurrentStatement_ =
false;
138 preventHollerith_ =
false;
139 parenthesisNesting_ = 0;
140 continuationLines_ = 0;
141 isPossibleMacroCall_ =
false;
142 disableSourceContinuation_ =
false;
145 Provenance GetProvenance(
const char *sourceChar)
const {
146 return startProvenance_ + (sourceChar - start_);
149 ProvenanceRange GetProvenanceRange(
150 const char *first,
const char *afterLast)
const {
151 std::size_t bytes = afterLast - first;
152 return {startProvenance_ + (first - start_), bytes};
156 tokens.PutNextTokenChar(ch, GetCurrentProvenance());
160 Provenance provenance{allSources_.CompilerInsertionProvenance(ch)};
161 tokens.PutNextTokenChar(ch, provenance);
165 EmitChar(tokens, ch);
170 bool InCompilerDirective()
const {
return directiveSentinel_ !=
nullptr; }
171 bool InOpenMPConditionalLine()
const {
172 return directiveSentinel_ && directiveSentinel_[0] ==
'$' &&
173 !directiveSentinel_[1];
175 bool InOpenACCOrCUDAConditionalLine()
const {
176 return directiveSentinel_ && directiveSentinel_[0] ==
'@' &&
177 ((directiveSentinel_[1] ==
'a' && directiveSentinel_[2] ==
'c' &&
178 directiveSentinel_[3] ==
'c') ||
179 (directiveSentinel_[1] ==
'c' && directiveSentinel_[2] ==
'u' &&
180 directiveSentinel_[3] ==
'f')) &&
181 directiveSentinel_[4] ==
'\0';
183 bool InConditionalLine()
const {
184 return InOpenMPConditionalLine() || InOpenACCOrCUDAConditionalLine();
186 bool IsOpenMPDirective()
const {
187 return directiveSentinel_ && std::strcmp(directiveSentinel_,
"$omp") == 0;
189 bool InFixedFormSource()
const {
190 return inFixedForm_ && !inPreprocessorDirective_ && !InCompilerDirective();
193 bool IsCComment(
const char *p)
const {
194 return p[0] ==
'/' && p[1] ==
'*' &&
195 (inPreprocessorDirective_ ||
198 common::LanguageFeature::ClassicCComments)));
204 void SkipToEndOfLine();
205 bool MustSkipToEndOfLine()
const;
208 bool SkipToNextSignificantCharacter();
209 void SkipCComments();
211 static const char *SkipWhiteSpace(
const char *);
212 const char *SkipWhiteSpaceIncludingEmptyMacros(
const char *)
const;
213 const char *SkipWhiteSpaceAndCComments(
const char *)
const;
214 const char *SkipCComment(
const char *)
const;
219 void QuotedCharacterLiteral(
TokenSequence &,
const char *start);
220 void Hollerith(
TokenSequence &,
int count,
const char *start);
222 bool SkipCommentLine(
bool afterAmpersand);
223 bool IsFixedFormCommentLine(
const char *)
const;
224 const char *IsFreeFormComment(
const char *)
const;
225 std::optional<std::size_t> IsIncludeLine(
const char *)
const;
226 void FortranInclude(
const char *quote);
227 const char *IsPreprocessorDirectiveLine(
const char *)
const;
228 const char *FixedFormContinuationLine(
bool atNewline);
229 const char *FreeFormContinuationLine(
bool ampersand);
230 bool IsImplicitContinuation()
const;
231 bool FixedFormContinuation(
bool atNewline);
232 bool FreeFormContinuation();
233 bool Continuation(
bool mightNeedFixedFormSpace);
234 std::optional<LineClassification> IsFixedFormCompilerDirectiveLine(
236 std::optional<LineClassification> IsFreeFormCompilerDirectiveLine(
238 LineClassification ClassifyLine(
const char *)
const;
239 LineClassification ClassifyLine(
241 bool SourceFormChange(std::string &&);
242 bool CompilerDirectiveContinuation(
TokenSequence &,
const char *sentinel);
250 bool preprocessingOnly_{
false};
251 bool expandIncludeLines_{
true};
252 bool isNestedInIncludeDirective_{
false};
253 bool backslashFreeFormContinuation_{
false};
254 bool inFixedForm_{
false};
255 int fixedFormColumnLimit_{72};
256 Encoding encoding_{Encoding::UTF_8};
257 int parenthesisNesting_{0};
258 int prescannerNesting_{0};
259 int continuationLines_{0};
260 bool isPossibleMacroCall_{
false};
261 bool afterPreprocessingDirective_{
false};
262 bool disableSourceContinuation_{
false};
265 const char *start_{
nullptr};
266 const char *limit_{
nullptr};
267 const char *nextLine_{
nullptr};
268 const char *directiveSentinel_{
nullptr};
272 const char *at_{
nullptr};
274 bool tabInCurrentLine_{
false};
275 bool slashInCurrentStatement_{
false};
276 bool preventHollerith_{
false};
277 bool inCharLiteral_{
false};
278 bool continuationInCharLiteral_{
false};
279 bool inPreprocessorDirective_{
false};
289 bool brokenToken_{
false};
296 bool omitNewline_{
false};
297 bool skipLeadingAmpersand_{
false};
299 const std::size_t firstCookedCharacterOffset_{cooked_.BufferedBytes()};
302 allSources_.CompilerInsertionProvenance(
' ')};
304 allSources_.CompilerInsertionProvenance(
'\\')};
308 static const int prime1{1019}, prime2{1021};
309 std::bitset<prime2> compilerDirectiveBloomFilter_;
310 std::unordered_set<std::string> compilerDirectiveSentinels_;