@@ -261,6 +261,68 @@ struct PragmaMSOptimizeHandler : public PragmaHandler {
261261 Token &FirstToken) override ;
262262};
263263
264+ // "\#pragma fenv_access (on)".
265+ struct PragmaMSFenvAccessHandler : public PragmaHandler {
266+ PragmaMSFenvAccessHandler () : PragmaHandler(" fenv_access" ) {}
267+ void HandlePragma (Preprocessor &PP, PragmaIntroducer Introducer,
268+ Token &FirstToken) override {
269+ StringRef PragmaName = FirstToken.getIdentifierInfo ()->getName ();
270+ if (!PP.getTargetInfo ().hasStrictFP () && !PP.getLangOpts ().ExpStrictFP ) {
271+ PP.Diag (FirstToken.getLocation (), diag::warn_pragma_fp_ignored)
272+ << PragmaName;
273+ return ;
274+ }
275+
276+ Token Tok;
277+ PP.Lex (Tok);
278+ if (Tok.isNot (tok::l_paren)) {
279+ PP.Diag (Tok.getLocation (), diag::warn_pragma_expected_lparen)
280+ << PragmaName;
281+ return ;
282+ }
283+ PP.Lex (Tok); // Consume the l_paren.
284+ if (Tok.isNot (tok::identifier)) {
285+ PP.Diag (Tok.getLocation (), diag::warn_pragma_ms_fenv_access);
286+ return ;
287+ }
288+ const IdentifierInfo *II = Tok.getIdentifierInfo ();
289+ tok::OnOffSwitch OOS;
290+ if (II->isStr (" on" )) {
291+ OOS = tok::OOS_ON;
292+ PP.Lex (Tok);
293+ } else if (II->isStr (" off" )) {
294+ OOS = tok::OOS_OFF;
295+ PP.Lex (Tok);
296+ } else {
297+ PP.Diag (Tok.getLocation (), diag::warn_pragma_ms_fenv_access);
298+ return ;
299+ }
300+ if (Tok.isNot (tok::r_paren)) {
301+ PP.Diag (Tok.getLocation (), diag::warn_pragma_expected_rparen)
302+ << PragmaName;
303+ return ;
304+ }
305+ PP.Lex (Tok); // Consume the r_paren.
306+
307+ if (Tok.isNot (tok::eod)) {
308+ PP.Diag (Tok.getLocation (), diag::warn_pragma_extra_tokens_at_eol)
309+ << PragmaName;
310+ return ;
311+ }
312+
313+ MutableArrayRef<Token> Toks (
314+ PP.getPreprocessorAllocator ().Allocate <Token>(1 ), 1 );
315+ Toks[0 ].startToken ();
316+ Toks[0 ].setKind (tok::annot_pragma_fenv_access_ms);
317+ Toks[0 ].setLocation (FirstToken.getLocation ());
318+ Toks[0 ].setAnnotationEndLoc (Tok.getLocation ());
319+ Toks[0 ].setAnnotationValue (
320+ reinterpret_cast <void *>(static_cast <uintptr_t >(OOS)));
321+ PP.EnterTokenStream (Toks, /* DisableMacroExpansion=*/ true ,
322+ /* IsReinject=*/ false );
323+ }
324+ };
325+
264326struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler {
265327 PragmaForceCUDAHostDeviceHandler (Sema &Actions)
266328 : PragmaHandler(" force_cuda_host_device" ), Actions(Actions) {}
@@ -389,6 +451,8 @@ void Parser::initializePragmaHandlers() {
389451 PP.AddPragmaHandler (MSIntrinsic.get ());
390452 MSOptimize = std::make_unique<PragmaMSOptimizeHandler>();
391453 PP.AddPragmaHandler (MSOptimize.get ());
454+ MSFenvAccess = std::make_unique<PragmaMSFenvAccessHandler>();
455+ PP.AddPragmaHandler (MSFenvAccess.get ());
392456 }
393457
394458 if (getLangOpts ().CUDA ) {
@@ -496,6 +560,8 @@ void Parser::resetPragmaHandlers() {
496560 MSIntrinsic.reset ();
497561 PP.RemovePragmaHandler (MSOptimize.get ());
498562 MSOptimize.reset ();
563+ PP.RemovePragmaHandler (MSFenvAccess.get ());
564+ MSFenvAccess.reset ();
499565 }
500566
501567 if (getLangOpts ().CUDA ) {
@@ -701,7 +767,8 @@ void Parser::HandlePragmaFloatControl() {
701767}
702768
703769void Parser::HandlePragmaFEnvAccess () {
704- assert (Tok.is (tok::annot_pragma_fenv_access));
770+ assert (Tok.is (tok::annot_pragma_fenv_access) ||
771+ Tok.is (tok::annot_pragma_fenv_access_ms));
705772 tok::OnOffSwitch OOS =
706773 static_cast <tok::OnOffSwitch>(
707774 reinterpret_cast <uintptr_t >(Tok.getAnnotationValue ()));
0 commit comments