22 #include "llvm/ADT/StringSwitch.h" 23 using namespace clang;
30 Token &FirstToken)
override;
34 explicit PragmaGCCVisibilityHandler() :
PragmaHandler(
"visibility") {}
36 Token &FirstToken)
override;
42 Token &FirstToken)
override;
48 Token &FirstToken)
override;
52 explicit PragmaClangSectionHandler(
Sema &S)
55 Token &FirstToken)
override;
62 explicit PragmaMSStructHandler() :
PragmaHandler(
"ms_struct") {}
64 Token &FirstToken)
override;
70 Token &FirstToken)
override;
76 Token &FirstToken)
override;
80 explicit PragmaRedefineExtnameHandler() :
PragmaHandler(
"redefine_extname") {}
82 Token &FirstToken)
override;
86 PragmaOpenCLExtensionHandler() :
PragmaHandler(
"EXTENSION") {}
88 Token &FirstToken)
override;
95 Token &FirstToken)
override;
101 struct PragmaSTDC_FENV_ACCESSHandler :
public PragmaHandler {
102 PragmaSTDC_FENV_ACCESSHandler() :
PragmaHandler(
"FENV_ACCESS") {}
110 PP.
Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
115 Toks[0].startToken();
116 Toks[0].setKind(tok::annot_pragma_fenv_access);
119 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
120 static_cast<uintptr_t>(OOS)));
121 PP.EnterTokenStream(Toks,
true,
127 struct PragmaSTDC_CX_LIMITED_RANGEHandler :
public PragmaHandler {
128 PragmaSTDC_CX_LIMITED_RANGEHandler() :
PragmaHandler(
"CX_LIMITED_RANGE") {}
131 Token &Tok)
override {
139 PragmaSTDC_UnknownHandler() =
default;
142 Token &UnknownTok)
override {
144 PP.
Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
151 Token &FirstToken)
override;
157 Token &FirstToken)
override;
163 Token &FirstToken)
override;
168 PragmaCommentHandler(
Sema &Actions)
171 Token &FirstToken)
override;
178 PragmaDetectMismatchHandler(
Sema &Actions)
181 Token &FirstToken)
override;
188 explicit PragmaMSPointersToMembers() :
PragmaHandler(
"pointers_to_members") {}
190 Token &FirstToken)
override;
196 Token &FirstToken)
override;
202 Token &FirstToken)
override;
207 PragmaOptimizeHandler(
Sema &S)
210 Token &FirstToken)
override;
219 Token &FirstToken)
override;
225 Token &FirstToken)
override;
235 Token &FirstToken)
override;
241 Token &FirstToken)
override;
244 struct PragmaForceCUDAHostDeviceHandler :
public PragmaHandler {
245 PragmaForceCUDAHostDeviceHandler(
Sema &Actions)
246 :
PragmaHandler(
"force_cuda_host_device"), Actions(Actions) {}
248 Token &FirstToken)
override;
257 :
PragmaHandler(
"attribute"), AttributesForPragmaAttribute(AttrFactory) {}
259 Token &FirstToken)
override;
267 void Parser::initializePragmaHandlers() {
268 AlignHandler = std::make_unique<PragmaAlignHandler>();
271 GCCVisibilityHandler = std::make_unique<PragmaGCCVisibilityHandler>();
274 OptionsHandler = std::make_unique<PragmaOptionsHandler>();
277 PackHandler = std::make_unique<PragmaPackHandler>();
280 MSStructHandler = std::make_unique<PragmaMSStructHandler>();
283 UnusedHandler = std::make_unique<PragmaUnusedHandler>();
286 WeakHandler = std::make_unique<PragmaWeakHandler>();
289 RedefineExtnameHandler = std::make_unique<PragmaRedefineExtnameHandler>();
292 FPContractHandler = std::make_unique<PragmaFPContractHandler>();
295 STDCFENVHandler = std::make_unique<PragmaSTDC_FENV_ACCESSHandler>();
298 STDCCXLIMITHandler = std::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>();
301 STDCUnknownHandler = std::make_unique<PragmaSTDC_UnknownHandler>();
304 PCSectionHandler = std::make_unique<PragmaClangSectionHandler>(Actions);
307 if (getLangOpts().OpenCL) {
308 OpenCLExtensionHandler = std::make_unique<PragmaOpenCLExtensionHandler>();
313 if (getLangOpts().OpenMP)
314 OpenMPHandler = std::make_unique<PragmaOpenMPHandler>();
316 OpenMPHandler = std::make_unique<PragmaNoOpenMPHandler>();
319 if (getLangOpts().MicrosoftExt ||
320 getTargetInfo().getTriple().isOSBinFormatELF()) {
321 MSCommentHandler = std::make_unique<PragmaCommentHandler>(Actions);
325 if (getLangOpts().MicrosoftExt) {
326 MSDetectMismatchHandler =
327 std::make_unique<PragmaDetectMismatchHandler>(Actions);
329 MSPointersToMembers = std::make_unique<PragmaMSPointersToMembers>();
331 MSVtorDisp = std::make_unique<PragmaMSVtorDisp>();
333 MSInitSeg = std::make_unique<PragmaMSPragma>(
"init_seg");
335 MSDataSeg = std::make_unique<PragmaMSPragma>(
"data_seg");
337 MSBSSSeg = std::make_unique<PragmaMSPragma>(
"bss_seg");
339 MSConstSeg = std::make_unique<PragmaMSPragma>(
"const_seg");
341 MSCodeSeg = std::make_unique<PragmaMSPragma>(
"code_seg");
343 MSSection = std::make_unique<PragmaMSPragma>(
"section");
345 MSRuntimeChecks = std::make_unique<PragmaMSRuntimeChecksHandler>();
347 MSIntrinsic = std::make_unique<PragmaMSIntrinsicHandler>();
349 MSOptimize = std::make_unique<PragmaMSOptimizeHandler>();
353 if (getLangOpts().CUDA) {
354 CUDAForceHostDeviceHandler =
355 std::make_unique<PragmaForceCUDAHostDeviceHandler>(Actions);
359 OptimizeHandler = std::make_unique<PragmaOptimizeHandler>(Actions);
362 LoopHintHandler = std::make_unique<PragmaLoopHintHandler>();
365 UnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>(
"unroll");
368 NoUnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>(
"nounroll");
371 UnrollAndJamHintHandler =
372 std::make_unique<PragmaUnrollHintHandler>(
"unroll_and_jam");
375 NoUnrollAndJamHintHandler =
376 std::make_unique<PragmaUnrollHintHandler>(
"nounroll_and_jam");
379 FPHandler = std::make_unique<PragmaFPHandler>();
382 AttributePragmaHandler =
383 std::make_unique<PragmaAttributeHandler>(AttrFactory);
387 void Parser::resetPragmaHandlers() {
390 AlignHandler.reset();
392 GCCVisibilityHandler.reset();
394 OptionsHandler.reset();
398 MSStructHandler.reset();
400 UnusedHandler.reset();
404 RedefineExtnameHandler.reset();
406 if (getLangOpts().
OpenCL) {
408 OpenCLExtensionHandler.reset();
412 OpenMPHandler.reset();
414 if (getLangOpts().MicrosoftExt ||
415 getTargetInfo().getTriple().isOSBinFormatELF()) {
417 MSCommentHandler.reset();
421 PCSectionHandler.reset();
423 if (getLangOpts().MicrosoftExt) {
425 MSDetectMismatchHandler.reset();
427 MSPointersToMembers.reset();
443 MSRuntimeChecks.reset();
450 if (getLangOpts().
CUDA) {
452 CUDAForceHostDeviceHandler.reset();
456 FPContractHandler.reset();
459 STDCFENVHandler.reset();
462 STDCCXLIMITHandler.reset();
465 STDCUnknownHandler.reset();
468 OptimizeHandler.reset();
471 LoopHintHandler.reset();
474 UnrollHintHandler.reset();
477 NoUnrollHintHandler.reset();
480 UnrollAndJamHintHandler.reset();
483 NoUnrollAndJamHintHandler.reset();
489 AttributePragmaHandler.reset();
497 void Parser::HandlePragmaUnused() {
498 assert(Tok.
is(tok::annot_pragma_unused));
500 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
504 void Parser::HandlePragmaVisibility() {
505 assert(Tok.
is(tok::annot_pragma_vis));
509 Actions.ActOnPragmaVisibility(VisType, VisLoc);
513 struct PragmaPackInfo {
520 void Parser::HandlePragmaPack() {
521 assert(Tok.
is(tok::annot_pragma_pack));
522 PragmaPackInfo *Info =
526 if (Info->Alignment.is(tok::numeric_constant)) {
527 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
529 ConsumeAnnotationToken();
533 Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
537 ConsumeAnnotationToken();
540 void Parser::HandlePragmaMSStruct() {
541 assert(Tok.
is(tok::annot_pragma_msstruct));
544 Actions.ActOnPragmaMSStruct(Kind);
545 ConsumeAnnotationToken();
548 void Parser::HandlePragmaAlign() {
549 assert(Tok.
is(tok::annot_pragma_align));
553 Actions.ActOnPragmaOptionsAlign(Kind, Tok.
getLocation());
556 ConsumeAnnotationToken();
559 void Parser::HandlePragmaDump() {
560 assert(Tok.
is(tok::annot_pragma_dump));
563 Actions.ActOnPragmaDump(getCurScope(), Tok.
getLocation(), II);
564 ConsumeAnnotationToken();
567 void Parser::HandlePragmaWeak() {
568 assert(Tok.
is(tok::annot_pragma_weak));
575 void Parser::HandlePragmaWeakAlias() {
576 assert(Tok.
is(tok::annot_pragma_weakalias));
584 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
585 WeakNameLoc, AliasNameLoc);
589 void Parser::HandlePragmaRedefineExtname() {
590 assert(Tok.
is(tok::annot_pragma_redefine_extname));
598 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
599 RedefNameLoc, AliasNameLoc);
602 void Parser::HandlePragmaFPContract() {
603 assert(Tok.
is(tok::annot_pragma_fp_contract));
617 FPC = getLangOpts().getDefaultFPContractMode();
621 Actions.ActOnPragmaFPContract(FPC);
622 ConsumeAnnotationToken();
625 void Parser::HandlePragmaFEnvAccess() {
626 assert(Tok.
is(tok::annot_pragma_fenv_access));
644 Actions.ActOnPragmaFEnvAccess(FPC);
645 ConsumeAnnotationToken();
651 assert(Tok.
is(tok::annot_pragma_captured));
652 ConsumeAnnotationToken();
654 if (Tok.
isNot(tok::l_brace)) {
655 PP.
Diag(Tok, diag::err_expected) << tok::l_brace;
663 Actions.ActOnCapturedRegionStart(Loc, getCurScope(),
CR_Default,
667 CapturedRegionScope.Exit();
670 Actions.ActOnCapturedRegionError();
674 return Actions.ActOnCapturedRegionEnd(R.get());
681 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
684 void Parser::HandlePragmaOpenCLExtension() {
685 assert(Tok.
is(tok::annot_pragma_opencl_extension));
687 auto State = Data->second;
688 auto Ident = Data->first;
690 ConsumeAnnotationToken();
692 auto &Opt = Actions.getOpenCLOptions();
693 auto Name = Ident->getName();
698 if (
State == Disable) {
700 Opt.enableSupportedCore(getLangOpts());
702 PP.
Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
705 if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
708 Actions.setCurrentOpenCLExtension(Name);
710 if (Name != Actions.getCurrentOpenCLExtension())
711 PP.
Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
712 Actions.setCurrentOpenCLExtension(
"");
713 }
else if (!Opt.isKnown(Name))
714 PP.
Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
715 else if (Opt.isSupportedExtension(Name, getLangOpts()))
716 Opt.enable(Name,
State == Enable);
717 else if (Opt.isSupportedCore(Name, getLangOpts()))
718 PP.
Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
720 PP.
Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
723 void Parser::HandlePragmaMSPointersToMembers() {
724 assert(Tok.
is(tok::annot_pragma_ms_pointers_to_members));
729 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
732 void Parser::HandlePragmaMSVtorDisp() {
733 assert(Tok.
is(tok::annot_pragma_ms_vtordisp));
739 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
742 void Parser::HandlePragmaMSPragma() {
743 assert(Tok.
is(tok::annot_pragma_ms_pragma));
747 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second,
true,
757 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
758 .Case(
"data_seg", &Parser::HandlePragmaMSSegment)
759 .Case(
"bss_seg", &Parser::HandlePragmaMSSegment)
760 .Case(
"const_seg", &Parser::HandlePragmaMSSegment)
761 .Case(
"code_seg", &Parser::HandlePragmaMSSegment)
762 .Case(
"section", &Parser::HandlePragmaMSSection)
763 .Case(
"init_seg", &Parser::HandlePragmaMSInitSeg);
765 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
774 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
776 if (Tok.
isNot(tok::l_paren)) {
777 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
782 if (Tok.
isNot(tok::string_literal)) {
783 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
787 ExprResult StringResult = ParseStringLiteralExpression();
792 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
797 bool SectionFlagsAreDefault =
true;
798 while (Tok.
is(tok::comma)) {
803 if (Tok.
is(tok::kw_long) || Tok.
is(tok::kw_short)) {
809 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
814 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
827 ? diag::warn_pragma_invalid_specific_action
828 : diag::warn_pragma_unsupported_action)
832 SectionFlags |= Flag;
833 SectionFlagsAreDefault =
false;
838 if (SectionFlagsAreDefault)
840 if (Tok.
isNot(tok::r_paren)) {
841 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
846 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
851 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
855 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
857 if (Tok.
isNot(tok::l_paren)) {
858 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
866 if (PushPop ==
"push")
868 else if (PushPop ==
"pop")
871 PP.
Diag(PragmaLocation,
872 diag::warn_pragma_expected_section_push_pop_or_name)
878 if (Tok.
is(tok::comma)) {
884 if (Tok.
is(tok::comma))
886 else if (Tok.
isNot(tok::r_paren)) {
887 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc)
892 }
else if (Tok.
isNot(tok::r_paren)) {
893 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
900 if (Tok.
isNot(tok::r_paren)) {
901 if (Tok.
isNot(tok::string_literal)) {
903 diag::warn_pragma_expected_section_name :
904 diag::warn_pragma_expected_section_label_or_name :
905 diag::warn_pragma_expected_section_push_pop_or_name;
906 PP.
Diag(PragmaLocation, DiagID) << PragmaName;
909 ExprResult StringResult = ParseStringLiteralExpression();
912 SegmentName = cast<StringLiteral>(StringResult.
get());
914 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
922 if (Tok.
isNot(tok::r_paren)) {
923 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
928 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
933 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
934 SegmentName, PragmaName);
939 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
941 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
942 PP.
Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
946 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
954 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
955 .Case(
"compiler",
"\".CRT$XCC\"")
956 .Case(
"lib",
"\".CRT$XCL\"")
957 .Case(
"user",
"\".CRT$XCU\"")
960 if (!Section.empty()) {
964 Toks[0].
setKind(tok::string_literal);
969 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks,
nullptr).get());
972 }
else if (Tok.
is(tok::string_literal)) {
973 ExprResult StringResult = ParseStringLiteralExpression();
976 SegmentName = cast<StringLiteral>(StringResult.
get());
978 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
986 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
990 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
992 ExpectAndConsume(
tok::eof, diag::warn_pragma_extra_tokens_at_eol,
996 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
1001 struct PragmaLoopHintInfo {
1010 std::string ClangLoopStr = (llvm::Twine(
"clang loop ") + Str).str();
1011 return llvm::StringSwitch<StringRef>(Str)
1012 .Case(
"loop", ClangLoopStr)
1013 .Case(
"unroll_and_jam", Str)
1014 .Case(
"unroll", Str)
1018 bool Parser::HandlePragmaLoopHint(
LoopHint &Hint) {
1019 assert(Tok.
is(tok::annot_pragma_loop_hint));
1020 PragmaLoopHintInfo *Info =
1023 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
1025 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
1030 ? Info->Option.getIdentifierInfo()
1033 Actions.Context, Info->Option.getLocation(), OptionInfo);
1039 auto IsLoopHint = llvm::StringSwitch<bool>(PragmaNameInfo->
getName())
1040 .Cases(
"unroll",
"nounroll",
"unroll_and_jam",
1041 "nounroll_and_jam",
true)
1044 if (Toks.empty() && IsLoopHint) {
1045 ConsumeAnnotationToken();
1046 Hint.
Range = Info->PragmaName.getLocation();
1052 assert(!Toks.empty() &&
1053 "PragmaLoopHintInfo::Toks must contain at least one token.");
1056 bool OptionUnroll =
false;
1057 bool OptionUnrollAndJam =
false;
1058 bool OptionDistribute =
false;
1059 bool OptionPipelineDisabled =
false;
1060 bool StateOption =
false;
1062 OptionUnroll = OptionInfo->isStr(
"unroll");
1063 OptionUnrollAndJam = OptionInfo->isStr(
"unroll_and_jam");
1064 OptionDistribute = OptionInfo->isStr(
"distribute");
1065 OptionPipelineDisabled = OptionInfo->isStr(
"pipeline");
1066 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
1067 .Case(
"vectorize",
true)
1068 .Case(
"interleave",
true)
1069 .Case(
"vectorize_predicate",
true)
1071 OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
1072 OptionPipelineDisabled;
1075 bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
1076 !OptionDistribute && !OptionPipelineDisabled;
1079 ConsumeAnnotationToken();
1080 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1082 << (OptionUnroll || OptionUnrollAndJam)
1089 ConsumeAnnotationToken();
1093 bool Valid = StateInfo &&
1094 llvm::StringSwitch<bool>(StateInfo->
getName())
1095 .Case(
"disable",
true)
1096 .Case(
"enable", !OptionPipelineDisabled)
1097 .Case(
"full", OptionUnroll || OptionUnrollAndJam)
1098 .Case(
"assume_safety", AssumeSafetyArg)
1101 if (OptionPipelineDisabled) {
1102 Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
1104 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1105 << (OptionUnroll || OptionUnrollAndJam)
1110 if (Toks.size() > 2)
1116 PP.EnterTokenStream(Toks,
false,
1118 ConsumeAnnotationToken();
1134 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation()))
1142 Info->Toks.back().getLocation());
1147 struct PragmaAttributeInfo {
1148 enum ActionType { Push,
Pop, Attribute };
1154 PragmaAttributeInfo(
ParsedAttributes &Attributes) : Attributes(Attributes) {}
1157 #include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc" 1162 if (Tok.
is(tok::identifier))
1171 using namespace attr;
1173 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \ 1176 #include "clang/Basic/AttrSubMatchRulesList.inc" 1178 llvm_unreachable(
"Invalid attribute subject match rule");
1186 PRef.
Diag(SubRuleLoc,
1187 diag::err_pragma_attribute_expected_subject_sub_identifier)
1189 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1200 PRef.
Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1201 << SubRuleName << PrimaryRuleName;
1202 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1208 bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1214 AnyLoc = ConsumeToken();
1224 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1227 std::pair<Optional<attr::SubjectMatchRule>,
1229 Rule = isAttributeSubjectMatchRule(Name);
1231 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1242 if (!SubjectMatchRules
1244 std::make_pair(PrimaryRule,
SourceRange(RuleLoc, RuleLoc)))
1246 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1249 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleLoc));
1250 LastMatchRuleEndLoc = RuleLoc;
1256 if (SubRuleName.empty()) {
1262 if (SubRuleName ==
"unless") {
1268 if (SubRuleName.empty()) {
1273 auto SubRuleOrNone = Rule.second(SubRuleName,
true);
1274 if (!SubRuleOrNone) {
1275 std::string SubRuleUnlessName =
"unless(" + SubRuleName.str() +
")";
1277 SubRuleUnlessName, SubRuleLoc);
1280 SubRule = *SubRuleOrNone;
1285 auto SubRuleOrNone = Rule.second(SubRuleName,
false);
1286 if (!SubRuleOrNone) {
1291 SubRule = *SubRuleOrNone;
1295 LastMatchRuleEndLoc = RuleEndLoc;
1298 if (!SubjectMatchRules
1299 .insert(std::make_pair(SubRule,
SourceRange(RuleLoc, RuleEndLoc)))
1301 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1304 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleEndLoc));
1307 }
while (IsAny && TryConsumeToken(tok::comma));
1328 getAttributeSubjectRulesRecoveryPointForToken(
const Token &Tok) {
1330 if (II->isStr(
"apply_to"))
1331 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1332 if (II->isStr(
"any"))
1333 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1335 if (Tok.
is(tok::equal))
1336 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1352 getAttributeSubjectRulesRecoveryPointForToken(PRef.
getCurToken());
1355 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1356 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1357 FixIt +=
"apply_to";
1358 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1359 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1366 if (SubjectMatchRuleSet.empty()) {
1372 bool NeedsComma =
false;
1373 for (
const auto &I : SubjectMatchRuleSet) {
1399 void Parser::HandlePragmaAttribute() {
1400 assert(Tok.
is(tok::annot_pragma_attribute) &&
1401 "Expected #pragma attribute annotation token");
1405 ConsumeAnnotationToken();
1406 Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
1410 assert((Info->Action == PragmaAttributeInfo::Push ||
1411 Info->Action == PragmaAttributeInfo::Attribute) &&
1412 "Unexpected #pragma attribute command");
1414 if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1415 ConsumeAnnotationToken();
1416 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1420 PP.EnterTokenStream(Info->Tokens,
false,
1422 ConsumeAnnotationToken();
1427 auto SkipToEnd = [
this]() {
1428 SkipUntil(
tok::eof, StopBeforeMatch);
1432 if (Tok.
is(tok::l_square) && NextToken().is(tok::l_square)) {
1434 ParseCXX11AttributeSpecifier(Attrs);
1435 }
else if (Tok.
is(tok::kw___attribute)) {
1437 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1440 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"("))
1443 if (Tok.
isNot(tok::identifier)) {
1444 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1451 if (Tok.
isNot(tok::l_paren))
1452 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1455 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs,
nullptr,
1460 if (ExpectAndConsume(tok::r_paren))
1462 if (ExpectAndConsume(tok::r_paren))
1464 }
else if (Tok.
is(tok::kw___declspec)) {
1465 ParseMicrosoftDeclSpecs(Attrs);
1467 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1476 if (Tok.
is(tok::l_paren)) {
1478 SkipUntil(tok::r_paren, StopBeforeMatch);
1479 if (Tok.
isNot(tok::r_paren))
1482 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1491 if (Attrs.
empty() || Attrs.
begin()->isInvalid()) {
1497 if (Attrs.
size() > 1) {
1499 Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1506 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1513 if (!TryConsumeToken(tok::comma)) {
1514 createExpectedAttributeSubjectRulesTokenDiagnostic(
1515 diag::err_expected, Attribute,
1522 if (Tok.
isNot(tok::identifier)) {
1523 createExpectedAttributeSubjectRulesTokenDiagnostic(
1524 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1525 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1530 if (!II->
isStr(
"apply_to")) {
1531 createExpectedAttributeSubjectRulesTokenDiagnostic(
1532 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1533 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1539 if (!TryConsumeToken(tok::equal)) {
1540 createExpectedAttributeSubjectRulesTokenDiagnostic(
1541 diag::err_expected, Attribute,
1542 MissingAttributeSubjectRulesRecoveryPoint::Equals, *
this)
1550 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1551 LastMatchRuleEndLoc)) {
1559 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1568 if (Info->Action == PragmaAttributeInfo::Push)
1569 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1571 Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
1572 std::move(SubjectMatchRules));
1578 void PragmaGCCVisibilityHandler::HandlePragma(
Preprocessor &PP,
1589 if (PushPop && PushPop->
isStr(
"pop")) {
1591 }
else if (PushPop && PushPop->
isStr(
"push")) {
1593 if (Tok.
isNot(tok::l_paren)) {
1606 if (Tok.
isNot(tok::r_paren)) {
1618 if (Tok.
isNot(tok::eod)) {
1624 auto Toks = std::make_unique<Token[]>(1);
1625 Toks[0].startToken();
1626 Toks[0].setKind(tok::annot_pragma_vis);
1627 Toks[0].setLocation(VisLoc);
1628 Toks[0].setAnnotationEndLoc(EndLoc);
1629 Toks[0].setAnnotationValue(
1630 const_cast<void *>(static_cast<const void *>(VisType)));
1631 PP.EnterTokenStream(std::move(Toks), 1,
true,
1646 if (Tok.
isNot(tok::l_paren)) {
1647 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"pack";
1652 StringRef SlotLabel;
1656 if (Tok.
is(tok::numeric_constant)) {
1666 }
else if (Tok.
is(tok::identifier)) {
1668 if (II->
isStr(
"show")) {
1672 if (II->
isStr(
"push")) {
1674 }
else if (II->
isStr(
"pop")) {
1677 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_invalid_action) <<
"pack";
1682 if (Tok.
is(tok::comma)) {
1685 if (Tok.
is(tok::numeric_constant)) {
1690 }
else if (Tok.
is(tok::identifier)) {
1694 if (Tok.
is(tok::comma)) {
1697 if (Tok.
isNot(tok::numeric_constant)) {
1720 if (Tok.
isNot(tok::r_paren)) {
1721 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"pack";
1727 if (Tok.
isNot(tok::eod)) {
1728 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"pack";
1732 PragmaPackInfo *Info =
1734 Info->Action = Action;
1735 Info->SlotLabel = SlotLabel;
1736 Info->Alignment = Alignment;
1740 Toks[0].startToken();
1741 Toks[0].setKind(tok::annot_pragma_pack);
1742 Toks[0].setLocation(PackLoc);
1743 Toks[0].setAnnotationEndLoc(RParenLoc);
1744 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1745 PP.EnterTokenStream(Toks,
true,
1751 void PragmaMSStructHandler::HandlePragma(
Preprocessor &PP,
1753 Token &MSStructTok) {
1758 if (Tok.
isNot(tok::identifier)) {
1764 if (II->
isStr(
"on")) {
1768 else if (II->
isStr(
"off") || II->
isStr(
"reset"))
1775 if (Tok.
isNot(tok::eod)) {
1783 Toks[0].startToken();
1784 Toks[0].setKind(tok::annot_pragma_msstruct);
1786 Toks[0].setAnnotationEndLoc(EndLoc);
1787 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1788 static_cast<uintptr_t>(Kind)));
1789 PP.EnterTokenStream(Toks,
true,
1794 void PragmaClangSectionHandler::HandlePragma(
Preprocessor &PP,
1796 Token &FirstToken) {
1799 auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1802 while (Tok.
isNot(tok::eod)) {
1803 if (Tok.
isNot(tok::identifier)) {
1804 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1809 if (SecType->
isStr(
"bss"))
1810 SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1811 else if (SecType->
isStr(
"data"))
1812 SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1813 else if (SecType->
isStr(
"rodata"))
1814 SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1815 else if (SecType->
isStr(
"relro"))
1816 SecKind = Sema::PragmaClangSectionKind::PCSK_Relro;
1817 else if (SecType->
isStr(
"text"))
1818 SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1820 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1825 if (Tok.
isNot(tok::equal)) {
1826 PP.
Diag(Tok.
getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1830 std::string SecName;
1834 Actions.ActOnPragmaClangSection(Tok.
getLocation(),
1835 (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1836 Sema::PragmaClangSectionAction::PCSA_Clear),
1849 if (Tok.
isNot(tok::identifier) ||
1857 if (Tok.
isNot(tok::equal)) {
1864 if (Tok.
isNot(tok::identifier)) {
1866 << (IsOptions ?
"options" :
"align");
1872 if (II->
isStr(
"native"))
1874 else if (II->
isStr(
"natural"))
1876 else if (II->
isStr(
"packed"))
1878 else if (II->
isStr(
"power"))
1880 else if (II->
isStr(
"mac68k"))
1882 else if (II->
isStr(
"reset"))
1892 if (Tok.
isNot(tok::eod)) {
1894 << (IsOptions ?
"options" :
"align");
1900 Toks[0].startToken();
1901 Toks[0].setKind(tok::annot_pragma_align);
1903 Toks[0].setAnnotationEndLoc(EndLoc);
1904 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1905 static_cast<uintptr_t>(Kind)));
1906 PP.EnterTokenStream(Toks,
true,
1910 void PragmaAlignHandler::HandlePragma(
Preprocessor &PP,
1916 void PragmaOptionsHandler::HandlePragma(
Preprocessor &PP,
1918 Token &OptionsTok) {
1923 void PragmaUnusedHandler::HandlePragma(
Preprocessor &PP,
1932 if (Tok.
isNot(tok::l_paren)) {
1933 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"unused";
1946 if (Tok.
is(tok::identifier)) {
1947 Identifiers.push_back(Tok);
1958 if (Tok.
is(tok::comma)) {
1963 if (Tok.
is(tok::r_paren)) {
1969 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_punc) <<
"unused";
1974 if (Tok.
isNot(tok::eod)) {
1981 assert(RParenLoc.
isValid() &&
"Valid '#pragma unused' must have ')'");
1982 assert(!Identifiers.empty() &&
"Valid '#pragma unused' must have arguments");
1991 2 * Identifiers.size());
1992 for (
unsigned i=0; i != Identifiers.size(); i++) {
1993 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1995 pragmaUnusedTok.
setKind(tok::annot_pragma_unused);
1997 idTok = Identifiers[i];
1999 PP.EnterTokenStream(Toks,
true,
2012 if (Tok.
isNot(tok::identifier)) {
2013 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_identifier) <<
"weak";
2018 bool HasAlias =
false;
2022 if (Tok.
is(tok::equal)) {
2025 if (Tok.
isNot(tok::identifier)) {
2034 if (Tok.
isNot(tok::eod)) {
2035 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"weak";
2042 Token &pragmaUnusedTok = Toks[0];
2044 pragmaUnusedTok.
setKind(tok::annot_pragma_weakalias);
2048 Toks[2] = AliasName;
2049 PP.EnterTokenStream(Toks,
true,
2054 Token &pragmaUnusedTok = Toks[0];
2056 pragmaUnusedTok.
setKind(tok::annot_pragma_weak);
2060 PP.EnterTokenStream(Toks,
true,
2066 void PragmaRedefineExtnameHandler::HandlePragma(
Preprocessor &PP,
2068 Token &RedefToken) {
2073 if (Tok.
isNot(tok::identifier)) {
2082 if (Tok.
isNot(tok::identifier)) {
2084 <<
"redefine_extname";
2091 if (Tok.
isNot(tok::eod)) {
2099 Token &pragmaRedefTok = Toks[0];
2101 pragmaRedefTok.
setKind(tok::annot_pragma_redefine_extname);
2104 Toks[1] = RedefName;
2105 Toks[2] = AliasName;
2106 PP.EnterTokenStream(Toks,
true,
2110 void PragmaFPContractHandler::HandlePragma(
Preprocessor &PP,
2119 Toks[0].startToken();
2120 Toks[0].setKind(tok::annot_pragma_fp_contract);
2123 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2124 static_cast<uintptr_t>(OOS)));
2125 PP.EnterTokenStream(Toks,
true,
2129 void PragmaOpenCLExtensionHandler::HandlePragma(
Preprocessor &PP,
2133 if (Tok.
isNot(tok::identifier)) {
2142 if (Tok.
isNot(tok::colon)) {
2148 if (Tok.
isNot(tok::identifier)) {
2149 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_predicate) << 0;
2155 if (Pred->
isStr(
"enable")) {
2157 }
else if (Pred->
isStr(
"disable")) {
2159 }
else if (Pred->
isStr(
"begin"))
2161 else if (Pred->
isStr(
"end"))
2165 << Ext->
isStr(
"all");
2171 if (Tok.
isNot(tok::eod)) {
2179 Info->second =
State;
2182 Toks[0].startToken();
2183 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2184 Toks[0].setLocation(NameLoc);
2185 Toks[0].setAnnotationValue(static_cast<void*>(Info));
2186 Toks[0].setAnnotationEndLoc(StateLoc);
2187 PP.EnterTokenStream(Toks,
true,
2197 void PragmaNoOpenMPHandler::HandlePragma(
Preprocessor &PP,
2202 PP.
Diag(FirstTok, diag::warn_pragma_omp_ignored);
2211 void PragmaOpenMPHandler::HandlePragma(
Preprocessor &PP,
2217 Tok.
setKind(tok::annot_pragma_openmp);
2221 Pragma.push_back(Tok);
2223 if (Tok.
is(tok::annot_pragma_openmp)) {
2224 PP.
Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2225 unsigned InnerPragmaCnt = 1;
2226 while (InnerPragmaCnt != 0) {
2228 if (Tok.
is(tok::annot_pragma_openmp))
2230 else if (Tok.
is(tok::annot_pragma_openmp_end))
2238 Tok.
setKind(tok::annot_pragma_openmp_end);
2240 Pragma.push_back(Tok);
2242 auto Toks = std::make_unique<Token[]>(Pragma.size());
2243 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2244 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2256 void PragmaMSPointersToMembers::HandlePragma(
Preprocessor &PP,
2261 if (Tok.
isNot(tok::l_paren)) {
2262 PP.
Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2263 <<
"pointers_to_members";
2270 <<
"pointers_to_members";
2276 if (Arg->
isStr(
"best_case")) {
2279 if (Arg->
isStr(
"full_generality")) {
2280 if (Tok.
is(tok::comma)) {
2286 diag::err_pragma_pointers_to_members_unknown_kind)
2291 }
else if (Tok.
is(tok::r_paren)) {
2298 <<
"full_generality";
2304 if (Arg->
isStr(
"single_inheritance")) {
2305 RepresentationMethod =
2307 }
else if (Arg->
isStr(
"multiple_inheritance")) {
2308 RepresentationMethod =
2310 }
else if (Arg->
isStr(
"virtual_inheritance")) {
2311 RepresentationMethod =
2315 diag::err_pragma_pointers_to_members_unknown_kind)
2322 if (Tok.
isNot(tok::r_paren)) {
2324 << (Arg ? Arg->
getName() :
"full_generality");
2330 if (Tok.
isNot(tok::eod)) {
2332 <<
"pointers_to_members";
2338 AnnotTok.
setKind(tok::annot_pragma_ms_pointers_to_members);
2342 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2358 if (Tok.
isNot(tok::l_paren)) {
2359 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) <<
"vtordisp";
2367 if (II->
isStr(
"push")) {
2370 if (Tok.
isNot(tok::comma)) {
2371 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_punc) <<
"vtordisp";
2377 }
else if (II->
isStr(
"pop")) {
2384 if (Tok.
is(tok::r_paren)) {
2394 if (II && II->
isStr(
"off")) {
2397 }
else if (II && II->
isStr(
"on")) {
2400 }
else if (Tok.
is(tok::numeric_constant) &&
2404 << 0 << 2 <<
"vtordisp";
2415 if (Tok.
isNot(tok::r_paren)) {
2416 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) <<
"vtordisp";
2421 if (Tok.
isNot(tok::eod)) {
2430 AnnotTok.
setKind(tok::annot_pragma_ms_vtordisp);
2434 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2442 Token EoF, AnnotTok;
2446 AnnotTok.
setKind(tok::annot_pragma_ms_pragma);
2451 for (; Tok.
isNot(tok::eod); PP.
Lex(Tok)) {
2452 TokenVector.push_back(Tok);
2456 TokenVector.push_back(EoF);
2459 auto TokenArray = std::make_unique<Token[]>(TokenVector.size());
2460 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2462 std::pair<std::unique_ptr<
Token[]>,
size_t>(std::move(TokenArray),
2463 TokenVector.size());
2478 void PragmaDetectMismatchHandler::HandlePragma(
Preprocessor &PP,
2483 if (Tok.
isNot(tok::l_paren)) {
2484 PP.
Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2489 std::string NameString;
2491 "pragma detect_mismatch",
2496 std::string ValueString;
2497 if (Tok.
isNot(tok::comma)) {
2498 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2506 if (Tok.
isNot(tok::r_paren)) {
2512 if (Tok.
isNot(tok::eod)) {
2513 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2522 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2534 void PragmaCommentHandler::HandlePragma(
Preprocessor &PP,
2539 if (Tok.
isNot(tok::l_paren)) {
2540 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2546 if (Tok.
isNot(tok::identifier)) {
2547 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2554 llvm::StringSwitch<PragmaMSCommentKind>(II->
getName())
2582 std::string ArgumentString;
2595 if (Tok.
isNot(tok::r_paren)) {
2601 if (Tok.
isNot(tok::eod)) {
2610 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2615 void PragmaOptimizeHandler::HandlePragma(
Preprocessor &PP,
2617 Token &FirstToken) {
2620 if (Tok.
is(tok::eod)) {
2622 <<
"clang optimize" <<
true <<
"'on' or 'off'";
2625 if (Tok.
isNot(tok::identifier)) {
2626 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2633 if (II->
isStr(
"on")) {
2635 }
else if (!II->
isStr(
"off")) {
2636 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2642 if (Tok.
isNot(tok::eod)) {
2648 Actions.ActOnPragmaOptimize(IsOn, FirstToken.
getLocation());
2653 struct TokFPAnnotValue {
2654 enum FlagKinds { Contract };
2655 enum FlagValues { On, Off, Fast };
2658 FlagValues FlagValue;
2669 if (Tok.
isNot(tok::identifier)) {
2675 while (Tok.
is(tok::identifier)) {
2679 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2681 .Case(
"contract", TokFPAnnotValue::Contract)
2685 <<
false << OptionInfo;
2691 if (Tok.
isNot(tok::l_paren)) {
2697 if (Tok.
isNot(tok::identifier)) {
2705 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2707 .Case(
"on", TokFPAnnotValue::On)
2708 .Case(
"off", TokFPAnnotValue::Off)
2709 .Case(
"fast", TokFPAnnotValue::Fast)
2720 if (Tok.
isNot(tok::r_paren)) {
2727 TokFPAnnotValue{*FlagKind, *FlagValue};
2731 FPTok.
setKind(tok::annot_pragma_fp);
2735 TokenList.push_back(FPTok);
2738 if (Tok.
isNot(tok::eod)) {
2744 auto TokenArray = std::make_unique<Token[]>(TokenList.size());
2745 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2747 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2751 void Parser::HandlePragmaFP() {
2752 assert(Tok.
is(tok::annot_pragma_fp));
2757 switch (AnnotValue->FlagValue) {
2758 case TokFPAnnotValue::On:
2761 case TokFPAnnotValue::Fast:
2764 case TokFPAnnotValue::Off:
2769 Actions.ActOnPragmaFPContract(FPC);
2770 ConsumeAnnotationToken();
2775 Token Option,
bool ValueInParens,
2776 PragmaLoopHintInfo &Info) {
2778 int OpenParens = ValueInParens ? 1 : 0;
2780 while (Tok.
isNot(tok::eod)) {
2781 if (Tok.
is(tok::l_paren))
2783 else if (Tok.
is(tok::r_paren)) {
2785 if (OpenParens == 0 && ValueInParens)
2789 ValueList.push_back(Tok);
2793 if (ValueInParens) {
2795 if (Tok.
isNot(tok::r_paren)) {
2806 ValueList.push_back(EOFTok);
2810 Info.PragmaName = PragmaName;
2811 Info.Option = Option;
2863 void PragmaLoopHintHandler::HandlePragma(
Preprocessor &PP,
2872 if (Tok.
isNot(tok::identifier)) {
2878 while (Tok.
is(tok::identifier)) {
2882 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->
getName())
2883 .Case(
"vectorize",
true)
2884 .Case(
"interleave",
true)
2885 .Case(
"unroll",
true)
2886 .Case(
"distribute",
true)
2887 .Case(
"vectorize_predicate",
true)
2888 .Case(
"vectorize_width",
true)
2889 .Case(
"interleave_count",
true)
2890 .Case(
"unroll_count",
true)
2891 .Case(
"pipeline",
true)
2892 .Case(
"pipeline_initiation_interval",
true)
2896 <<
false << OptionInfo;
2902 if (Tok.
isNot(tok::l_paren)) {
2916 LoopHintTok.
setKind(tok::annot_pragma_loop_hint);
2920 TokenList.push_back(LoopHintTok);
2923 if (Tok.
isNot(tok::eod)) {
2929 auto TokenArray = std::make_unique<Token[]>(TokenList.size());
2930 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2932 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2957 void PragmaUnrollHintHandler::HandlePragma(
Preprocessor &PP,
2965 if (Tok.
is(tok::eod)) {
2967 Info->PragmaName = PragmaName;
2978 bool ValueInParens = Tok.
is(tok::l_paren);
2990 PP.
Diag(Info->Toks[0].getLocation(),
2991 diag::warn_pragma_unroll_cuda_value_in_parens);
2993 if (Tok.
isNot(tok::eod)) {
3001 auto TokenArray = std::make_unique<Token[]>(1);
3002 TokenArray[0].startToken();
3003 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
3004 TokenArray[0].setLocation(PragmaName.
getLocation());
3005 TokenArray[0].setAnnotationEndLoc(PragmaName.
getLocation());
3006 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3007 PP.EnterTokenStream(std::move(TokenArray), 1,
3023 void PragmaMSIntrinsicHandler::HandlePragma(
Preprocessor &PP,
3028 if (Tok.
isNot(tok::l_paren)) {
3037 while (Tok.
is(tok::identifier)) {
3041 << II << SuggestIntrinH;
3044 if (Tok.
isNot(tok::comma))
3049 if (Tok.
isNot(tok::r_paren)) {
3056 if (Tok.
isNot(tok::eod))
3062 void PragmaMSOptimizeHandler::HandlePragma(
Preprocessor &PP,
3068 if (Tok.
isNot(tok::l_paren)) {
3069 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"optimize";
3074 if (Tok.
isNot(tok::string_literal)) {
3075 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_string) <<
"optimize";
3081 if (Tok.
isNot(tok::comma)) {
3082 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_comma) <<
"optimize";
3087 if (Tok.
is(tok::eod) || Tok.
is(tok::r_paren)) {
3089 <<
"optimize" <<
true <<
"'on' or 'off'";
3093 if (!II || (!II->
isStr(
"on") && !II->
isStr(
"off"))) {
3101 if (Tok.
isNot(tok::r_paren)) {
3102 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"optimize";
3107 if (Tok.
isNot(tok::eod)) {
3112 PP.
Diag(StartLoc, diag::warn_pragma_optimize);
3115 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3121 if (!Info || (!Info->
isStr(
"begin") && !Info->
isStr(
"end"))) {
3123 diag::warn_pragma_force_cuda_host_device_bad_arg);
3127 if (Info->
isStr(
"begin"))
3128 Actions.PushForceCUDAHostDevice();
3129 else if (!Actions.PopForceCUDAHostDevice())
3131 diag::err_pragma_cannot_end_force_cuda_host_device);
3134 if (!Tok.
is(tok::eod))
3136 diag::warn_pragma_force_cuda_host_device_bad_arg);
3166 void PragmaAttributeHandler::HandlePragma(
Preprocessor &PP,
3168 Token &FirstToken) {
3172 PragmaAttributeInfo(AttributesForPragmaAttribute);
3175 if (Tok.
is(tok::identifier)) {
3177 if (!II->
isStr(
"push") && !II->
isStr(
"pop")) {
3178 Info->Namespace = II;
3181 if (!Tok.
is(tok::period)) {
3182 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_period)
3190 if (!Tok.
isOneOf(tok::identifier, tok::l_paren)) {
3192 diag::err_pragma_attribute_expected_push_pop_paren);
3197 if (Tok.
is(tok::l_paren)) {
3198 if (Info->Namespace) {
3200 diag::err_pragma_attribute_namespace_on_attribute);
3202 diag::note_pragma_attribute_namespace_on_attribute);
3205 Info->Action = PragmaAttributeInfo::Attribute;
3208 if (II->
isStr(
"push"))
3209 Info->Action = PragmaAttributeInfo::Push;
3213 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_invalid_argument)
3222 if ((Info->Action == PragmaAttributeInfo::Push && Tok.
isNot(tok::eod)) ||
3223 Info->Action == PragmaAttributeInfo::Attribute) {
3224 if (Tok.
isNot(tok::l_paren)) {
3233 while (Tok.
isNot(tok::eod)) {
3234 if (Tok.
is(tok::l_paren))
3236 else if (Tok.
is(tok::r_paren)) {
3238 if (OpenParens == 0)
3242 AttributeTokens.push_back(Tok);
3246 if (AttributeTokens.empty()) {
3247 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_attribute);
3250 if (Tok.
isNot(tok::r_paren)) {
3262 AttributeTokens.push_back(EOFTok);
3268 if (Tok.
isNot(tok::eod))
3270 <<
"clang attribute";
3273 auto TokenArray = std::make_unique<Token[]>(1);
3274 TokenArray[0].startToken();
3275 TokenArray[0].setKind(tok::annot_pragma_attribute);
3276 TokenArray[0].setLocation(FirstToken.
getLocation());
3277 TokenArray[0].setAnnotationEndLoc(FirstToken.
getLocation());
3278 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3279 PP.EnterTokenStream(std::move(TokenArray), 1,
Defines the clang::ASTContext interface.
IdentifierLoc * PragmaNameLoc
MSVtorDispMode
In the Microsoft ABI, this controls the placement of virtual displacement members used to implement v...
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::BumpPtrAllocator & getPreprocessorAllocator()
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
SourceLocation getEndOfPreviousToken()
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName, Token Option, bool ValueInParens, PragmaLoopHintInfo &Info)
Parses loop or unroll pragma hint value and fills in Info.
virtual void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, SourceLocation StateLoc, unsigned State)
Called when an OpenCL extension is either disabled or enabled with a pragma.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool Pop(InterpState &S, CodePtr OpPC)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
bool LexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)
Lex a string literal, which may be the concatenation of multiple string literals and may even come fr...
This indicates that the scope corresponds to a function, which means that labels are set here...
Parser - This implements a parser for the C family of languages.
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)
Parses a simple integer literal to get its numeric value.
ActionResult< Stmt * > StmtResult
static void diagnoseUnknownAttributeSubjectSubRule(Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, StringRef SubRuleName, SourceLocation SubRuleLoc)
static std::string PragmaLoopHintString(Token PragmaName, Token Option)
IdentifierLoc * OptionLoc
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
Parse and apply any fixits to the source.
tok::TokenKind getKind() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
One of these records is kept for each identifier that is lexed.
SubjectMatchRule
A list of all the recognized kinds of attributes.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
const TargetInfo & getTargetInfo() const
Token - This structure provides full information about a lexed token.
void setKind(tok::TokenKind K)
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
unsigned getCharByteWidth() const
const LangOptions & getLangOpts() const
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
MissingAttributeSubjectRulesRecoveryPoint
Describes the stage at which attribute subject rule parsing was interrupted.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
unsigned getLength() const
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
Sema - This implements semantic analysis and AST building for C.
A little helper class used to produce diagnostics.
EmptyPragmaHandler - A pragma handler which takes no action, which can be used to ignore particular p...
void setAnnotationValue(void *val)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
const Token & getCurToken() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Remove the specific pragma handler from this preprocessor.
This is a compound statement scope.
static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule)
SourceLocation getEnd() const
PPCallbacks * getPPCallbacks() const
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, StringRef Str)
Callback invoked when a #pragma comment directive is read.
static StringRef getIdentifier(const Token &Tok)
const LangOptions & getLangOpts() const
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
static CharSourceRange getCharRange(SourceRange R)
static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, bool IsOptions)
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
const char * getSubjectMatchRuleSpelling(SubjectMatchRule Rule)
void setLength(unsigned Len)
IdentifierInfo * getIdentifierInfo() const
void setAnnotationEndLoc(SourceLocation L)
ParsedAttr - Represents a syntactic attribute.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
void Lex(Token &Result)
Lex the next token for this preprocessor.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
PragmaMSPointersToMembersKind
StringRef getName() const
Return the actual identifier string.
bool isMacroDefined(StringRef Id)
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool expectAndConsume(unsigned DiagID=diag::err_expected, const char *Msg="", tok::TokenKind SkipToTok=tok::unknown)
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, StringRef Value)
Callback invoked when a #pragma detect_mismatch directive is read.
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
static void diagnoseExpectedAttributeSubjectSubRule(Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, SourceLocation SubRuleLoc)
void setLiteralData(const char *Ptr)
OnOffSwitch
Defines the possible values of an on-off-switch (C99 6.10.6p2).
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
This is a scope that can contain a declaration.
bool LexOnOffSwitch(tok::OnOffSwitch &Result)
Lex an on-off-switch (C99 6.10.6p2) and verify that it is followed by EOD.
void setEnd(SourceLocation e)
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
DiagnosticsEngine & getDiagnostics() const
Do not present this diagnostic, ignore it.
llvm::DenseMap< int, SourceRange > ParsedSubjectMatchRuleSet
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine) ...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
bool isSupportedByPragmaAttribute() const
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Describes how and where the pragma was introduced.
Loop optimization hint for loop and unroll pragmas.
Kind getParsedKind() const
void setLocation(SourceLocation L)
A trivial tuple used to represent a source range.
void * getAnnotationValue() const
SourceLocation getBegin() const
ParsedAttributes - A collection of parsed attributes.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void startToken()
Reset all flags to cleared.
ArrayRef< SVal > ValueList
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Stop skipping at specified token, but don't skip the token itself.
SourceLocation getEndLoc() const