23 #include "llvm/ADT/StringSwitch.h" 24 using namespace clang;
31 Token &FirstToken)
override;
35 explicit PragmaGCCVisibilityHandler() :
PragmaHandler(
"visibility") {}
37 Token &FirstToken)
override;
43 Token &FirstToken)
override;
49 Token &FirstToken)
override;
53 explicit PragmaClangSectionHandler(
Sema &S)
56 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);
126 struct PragmaSTDC_CX_LIMITED_RANGEHandler :
public PragmaHandler {
127 PragmaSTDC_CX_LIMITED_RANGEHandler() :
PragmaHandler(
"CX_LIMITED_RANGE") {}
130 Token &Tok)
override {
138 PragmaSTDC_UnknownHandler() =
default;
141 Token &UnknownTok)
override {
143 PP.
Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
150 Token &FirstToken)
override;
156 Token &FirstToken)
override;
162 Token &FirstToken)
override;
167 PragmaCommentHandler(
Sema &Actions)
170 Token &FirstToken)
override;
176 PragmaDetectMismatchHandler(
Sema &Actions)
179 Token &FirstToken)
override;
185 explicit PragmaMSPointersToMembers() :
PragmaHandler(
"pointers_to_members") {}
187 Token &FirstToken)
override;
193 Token &FirstToken)
override;
197 explicit PragmaMSPragma(
const char *name) :
PragmaHandler(name) {}
199 Token &FirstToken)
override;
204 PragmaOptimizeHandler(
Sema &S)
207 Token &FirstToken)
override;
215 Token &FirstToken)
override;
219 PragmaUnrollHintHandler(
const char *name) :
PragmaHandler(name) {}
221 Token &FirstToken)
override;
231 Token &FirstToken)
override;
237 Token &FirstToken)
override;
240 struct PragmaForceCUDAHostDeviceHandler :
public PragmaHandler {
241 PragmaForceCUDAHostDeviceHandler(
Sema &Actions)
242 :
PragmaHandler(
"force_cuda_host_device"), Actions(Actions) {}
244 Token &FirstToken)
override;
253 :
PragmaHandler(
"attribute"), AttributesForPragmaAttribute(AttrFactory) {}
255 Token &FirstToken)
override;
263 void Parser::initializePragmaHandlers() {
264 AlignHandler = llvm::make_unique<PragmaAlignHandler>();
267 GCCVisibilityHandler = llvm::make_unique<PragmaGCCVisibilityHandler>();
270 OptionsHandler = llvm::make_unique<PragmaOptionsHandler>();
273 PackHandler = llvm::make_unique<PragmaPackHandler>();
276 MSStructHandler = llvm::make_unique<PragmaMSStructHandler>();
279 UnusedHandler = llvm::make_unique<PragmaUnusedHandler>();
282 WeakHandler = llvm::make_unique<PragmaWeakHandler>();
285 RedefineExtnameHandler = llvm::make_unique<PragmaRedefineExtnameHandler>();
288 FPContractHandler = llvm::make_unique<PragmaFPContractHandler>();
291 STDCFENVHandler = llvm::make_unique<PragmaSTDC_FENV_ACCESSHandler>();
294 STDCCXLIMITHandler = llvm::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>();
297 STDCUnknownHandler = llvm::make_unique<PragmaSTDC_UnknownHandler>();
300 PCSectionHandler = llvm::make_unique<PragmaClangSectionHandler>(Actions);
303 if (getLangOpts().OpenCL) {
304 OpenCLExtensionHandler = llvm::make_unique<PragmaOpenCLExtensionHandler>();
309 if (getLangOpts().OpenMP)
310 OpenMPHandler = llvm::make_unique<PragmaOpenMPHandler>();
312 OpenMPHandler = llvm::make_unique<PragmaNoOpenMPHandler>();
315 if (getLangOpts().MicrosoftExt ||
316 getTargetInfo().getTriple().isOSBinFormatELF()) {
317 MSCommentHandler = llvm::make_unique<PragmaCommentHandler>(Actions);
321 if (getLangOpts().MicrosoftExt) {
322 MSDetectMismatchHandler =
323 llvm::make_unique<PragmaDetectMismatchHandler>(Actions);
325 MSPointersToMembers = llvm::make_unique<PragmaMSPointersToMembers>();
327 MSVtorDisp = llvm::make_unique<PragmaMSVtorDisp>();
329 MSInitSeg = llvm::make_unique<PragmaMSPragma>(
"init_seg");
331 MSDataSeg = llvm::make_unique<PragmaMSPragma>(
"data_seg");
333 MSBSSSeg = llvm::make_unique<PragmaMSPragma>(
"bss_seg");
335 MSConstSeg = llvm::make_unique<PragmaMSPragma>(
"const_seg");
337 MSCodeSeg = llvm::make_unique<PragmaMSPragma>(
"code_seg");
339 MSSection = llvm::make_unique<PragmaMSPragma>(
"section");
341 MSRuntimeChecks = llvm::make_unique<PragmaMSRuntimeChecksHandler>();
343 MSIntrinsic = llvm::make_unique<PragmaMSIntrinsicHandler>();
345 MSOptimize = llvm::make_unique<PragmaMSOptimizeHandler>();
349 if (getLangOpts().CUDA) {
350 CUDAForceHostDeviceHandler =
351 llvm::make_unique<PragmaForceCUDAHostDeviceHandler>(Actions);
355 OptimizeHandler = llvm::make_unique<PragmaOptimizeHandler>(Actions);
358 LoopHintHandler = llvm::make_unique<PragmaLoopHintHandler>();
361 UnrollHintHandler = llvm::make_unique<PragmaUnrollHintHandler>(
"unroll");
364 NoUnrollHintHandler = llvm::make_unique<PragmaUnrollHintHandler>(
"nounroll");
367 UnrollAndJamHintHandler =
368 llvm::make_unique<PragmaUnrollHintHandler>(
"unroll_and_jam");
371 NoUnrollAndJamHintHandler =
372 llvm::make_unique<PragmaUnrollHintHandler>(
"nounroll_and_jam");
375 FPHandler = llvm::make_unique<PragmaFPHandler>();
378 AttributePragmaHandler =
379 llvm::make_unique<PragmaAttributeHandler>(AttrFactory);
383 void Parser::resetPragmaHandlers() {
386 AlignHandler.reset();
388 GCCVisibilityHandler.reset();
390 OptionsHandler.reset();
394 MSStructHandler.reset();
396 UnusedHandler.reset();
400 RedefineExtnameHandler.reset();
402 if (getLangOpts().
OpenCL) {
404 OpenCLExtensionHandler.reset();
408 OpenMPHandler.reset();
410 if (getLangOpts().MicrosoftExt ||
411 getTargetInfo().getTriple().isOSBinFormatELF()) {
413 MSCommentHandler.reset();
417 PCSectionHandler.reset();
419 if (getLangOpts().MicrosoftExt) {
421 MSDetectMismatchHandler.reset();
423 MSPointersToMembers.reset();
439 MSRuntimeChecks.reset();
446 if (getLangOpts().CUDA) {
448 CUDAForceHostDeviceHandler.reset();
452 FPContractHandler.reset();
455 STDCFENVHandler.reset();
458 STDCCXLIMITHandler.reset();
461 STDCUnknownHandler.reset();
464 OptimizeHandler.reset();
467 LoopHintHandler.reset();
470 UnrollHintHandler.reset();
473 NoUnrollHintHandler.reset();
476 UnrollAndJamHintHandler.reset();
479 NoUnrollAndJamHintHandler.reset();
485 AttributePragmaHandler.reset();
493 void Parser::HandlePragmaUnused() {
494 assert(Tok.
is(tok::annot_pragma_unused));
496 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
500 void Parser::HandlePragmaVisibility() {
501 assert(Tok.
is(tok::annot_pragma_vis));
505 Actions.ActOnPragmaVisibility(VisType, VisLoc);
509 struct PragmaPackInfo {
516 void Parser::HandlePragmaPack() {
517 assert(Tok.
is(tok::annot_pragma_pack));
518 PragmaPackInfo *Info =
522 if (Info->Alignment.is(tok::numeric_constant)) {
523 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
525 ConsumeAnnotationToken();
529 Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
533 ConsumeAnnotationToken();
536 void Parser::HandlePragmaMSStruct() {
537 assert(Tok.
is(tok::annot_pragma_msstruct));
540 Actions.ActOnPragmaMSStruct(Kind);
541 ConsumeAnnotationToken();
544 void Parser::HandlePragmaAlign() {
545 assert(Tok.
is(tok::annot_pragma_align));
549 Actions.ActOnPragmaOptionsAlign(Kind, Tok.
getLocation());
552 ConsumeAnnotationToken();
555 void Parser::HandlePragmaDump() {
556 assert(Tok.
is(tok::annot_pragma_dump));
559 Actions.ActOnPragmaDump(getCurScope(), Tok.
getLocation(), II);
560 ConsumeAnnotationToken();
563 void Parser::HandlePragmaWeak() {
564 assert(Tok.
is(tok::annot_pragma_weak));
571 void Parser::HandlePragmaWeakAlias() {
572 assert(Tok.
is(tok::annot_pragma_weakalias));
580 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
581 WeakNameLoc, AliasNameLoc);
585 void Parser::HandlePragmaRedefineExtname() {
586 assert(Tok.
is(tok::annot_pragma_redefine_extname));
594 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
595 RedefNameLoc, AliasNameLoc);
598 void Parser::HandlePragmaFPContract() {
599 assert(Tok.
is(tok::annot_pragma_fp_contract));
613 FPC = getLangOpts().getDefaultFPContractMode();
617 Actions.ActOnPragmaFPContract(FPC);
618 ConsumeAnnotationToken();
621 void Parser::HandlePragmaFEnvAccess() {
622 assert(Tok.
is(tok::annot_pragma_fenv_access));
640 Actions.ActOnPragmaFEnvAccess(FPC);
641 ConsumeAnnotationToken();
647 assert(Tok.
is(tok::annot_pragma_captured));
648 ConsumeAnnotationToken();
650 if (Tok.
isNot(tok::l_brace)) {
651 PP.
Diag(Tok, diag::err_expected) << tok::l_brace;
659 Actions.ActOnCapturedRegionStart(Loc, getCurScope(),
CR_Default,
663 CapturedRegionScope.Exit();
666 Actions.ActOnCapturedRegionError();
670 return Actions.ActOnCapturedRegionEnd(R.get());
677 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
680 void Parser::HandlePragmaOpenCLExtension() {
681 assert(Tok.
is(tok::annot_pragma_opencl_extension));
683 auto State = Data->second;
684 auto Ident = Data->first;
686 ConsumeAnnotationToken();
688 auto &Opt = Actions.getOpenCLOptions();
689 auto Name = Ident->getName();
694 if (
State == Disable) {
696 Opt.enableSupportedCore(getLangOpts());
698 PP.
Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
701 if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
704 Actions.setCurrentOpenCLExtension(Name);
706 if (Name != Actions.getCurrentOpenCLExtension())
707 PP.
Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
708 Actions.setCurrentOpenCLExtension(
"");
709 }
else if (!Opt.isKnown(Name))
710 PP.
Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
711 else if (Opt.isSupportedExtension(Name, getLangOpts()))
712 Opt.enable(Name,
State == Enable);
713 else if (Opt.isSupportedCore(Name, getLangOpts()))
714 PP.
Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
716 PP.
Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
719 void Parser::HandlePragmaMSPointersToMembers() {
720 assert(Tok.
is(tok::annot_pragma_ms_pointers_to_members));
725 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
728 void Parser::HandlePragmaMSVtorDisp() {
729 assert(Tok.
is(tok::annot_pragma_ms_vtordisp));
733 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
735 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
738 void Parser::HandlePragmaMSPragma() {
739 assert(Tok.
is(tok::annot_pragma_ms_pragma));
743 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second,
true);
752 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
753 .Case(
"data_seg", &Parser::HandlePragmaMSSegment)
754 .Case(
"bss_seg", &Parser::HandlePragmaMSSegment)
755 .Case(
"const_seg", &Parser::HandlePragmaMSSegment)
756 .Case(
"code_seg", &Parser::HandlePragmaMSSegment)
757 .Case(
"section", &Parser::HandlePragmaMSSection)
758 .Case(
"init_seg", &Parser::HandlePragmaMSInitSeg);
760 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
769 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
771 if (Tok.
isNot(tok::l_paren)) {
772 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
777 if (Tok.
isNot(tok::string_literal)) {
778 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
782 ExprResult StringResult = ParseStringLiteralExpression();
787 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
792 bool SectionFlagsAreDefault =
true;
793 while (Tok.
is(tok::comma)) {
798 if (Tok.
is(tok::kw_long) || Tok.
is(tok::kw_short)) {
804 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
809 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
822 ? diag::warn_pragma_invalid_specific_action
823 : diag::warn_pragma_unsupported_action)
827 SectionFlags |= Flag;
828 SectionFlagsAreDefault =
false;
833 if (SectionFlagsAreDefault)
835 if (Tok.
isNot(tok::r_paren)) {
836 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
841 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
846 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
850 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
852 if (Tok.
isNot(tok::l_paren)) {
853 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
861 if (PushPop ==
"push")
863 else if (PushPop ==
"pop")
866 PP.
Diag(PragmaLocation,
867 diag::warn_pragma_expected_section_push_pop_or_name)
873 if (Tok.
is(tok::comma)) {
879 if (Tok.
is(tok::comma))
881 else if (Tok.
isNot(tok::r_paren)) {
882 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc)
887 }
else if (Tok.
isNot(tok::r_paren)) {
888 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
895 if (Tok.
isNot(tok::r_paren)) {
896 if (Tok.
isNot(tok::string_literal)) {
898 diag::warn_pragma_expected_section_name :
899 diag::warn_pragma_expected_section_label_or_name :
900 diag::warn_pragma_expected_section_push_pop_or_name;
901 PP.
Diag(PragmaLocation, DiagID) << PragmaName;
904 ExprResult StringResult = ParseStringLiteralExpression();
907 SegmentName = cast<StringLiteral>(StringResult.
get());
909 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
917 if (Tok.
isNot(tok::r_paren)) {
918 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
923 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
928 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
929 SegmentName, PragmaName);
934 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
936 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
937 PP.
Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
941 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
949 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
950 .Case(
"compiler",
"\".CRT$XCC\"")
951 .Case(
"lib",
"\".CRT$XCL\"")
952 .Case(
"user",
"\".CRT$XCU\"")
955 if (!Section.empty()) {
959 Toks[0].
setKind(tok::string_literal);
964 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks,
nullptr).get());
967 }
else if (Tok.
is(tok::string_literal)) {
968 ExprResult StringResult = ParseStringLiteralExpression();
971 SegmentName = cast<StringLiteral>(StringResult.
get());
973 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
981 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
985 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
987 ExpectAndConsume(
tok::eof, diag::warn_pragma_extra_tokens_at_eol,
991 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
996 struct PragmaLoopHintInfo {
1004 std::string PragmaString;
1006 PragmaString =
"clang loop ";
1009 PragmaString =
"unroll_and_jam";
1012 "Unexpected pragma name");
1013 PragmaString =
"unroll";
1015 return PragmaString;
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 bool PragmaUnroll = PragmaNameInfo->
getName() ==
"unroll";
1040 bool PragmaNoUnroll = PragmaNameInfo->
getName() ==
"nounroll";
1041 bool PragmaUnrollAndJam = PragmaNameInfo->
getName() ==
"unroll_and_jam";
1042 bool PragmaNoUnrollAndJam = PragmaNameInfo->
getName() ==
"nounroll_and_jam";
1043 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll || PragmaUnrollAndJam ||
1044 PragmaNoUnrollAndJam)) {
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)
1070 OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
1071 OptionPipelineDisabled;
1074 bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
1075 !OptionDistribute && !OptionPipelineDisabled;
1078 ConsumeAnnotationToken();
1079 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1081 << (OptionUnroll || OptionUnrollAndJam)
1088 ConsumeAnnotationToken();
1092 bool Valid = StateInfo &&
1093 llvm::StringSwitch<bool>(StateInfo->
getName())
1094 .Case(
"disable",
true)
1095 .Case(
"enable", !OptionPipelineDisabled)
1096 .Case(
"full", OptionUnroll || OptionUnrollAndJam)
1097 .Case(
"assume_safety", AssumeSafetyArg)
1100 if (OptionPipelineDisabled) {
1101 Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
1103 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1104 << (OptionUnroll || OptionUnrollAndJam)
1109 if (Toks.size() > 2)
1115 PP.EnterTokenStream(Toks,
false);
1116 ConsumeAnnotationToken();
1132 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation()))
1140 Info->Toks.back().getLocation());
1145 struct PragmaAttributeInfo {
1146 enum ActionType { Push, Pop, Attribute };
1152 PragmaAttributeInfo(
ParsedAttributes &Attributes) : Attributes(Attributes) {}
1155 #include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc" 1160 if (Tok.
is(tok::identifier))
1169 using namespace attr;
1171 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \ 1174 #include "clang/Basic/AttrSubMatchRulesList.inc" 1176 llvm_unreachable(
"Invalid attribute subject match rule");
1184 PRef.
Diag(SubRuleLoc,
1185 diag::err_pragma_attribute_expected_subject_sub_identifier)
1187 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1198 PRef.
Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1199 << SubRuleName << PrimaryRuleName;
1200 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1206 bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1212 AnyLoc = ConsumeToken();
1222 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1225 std::pair<Optional<attr::SubjectMatchRule>,
1227 Rule = isAttributeSubjectMatchRule(Name);
1229 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1240 if (!SubjectMatchRules
1242 std::make_pair(PrimaryRule,
SourceRange(RuleLoc, RuleLoc)))
1244 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1247 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleLoc));
1248 LastMatchRuleEndLoc = RuleLoc;
1254 if (SubRuleName.empty()) {
1260 if (SubRuleName ==
"unless") {
1266 if (SubRuleName.empty()) {
1271 auto SubRuleOrNone = Rule.second(SubRuleName,
true);
1272 if (!SubRuleOrNone) {
1273 std::string SubRuleUnlessName =
"unless(" + SubRuleName.str() +
")";
1275 SubRuleUnlessName, SubRuleLoc);
1278 SubRule = *SubRuleOrNone;
1283 auto SubRuleOrNone = Rule.second(SubRuleName,
false);
1284 if (!SubRuleOrNone) {
1289 SubRule = *SubRuleOrNone;
1293 LastMatchRuleEndLoc = RuleEndLoc;
1296 if (!SubjectMatchRules
1297 .insert(std::make_pair(SubRule,
SourceRange(RuleLoc, RuleEndLoc)))
1299 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1302 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleEndLoc));
1305 }
while (IsAny && TryConsumeToken(tok::comma));
1326 getAttributeSubjectRulesRecoveryPointForToken(
const Token &Tok) {
1328 if (II->isStr(
"apply_to"))
1329 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1330 if (II->isStr(
"any"))
1331 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1333 if (Tok.
is(tok::equal))
1334 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1350 getAttributeSubjectRulesRecoveryPointForToken(PRef.
getCurToken());
1353 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1354 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1355 FixIt +=
"apply_to";
1356 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1357 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1364 if (SubjectMatchRuleSet.empty()) {
1370 bool NeedsComma =
false;
1371 for (
const auto &I : SubjectMatchRuleSet) {
1397 void Parser::HandlePragmaAttribute() {
1398 assert(Tok.
is(tok::annot_pragma_attribute) &&
1399 "Expected #pragma attribute annotation token");
1402 if (Info->Action == PragmaAttributeInfo::Pop) {
1403 ConsumeAnnotationToken();
1404 Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
1408 assert((Info->Action == PragmaAttributeInfo::Push ||
1409 Info->Action == PragmaAttributeInfo::Attribute) &&
1410 "Unexpected #pragma attribute command");
1412 if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1413 ConsumeAnnotationToken();
1414 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1418 PP.EnterTokenStream(Info->Tokens,
false);
1419 ConsumeAnnotationToken();
1424 auto SkipToEnd = [
this]() {
1425 SkipUntil(
tok::eof, StopBeforeMatch);
1429 if (Tok.
is(tok::l_square) && NextToken().is(tok::l_square)) {
1431 ParseCXX11AttributeSpecifier(Attrs);
1432 }
else if (Tok.
is(tok::kw___attribute)) {
1434 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1437 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"("))
1440 if (Tok.
isNot(tok::identifier)) {
1441 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1448 if (Tok.
isNot(tok::l_paren))
1449 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1452 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs,
nullptr,
1457 if (ExpectAndConsume(tok::r_paren))
1459 if (ExpectAndConsume(tok::r_paren))
1461 }
else if (Tok.
is(tok::kw___declspec)) {
1462 ParseMicrosoftDeclSpecs(Attrs);
1464 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1473 if (Tok.
is(tok::l_paren)) {
1475 SkipUntil(tok::r_paren, StopBeforeMatch);
1476 if (Tok.
isNot(tok::r_paren))
1479 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1488 if (Attrs.
empty() || Attrs.
begin()->isInvalid()) {
1494 if (Attrs.
size() > 1) {
1496 Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1503 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1510 if (!TryConsumeToken(tok::comma)) {
1511 createExpectedAttributeSubjectRulesTokenDiagnostic(
1512 diag::err_expected, Attribute,
1519 if (Tok.
isNot(tok::identifier)) {
1520 createExpectedAttributeSubjectRulesTokenDiagnostic(
1521 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1522 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1527 if (!II->
isStr(
"apply_to")) {
1528 createExpectedAttributeSubjectRulesTokenDiagnostic(
1529 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1530 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1536 if (!TryConsumeToken(tok::equal)) {
1537 createExpectedAttributeSubjectRulesTokenDiagnostic(
1538 diag::err_expected, Attribute,
1539 MissingAttributeSubjectRulesRecoveryPoint::Equals, *
this)
1547 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1548 LastMatchRuleEndLoc)) {
1556 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1565 if (Info->Action == PragmaAttributeInfo::Push)
1566 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1568 Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
1569 std::move(SubjectMatchRules));
1575 void PragmaGCCVisibilityHandler::HandlePragma(
Preprocessor &PP,
1586 if (PushPop && PushPop->
isStr(
"pop")) {
1588 }
else if (PushPop && PushPop->
isStr(
"push")) {
1590 if (Tok.
isNot(tok::l_paren)) {
1603 if (Tok.
isNot(tok::r_paren)) {
1615 if (Tok.
isNot(tok::eod)) {
1621 auto Toks = llvm::make_unique<Token[]>(1);
1622 Toks[0].startToken();
1623 Toks[0].setKind(tok::annot_pragma_vis);
1624 Toks[0].setLocation(VisLoc);
1625 Toks[0].setAnnotationEndLoc(EndLoc);
1626 Toks[0].setAnnotationValue(
1627 const_cast<void*>(static_cast<const void*>(VisType)));
1628 PP.EnterTokenStream(std::move(Toks), 1,
true);
1642 if (Tok.
isNot(tok::l_paren)) {
1643 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"pack";
1648 StringRef SlotLabel;
1652 if (Tok.
is(tok::numeric_constant)) {
1662 }
else if (Tok.
is(tok::identifier)) {
1664 if (II->
isStr(
"show")) {
1668 if (II->
isStr(
"push")) {
1670 }
else if (II->
isStr(
"pop")) {
1673 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_invalid_action) <<
"pack";
1678 if (Tok.
is(tok::comma)) {
1681 if (Tok.
is(tok::numeric_constant)) {
1686 }
else if (Tok.
is(tok::identifier)) {
1690 if (Tok.
is(tok::comma)) {
1693 if (Tok.
isNot(tok::numeric_constant)) {
1716 if (Tok.
isNot(tok::r_paren)) {
1717 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"pack";
1723 if (Tok.
isNot(tok::eod)) {
1724 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"pack";
1728 PragmaPackInfo *Info =
1730 Info->Action = Action;
1731 Info->SlotLabel = SlotLabel;
1732 Info->Alignment = Alignment;
1736 Toks[0].startToken();
1737 Toks[0].setKind(tok::annot_pragma_pack);
1738 Toks[0].setLocation(PackLoc);
1739 Toks[0].setAnnotationEndLoc(RParenLoc);
1740 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1741 PP.EnterTokenStream(Toks,
true);
1746 void PragmaMSStructHandler::HandlePragma(
Preprocessor &PP,
1748 Token &MSStructTok) {
1753 if (Tok.
isNot(tok::identifier)) {
1759 if (II->
isStr(
"on")) {
1763 else if (II->
isStr(
"off") || II->
isStr(
"reset"))
1770 if (Tok.
isNot(tok::eod)) {
1778 Toks[0].startToken();
1779 Toks[0].setKind(tok::annot_pragma_msstruct);
1781 Toks[0].setAnnotationEndLoc(EndLoc);
1782 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1783 static_cast<uintptr_t>(Kind)));
1784 PP.EnterTokenStream(Toks,
true);
1788 void PragmaClangSectionHandler::HandlePragma(
Preprocessor &PP,
1792 auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1795 while (Tok.
isNot(tok::eod)) {
1796 if (Tok.
isNot(tok::identifier)) {
1797 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1802 if (SecType->
isStr(
"bss"))
1803 SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1804 else if (SecType->
isStr(
"data"))
1805 SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1806 else if (SecType->
isStr(
"rodata"))
1807 SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1808 else if (SecType->
isStr(
"text"))
1809 SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1811 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1816 if (Tok.
isNot(tok::equal)) {
1817 PP.
Diag(Tok.
getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1821 std::string SecName;
1825 Actions.ActOnPragmaClangSection(Tok.
getLocation(),
1826 (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1827 Sema::PragmaClangSectionAction::PCSA_Clear),
1840 if (Tok.
isNot(tok::identifier) ||
1848 if (Tok.
isNot(tok::equal)) {
1855 if (Tok.
isNot(tok::identifier)) {
1857 << (IsOptions ?
"options" :
"align");
1863 if (II->
isStr(
"native"))
1865 else if (II->
isStr(
"natural"))
1867 else if (II->
isStr(
"packed"))
1869 else if (II->
isStr(
"power"))
1871 else if (II->
isStr(
"mac68k"))
1873 else if (II->
isStr(
"reset"))
1883 if (Tok.
isNot(tok::eod)) {
1885 << (IsOptions ?
"options" :
"align");
1891 Toks[0].startToken();
1892 Toks[0].setKind(tok::annot_pragma_align);
1894 Toks[0].setAnnotationEndLoc(EndLoc);
1895 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1896 static_cast<uintptr_t>(Kind)));
1897 PP.EnterTokenStream(Toks,
true);
1900 void PragmaAlignHandler::HandlePragma(
Preprocessor &PP,
1906 void PragmaOptionsHandler::HandlePragma(
Preprocessor &PP,
1908 Token &OptionsTok) {
1913 void PragmaUnusedHandler::HandlePragma(
Preprocessor &PP,
1922 if (Tok.
isNot(tok::l_paren)) {
1923 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"unused";
1936 if (Tok.
is(tok::identifier)) {
1937 Identifiers.push_back(Tok);
1948 if (Tok.
is(tok::comma)) {
1953 if (Tok.
is(tok::r_paren)) {
1959 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_punc) <<
"unused";
1964 if (Tok.
isNot(tok::eod)) {
1971 assert(RParenLoc.
isValid() &&
"Valid '#pragma unused' must have ')'");
1972 assert(!Identifiers.empty() &&
"Valid '#pragma unused' must have arguments");
1981 2 * Identifiers.size());
1982 for (
unsigned i=0; i != Identifiers.size(); i++) {
1983 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1985 pragmaUnusedTok.
setKind(tok::annot_pragma_unused);
1987 idTok = Identifiers[i];
1989 PP.EnterTokenStream(Toks,
true);
2001 if (Tok.
isNot(tok::identifier)) {
2002 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_identifier) <<
"weak";
2007 bool HasAlias =
false;
2011 if (Tok.
is(tok::equal)) {
2014 if (Tok.
isNot(tok::identifier)) {
2023 if (Tok.
isNot(tok::eod)) {
2024 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"weak";
2031 Token &pragmaUnusedTok = Toks[0];
2033 pragmaUnusedTok.
setKind(tok::annot_pragma_weakalias);
2037 Toks[2] = AliasName;
2038 PP.EnterTokenStream(Toks,
true);
2042 Token &pragmaUnusedTok = Toks[0];
2044 pragmaUnusedTok.
setKind(tok::annot_pragma_weak);
2048 PP.EnterTokenStream(Toks,
true);
2053 void PragmaRedefineExtnameHandler::HandlePragma(
Preprocessor &PP,
2055 Token &RedefToken) {
2060 if (Tok.
isNot(tok::identifier)) {
2069 if (Tok.
isNot(tok::identifier)) {
2071 <<
"redefine_extname";
2078 if (Tok.
isNot(tok::eod)) {
2086 Token &pragmaRedefTok = Toks[0];
2088 pragmaRedefTok.
setKind(tok::annot_pragma_redefine_extname);
2091 Toks[1] = RedefName;
2092 Toks[2] = AliasName;
2093 PP.EnterTokenStream(Toks,
true);
2098 PragmaFPContractHandler::HandlePragma(
Preprocessor &PP,
2107 Toks[0].startToken();
2108 Toks[0].setKind(tok::annot_pragma_fp_contract);
2111 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2112 static_cast<uintptr_t>(OOS)));
2113 PP.EnterTokenStream(Toks,
true);
2117 PragmaOpenCLExtensionHandler::HandlePragma(
Preprocessor &PP,
2121 if (Tok.
isNot(tok::identifier)) {
2130 if (Tok.
isNot(tok::colon)) {
2136 if (Tok.
isNot(tok::identifier)) {
2137 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_predicate) << 0;
2143 if (Pred->
isStr(
"enable")) {
2145 }
else if (Pred->
isStr(
"disable")) {
2147 }
else if (Pred->
isStr(
"begin"))
2149 else if (Pred->
isStr(
"end"))
2153 << Ext->
isStr(
"all");
2159 if (Tok.
isNot(tok::eod)) {
2167 Info->second =
State;
2170 Toks[0].startToken();
2171 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2172 Toks[0].setLocation(NameLoc);
2173 Toks[0].setAnnotationValue(static_cast<void*>(Info));
2174 Toks[0].setAnnotationEndLoc(StateLoc);
2175 PP.EnterTokenStream(Toks,
true);
2190 PP.
Diag(FirstTok, diag::warn_pragma_omp_ignored);
2206 Tok.
setKind(tok::annot_pragma_openmp);
2210 Pragma.push_back(Tok);
2212 if (Tok.
is(tok::annot_pragma_openmp)) {
2213 PP.
Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2214 unsigned InnerPragmaCnt = 1;
2215 while (InnerPragmaCnt != 0) {
2217 if (Tok.
is(tok::annot_pragma_openmp))
2219 else if (Tok.
is(tok::annot_pragma_openmp_end))
2227 Tok.
setKind(tok::annot_pragma_openmp_end);
2229 Pragma.push_back(Tok);
2231 auto Toks = llvm::make_unique<Token[]>(Pragma.size());
2232 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2233 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2245 void PragmaMSPointersToMembers::HandlePragma(
Preprocessor &PP,
2250 if (Tok.
isNot(tok::l_paren)) {
2251 PP.
Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2252 <<
"pointers_to_members";
2259 <<
"pointers_to_members";
2265 if (Arg->
isStr(
"best_case")) {
2268 if (Arg->
isStr(
"full_generality")) {
2269 if (Tok.
is(tok::comma)) {
2275 diag::err_pragma_pointers_to_members_unknown_kind)
2280 }
else if (Tok.
is(tok::r_paren)) {
2287 <<
"full_generality";
2293 if (Arg->
isStr(
"single_inheritance")) {
2294 RepresentationMethod =
2296 }
else if (Arg->
isStr(
"multiple_inheritance")) {
2297 RepresentationMethod =
2299 }
else if (Arg->
isStr(
"virtual_inheritance")) {
2300 RepresentationMethod =
2304 diag::err_pragma_pointers_to_members_unknown_kind)
2311 if (Tok.
isNot(tok::r_paren)) {
2313 << (Arg ? Arg->
getName() :
"full_generality");
2319 if (Tok.
isNot(tok::eod)) {
2321 <<
"pointers_to_members";
2327 AnnotTok.
setKind(tok::annot_pragma_ms_pointers_to_members);
2331 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2348 if (Tok.
isNot(tok::l_paren)) {
2349 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) <<
"vtordisp";
2357 if (II->
isStr(
"push")) {
2360 if (Tok.
isNot(tok::comma)) {
2361 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_punc) <<
"vtordisp";
2367 }
else if (II->
isStr(
"pop")) {
2374 if (Tok.
is(tok::r_paren)) {
2384 if (II && II->
isStr(
"off")) {
2387 }
else if (II && II->
isStr(
"on")) {
2390 }
else if (Tok.
is(tok::numeric_constant) &&
2394 << 0 << 2 <<
"vtordisp";
2405 if (Tok.
isNot(tok::r_paren)) {
2406 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) <<
"vtordisp";
2411 if (Tok.
isNot(tok::eod)) {
2420 AnnotTok.
setKind(tok::annot_pragma_ms_vtordisp);
2424 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2433 Token EoF, AnnotTok;
2437 AnnotTok.
setKind(tok::annot_pragma_ms_pragma);
2442 for (; Tok.
isNot(tok::eod); PP.
Lex(Tok)) {
2443 TokenVector.push_back(Tok);
2447 TokenVector.push_back(EoF);
2450 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
2451 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2453 std::pair<std::unique_ptr<
Token[]>,
size_t>(std::move(TokenArray),
2454 TokenVector.size());
2469 void PragmaDetectMismatchHandler::HandlePragma(
Preprocessor &PP,
2474 if (Tok.
isNot(tok::l_paren)) {
2475 PP.
Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2480 std::string NameString;
2482 "pragma detect_mismatch",
2487 std::string ValueString;
2488 if (Tok.
isNot(tok::comma)) {
2489 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2497 if (Tok.
isNot(tok::r_paren)) {
2503 if (Tok.
isNot(tok::eod)) {
2504 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2513 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2525 void PragmaCommentHandler::HandlePragma(
Preprocessor &PP,
2530 if (Tok.
isNot(tok::l_paren)) {
2531 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2537 if (Tok.
isNot(tok::identifier)) {
2538 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2545 llvm::StringSwitch<PragmaMSCommentKind>(II->
getName())
2573 std::string ArgumentString;
2586 if (Tok.
isNot(tok::r_paren)) {
2592 if (Tok.
isNot(tok::eod)) {
2601 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2606 void PragmaOptimizeHandler::HandlePragma(
Preprocessor &PP,
2608 Token &FirstToken) {
2611 if (Tok.
is(tok::eod)) {
2613 <<
"clang optimize" <<
true <<
"'on' or 'off'";
2616 if (Tok.
isNot(tok::identifier)) {
2617 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2624 if (II->
isStr(
"on")) {
2626 }
else if (!II->
isStr(
"off")) {
2627 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2633 if (Tok.
isNot(tok::eod)) {
2639 Actions.ActOnPragmaOptimize(IsOn, FirstToken.
getLocation());
2644 struct TokFPAnnotValue {
2645 enum FlagKinds { Contract };
2646 enum FlagValues { On, Off, Fast };
2649 FlagValues FlagValue;
2661 if (Tok.
isNot(tok::identifier)) {
2667 while (Tok.
is(tok::identifier)) {
2671 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2673 .Case(
"contract", TokFPAnnotValue::Contract)
2677 <<
false << OptionInfo;
2683 if (Tok.
isNot(tok::l_paren)) {
2689 if (Tok.
isNot(tok::identifier)) {
2697 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2699 .Case(
"on", TokFPAnnotValue::On)
2700 .Case(
"off", TokFPAnnotValue::Off)
2701 .Case(
"fast", TokFPAnnotValue::Fast)
2712 if (Tok.
isNot(tok::r_paren)) {
2719 TokFPAnnotValue{*FlagKind, *FlagValue};
2723 FPTok.
setKind(tok::annot_pragma_fp);
2727 TokenList.push_back(FPTok);
2730 if (Tok.
isNot(tok::eod)) {
2736 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2737 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2739 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2743 void Parser::HandlePragmaFP() {
2744 assert(Tok.
is(tok::annot_pragma_fp));
2749 switch (AnnotValue->FlagValue) {
2750 case TokFPAnnotValue::On:
2753 case TokFPAnnotValue::Fast:
2756 case TokFPAnnotValue::Off:
2761 Actions.ActOnPragmaFPContract(FPC);
2762 ConsumeAnnotationToken();
2767 Token Option,
bool ValueInParens,
2768 PragmaLoopHintInfo &Info) {
2770 int OpenParens = ValueInParens ? 1 : 0;
2772 while (Tok.
isNot(tok::eod)) {
2773 if (Tok.
is(tok::l_paren))
2775 else if (Tok.
is(tok::r_paren)) {
2777 if (OpenParens == 0 && ValueInParens)
2781 ValueList.push_back(Tok);
2785 if (ValueInParens) {
2787 if (Tok.
isNot(tok::r_paren)) {
2798 ValueList.push_back(EOFTok);
2802 Info.PragmaName = PragmaName;
2803 Info.Option = Option;
2854 void PragmaLoopHintHandler::HandlePragma(
Preprocessor &PP,
2863 if (Tok.
isNot(tok::identifier)) {
2869 while (Tok.
is(tok::identifier)) {
2873 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->
getName())
2874 .Case(
"vectorize",
true)
2875 .Case(
"interleave",
true)
2876 .Case(
"unroll",
true)
2877 .Case(
"distribute",
true)
2878 .Case(
"vectorize_width",
true)
2879 .Case(
"interleave_count",
true)
2880 .Case(
"unroll_count",
true)
2881 .Case(
"pipeline",
true)
2882 .Case(
"pipeline_initiation_interval",
true)
2886 <<
false << OptionInfo;
2892 if (Tok.
isNot(tok::l_paren)) {
2906 LoopHintTok.
setKind(tok::annot_pragma_loop_hint);
2910 TokenList.push_back(LoopHintTok);
2913 if (Tok.
isNot(tok::eod)) {
2919 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2920 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2922 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2947 void PragmaUnrollHintHandler::HandlePragma(
Preprocessor &PP,
2955 if (Tok.
is(tok::eod)) {
2957 Info->PragmaName = PragmaName;
2968 bool ValueInParens = Tok.
is(tok::l_paren);
2980 PP.
Diag(Info->Toks[0].getLocation(),
2981 diag::warn_pragma_unroll_cuda_value_in_parens);
2983 if (Tok.
isNot(tok::eod)) {
2991 auto TokenArray = llvm::make_unique<Token[]>(1);
2992 TokenArray[0].startToken();
2993 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2994 TokenArray[0].setLocation(PragmaName.
getLocation());
2995 TokenArray[0].setAnnotationEndLoc(PragmaName.
getLocation());
2996 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2997 PP.EnterTokenStream(std::move(TokenArray), 1,
3013 void PragmaMSIntrinsicHandler::HandlePragma(
Preprocessor &PP,
3018 if (Tok.
isNot(tok::l_paren)) {
3027 while (Tok.
is(tok::identifier)) {
3031 << II << SuggestIntrinH;
3034 if (Tok.
isNot(tok::comma))
3039 if (Tok.
isNot(tok::r_paren)) {
3046 if (Tok.
isNot(tok::eod))
3052 void PragmaMSOptimizeHandler::HandlePragma(
Preprocessor &PP,
3058 if (Tok.
isNot(tok::l_paren)) {
3059 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"optimize";
3064 if (Tok.
isNot(tok::string_literal)) {
3065 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_string) <<
"optimize";
3071 if (Tok.
isNot(tok::comma)) {
3072 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_comma) <<
"optimize";
3077 if (Tok.
is(tok::eod) || Tok.
is(tok::r_paren)) {
3079 <<
"optimize" <<
true <<
"'on' or 'off'";
3083 if (!II || (!II->
isStr(
"on") && !II->
isStr(
"off"))) {
3091 if (Tok.
isNot(tok::r_paren)) {
3092 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"optimize";
3097 if (Tok.
isNot(tok::eod)) {
3102 PP.
Diag(StartLoc, diag::warn_pragma_optimize);
3105 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3111 if (!Info || (!Info->
isStr(
"begin") && !Info->
isStr(
"end"))) {
3113 diag::warn_pragma_force_cuda_host_device_bad_arg);
3117 if (Info->
isStr(
"begin"))
3118 Actions.PushForceCUDAHostDevice();
3119 else if (!Actions.PopForceCUDAHostDevice())
3121 diag::err_pragma_cannot_end_force_cuda_host_device);
3124 if (!Tok.
is(tok::eod))
3126 diag::warn_pragma_force_cuda_host_device_bad_arg);
3156 void PragmaAttributeHandler::HandlePragma(
Preprocessor &PP,
3158 Token &FirstToken) {
3162 PragmaAttributeInfo(AttributesForPragmaAttribute);
3165 if (Tok.
is(tok::identifier)) {
3167 if (!II->
isStr(
"push") && !II->
isStr(
"pop")) {
3168 Info->Namespace = II;
3171 if (!Tok.
is(tok::period)) {
3172 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_period)
3180 if (!Tok.
isOneOf(tok::identifier, tok::l_paren)) {
3182 diag::err_pragma_attribute_expected_push_pop_paren);
3187 if (Tok.
is(tok::l_paren)) {
3188 if (Info->Namespace) {
3190 diag::err_pragma_attribute_namespace_on_attribute);
3192 diag::note_pragma_attribute_namespace_on_attribute);
3195 Info->Action = PragmaAttributeInfo::Attribute;
3198 if (II->
isStr(
"push"))
3199 Info->Action = PragmaAttributeInfo::Push;
3201 Info->Action = PragmaAttributeInfo::Pop;
3203 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_invalid_argument)
3212 if ((Info->Action == PragmaAttributeInfo::Push && Tok.
isNot(tok::eod)) ||
3213 Info->Action == PragmaAttributeInfo::Attribute) {
3214 if (Tok.
isNot(tok::l_paren)) {
3223 while (Tok.
isNot(tok::eod)) {
3224 if (Tok.
is(tok::l_paren))
3226 else if (Tok.
is(tok::r_paren)) {
3228 if (OpenParens == 0)
3232 AttributeTokens.push_back(Tok);
3236 if (AttributeTokens.empty()) {
3237 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_attribute);
3240 if (Tok.
isNot(tok::r_paren)) {
3252 AttributeTokens.push_back(EOFTok);
3258 if (Tok.
isNot(tok::eod))
3260 <<
"clang attribute";
3263 auto TokenArray = llvm::make_unique<Token[]>(1);
3264 TokenArray[0].startToken();
3265 TokenArray[0].setKind(tok::annot_pragma_attribute);
3266 TokenArray[0].setLocation(FirstToken.
getLocation());
3267 TokenArray[0].setAnnotationEndLoc(FirstToken.
getLocation());
3268 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3269 PP.EnterTokenStream(std::move(TokenArray), 1,
Defines the clang::ASTContext interface.
IdentifierLoc * PragmaNameLoc
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 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.
void EnterToken(const Token &Tok)
Enters a token in the token stream to be lexed next.
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
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 ...
PragmaIntroducerKind
Describes how the pragma was introduced, e.g., with #pragma, _Pragma, or __pragma.
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)
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)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
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.
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
IdentifierInfo * getName() 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
void DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Loop optimization hint for loop and unroll pragmas.
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