@@ -79,16 +79,24 @@ const SourceFile *Parsing::Prescan(const std::string &path, Options options) {
7979 .set_expandIncludeLines (!options.prescanAndReformat ||
8080 options.expandIncludeLinesInPreprocessedOutput )
8181 .AddCompilerDirectiveSentinel (" dir$" );
82- if (options.features .IsEnabled (LanguageFeature::OpenACC)) {
82+ bool noneOfTheAbove{!options.features .IsEnabled (LanguageFeature::OpenACC) &&
83+ !options.features .IsEnabled (LanguageFeature::OpenMP) &&
84+ !options.features .IsEnabled (LanguageFeature::CUDA)};
85+ if (options.features .IsEnabled (LanguageFeature::OpenACC) ||
86+ (options.prescanAndReformat && noneOfTheAbove)) {
8387 prescanner.AddCompilerDirectiveSentinel (" $acc" );
8488 }
85- if (options.features .IsEnabled (LanguageFeature::OpenMP)) {
89+ if (options.features .IsEnabled (LanguageFeature::OpenMP) ||
90+ (options.prescanAndReformat && noneOfTheAbove)) {
8691 prescanner.AddCompilerDirectiveSentinel (" $omp" );
8792 prescanner.AddCompilerDirectiveSentinel (" $" ); // OMP conditional line
8893 }
89- if (options.features .IsEnabled (LanguageFeature::CUDA)) {
94+ if (options.features .IsEnabled (LanguageFeature::CUDA) ||
95+ (options.prescanAndReformat && noneOfTheAbove)) {
9096 prescanner.AddCompilerDirectiveSentinel (" $cuf" );
9197 prescanner.AddCompilerDirectiveSentinel (" @cuf" );
98+ }
99+ if (options.features .IsEnabled (LanguageFeature::CUDA)) {
92100 preprocessor_.Define (" _CUDA" , " 1" );
93101 }
94102 ProvenanceRange range{allSources.AddIncludedFile (
@@ -119,11 +127,13 @@ void Parsing::EmitPreprocessedSource(
119127 int sourceLine{0 };
120128 int column{1 };
121129 bool inDirective{false };
130+ bool ompConditionalLine{false };
122131 bool inContinuation{false };
123132 bool lineWasBlankBefore{true };
124133 const AllSources &allSources{allCooked ().allSources ()};
125- // All directives that flang support are known to have a length of 3 chars
126- constexpr int directiveNameLength{3 };
134+ // All directives that flang supports are known to have a length of 4 chars,
135+ // except for OpenMP conditional compilation lines (!$).
136+ constexpr int directiveNameLength{4 };
127137 // We need to know the current directive in order to provide correct
128138 // continuation for the directive
129139 std::string directive;
@@ -133,6 +143,7 @@ void Parsing::EmitPreprocessedSource(
133143 out << ' \n ' ; // TODO: DOS CR-LF line ending if necessary
134144 column = 1 ;
135145 inDirective = false ;
146+ ompConditionalLine = false ;
136147 inContinuation = false ;
137148 lineWasBlankBefore = true ;
138149 ++sourceLine;
@@ -153,16 +164,21 @@ void Parsing::EmitPreprocessedSource(
153164 return ch;
154165 }};
155166
167+ bool inDirectiveSentinel{false };
156168 if (ch == ' !' && lineWasBlankBefore) {
157169 // Other comment markers (C, *, D) in original fixed form source
158170 // input card column 1 will have been deleted or normalized to !,
159171 // which signifies a comment (directive) in both source forms.
160172 inDirective = true ;
161- }
162- bool inDirectiveSentinel{
163- inDirective && directive.size () < directiveNameLength};
164- if (inDirectiveSentinel && IsLetter (ch)) {
165- directive += getOriginalChar (ch);
173+ inDirectiveSentinel = true ;
174+ } else if (inDirective && !ompConditionalLine &&
175+ directive.size () < directiveNameLength) {
176+ if (IsLetter (ch) || ch == ' $' || ch == ' @' ) {
177+ directive += getOriginalChar (ch);
178+ inDirectiveSentinel = true ;
179+ } else if (directive == " $" s) {
180+ ompConditionalLine = true ;
181+ }
166182 }
167183
168184 std::optional<SourcePosition> position{provenance
@@ -199,9 +215,16 @@ void Parsing::EmitPreprocessedSource(
199215 // column limit override option.
200216 // OpenMP and OpenACC directives' continuations should have the
201217 // corresponding sentinel at the next line.
202- const auto continuation{
203- inDirective ? " &\n !$" + directive + " &" : " &\n &" s};
204- out << continuation;
218+ out << " &\n " ;
219+ if (inDirective) {
220+ if (ompConditionalLine) {
221+ out << " !$ &" ;
222+ } else {
223+ out << ' !' << directive << ' &' ;
224+ }
225+ } else {
226+ out << " &" ;
227+ }
205228 column = 7 ; // start of fixed form source field
206229 ++sourceLine;
207230 inContinuation = true ;
@@ -212,11 +235,20 @@ void Parsing::EmitPreprocessedSource(
212235 out << ' ' ;
213236 }
214237 }
215- if (!inContinuation && !inDirectiveSentinel && position &&
216- position->column <= 72 && ch != ' ' ) {
217- // Preserve original indentation
218- for (; column < position->column ; ++column) {
219- out << ' ' ;
238+ if (ch != ' ' ) {
239+ if (ompConditionalLine) {
240+ // Only digits can stay in the label field
241+ if (!(ch >= ' 0' && ch <= ' 9' )) {
242+ for (; column < 7 ; ++column) {
243+ out << ' ' ;
244+ }
245+ }
246+ } else if (!inContinuation && !inDirectiveSentinel && position &&
247+ position->column <= 72 ) {
248+ // Preserve original indentation
249+ for (; column < position->column ; ++column) {
250+ out << ' ' ;
251+ }
220252 }
221253 }
222254 out << getOriginalChar (ch);
0 commit comments