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 InFixedFormSource()
const {
187 return inFixedForm_ && !inPreprocessorDirective_ && !InCompilerDirective();
190 bool IsCComment(
const char *p)
const {
191 return p[0] ==
'/' && p[1] ==
'*' &&
192 (inPreprocessorDirective_ ||
195 common::LanguageFeature::ClassicCComments)));
201 void SkipToEndOfLine();
202 bool MustSkipToEndOfLine()
const;
205 bool SkipToNextSignificantCharacter();
206 void SkipCComments();
208 static const char *SkipWhiteSpace(
const char *);
209 const char *SkipWhiteSpaceIncludingEmptyMacros(
const char *)
const;
210 const char *SkipWhiteSpaceAndCComments(
const char *)
const;
211 const char *SkipCComment(
const char *)
const;
216 void QuotedCharacterLiteral(
TokenSequence &,
const char *start);
217 void Hollerith(
TokenSequence &,
int count,
const char *start);
219 bool SkipCommentLine(
bool afterAmpersand);
220 bool IsFixedFormCommentLine(
const char *)
const;
221 const char *IsFreeFormComment(
const char *)
const;
222 std::optional<std::size_t> IsIncludeLine(
const char *)
const;
223 void FortranInclude(
const char *quote);
224 const char *IsPreprocessorDirectiveLine(
const char *)
const;
225 const char *FixedFormContinuationLine(
bool atNewline);
226 const char *FreeFormContinuationLine(
bool ampersand);
227 bool IsImplicitContinuation()
const;
228 bool FixedFormContinuation(
bool atNewline);
229 bool FreeFormContinuation();
230 bool Continuation(
bool mightNeedFixedFormSpace);
231 std::optional<LineClassification> IsFixedFormCompilerDirectiveLine(
233 std::optional<LineClassification> IsFreeFormCompilerDirectiveLine(
235 LineClassification ClassifyLine(
const char *)
const;
236 LineClassification ClassifyLine(
238 bool SourceFormChange(std::string &&);
239 bool CompilerDirectiveContinuation(
TokenSequence &,
const char *sentinel);
247 bool preprocessingOnly_{
false};
248 bool expandIncludeLines_{
true};
249 bool isNestedInIncludeDirective_{
false};
250 bool backslashFreeFormContinuation_{
false};
251 bool inFixedForm_{
false};
252 int fixedFormColumnLimit_{72};
253 Encoding encoding_{Encoding::UTF_8};
254 int parenthesisNesting_{0};
255 int prescannerNesting_{0};
256 int continuationLines_{0};
257 bool isPossibleMacroCall_{
false};
258 bool afterPreprocessingDirective_{
false};
259 bool disableSourceContinuation_{
false};
262 const char *start_{
nullptr};
263 const char *limit_{
nullptr};
264 const char *nextLine_{
nullptr};
265 const char *directiveSentinel_{
nullptr};
269 const char *at_{
nullptr};
271 bool tabInCurrentLine_{
false};
272 bool slashInCurrentStatement_{
false};
273 bool preventHollerith_{
false};
274 bool inCharLiteral_{
false};
275 bool continuationInCharLiteral_{
false};
276 bool inPreprocessorDirective_{
false};
286 bool brokenToken_{
false};
293 bool omitNewline_{
false};
294 bool skipLeadingAmpersand_{
false};
296 const std::size_t firstCookedCharacterOffset_{cooked_.BufferedBytes()};
299 allSources_.CompilerInsertionProvenance(
' ')};
301 allSources_.CompilerInsertionProvenance(
'\\')};
305 static const int prime1{1019}, prime2{1021};
306 std::bitset<prime2> compilerDirectiveBloomFilter_;
307 std::unordered_set<std::string> compilerDirectiveSentinels_;