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];
176 bool InFixedFormSource()
const {
177 return inFixedForm_ && !inPreprocessorDirective_ && !InCompilerDirective();
180 bool IsCComment(
const char *p)
const {
181 return p[0] ==
'/' && p[1] ==
'*' &&
182 (inPreprocessorDirective_ ||
185 common::LanguageFeature::ClassicCComments)));
191 void SkipToEndOfLine();
192 bool MustSkipToEndOfLine()
const;
195 bool SkipToNextSignificantCharacter();
196 void SkipCComments();
198 static const char *SkipWhiteSpace(
const char *);
199 const char *SkipWhiteSpaceIncludingEmptyMacros(
const char *)
const;
200 const char *SkipWhiteSpaceAndCComments(
const char *)
const;
201 const char *SkipCComment(
const char *)
const;
206 void QuotedCharacterLiteral(
TokenSequence &,
const char *start);
207 void Hollerith(
TokenSequence &,
int count,
const char *start);
209 bool SkipCommentLine(
bool afterAmpersand);
210 bool IsFixedFormCommentLine(
const char *)
const;
211 const char *IsFreeFormComment(
const char *)
const;
212 std::optional<std::size_t> IsIncludeLine(
const char *)
const;
213 void FortranInclude(
const char *quote);
214 const char *IsPreprocessorDirectiveLine(
const char *)
const;
215 const char *FixedFormContinuationLine(
bool atNewline);
216 const char *FreeFormContinuationLine(
bool ampersand);
217 bool IsImplicitContinuation()
const;
218 bool FixedFormContinuation(
bool atNewline);
219 bool FreeFormContinuation();
220 bool Continuation(
bool mightNeedFixedFormSpace);
221 std::optional<LineClassification> IsFixedFormCompilerDirectiveLine(
223 std::optional<LineClassification> IsFreeFormCompilerDirectiveLine(
225 LineClassification ClassifyLine(
const char *)
const;
226 LineClassification ClassifyLine(
228 void SourceFormChange(std::string &&);
229 bool CompilerDirectiveContinuation(
TokenSequence &,
const char *sentinel);
237 bool preprocessingOnly_{
false};
238 bool expandIncludeLines_{
true};
239 bool isNestedInIncludeDirective_{
false};
240 bool backslashFreeFormContinuation_{
false};
241 bool inFixedForm_{
false};
242 int fixedFormColumnLimit_{72};
243 Encoding encoding_{Encoding::UTF_8};
244 int parenthesisNesting_{0};
245 int prescannerNesting_{0};
246 int continuationLines_{0};
247 bool isPossibleMacroCall_{
false};
248 bool afterPreprocessingDirective_{
false};
249 bool disableSourceContinuation_{
false};
252 const char *start_{
nullptr};
253 const char *limit_{
nullptr};
254 const char *nextLine_{
nullptr};
255 const char *directiveSentinel_{
nullptr};
259 const char *at_{
nullptr};
261 bool tabInCurrentLine_{
false};
262 bool slashInCurrentStatement_{
false};
263 bool preventHollerith_{
false};
264 bool inCharLiteral_{
false};
265 bool continuationInCharLiteral_{
false};
266 bool inPreprocessorDirective_{
false};
276 bool brokenToken_{
false};
283 bool omitNewline_{
false};
284 bool skipLeadingAmpersand_{
false};
286 const std::size_t firstCookedCharacterOffset_{cooked_.BufferedBytes()};
289 allSources_.CompilerInsertionProvenance(
' ')};
291 allSources_.CompilerInsertionProvenance(
'\\')};
295 static const int prime1{1019}, prime2{1021};
296 std::bitset<prime2> compilerDirectiveBloomFilter_;
297 std::unordered_set<std::string> compilerDirectiveSentinels_;