Mercurial > hg > CbC > CbC_llvm
diff clang/lib/Parse/ParsePragma.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | c4bab56944e8 |
line wrap: on
line diff
--- a/clang/lib/Parse/ParsePragma.cpp Mon May 25 11:55:54 2020 +0900 +++ b/clang/lib/Parse/ParsePragma.cpp Tue Jun 08 06:07:14 2021 +0900 @@ -14,11 +14,13 @@ #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/Token.h" #include "clang/Parse/LoopHint.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/Scope.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringSwitch.h" using namespace clang; @@ -103,13 +105,15 @@ void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) override { + Token PragmaName = Tok; + if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored) + << PragmaName.getIdentifierInfo()->getName(); + return; + } tok::OnOffSwitch OOS; if (PP.LexOnOffSwitch(OOS)) return; - if (OOS == tok::OOS_ON) { - PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported); - return; - } MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), 1); @@ -135,6 +139,14 @@ } }; +/// Handler for "\#pragma STDC FENV_ROUND ...". +struct PragmaSTDC_FENV_ROUNDHandler : public PragmaHandler { + PragmaSTDC_FENV_ROUNDHandler() : PragmaHandler("FENV_ROUND") {} + + void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, + Token &Tok) override; +}; + /// PragmaSTDC_UnknownHandler - "\#pragma STDC ...". struct PragmaSTDC_UnknownHandler : public PragmaHandler { PragmaSTDC_UnknownHandler() = default; @@ -282,6 +294,10 @@ Token &FirstToken) override; }; +void markAsReinjectedForRelexing(llvm::MutableArrayRef<clang::Token> Toks) { + for (auto &T : Toks) + T.setFlag(clang::Token::IsReinjected); +} } // end namespace void Parser::initializePragmaHandlers() { @@ -312,8 +328,11 @@ FPContractHandler = std::make_unique<PragmaFPContractHandler>(); PP.AddPragmaHandler("STDC", FPContractHandler.get()); - STDCFENVHandler = std::make_unique<PragmaSTDC_FENV_ACCESSHandler>(); - PP.AddPragmaHandler("STDC", STDCFENVHandler.get()); + STDCFenvAccessHandler = std::make_unique<PragmaSTDC_FENV_ACCESSHandler>(); + PP.AddPragmaHandler("STDC", STDCFenvAccessHandler.get()); + + STDCFenvRoundHandler = std::make_unique<PragmaSTDC_FENV_ROUNDHandler>(); + PP.AddPragmaHandler("STDC", STDCFenvRoundHandler.get()); STDCCXLIMITHandler = std::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>(); PP.AddPragmaHandler("STDC", STDCCXLIMITHandler.get()); @@ -386,9 +405,11 @@ UnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>("unroll"); PP.AddPragmaHandler(UnrollHintHandler.get()); + PP.AddPragmaHandler("GCC", UnrollHintHandler.get()); NoUnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>("nounroll"); PP.AddPragmaHandler(NoUnrollHintHandler.get()); + PP.AddPragmaHandler("GCC", NoUnrollHintHandler.get()); UnrollAndJamHintHandler = std::make_unique<PragmaUnrollHintHandler>("unroll_and_jam"); @@ -485,8 +506,11 @@ PP.RemovePragmaHandler("STDC", FPContractHandler.get()); FPContractHandler.reset(); - PP.RemovePragmaHandler("STDC", STDCFENVHandler.get()); - STDCFENVHandler.reset(); + PP.RemovePragmaHandler("STDC", STDCFenvAccessHandler.get()); + STDCFenvAccessHandler.reset(); + + PP.RemovePragmaHandler("STDC", STDCFenvRoundHandler.get()); + STDCFenvRoundHandler.reset(); PP.RemovePragmaHandler("STDC", STDCCXLIMITHandler.get()); STDCCXLIMITHandler.reset(); @@ -501,9 +525,11 @@ LoopHintHandler.reset(); PP.RemovePragmaHandler(UnrollHintHandler.get()); + PP.RemovePragmaHandler("GCC", UnrollHintHandler.get()); UnrollHintHandler.reset(); PP.RemovePragmaHandler(NoUnrollHintHandler.get()); + PP.RemovePragmaHandler("GCC", NoUnrollHintHandler.get()); NoUnrollHintHandler.reset(); PP.RemovePragmaHandler(UnrollAndJamHintHandler.get()); @@ -654,8 +680,8 @@ break; } - Actions.ActOnPragmaFPContract(FPC); - ConsumeAnnotationToken(); + SourceLocation PragmaLoc = ConsumeAnnotationToken(); + Actions.ActOnPragmaFPContract(PragmaLoc, FPC); } void Parser::HandlePragmaFloatControl() { @@ -697,6 +723,14 @@ Actions.ActOnPragmaFEnvAccess(PragmaLoc, IsEnabled); } +void Parser::HandlePragmaFEnvRound() { + assert(Tok.is(tok::annot_pragma_fenv_round)); + auto RM = static_cast<llvm::RoundingMode>( + reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); + + SourceLocation PragmaLoc = ConsumeAnnotationToken(); + Actions.setRoundingMode(PragmaLoc, RM); +} StmtResult Parser::HandlePragmaCaptured() { @@ -747,26 +781,25 @@ // overriding all previously issued extension directives, but only if the // behavior is set to disable." if (Name == "all") { - if (State == Disable) { + if (State == Disable) Opt.disableAll(); - Opt.enableSupportedCore(getLangOpts()); - } else { + else PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1; - } } else if (State == Begin) { if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) { Opt.support(Name); + // FIXME: Default behavior of the extension pragma is not defined. + // Therefore, it should never be added by default. + Opt.acceptsPragma(Name); } - Actions.setCurrentOpenCLExtension(Name); } else if (State == End) { - if (Name != Actions.getCurrentOpenCLExtension()) - PP.Diag(NameLoc, diag::warn_pragma_begin_end_mismatch); - Actions.setCurrentOpenCLExtension(""); - } else if (!Opt.isKnown(Name)) + // There is no behavior for this directive. We only accept this for + // backward compatibility. + } else if (!Opt.isKnown(Name) || !Opt.isWithPragma(Name)) PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident; else if (Opt.isSupportedExtension(Name, getLangOpts())) Opt.enable(Name, State == Enable); - else if (Opt.isSupportedCore(Name, getLangOpts())) + else if (Opt.isSupportedCoreOrOptionalCore(Name, getLangOpts())) PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident; else PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident; @@ -1163,12 +1196,79 @@ Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << PragmaLoopHintString(Info->PragmaName, Info->Option); Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo); + } else if (OptionInfo && OptionInfo->getName() == "vectorize_width") { + PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false, + /*IsReinject=*/false); + ConsumeAnnotationToken(); + + SourceLocation StateLoc = Toks[0].getLocation(); + IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo(); + StringRef IsScalableStr = StateInfo ? StateInfo->getName() : ""; + + // Look for vectorize_width(fixed|scalable) + if (IsScalableStr == "scalable" || IsScalableStr == "fixed") { + PP.Lex(Tok); // Identifier + + if (Toks.size() > 2) { + Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) + << PragmaLoopHintString(Info->PragmaName, Info->Option); + while (Tok.isNot(tok::eof)) + ConsumeAnyToken(); + } + + Hint.StateLoc = + IdentifierLoc::create(Actions.Context, StateLoc, StateInfo); + + ConsumeToken(); // Consume the constant expression eof terminator. + } else { + // Enter constant expression including eof terminator into token stream. + ExprResult R = ParseConstantExpression(); + + if (R.isInvalid() && !Tok.is(tok::comma)) + Diag(Toks[0].getLocation(), + diag::note_pragma_loop_invalid_vectorize_option); + + bool Arg2Error = false; + if (Tok.is(tok::comma)) { + PP.Lex(Tok); // , + + StateInfo = Tok.getIdentifierInfo(); + IsScalableStr = StateInfo->getName(); + + if (IsScalableStr != "scalable" && IsScalableStr != "fixed") { + Diag(Tok.getLocation(), + diag::err_pragma_loop_invalid_vectorize_option); + Arg2Error = true; + } else + Hint.StateLoc = + IdentifierLoc::create(Actions.Context, StateLoc, StateInfo); + + PP.Lex(Tok); // Identifier + } + + // Tokens following an error in an ill-formed constant expression will + // remain in the token stream and must be removed. + if (Tok.isNot(tok::eof)) { + Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) + << PragmaLoopHintString(Info->PragmaName, Info->Option); + while (Tok.isNot(tok::eof)) + ConsumeAnyToken(); + } + + ConsumeToken(); // Consume the constant expression eof terminator. + + if (Arg2Error || R.isInvalid() || + Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation())) + return false; + + // Argument is a constant expression with an integer type. + Hint.ValueExpr = R.get(); + } } else { // Enter constant expression including eof terminator into token stream. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false, /*IsReinject=*/false); ConsumeAnnotationToken(); - ExprResult R = ParseConstantExpression(); // Tokens following an error in an ill-formed constant expression will @@ -1712,9 +1812,10 @@ // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting // the push/pop stack. - // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4) - Action = - PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set; + // In Apple gcc/XL, #pragma pack(4) is equivalent to #pragma pack(push, 4) + Action = (PP.getLangOpts().ApplePragmaPack || PP.getLangOpts().XLPragmaPack) + ? Sema::PSK_Push_Set + : Sema::PSK_Set; } else if (Tok.is(tok::identifier)) { const IdentifierInfo *II = Tok.getIdentifierInfo(); if (II->isStr("show")) { @@ -1762,10 +1863,12 @@ } } } - } else if (PP.getLangOpts().ApplePragmaPack) { + } else if (PP.getLangOpts().ApplePragmaPack || + PP.getLangOpts().XLPragmaPack) { // In MSVC/gcc, #pragma pack() resets the alignment without affecting // the push/pop stack. - // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop). + // In Apple gcc and IBM XL, #pragma pack() is equivalent to #pragma + // pack(pop). Action = Sema::PSK_Pop; } @@ -1894,6 +1997,7 @@ // #pragma 'align' '=' {'native','natural','mac68k','power','reset'} // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'} +// #pragma 'align' '(' {'native','natural','mac68k','power','reset'} ')' static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, bool IsOptions) { Token Tok; @@ -1908,7 +2012,12 @@ } PP.Lex(Tok); - if (Tok.isNot(tok::equal)) { + if (PP.getLangOpts().XLPragmaPack) { + if (Tok.isNot(tok::l_paren)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "align"; + return; + } + } else if (Tok.isNot(tok::equal)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal) << IsOptions; return; @@ -1941,6 +2050,14 @@ return; } + if (PP.getLangOpts().XLPragmaPack) { + PP.Lex(Tok); + if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "align"; + return; + } + } + SourceLocation EndLoc = Tok.getLocation(); PP.Lex(Tok); if (Tok.isNot(tok::eod)) { @@ -2510,6 +2627,7 @@ TokenVector.push_back(EoF); // We must allocate this array with new because EnterTokenStream is going to // delete it later. + markAsReinjectedForRelexing(TokenVector); auto TokenArray = std::make_unique<Token[]>(TokenVector.size()); std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get()); auto Value = new (PP.getPreprocessorAllocator()) @@ -2535,6 +2653,12 @@ Token &Tok) { Sema::PragmaMsStackAction Action = Sema::PSK_Set; SourceLocation FloatControlLoc = Tok.getLocation(); + Token PragmaName = Tok; + if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored) + << PragmaName.getIdentifierInfo()->getName(); + return; + } PP.Lex(Tok); if (Tok.isNot(tok::l_paren)) { PP.Diag(FloatControlLoc, diag::err_expected) << tok::l_paren; @@ -2725,7 +2849,7 @@ return; } - // Verify that this is one of the 5 whitelisted options. + // Verify that this is one of the 5 explicitly listed options. IdentifierInfo *II = Tok.getIdentifierInfo(); PragmaMSCommentKind Kind = llvm::StringSwitch<PragmaMSCommentKind>(II->getName()) @@ -2766,7 +2890,7 @@ // FIXME: If the kind is "compiler" warn if the string is present (it is // ignored). // The MSDN docs say that "lib" and "linker" require a string and have a short - // whitelist of linker options they support, but in practice MSVC doesn't + // list of linker options they support, but in practice MSVC doesn't // issue a diagnostic. Therefore neither does clang. if (Tok.isNot(tok::r_paren)) { @@ -2828,11 +2952,12 @@ namespace { /// Used as the annotation value for tok::annot_pragma_fp. struct TokFPAnnotValue { - enum FlagKinds { Contract, Reassociate }; + enum FlagKinds { Contract, Reassociate, Exceptions }; enum FlagValues { On, Off, Fast }; - FlagKinds FlagKind; - FlagValues FlagValue; + llvm::Optional<LangOptions::FPModeKind> ContractValue; + llvm::Optional<LangOptions::FPModeKind> ReassociateValue; + llvm::Optional<LangOptions::FPExceptionModeKind> ExceptionsValue; }; } // end anonymous namespace @@ -2849,6 +2974,7 @@ return; } + auto *AnnotValue = new (PP.getPreprocessorAllocator()) TokFPAnnotValue; while (Tok.is(tok::identifier)) { IdentifierInfo *OptionInfo = Tok.getIdentifierInfo(); @@ -2857,6 +2983,7 @@ OptionInfo->getName()) .Case("contract", TokFPAnnotValue::Contract) .Case("reassociate", TokFPAnnotValue::Reassociate) + .Case("exceptions", TokFPAnnotValue::Exceptions) .Default(None); if (!FlagKind) { PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option) @@ -2875,25 +3002,49 @@ if (Tok.isNot(tok::identifier)) { PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument) << PP.getSpelling(Tok) << OptionInfo->getName() - << (FlagKind == TokFPAnnotValue::Reassociate); + << static_cast<int>(*FlagKind); return; } const IdentifierInfo *II = Tok.getIdentifierInfo(); - auto FlagValue = - llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>( - II->getName()) - .Case("on", TokFPAnnotValue::On) - .Case("off", TokFPAnnotValue::Off) - .Case("fast", TokFPAnnotValue::Fast) - .Default(llvm::None); - - if (!FlagValue || (FlagKind == TokFPAnnotValue::Reassociate && - FlagValue == TokFPAnnotValue::Fast)) { - PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument) - << PP.getSpelling(Tok) << OptionInfo->getName() - << (FlagKind == TokFPAnnotValue::Reassociate); - return; + if (FlagKind == TokFPAnnotValue::Contract) { + AnnotValue->ContractValue = + llvm::StringSwitch<llvm::Optional<LangOptions::FPModeKind>>( + II->getName()) + .Case("on", LangOptions::FPModeKind::FPM_On) + .Case("off", LangOptions::FPModeKind::FPM_Off) + .Case("fast", LangOptions::FPModeKind::FPM_Fast) + .Default(llvm::None); + if (!AnnotValue->ContractValue) { + PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument) + << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind; + return; + } + } else if (FlagKind == TokFPAnnotValue::Reassociate) { + AnnotValue->ReassociateValue = + llvm::StringSwitch<llvm::Optional<LangOptions::FPModeKind>>( + II->getName()) + .Case("on", LangOptions::FPModeKind::FPM_On) + .Case("off", LangOptions::FPModeKind::FPM_Off) + .Default(llvm::None); + if (!AnnotValue->ReassociateValue) { + PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument) + << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind; + return; + } + } else if (FlagKind == TokFPAnnotValue::Exceptions) { + AnnotValue->ExceptionsValue = + llvm::StringSwitch<llvm::Optional<LangOptions::FPExceptionModeKind>>( + II->getName()) + .Case("ignore", LangOptions::FPE_Ignore) + .Case("maytrap", LangOptions::FPE_MayTrap) + .Case("strict", LangOptions::FPE_Strict) + .Default(llvm::None); + if (!AnnotValue->ExceptionsValue) { + PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument) + << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind; + return; + } } PP.Lex(Tok); @@ -2903,17 +3054,6 @@ return; } PP.Lex(Tok); - - auto *AnnotValue = new (PP.getPreprocessorAllocator()) - TokFPAnnotValue{*FlagKind, *FlagValue}; - // Generate the fp annotation token. - Token FPTok; - FPTok.startToken(); - FPTok.setKind(tok::annot_pragma_fp); - FPTok.setLocation(PragmaName.getLocation()); - FPTok.setAnnotationEndLoc(PragmaName.getLocation()); - FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue)); - TokenList.push_back(FPTok); } if (Tok.isNot(tok::eod)) { @@ -2922,6 +3062,14 @@ return; } + Token FPTok; + FPTok.startToken(); + FPTok.setKind(tok::annot_pragma_fp); + FPTok.setLocation(PragmaName.getLocation()); + FPTok.setAnnotationEndLoc(PragmaName.getLocation()); + FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue)); + TokenList.push_back(FPTok); + auto TokenArray = std::make_unique<Token[]>(TokenList.size()); std::copy(TokenList.begin(), TokenList.end(), TokenArray.get()); @@ -2929,29 +3077,76 @@ /*DisableMacroExpansion=*/false, /*IsReinject=*/false); } +void PragmaSTDC_FENV_ROUNDHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducer Introducer, + Token &Tok) { + Token PragmaName = Tok; + SmallVector<Token, 1> TokenList; + if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored) + << PragmaName.getIdentifierInfo()->getName(); + return; + } + + PP.Lex(Tok); + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) + << PragmaName.getIdentifierInfo()->getName(); + return; + } + IdentifierInfo *II = Tok.getIdentifierInfo(); + + auto RM = + llvm::StringSwitch<llvm::RoundingMode>(II->getName()) + .Case("FE_TOWARDZERO", llvm::RoundingMode::TowardZero) + .Case("FE_TONEAREST", llvm::RoundingMode::NearestTiesToEven) + .Case("FE_UPWARD", llvm::RoundingMode::TowardPositive) + .Case("FE_DOWNWARD", llvm::RoundingMode::TowardNegative) + .Case("FE_TONEARESTFROMZERO", llvm::RoundingMode::NearestTiesToAway) + .Case("FE_DYNAMIC", llvm::RoundingMode::Dynamic) + .Default(llvm::RoundingMode::Invalid); + if (RM == llvm::RoundingMode::Invalid) { + PP.Diag(Tok.getLocation(), diag::warn_stdc_unknown_rounding_mode); + return; + } + PP.Lex(Tok); + + if (Tok.isNot(tok::eod)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) + << "STDC FENV_ROUND"; + return; + } + + // Until the pragma is fully implemented, issue a warning. + PP.Diag(Tok.getLocation(), diag::warn_stdc_fenv_round_not_supported); + + MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), + 1); + Toks[0].startToken(); + Toks[0].setKind(tok::annot_pragma_fenv_round); + Toks[0].setLocation(Tok.getLocation()); + Toks[0].setAnnotationEndLoc(Tok.getLocation()); + Toks[0].setAnnotationValue( + reinterpret_cast<void *>(static_cast<uintptr_t>(RM))); + PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true, + /*IsReinject=*/false); +} + void Parser::HandlePragmaFP() { assert(Tok.is(tok::annot_pragma_fp)); auto *AnnotValue = reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue()); - if (AnnotValue->FlagKind == TokFPAnnotValue::Reassociate) - Actions.ActOnPragmaFPReassociate(AnnotValue->FlagValue == - TokFPAnnotValue::On); - else { - LangOptions::FPModeKind FPC; - switch (AnnotValue->FlagValue) { - case TokFPAnnotValue::Off: - FPC = LangOptions::FPM_Off; - break; - case TokFPAnnotValue::On: - FPC = LangOptions::FPM_On; - break; - case TokFPAnnotValue::Fast: - FPC = LangOptions::FPM_Fast; - break; - } - Actions.ActOnPragmaFPContract(FPC); - } + if (AnnotValue->ReassociateValue) + Actions.ActOnPragmaFPReassociate(Tok.getLocation(), + *AnnotValue->ReassociateValue == + LangOptions::FPModeKind::FPM_On); + if (AnnotValue->ContractValue) + Actions.ActOnPragmaFPContract(Tok.getLocation(), + *AnnotValue->ContractValue); + if (AnnotValue->ExceptionsValue) + Actions.ActOnPragmaFPExceptions(Tok.getLocation(), + *AnnotValue->ExceptionsValue); ConsumeAnnotationToken(); } @@ -2990,6 +3185,7 @@ EOFTok.setLocation(Tok.getLocation()); ValueList.push_back(EOFTok); // Terminates expression for parsing. + markAsReinjectedForRelexing(ValueList); Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator()); Info.PragmaName = PragmaName; @@ -3099,7 +3295,7 @@ Token LoopHintTok; LoopHintTok.startToken(); LoopHintTok.setKind(tok::annot_pragma_loop_hint); - LoopHintTok.setLocation(PragmaName.getLocation()); + LoopHintTok.setLocation(Introducer.Loc); LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation()); LoopHintTok.setAnnotationValue(static_cast<void *>(Info)); TokenList.push_back(LoopHintTok); @@ -3186,7 +3382,7 @@ auto TokenArray = std::make_unique<Token[]>(1); TokenArray[0].startToken(); TokenArray[0].setKind(tok::annot_pragma_loop_hint); - TokenArray[0].setLocation(PragmaName.getLocation()); + TokenArray[0].setLocation(Introducer.Loc); TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation()); TokenArray[0].setAnnotationValue(static_cast<void *>(Info)); PP.EnterTokenStream(std::move(TokenArray), 1, @@ -3446,6 +3642,7 @@ EOFTok.setLocation(EndLoc); AttributeTokens.push_back(EOFTok); + markAsReinjectedForRelexing(AttributeTokens); Info->Tokens = llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator()); }