diff options
Diffstat (limited to 'clang/lib/Parse/ParsePragma.cpp')
-rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 108 |
1 files changed, 81 insertions, 27 deletions
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 74fa70379858..658853d42b74 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -22,6 +22,7 @@ #include "clang/Sema/Scope.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringSwitch.h" +#include <optional> using namespace clang; namespace { @@ -449,6 +450,9 @@ void Parser::initializePragmaHandlers() { PP.AddPragmaHandler(MSCodeSeg.get()); MSSection = std::make_unique<PragmaMSPragma>("section"); PP.AddPragmaHandler(MSSection.get()); + MSStrictGuardStackCheck = + std::make_unique<PragmaMSPragma>("strict_gs_check"); + PP.AddPragmaHandler(MSStrictGuardStackCheck.get()); MSFunction = std::make_unique<PragmaMSPragma>("function"); PP.AddPragmaHandler(MSFunction.get()); MSAllocText = std::make_unique<PragmaMSPragma>("alloc_text"); @@ -567,6 +571,8 @@ void Parser::resetPragmaHandlers() { MSCodeSeg.reset(); PP.RemovePragmaHandler(MSSection.get()); MSSection.reset(); + PP.RemovePragmaHandler(MSStrictGuardStackCheck.get()); + MSStrictGuardStackCheck.reset(); PP.RemovePragmaHandler(MSFunction.get()); MSFunction.reset(); PP.RemovePragmaHandler(MSAllocText.get()); @@ -936,6 +942,7 @@ void Parser::HandlePragmaMSPragma() { .Case("code_seg", &Parser::HandlePragmaMSSegment) .Case("section", &Parser::HandlePragmaMSSection) .Case("init_seg", &Parser::HandlePragmaMSInitSeg) + .Case("strict_gs_check", &Parser::HandlePragmaMSStrictGuardStackCheck) .Case("function", &Parser::HandlePragmaMSFunction) .Case("alloc_text", &Parser::HandlePragmaMSAllocText) .Case("optimize", &Parser::HandlePragmaMSOptimize); @@ -1175,6 +1182,59 @@ bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName, return true; } +// #pragma strict_gs_check(pop) +// #pragma strict_gs_check(push, "on" | "off") +// #pragma strict_gs_check("on" | "off") +bool Parser::HandlePragmaMSStrictGuardStackCheck( + StringRef PragmaName, SourceLocation PragmaLocation) { + if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen, + PragmaName)) + return false; + + Sema::PragmaMsStackAction Action = Sema::PSK_Set; + if (Tok.is(tok::identifier)) { + StringRef PushPop = Tok.getIdentifierInfo()->getName(); + if (PushPop == "push") { + PP.Lex(Tok); + Action = Sema::PSK_Push; + if (ExpectAndConsume(tok::comma, diag::warn_pragma_expected_punc, + PragmaName)) + return false; + } else if (PushPop == "pop") { + PP.Lex(Tok); + Action = Sema::PSK_Pop; + } + } + + bool Value = false; + if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) { + const IdentifierInfo *II = Tok.getIdentifierInfo(); + if (II && II->isStr("off")) { + PP.Lex(Tok); + Value = false; + } else if (II && II->isStr("on")) { + PP.Lex(Tok); + Value = true; + } else { + PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) + << PragmaName; + return false; + } + } + + // Finish the pragma: ')' $ + if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen, + PragmaName)) + return false; + + if (ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol, + PragmaName)) + return false; + + Actions.ActOnPragmaMSStrictGuardStackCheck(PragmaLocation, Action, Value); + return true; +} + bool Parser::HandlePragmaMSAllocText(StringRef PragmaName, SourceLocation PragmaLocation) { Token FirstTok = Tok; @@ -1234,17 +1294,11 @@ bool Parser::HandlePragmaMSAllocText(StringRef PragmaName, return true; } -namespace { -struct PragmaLoopHintInfo { - Token PragmaName; - Token Option; - ArrayRef<Token> Toks; -}; -} // end anonymous namespace - static std::string PragmaLoopHintString(Token PragmaName, Token Option) { StringRef Str = PragmaName.getIdentifierInfo()->getName(); - std::string ClangLoopStr = (llvm::Twine("clang loop ") + Str).str(); + std::string ClangLoopStr("clang loop "); + if (Str == "loop" && Option.getIdentifierInfo()) + ClangLoopStr += Option.getIdentifierInfo()->getName(); return std::string(llvm::StringSwitch<StringRef>(Str) .Case("loop", ClangLoopStr) .Case("unroll_and_jam", Str) @@ -1528,8 +1582,8 @@ bool Parser::ParsePragmaAttributeSubjectMatchRuleSet( Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier); return true; } - std::pair<Optional<attr::SubjectMatchRule>, - Optional<attr::SubjectMatchRule> (*)(StringRef, bool)> + std::pair<std::optional<attr::SubjectMatchRule>, + std::optional<attr::SubjectMatchRule> (*)(StringRef, bool)> Rule = isAttributeSubjectMatchRule(Name); if (!Rule.first) { Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name; @@ -3119,10 +3173,10 @@ struct TokFPAnnotValue { enum FlagKinds { Contract, Reassociate, Exceptions, EvalMethod }; enum FlagValues { On, Off, Fast }; - llvm::Optional<LangOptions::FPModeKind> ContractValue; - llvm::Optional<LangOptions::FPModeKind> ReassociateValue; - llvm::Optional<LangOptions::FPExceptionModeKind> ExceptionsValue; - llvm::Optional<LangOptions::FPEvalMethodKind> EvalMethodValue; + std::optional<LangOptions::FPModeKind> ContractValue; + std::optional<LangOptions::FPModeKind> ReassociateValue; + std::optional<LangOptions::FPExceptionModeKind> ExceptionsValue; + std::optional<LangOptions::FPEvalMethodKind> EvalMethodValue; }; } // end anonymous namespace @@ -3144,13 +3198,13 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP, IdentifierInfo *OptionInfo = Tok.getIdentifierInfo(); auto FlagKind = - llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>( + llvm::StringSwitch<std::optional<TokFPAnnotValue::FlagKinds>>( OptionInfo->getName()) .Case("contract", TokFPAnnotValue::Contract) .Case("reassociate", TokFPAnnotValue::Reassociate) .Case("exceptions", TokFPAnnotValue::Exceptions) .Case("eval_method", TokFPAnnotValue::EvalMethod) - .Default(None); + .Default(std::nullopt); if (!FlagKind) { PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option) << /*MissingOption=*/false << OptionInfo; @@ -3178,12 +3232,12 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP, if (FlagKind == TokFPAnnotValue::Contract) { AnnotValue->ContractValue = - llvm::StringSwitch<llvm::Optional<LangOptions::FPModeKind>>( + llvm::StringSwitch<std::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); + .Default(std::nullopt); if (!AnnotValue->ContractValue) { PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument) << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind; @@ -3191,11 +3245,11 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP, } } else if (FlagKind == TokFPAnnotValue::Reassociate) { AnnotValue->ReassociateValue = - llvm::StringSwitch<llvm::Optional<LangOptions::FPModeKind>>( + llvm::StringSwitch<std::optional<LangOptions::FPModeKind>>( II->getName()) .Case("on", LangOptions::FPModeKind::FPM_On) .Case("off", LangOptions::FPModeKind::FPM_Off) - .Default(llvm::None); + .Default(std::nullopt); if (!AnnotValue->ReassociateValue) { PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument) << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind; @@ -3203,12 +3257,12 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP, } } else if (FlagKind == TokFPAnnotValue::Exceptions) { AnnotValue->ExceptionsValue = - llvm::StringSwitch<llvm::Optional<LangOptions::FPExceptionModeKind>>( + llvm::StringSwitch<std::optional<LangOptions::FPExceptionModeKind>>( II->getName()) .Case("ignore", LangOptions::FPE_Ignore) .Case("maytrap", LangOptions::FPE_MayTrap) .Case("strict", LangOptions::FPE_Strict) - .Default(llvm::None); + .Default(std::nullopt); if (!AnnotValue->ExceptionsValue) { PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument) << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind; @@ -3216,12 +3270,12 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP, } } else if (FlagKind == TokFPAnnotValue::EvalMethod) { AnnotValue->EvalMethodValue = - llvm::StringSwitch<llvm::Optional<LangOptions::FPEvalMethodKind>>( + llvm::StringSwitch<std::optional<LangOptions::FPEvalMethodKind>>( II->getName()) .Case("source", LangOptions::FPEvalMethodKind::FEM_Source) .Case("double", LangOptions::FPEvalMethodKind::FEM_Double) .Case("extended", LangOptions::FPEvalMethodKind::FEM_Extended) - .Default(llvm::None); + .Default(std::nullopt); if (!AnnotValue->EvalMethodValue) { PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument) << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind; @@ -3371,7 +3425,7 @@ static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName, ValueList.push_back(EOFTok); // Terminates expression for parsing. markAsReinjectedForRelexing(ValueList); - Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator()); + Info.Toks = llvm::ArrayRef(ValueList).copy(PP.getPreprocessorAllocator()); Info.PragmaName = PragmaName; Info.Option = Option; @@ -3871,7 +3925,7 @@ void PragmaAttributeHandler::HandlePragma(Preprocessor &PP, markAsReinjectedForRelexing(AttributeTokens); Info->Tokens = - llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator()); + llvm::ArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator()); } if (Tok.isNot(tok::eod)) |