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().OpenCLVersion);
698 PP.
Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
701 if (!Opt.isKnown(Name) ||
702 !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
705 Actions.setCurrentOpenCLExtension(Name);
707 if (Name != Actions.getCurrentOpenCLExtension())
708 PP.
Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
709 Actions.setCurrentOpenCLExtension(
"");
710 }
else if (!Opt.isKnown(Name))
711 PP.
Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
712 else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
713 Opt.enable(Name,
State == Enable);
714 else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
715 PP.
Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
717 PP.
Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
720 void Parser::HandlePragmaMSPointersToMembers() {
721 assert(Tok.
is(tok::annot_pragma_ms_pointers_to_members));
726 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
729 void Parser::HandlePragmaMSVtorDisp() {
730 assert(Tok.
is(tok::annot_pragma_ms_vtordisp));
734 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
736 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
739 void Parser::HandlePragmaMSPragma() {
740 assert(Tok.
is(tok::annot_pragma_ms_pragma));
744 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second,
true);
753 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
754 .Case(
"data_seg", &Parser::HandlePragmaMSSegment)
755 .Case(
"bss_seg", &Parser::HandlePragmaMSSegment)
756 .Case(
"const_seg", &Parser::HandlePragmaMSSegment)
757 .Case(
"code_seg", &Parser::HandlePragmaMSSegment)
758 .Case(
"section", &Parser::HandlePragmaMSSection)
759 .Case(
"init_seg", &Parser::HandlePragmaMSInitSeg);
761 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
770 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
772 if (Tok.
isNot(tok::l_paren)) {
773 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
778 if (Tok.
isNot(tok::string_literal)) {
779 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
783 ExprResult StringResult = ParseStringLiteralExpression();
788 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
793 bool SectionFlagsAreDefault =
true;
794 while (Tok.
is(tok::comma)) {
799 if (Tok.
is(tok::kw_long) || Tok.
is(tok::kw_short)) {
805 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
810 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
823 ? diag::warn_pragma_invalid_specific_action
824 : diag::warn_pragma_unsupported_action)
828 SectionFlags |= Flag;
829 SectionFlagsAreDefault =
false;
834 if (SectionFlagsAreDefault)
836 if (Tok.
isNot(tok::r_paren)) {
837 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
842 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
847 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
851 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
853 if (Tok.
isNot(tok::l_paren)) {
854 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
862 if (PushPop ==
"push")
864 else if (PushPop ==
"pop")
867 PP.
Diag(PragmaLocation,
868 diag::warn_pragma_expected_section_push_pop_or_name)
874 if (Tok.
is(tok::comma)) {
880 if (Tok.
is(tok::comma))
882 else if (Tok.
isNot(tok::r_paren)) {
883 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc)
888 }
else if (Tok.
isNot(tok::r_paren)) {
889 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
896 if (Tok.
isNot(tok::r_paren)) {
897 if (Tok.
isNot(tok::string_literal)) {
899 diag::warn_pragma_expected_section_name :
900 diag::warn_pragma_expected_section_label_or_name :
901 diag::warn_pragma_expected_section_push_pop_or_name;
902 PP.
Diag(PragmaLocation, DiagID) << PragmaName;
905 ExprResult StringResult = ParseStringLiteralExpression();
908 SegmentName = cast<StringLiteral>(StringResult.
get());
910 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
918 if (Tok.
isNot(tok::r_paren)) {
919 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
924 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
929 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
930 SegmentName, PragmaName);
935 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
937 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
938 PP.
Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
942 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
950 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
951 .Case(
"compiler",
"\".CRT$XCC\"")
952 .Case(
"lib",
"\".CRT$XCL\"")
953 .Case(
"user",
"\".CRT$XCU\"")
956 if (!Section.empty()) {
960 Toks[0].
setKind(tok::string_literal);
965 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks,
nullptr).get());
968 }
else if (Tok.
is(tok::string_literal)) {
969 ExprResult StringResult = ParseStringLiteralExpression();
972 SegmentName = cast<StringLiteral>(StringResult.
get());
974 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
982 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
986 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
988 ExpectAndConsume(
tok::eof, diag::warn_pragma_extra_tokens_at_eol,
992 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
997 struct PragmaLoopHintInfo {
1005 std::string PragmaString;
1007 PragmaString =
"clang loop ";
1010 PragmaString =
"unroll_and_jam";
1013 "Unexpected pragma name");
1014 PragmaString =
"unroll";
1016 return PragmaString;
1019 bool Parser::HandlePragmaLoopHint(
LoopHint &Hint) {
1020 assert(Tok.
is(tok::annot_pragma_loop_hint));
1021 PragmaLoopHintInfo *Info =
1024 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
1026 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
1031 ? Info->Option.getIdentifierInfo()
1034 Actions.Context, Info->Option.getLocation(), OptionInfo);
1040 bool PragmaUnroll = PragmaNameInfo->
getName() ==
"unroll";
1041 bool PragmaNoUnroll = PragmaNameInfo->
getName() ==
"nounroll";
1042 bool PragmaUnrollAndJam = PragmaNameInfo->
getName() ==
"unroll_and_jam";
1043 bool PragmaNoUnrollAndJam = PragmaNameInfo->
getName() ==
"nounroll_and_jam";
1044 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll || PragmaUnrollAndJam ||
1045 PragmaNoUnrollAndJam)) {
1046 ConsumeAnnotationToken();
1047 Hint.
Range = Info->PragmaName.getLocation();
1053 assert(!Toks.empty() &&
1054 "PragmaLoopHintInfo::Toks must contain at least one token.");
1057 bool OptionUnroll =
false;
1058 bool OptionUnrollAndJam =
false;
1059 bool OptionDistribute =
false;
1060 bool OptionPipelineDisabled =
false;
1061 bool StateOption =
false;
1063 OptionUnroll = OptionInfo->isStr(
"unroll");
1064 OptionUnrollAndJam = OptionInfo->isStr(
"unroll_and_jam");
1065 OptionDistribute = OptionInfo->isStr(
"distribute");
1066 OptionPipelineDisabled = OptionInfo->isStr(
"pipeline");
1067 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
1068 .Case(
"vectorize",
true)
1069 .Case(
"interleave",
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);
1117 ConsumeAnnotationToken();
1133 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation()))
1141 Info->Toks.back().getLocation());
1146 struct PragmaAttributeInfo {
1147 enum ActionType { Push, Pop, Attribute };
1153 PragmaAttributeInfo(
ParsedAttributes &Attributes) : Attributes(Attributes) {}
1156 #include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc" 1161 if (Tok.
is(tok::identifier))
1170 using namespace attr;
1172 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \ 1175 #include "clang/Basic/AttrSubMatchRulesList.inc" 1177 llvm_unreachable(
"Invalid attribute subject match rule");
1185 PRef.
Diag(SubRuleLoc,
1186 diag::err_pragma_attribute_expected_subject_sub_identifier)
1188 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1199 PRef.
Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1200 << SubRuleName << PrimaryRuleName;
1201 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1207 bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1213 AnyLoc = ConsumeToken();
1223 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1226 std::pair<Optional<attr::SubjectMatchRule>,
1228 Rule = isAttributeSubjectMatchRule(Name);
1230 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1241 if (!SubjectMatchRules
1243 std::make_pair(PrimaryRule,
SourceRange(RuleLoc, RuleLoc)))
1245 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1248 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleLoc));
1249 LastMatchRuleEndLoc = RuleLoc;
1255 if (SubRuleName.empty()) {
1261 if (SubRuleName ==
"unless") {
1267 if (SubRuleName.empty()) {
1272 auto SubRuleOrNone = Rule.second(SubRuleName,
true);
1273 if (!SubRuleOrNone) {
1274 std::string SubRuleUnlessName =
"unless(" + SubRuleName.str() +
")";
1276 SubRuleUnlessName, SubRuleLoc);
1279 SubRule = *SubRuleOrNone;
1284 auto SubRuleOrNone = Rule.second(SubRuleName,
false);
1285 if (!SubRuleOrNone) {
1290 SubRule = *SubRuleOrNone;
1294 LastMatchRuleEndLoc = RuleEndLoc;
1297 if (!SubjectMatchRules
1298 .insert(std::make_pair(SubRule,
SourceRange(RuleLoc, RuleEndLoc)))
1300 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1303 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleEndLoc));
1306 }
while (IsAny && TryConsumeToken(tok::comma));
1327 getAttributeSubjectRulesRecoveryPointForToken(
const Token &Tok) {
1329 if (II->isStr(
"apply_to"))
1330 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1331 if (II->isStr(
"any"))
1332 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1334 if (Tok.
is(tok::equal))
1335 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1351 getAttributeSubjectRulesRecoveryPointForToken(PRef.
getCurToken());
1354 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1355 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1356 FixIt +=
"apply_to";
1357 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1358 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1365 if (SubjectMatchRuleSet.empty()) {
1371 bool NeedsComma =
false;
1372 for (
const auto &I : SubjectMatchRuleSet) {
1398 void Parser::HandlePragmaAttribute() {
1399 assert(Tok.
is(tok::annot_pragma_attribute) &&
1400 "Expected #pragma attribute annotation token");
1403 if (Info->Action == PragmaAttributeInfo::Pop) {
1404 ConsumeAnnotationToken();
1405 Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
1409 assert((Info->Action == PragmaAttributeInfo::Push ||
1410 Info->Action == PragmaAttributeInfo::Attribute) &&
1411 "Unexpected #pragma attribute command");
1413 if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1414 ConsumeAnnotationToken();
1415 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1419 PP.EnterTokenStream(Info->Tokens,
false);
1420 ConsumeAnnotationToken();
1425 auto SkipToEnd = [
this]() {
1426 SkipUntil(
tok::eof, StopBeforeMatch);
1430 if (Tok.
is(tok::l_square) && NextToken().is(tok::l_square)) {
1432 ParseCXX11AttributeSpecifier(Attrs);
1433 }
else if (Tok.
is(tok::kw___attribute)) {
1435 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1438 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"("))
1441 if (Tok.
isNot(tok::identifier)) {
1442 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1449 if (Tok.
isNot(tok::l_paren))
1450 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1453 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs,
nullptr,
1458 if (ExpectAndConsume(tok::r_paren))
1460 if (ExpectAndConsume(tok::r_paren))
1462 }
else if (Tok.
is(tok::kw___declspec)) {
1463 ParseMicrosoftDeclSpecs(Attrs);
1465 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1474 if (Tok.
is(tok::l_paren)) {
1476 SkipUntil(tok::r_paren, StopBeforeMatch);
1477 if (Tok.
isNot(tok::r_paren))
1480 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1489 if (Attrs.
empty() || Attrs.
begin()->isInvalid()) {
1495 if (Attrs.
size() > 1) {
1497 Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1504 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1511 if (!TryConsumeToken(tok::comma)) {
1512 createExpectedAttributeSubjectRulesTokenDiagnostic(
1513 diag::err_expected, Attribute,
1520 if (Tok.
isNot(tok::identifier)) {
1521 createExpectedAttributeSubjectRulesTokenDiagnostic(
1522 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1523 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1528 if (!II->
isStr(
"apply_to")) {
1529 createExpectedAttributeSubjectRulesTokenDiagnostic(
1530 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1531 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1537 if (!TryConsumeToken(tok::equal)) {
1538 createExpectedAttributeSubjectRulesTokenDiagnostic(
1539 diag::err_expected, Attribute,
1540 MissingAttributeSubjectRulesRecoveryPoint::Equals, *
this)
1548 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1549 LastMatchRuleEndLoc)) {
1557 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1566 if (Info->Action == PragmaAttributeInfo::Push)
1567 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1569 Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
1570 std::move(SubjectMatchRules));
1576 void PragmaGCCVisibilityHandler::HandlePragma(
Preprocessor &PP,
1587 if (PushPop && PushPop->
isStr(
"pop")) {
1589 }
else if (PushPop && PushPop->
isStr(
"push")) {
1591 if (Tok.
isNot(tok::l_paren)) {
1604 if (Tok.
isNot(tok::r_paren)) {
1616 if (Tok.
isNot(tok::eod)) {
1622 auto Toks = llvm::make_unique<Token[]>(1);
1623 Toks[0].startToken();
1624 Toks[0].setKind(tok::annot_pragma_vis);
1625 Toks[0].setLocation(VisLoc);
1626 Toks[0].setAnnotationEndLoc(EndLoc);
1627 Toks[0].setAnnotationValue(
1628 const_cast<void*>(static_cast<const void*>(VisType)));
1629 PP.EnterTokenStream(std::move(Toks), 1,
true);
1643 if (Tok.
isNot(tok::l_paren)) {
1644 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"pack";
1649 StringRef SlotLabel;
1653 if (Tok.
is(tok::numeric_constant)) {
1663 }
else if (Tok.
is(tok::identifier)) {
1665 if (II->
isStr(
"show")) {
1669 if (II->
isStr(
"push")) {
1671 }
else if (II->
isStr(
"pop")) {
1674 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_invalid_action) <<
"pack";
1679 if (Tok.
is(tok::comma)) {
1682 if (Tok.
is(tok::numeric_constant)) {
1687 }
else if (Tok.
is(tok::identifier)) {
1691 if (Tok.
is(tok::comma)) {
1694 if (Tok.
isNot(tok::numeric_constant)) {
1717 if (Tok.
isNot(tok::r_paren)) {
1718 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"pack";
1724 if (Tok.
isNot(tok::eod)) {
1725 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"pack";
1729 PragmaPackInfo *Info =
1731 Info->Action = Action;
1732 Info->SlotLabel = SlotLabel;
1733 Info->Alignment = Alignment;
1737 Toks[0].startToken();
1738 Toks[0].setKind(tok::annot_pragma_pack);
1739 Toks[0].setLocation(PackLoc);
1740 Toks[0].setAnnotationEndLoc(RParenLoc);
1741 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1742 PP.EnterTokenStream(Toks,
true);
1747 void PragmaMSStructHandler::HandlePragma(
Preprocessor &PP,
1749 Token &MSStructTok) {
1754 if (Tok.
isNot(tok::identifier)) {
1760 if (II->
isStr(
"on")) {
1764 else if (II->
isStr(
"off") || II->
isStr(
"reset"))
1771 if (Tok.
isNot(tok::eod)) {
1779 Toks[0].startToken();
1780 Toks[0].setKind(tok::annot_pragma_msstruct);
1782 Toks[0].setAnnotationEndLoc(EndLoc);
1783 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1784 static_cast<uintptr_t>(Kind)));
1785 PP.EnterTokenStream(Toks,
true);
1789 void PragmaClangSectionHandler::HandlePragma(
Preprocessor &PP,
1793 auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1796 while (Tok.
isNot(tok::eod)) {
1797 if (Tok.
isNot(tok::identifier)) {
1798 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1803 if (SecType->
isStr(
"bss"))
1804 SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1805 else if (SecType->
isStr(
"data"))
1806 SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1807 else if (SecType->
isStr(
"rodata"))
1808 SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1809 else if (SecType->
isStr(
"text"))
1810 SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1812 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1817 if (Tok.
isNot(tok::equal)) {
1818 PP.
Diag(Tok.
getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1822 std::string SecName;
1826 Actions.ActOnPragmaClangSection(Tok.
getLocation(),
1827 (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1828 Sema::PragmaClangSectionAction::PCSA_Clear),
1841 if (Tok.
isNot(tok::identifier) ||
1849 if (Tok.
isNot(tok::equal)) {
1856 if (Tok.
isNot(tok::identifier)) {
1858 << (IsOptions ?
"options" :
"align");
1864 if (II->
isStr(
"native"))
1866 else if (II->
isStr(
"natural"))
1868 else if (II->
isStr(
"packed"))
1870 else if (II->
isStr(
"power"))
1872 else if (II->
isStr(
"mac68k"))
1874 else if (II->
isStr(
"reset"))
1884 if (Tok.
isNot(tok::eod)) {
1886 << (IsOptions ?
"options" :
"align");
1892 Toks[0].startToken();
1893 Toks[0].setKind(tok::annot_pragma_align);
1895 Toks[0].setAnnotationEndLoc(EndLoc);
1896 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1897 static_cast<uintptr_t>(Kind)));
1898 PP.EnterTokenStream(Toks,
true);
1901 void PragmaAlignHandler::HandlePragma(
Preprocessor &PP,
1907 void PragmaOptionsHandler::HandlePragma(
Preprocessor &PP,
1909 Token &OptionsTok) {
1914 void PragmaUnusedHandler::HandlePragma(
Preprocessor &PP,
1923 if (Tok.
isNot(tok::l_paren)) {
1924 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"unused";
1937 if (Tok.
is(tok::identifier)) {
1938 Identifiers.push_back(Tok);
1949 if (Tok.
is(tok::comma)) {
1954 if (Tok.
is(tok::r_paren)) {
1960 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_punc) <<
"unused";
1965 if (Tok.
isNot(tok::eod)) {
1972 assert(RParenLoc.
isValid() &&
"Valid '#pragma unused' must have ')'");
1973 assert(!Identifiers.empty() &&
"Valid '#pragma unused' must have arguments");
1982 2 * Identifiers.size());
1983 for (
unsigned i=0; i != Identifiers.size(); i++) {
1984 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1986 pragmaUnusedTok.
setKind(tok::annot_pragma_unused);
1988 idTok = Identifiers[i];
1990 PP.EnterTokenStream(Toks,
true);
2002 if (Tok.
isNot(tok::identifier)) {
2003 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_identifier) <<
"weak";
2008 bool HasAlias =
false;
2012 if (Tok.
is(tok::equal)) {
2015 if (Tok.
isNot(tok::identifier)) {
2024 if (Tok.
isNot(tok::eod)) {
2025 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"weak";
2032 Token &pragmaUnusedTok = Toks[0];
2034 pragmaUnusedTok.
setKind(tok::annot_pragma_weakalias);
2038 Toks[2] = AliasName;
2039 PP.EnterTokenStream(Toks,
true);
2043 Token &pragmaUnusedTok = Toks[0];
2045 pragmaUnusedTok.
setKind(tok::annot_pragma_weak);
2049 PP.EnterTokenStream(Toks,
true);
2054 void PragmaRedefineExtnameHandler::HandlePragma(
Preprocessor &PP,
2056 Token &RedefToken) {
2061 if (Tok.
isNot(tok::identifier)) {
2070 if (Tok.
isNot(tok::identifier)) {
2072 <<
"redefine_extname";
2079 if (Tok.
isNot(tok::eod)) {
2087 Token &pragmaRedefTok = Toks[0];
2089 pragmaRedefTok.
setKind(tok::annot_pragma_redefine_extname);
2092 Toks[1] = RedefName;
2093 Toks[2] = AliasName;
2094 PP.EnterTokenStream(Toks,
true);
2099 PragmaFPContractHandler::HandlePragma(
Preprocessor &PP,
2108 Toks[0].startToken();
2109 Toks[0].setKind(tok::annot_pragma_fp_contract);
2112 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2113 static_cast<uintptr_t>(OOS)));
2114 PP.EnterTokenStream(Toks,
true);
2118 PragmaOpenCLExtensionHandler::HandlePragma(
Preprocessor &PP,
2122 if (Tok.
isNot(tok::identifier)) {
2131 if (Tok.
isNot(tok::colon)) {
2137 if (Tok.
isNot(tok::identifier)) {
2138 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_predicate) << 0;
2144 if (Pred->
isStr(
"enable")) {
2146 }
else if (Pred->
isStr(
"disable")) {
2148 }
else if (Pred->
isStr(
"begin"))
2150 else if (Pred->
isStr(
"end"))
2154 << Ext->
isStr(
"all");
2160 if (Tok.
isNot(tok::eod)) {
2168 Info->second =
State;
2171 Toks[0].startToken();
2172 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2173 Toks[0].setLocation(NameLoc);
2174 Toks[0].setAnnotationValue(static_cast<void*>(Info));
2175 Toks[0].setAnnotationEndLoc(StateLoc);
2176 PP.EnterTokenStream(Toks,
true);
2191 PP.
Diag(FirstTok, diag::warn_pragma_omp_ignored);
2207 Tok.
setKind(tok::annot_pragma_openmp);
2211 Pragma.push_back(Tok);
2213 if (Tok.
is(tok::annot_pragma_openmp)) {
2214 PP.
Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2215 unsigned InnerPragmaCnt = 1;
2216 while (InnerPragmaCnt != 0) {
2218 if (Tok.
is(tok::annot_pragma_openmp))
2220 else if (Tok.
is(tok::annot_pragma_openmp_end))
2228 Tok.
setKind(tok::annot_pragma_openmp_end);
2230 Pragma.push_back(Tok);
2232 auto Toks = llvm::make_unique<Token[]>(Pragma.size());
2233 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2234 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2246 void PragmaMSPointersToMembers::HandlePragma(
Preprocessor &PP,
2251 if (Tok.
isNot(tok::l_paren)) {
2252 PP.
Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2253 <<
"pointers_to_members";
2260 <<
"pointers_to_members";
2266 if (Arg->
isStr(
"best_case")) {
2269 if (Arg->
isStr(
"full_generality")) {
2270 if (Tok.
is(tok::comma)) {
2276 diag::err_pragma_pointers_to_members_unknown_kind)
2281 }
else if (Tok.
is(tok::r_paren)) {
2288 <<
"full_generality";
2294 if (Arg->
isStr(
"single_inheritance")) {
2295 RepresentationMethod =
2297 }
else if (Arg->
isStr(
"multiple_inheritance")) {
2298 RepresentationMethod =
2300 }
else if (Arg->
isStr(
"virtual_inheritance")) {
2301 RepresentationMethod =
2305 diag::err_pragma_pointers_to_members_unknown_kind)
2312 if (Tok.
isNot(tok::r_paren)) {
2314 << (Arg ? Arg->
getName() :
"full_generality");
2320 if (Tok.
isNot(tok::eod)) {
2322 <<
"pointers_to_members";
2328 AnnotTok.
setKind(tok::annot_pragma_ms_pointers_to_members);
2332 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2349 if (Tok.
isNot(tok::l_paren)) {
2350 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) <<
"vtordisp";
2358 if (II->
isStr(
"push")) {
2361 if (Tok.
isNot(tok::comma)) {
2362 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_punc) <<
"vtordisp";
2368 }
else if (II->
isStr(
"pop")) {
2375 if (Tok.
is(tok::r_paren)) {
2385 if (II && II->
isStr(
"off")) {
2388 }
else if (II && II->
isStr(
"on")) {
2391 }
else if (Tok.
is(tok::numeric_constant) &&
2395 << 0 << 2 <<
"vtordisp";
2406 if (Tok.
isNot(tok::r_paren)) {
2407 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) <<
"vtordisp";
2412 if (Tok.
isNot(tok::eod)) {
2421 AnnotTok.
setKind(tok::annot_pragma_ms_vtordisp);
2425 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2434 Token EoF, AnnotTok;
2438 AnnotTok.
setKind(tok::annot_pragma_ms_pragma);
2443 for (; Tok.
isNot(tok::eod); PP.
Lex(Tok)) {
2444 TokenVector.push_back(Tok);
2448 TokenVector.push_back(EoF);
2451 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
2452 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2454 std::pair<std::unique_ptr<
Token[]>,
size_t>(std::move(TokenArray),
2455 TokenVector.size());
2470 void PragmaDetectMismatchHandler::HandlePragma(
Preprocessor &PP,
2475 if (Tok.
isNot(tok::l_paren)) {
2476 PP.
Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2481 std::string NameString;
2483 "pragma detect_mismatch",
2488 std::string ValueString;
2489 if (Tok.
isNot(tok::comma)) {
2490 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2498 if (Tok.
isNot(tok::r_paren)) {
2504 if (Tok.
isNot(tok::eod)) {
2505 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2514 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2526 void PragmaCommentHandler::HandlePragma(
Preprocessor &PP,
2531 if (Tok.
isNot(tok::l_paren)) {
2532 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2538 if (Tok.
isNot(tok::identifier)) {
2539 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2546 llvm::StringSwitch<PragmaMSCommentKind>(II->
getName())
2574 std::string ArgumentString;
2587 if (Tok.
isNot(tok::r_paren)) {
2593 if (Tok.
isNot(tok::eod)) {
2602 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2607 void PragmaOptimizeHandler::HandlePragma(
Preprocessor &PP,
2609 Token &FirstToken) {
2612 if (Tok.
is(tok::eod)) {
2614 <<
"clang optimize" <<
true <<
"'on' or 'off'";
2617 if (Tok.
isNot(tok::identifier)) {
2618 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2625 if (II->
isStr(
"on")) {
2627 }
else if (!II->
isStr(
"off")) {
2628 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2634 if (Tok.
isNot(tok::eod)) {
2640 Actions.ActOnPragmaOptimize(IsOn, FirstToken.
getLocation());
2645 struct TokFPAnnotValue {
2646 enum FlagKinds { Contract };
2647 enum FlagValues { On, Off, Fast };
2650 FlagValues FlagValue;
2662 if (Tok.
isNot(tok::identifier)) {
2668 while (Tok.
is(tok::identifier)) {
2672 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2674 .Case(
"contract", TokFPAnnotValue::Contract)
2678 <<
false << OptionInfo;
2684 if (Tok.
isNot(tok::l_paren)) {
2690 if (Tok.
isNot(tok::identifier)) {
2698 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2700 .Case(
"on", TokFPAnnotValue::On)
2701 .Case(
"off", TokFPAnnotValue::Off)
2702 .Case(
"fast", TokFPAnnotValue::Fast)
2713 if (Tok.
isNot(tok::r_paren)) {
2720 TokFPAnnotValue{*FlagKind, *FlagValue};
2724 FPTok.
setKind(tok::annot_pragma_fp);
2728 TokenList.push_back(FPTok);
2731 if (Tok.
isNot(tok::eod)) {
2737 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2738 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2740 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2744 void Parser::HandlePragmaFP() {
2745 assert(Tok.
is(tok::annot_pragma_fp));
2750 switch (AnnotValue->FlagValue) {
2751 case TokFPAnnotValue::On:
2754 case TokFPAnnotValue::Fast:
2757 case TokFPAnnotValue::Off:
2762 Actions.ActOnPragmaFPContract(FPC);
2763 ConsumeAnnotationToken();
2768 Token Option,
bool ValueInParens,
2769 PragmaLoopHintInfo &Info) {
2771 int OpenParens = ValueInParens ? 1 : 0;
2773 while (Tok.
isNot(tok::eod)) {
2774 if (Tok.
is(tok::l_paren))
2776 else if (Tok.
is(tok::r_paren)) {
2778 if (OpenParens == 0 && ValueInParens)
2782 ValueList.push_back(Tok);
2786 if (ValueInParens) {
2788 if (Tok.
isNot(tok::r_paren)) {
2799 ValueList.push_back(EOFTok);
2803 Info.PragmaName = PragmaName;
2804 Info.Option = Option;
2855 void PragmaLoopHintHandler::HandlePragma(
Preprocessor &PP,
2864 if (Tok.
isNot(tok::identifier)) {
2870 while (Tok.
is(tok::identifier)) {
2874 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->
getName())
2875 .Case(
"vectorize",
true)
2876 .Case(
"interleave",
true)
2877 .Case(
"unroll",
true)
2878 .Case(
"distribute",
true)
2879 .Case(
"vectorize_width",
true)
2880 .Case(
"interleave_count",
true)
2881 .Case(
"unroll_count",
true)
2882 .Case(
"pipeline",
true)
2883 .Case(
"pipeline_initiation_interval",
true)
2887 <<
false << OptionInfo;
2893 if (Tok.
isNot(tok::l_paren)) {
2907 LoopHintTok.
setKind(tok::annot_pragma_loop_hint);
2911 TokenList.push_back(LoopHintTok);
2914 if (Tok.
isNot(tok::eod)) {
2920 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2921 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2923 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2948 void PragmaUnrollHintHandler::HandlePragma(
Preprocessor &PP,
2956 if (Tok.
is(tok::eod)) {
2958 Info->PragmaName = PragmaName;
2969 bool ValueInParens = Tok.
is(tok::l_paren);
2981 PP.
Diag(Info->Toks[0].getLocation(),
2982 diag::warn_pragma_unroll_cuda_value_in_parens);
2984 if (Tok.
isNot(tok::eod)) {
2992 auto TokenArray = llvm::make_unique<Token[]>(1);
2993 TokenArray[0].startToken();
2994 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2995 TokenArray[0].setLocation(PragmaName.
getLocation());
2996 TokenArray[0].setAnnotationEndLoc(PragmaName.
getLocation());
2997 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2998 PP.EnterTokenStream(std::move(TokenArray), 1,
3014 void PragmaMSIntrinsicHandler::HandlePragma(
Preprocessor &PP,
3019 if (Tok.
isNot(tok::l_paren)) {
3028 while (Tok.
is(tok::identifier)) {
3032 << II << SuggestIntrinH;
3035 if (Tok.
isNot(tok::comma))
3040 if (Tok.
isNot(tok::r_paren)) {
3047 if (Tok.
isNot(tok::eod))
3053 void PragmaMSOptimizeHandler::HandlePragma(
Preprocessor &PP,
3059 if (Tok.
isNot(tok::l_paren)) {
3060 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"optimize";
3065 if (Tok.
isNot(tok::string_literal)) {
3066 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_string) <<
"optimize";
3072 if (Tok.
isNot(tok::comma)) {
3073 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_comma) <<
"optimize";
3078 if (Tok.
is(tok::eod) || Tok.
is(tok::r_paren)) {
3080 <<
"optimize" <<
true <<
"'on' or 'off'";
3084 if (!II || (!II->
isStr(
"on") && !II->
isStr(
"off"))) {
3092 if (Tok.
isNot(tok::r_paren)) {
3093 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"optimize";
3098 if (Tok.
isNot(tok::eod)) {
3103 PP.
Diag(StartLoc, diag::warn_pragma_optimize);
3106 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3112 if (!Info || (!Info->
isStr(
"begin") && !Info->
isStr(
"end"))) {
3114 diag::warn_pragma_force_cuda_host_device_bad_arg);
3118 if (Info->
isStr(
"begin"))
3119 Actions.PushForceCUDAHostDevice();
3120 else if (!Actions.PopForceCUDAHostDevice())
3122 diag::err_pragma_cannot_end_force_cuda_host_device);
3125 if (!Tok.
is(tok::eod))
3127 diag::warn_pragma_force_cuda_host_device_bad_arg);
3157 void PragmaAttributeHandler::HandlePragma(
Preprocessor &PP,
3159 Token &FirstToken) {
3163 PragmaAttributeInfo(AttributesForPragmaAttribute);
3166 if (Tok.
is(tok::identifier)) {
3168 if (!II->
isStr(
"push") && !II->
isStr(
"pop")) {
3169 Info->Namespace = II;
3172 if (!Tok.
is(tok::period)) {
3173 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_period)
3181 if (!Tok.
isOneOf(tok::identifier, tok::l_paren)) {
3183 diag::err_pragma_attribute_expected_push_pop_paren);
3188 if (Tok.
is(tok::l_paren)) {
3189 if (Info->Namespace) {
3191 diag::err_pragma_attribute_namespace_on_attribute);
3193 diag::note_pragma_attribute_namespace_on_attribute);
3196 Info->Action = PragmaAttributeInfo::Attribute;
3199 if (II->
isStr(
"push"))
3200 Info->Action = PragmaAttributeInfo::Push;
3202 Info->Action = PragmaAttributeInfo::Pop;
3204 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_invalid_argument)
3213 if ((Info->Action == PragmaAttributeInfo::Push && Tok.
isNot(tok::eod)) ||
3214 Info->Action == PragmaAttributeInfo::Attribute) {
3215 if (Tok.
isNot(tok::l_paren)) {
3224 while (Tok.
isNot(tok::eod)) {
3225 if (Tok.
is(tok::l_paren))
3227 else if (Tok.
is(tok::r_paren)) {
3229 if (OpenParens == 0)
3233 AttributeTokens.push_back(Tok);
3237 if (AttributeTokens.empty()) {
3238 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_attribute);
3241 if (Tok.
isNot(tok::r_paren)) {
3253 AttributeTokens.push_back(EOFTok);
3259 if (Tok.
isNot(tok::eod))
3261 <<
"clang attribute";
3264 auto TokenArray = llvm::make_unique<Token[]>(1);
3265 TokenArray[0].startToken();
3266 TokenArray[0].setKind(tok::annot_pragma_attribute);
3267 TokenArray[0].setLocation(FirstToken.
getLocation());
3268 TokenArray[0].setAnnotationEndLoc(FirstToken.
getLocation());
3269 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3270 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