22 #include "llvm/ADT/StringSwitch.h" 23 using namespace clang;
30 Token &FirstToken)
override;
34 explicit PragmaGCCVisibilityHandler() :
PragmaHandler(
"visibility") {}
36 Token &FirstToken)
override;
42 Token &FirstToken)
override;
48 Token &FirstToken)
override;
52 explicit PragmaClangSectionHandler(
Sema &S)
55 Token &FirstToken)
override;
62 explicit PragmaMSStructHandler() :
PragmaHandler(
"ms_struct") {}
64 Token &FirstToken)
override;
70 Token &FirstToken)
override;
76 Token &FirstToken)
override;
80 explicit PragmaRedefineExtnameHandler() :
PragmaHandler(
"redefine_extname") {}
82 Token &FirstToken)
override;
86 PragmaOpenCLExtensionHandler() :
PragmaHandler(
"EXTENSION") {}
88 Token &FirstToken)
override;
95 Token &FirstToken)
override;
101 struct PragmaSTDC_FENV_ACCESSHandler :
public PragmaHandler {
102 PragmaSTDC_FENV_ACCESSHandler() :
PragmaHandler(
"FENV_ACCESS") {}
110 PP.
Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
115 Toks[0].startToken();
116 Toks[0].setKind(tok::annot_pragma_fenv_access);
119 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
120 static_cast<uintptr_t>(OOS)));
121 PP.EnterTokenStream(Toks,
true,
127 struct PragmaSTDC_CX_LIMITED_RANGEHandler :
public PragmaHandler {
128 PragmaSTDC_CX_LIMITED_RANGEHandler() :
PragmaHandler(
"CX_LIMITED_RANGE") {}
131 Token &Tok)
override {
139 PragmaSTDC_UnknownHandler() =
default;
142 Token &UnknownTok)
override {
144 PP.
Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
151 Token &FirstToken)
override;
157 Token &FirstToken)
override;
163 Token &FirstToken)
override;
168 PragmaCommentHandler(
Sema &Actions)
171 Token &FirstToken)
override;
178 PragmaDetectMismatchHandler(
Sema &Actions)
181 Token &FirstToken)
override;
188 explicit PragmaMSPointersToMembers() :
PragmaHandler(
"pointers_to_members") {}
190 Token &FirstToken)
override;
196 Token &FirstToken)
override;
202 Token &FirstToken)
override;
207 PragmaOptimizeHandler(
Sema &S)
210 Token &FirstToken)
override;
219 Token &FirstToken)
override;
225 Token &FirstToken)
override;
235 Token &FirstToken)
override;
241 Token &FirstToken)
override;
244 struct PragmaForceCUDAHostDeviceHandler :
public PragmaHandler {
245 PragmaForceCUDAHostDeviceHandler(
Sema &Actions)
246 :
PragmaHandler(
"force_cuda_host_device"), Actions(Actions) {}
248 Token &FirstToken)
override;
257 :
PragmaHandler(
"attribute"), AttributesForPragmaAttribute(AttrFactory) {}
259 Token &FirstToken)
override;
267 void Parser::initializePragmaHandlers() {
268 AlignHandler = llvm::make_unique<PragmaAlignHandler>();
271 GCCVisibilityHandler = llvm::make_unique<PragmaGCCVisibilityHandler>();
274 OptionsHandler = llvm::make_unique<PragmaOptionsHandler>();
277 PackHandler = llvm::make_unique<PragmaPackHandler>();
280 MSStructHandler = llvm::make_unique<PragmaMSStructHandler>();
283 UnusedHandler = llvm::make_unique<PragmaUnusedHandler>();
286 WeakHandler = llvm::make_unique<PragmaWeakHandler>();
289 RedefineExtnameHandler = llvm::make_unique<PragmaRedefineExtnameHandler>();
292 FPContractHandler = llvm::make_unique<PragmaFPContractHandler>();
295 STDCFENVHandler = llvm::make_unique<PragmaSTDC_FENV_ACCESSHandler>();
298 STDCCXLIMITHandler = llvm::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>();
301 STDCUnknownHandler = llvm::make_unique<PragmaSTDC_UnknownHandler>();
304 PCSectionHandler = llvm::make_unique<PragmaClangSectionHandler>(Actions);
307 if (getLangOpts().OpenCL) {
308 OpenCLExtensionHandler = llvm::make_unique<PragmaOpenCLExtensionHandler>();
313 if (getLangOpts().OpenMP)
314 OpenMPHandler = llvm::make_unique<PragmaOpenMPHandler>();
316 OpenMPHandler = llvm::make_unique<PragmaNoOpenMPHandler>();
319 if (getLangOpts().MicrosoftExt ||
320 getTargetInfo().getTriple().isOSBinFormatELF()) {
321 MSCommentHandler = llvm::make_unique<PragmaCommentHandler>(Actions);
325 if (getLangOpts().MicrosoftExt) {
326 MSDetectMismatchHandler =
327 llvm::make_unique<PragmaDetectMismatchHandler>(Actions);
329 MSPointersToMembers = llvm::make_unique<PragmaMSPointersToMembers>();
331 MSVtorDisp = llvm::make_unique<PragmaMSVtorDisp>();
333 MSInitSeg = llvm::make_unique<PragmaMSPragma>(
"init_seg");
335 MSDataSeg = llvm::make_unique<PragmaMSPragma>(
"data_seg");
337 MSBSSSeg = llvm::make_unique<PragmaMSPragma>(
"bss_seg");
339 MSConstSeg = llvm::make_unique<PragmaMSPragma>(
"const_seg");
341 MSCodeSeg = llvm::make_unique<PragmaMSPragma>(
"code_seg");
343 MSSection = llvm::make_unique<PragmaMSPragma>(
"section");
345 MSRuntimeChecks = llvm::make_unique<PragmaMSRuntimeChecksHandler>();
347 MSIntrinsic = llvm::make_unique<PragmaMSIntrinsicHandler>();
349 MSOptimize = llvm::make_unique<PragmaMSOptimizeHandler>();
353 if (getLangOpts().CUDA) {
354 CUDAForceHostDeviceHandler =
355 llvm::make_unique<PragmaForceCUDAHostDeviceHandler>(Actions);
359 OptimizeHandler = llvm::make_unique<PragmaOptimizeHandler>(Actions);
362 LoopHintHandler = llvm::make_unique<PragmaLoopHintHandler>();
365 UnrollHintHandler = llvm::make_unique<PragmaUnrollHintHandler>(
"unroll");
368 NoUnrollHintHandler = llvm::make_unique<PragmaUnrollHintHandler>(
"nounroll");
371 UnrollAndJamHintHandler =
372 llvm::make_unique<PragmaUnrollHintHandler>(
"unroll_and_jam");
375 NoUnrollAndJamHintHandler =
376 llvm::make_unique<PragmaUnrollHintHandler>(
"nounroll_and_jam");
379 FPHandler = llvm::make_unique<PragmaFPHandler>();
382 AttributePragmaHandler =
383 llvm::make_unique<PragmaAttributeHandler>(AttrFactory);
387 void Parser::resetPragmaHandlers() {
390 AlignHandler.reset();
392 GCCVisibilityHandler.reset();
394 OptionsHandler.reset();
398 MSStructHandler.reset();
400 UnusedHandler.reset();
404 RedefineExtnameHandler.reset();
406 if (getLangOpts().
OpenCL) {
408 OpenCLExtensionHandler.reset();
412 OpenMPHandler.reset();
414 if (getLangOpts().MicrosoftExt ||
415 getTargetInfo().getTriple().isOSBinFormatELF()) {
417 MSCommentHandler.reset();
421 PCSectionHandler.reset();
423 if (getLangOpts().MicrosoftExt) {
425 MSDetectMismatchHandler.reset();
427 MSPointersToMembers.reset();
443 MSRuntimeChecks.reset();
450 if (getLangOpts().CUDA) {
452 CUDAForceHostDeviceHandler.reset();
456 FPContractHandler.reset();
459 STDCFENVHandler.reset();
462 STDCCXLIMITHandler.reset();
465 STDCUnknownHandler.reset();
468 OptimizeHandler.reset();
471 LoopHintHandler.reset();
474 UnrollHintHandler.reset();
477 NoUnrollHintHandler.reset();
480 UnrollAndJamHintHandler.reset();
483 NoUnrollAndJamHintHandler.reset();
489 AttributePragmaHandler.reset();
497 void Parser::HandlePragmaUnused() {
498 assert(Tok.
is(tok::annot_pragma_unused));
500 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
504 void Parser::HandlePragmaVisibility() {
505 assert(Tok.
is(tok::annot_pragma_vis));
509 Actions.ActOnPragmaVisibility(VisType, VisLoc);
513 struct PragmaPackInfo {
520 void Parser::HandlePragmaPack() {
521 assert(Tok.
is(tok::annot_pragma_pack));
522 PragmaPackInfo *Info =
526 if (Info->Alignment.is(tok::numeric_constant)) {
527 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
529 ConsumeAnnotationToken();
533 Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
537 ConsumeAnnotationToken();
540 void Parser::HandlePragmaMSStruct() {
541 assert(Tok.
is(tok::annot_pragma_msstruct));
544 Actions.ActOnPragmaMSStruct(Kind);
545 ConsumeAnnotationToken();
548 void Parser::HandlePragmaAlign() {
549 assert(Tok.
is(tok::annot_pragma_align));
553 Actions.ActOnPragmaOptionsAlign(Kind, Tok.
getLocation());
556 ConsumeAnnotationToken();
559 void Parser::HandlePragmaDump() {
560 assert(Tok.
is(tok::annot_pragma_dump));
563 Actions.ActOnPragmaDump(getCurScope(), Tok.
getLocation(), II);
564 ConsumeAnnotationToken();
567 void Parser::HandlePragmaWeak() {
568 assert(Tok.
is(tok::annot_pragma_weak));
575 void Parser::HandlePragmaWeakAlias() {
576 assert(Tok.
is(tok::annot_pragma_weakalias));
584 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
585 WeakNameLoc, AliasNameLoc);
589 void Parser::HandlePragmaRedefineExtname() {
590 assert(Tok.
is(tok::annot_pragma_redefine_extname));
598 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
599 RedefNameLoc, AliasNameLoc);
602 void Parser::HandlePragmaFPContract() {
603 assert(Tok.
is(tok::annot_pragma_fp_contract));
617 FPC = getLangOpts().getDefaultFPContractMode();
621 Actions.ActOnPragmaFPContract(FPC);
622 ConsumeAnnotationToken();
625 void Parser::HandlePragmaFEnvAccess() {
626 assert(Tok.
is(tok::annot_pragma_fenv_access));
644 Actions.ActOnPragmaFEnvAccess(FPC);
645 ConsumeAnnotationToken();
651 assert(Tok.
is(tok::annot_pragma_captured));
652 ConsumeAnnotationToken();
654 if (Tok.
isNot(tok::l_brace)) {
655 PP.
Diag(Tok, diag::err_expected) << tok::l_brace;
663 Actions.ActOnCapturedRegionStart(Loc, getCurScope(),
CR_Default,
667 CapturedRegionScope.Exit();
670 Actions.ActOnCapturedRegionError();
674 return Actions.ActOnCapturedRegionEnd(R.get());
681 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
684 void Parser::HandlePragmaOpenCLExtension() {
685 assert(Tok.
is(tok::annot_pragma_opencl_extension));
687 auto State = Data->second;
688 auto Ident = Data->first;
690 ConsumeAnnotationToken();
692 auto &Opt = Actions.getOpenCLOptions();
693 auto Name = Ident->getName();
698 if (
State == Disable) {
700 Opt.enableSupportedCore(getLangOpts());
702 PP.
Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
705 if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
708 Actions.setCurrentOpenCLExtension(Name);
710 if (Name != Actions.getCurrentOpenCLExtension())
711 PP.
Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
712 Actions.setCurrentOpenCLExtension(
"");
713 }
else if (!Opt.isKnown(Name))
714 PP.
Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
715 else if (Opt.isSupportedExtension(Name, getLangOpts()))
716 Opt.enable(Name,
State == Enable);
717 else if (Opt.isSupportedCore(Name, getLangOpts()))
718 PP.
Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
720 PP.
Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
723 void Parser::HandlePragmaMSPointersToMembers() {
724 assert(Tok.
is(tok::annot_pragma_ms_pointers_to_members));
729 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
732 void Parser::HandlePragmaMSVtorDisp() {
733 assert(Tok.
is(tok::annot_pragma_ms_vtordisp));
737 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
739 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
742 void Parser::HandlePragmaMSPragma() {
743 assert(Tok.
is(tok::annot_pragma_ms_pragma));
747 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second,
true,
757 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
758 .Case(
"data_seg", &Parser::HandlePragmaMSSegment)
759 .Case(
"bss_seg", &Parser::HandlePragmaMSSegment)
760 .Case(
"const_seg", &Parser::HandlePragmaMSSegment)
761 .Case(
"code_seg", &Parser::HandlePragmaMSSegment)
762 .Case(
"section", &Parser::HandlePragmaMSSection)
763 .Case(
"init_seg", &Parser::HandlePragmaMSInitSeg);
765 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
774 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
776 if (Tok.
isNot(tok::l_paren)) {
777 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
782 if (Tok.
isNot(tok::string_literal)) {
783 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
787 ExprResult StringResult = ParseStringLiteralExpression();
792 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
797 bool SectionFlagsAreDefault =
true;
798 while (Tok.
is(tok::comma)) {
803 if (Tok.
is(tok::kw_long) || Tok.
is(tok::kw_short)) {
809 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
814 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
827 ? diag::warn_pragma_invalid_specific_action
828 : diag::warn_pragma_unsupported_action)
832 SectionFlags |= Flag;
833 SectionFlagsAreDefault =
false;
838 if (SectionFlagsAreDefault)
840 if (Tok.
isNot(tok::r_paren)) {
841 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
846 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
851 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
855 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
857 if (Tok.
isNot(tok::l_paren)) {
858 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
866 if (PushPop ==
"push")
868 else if (PushPop ==
"pop")
871 PP.
Diag(PragmaLocation,
872 diag::warn_pragma_expected_section_push_pop_or_name)
878 if (Tok.
is(tok::comma)) {
884 if (Tok.
is(tok::comma))
886 else if (Tok.
isNot(tok::r_paren)) {
887 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc)
892 }
else if (Tok.
isNot(tok::r_paren)) {
893 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
900 if (Tok.
isNot(tok::r_paren)) {
901 if (Tok.
isNot(tok::string_literal)) {
903 diag::warn_pragma_expected_section_name :
904 diag::warn_pragma_expected_section_label_or_name :
905 diag::warn_pragma_expected_section_push_pop_or_name;
906 PP.
Diag(PragmaLocation, DiagID) << PragmaName;
909 ExprResult StringResult = ParseStringLiteralExpression();
912 SegmentName = cast<StringLiteral>(StringResult.
get());
914 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
922 if (Tok.
isNot(tok::r_paren)) {
923 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
928 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
933 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
934 SegmentName, PragmaName);
939 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
941 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
942 PP.
Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
946 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
954 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
955 .Case(
"compiler",
"\".CRT$XCC\"")
956 .Case(
"lib",
"\".CRT$XCL\"")
957 .Case(
"user",
"\".CRT$XCU\"")
960 if (!Section.empty()) {
964 Toks[0].
setKind(tok::string_literal);
969 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks,
nullptr).get());
972 }
else if (Tok.
is(tok::string_literal)) {
973 ExprResult StringResult = ParseStringLiteralExpression();
976 SegmentName = cast<StringLiteral>(StringResult.
get());
978 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
986 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
990 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
992 ExpectAndConsume(
tok::eof, diag::warn_pragma_extra_tokens_at_eol,
996 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
1001 struct PragmaLoopHintInfo {
1009 std::string PragmaString;
1011 PragmaString =
"clang loop ";
1014 PragmaString =
"unroll_and_jam";
1017 "Unexpected pragma name");
1018 PragmaString =
"unroll";
1020 return PragmaString;
1023 bool Parser::HandlePragmaLoopHint(
LoopHint &Hint) {
1024 assert(Tok.
is(tok::annot_pragma_loop_hint));
1025 PragmaLoopHintInfo *Info =
1028 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
1030 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
1035 ? Info->Option.getIdentifierInfo()
1038 Actions.Context, Info->Option.getLocation(), OptionInfo);
1044 bool PragmaUnroll = PragmaNameInfo->
getName() ==
"unroll";
1045 bool PragmaNoUnroll = PragmaNameInfo->
getName() ==
"nounroll";
1046 bool PragmaUnrollAndJam = PragmaNameInfo->
getName() ==
"unroll_and_jam";
1047 bool PragmaNoUnrollAndJam = PragmaNameInfo->
getName() ==
"nounroll_and_jam";
1048 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll || PragmaUnrollAndJam ||
1049 PragmaNoUnrollAndJam)) {
1050 ConsumeAnnotationToken();
1051 Hint.
Range = Info->PragmaName.getLocation();
1057 assert(!Toks.empty() &&
1058 "PragmaLoopHintInfo::Toks must contain at least one token.");
1061 bool OptionUnroll =
false;
1062 bool OptionUnrollAndJam =
false;
1063 bool OptionDistribute =
false;
1064 bool OptionPipelineDisabled =
false;
1065 bool StateOption =
false;
1067 OptionUnroll = OptionInfo->isStr(
"unroll");
1068 OptionUnrollAndJam = OptionInfo->isStr(
"unroll_and_jam");
1069 OptionDistribute = OptionInfo->isStr(
"distribute");
1070 OptionPipelineDisabled = OptionInfo->isStr(
"pipeline");
1071 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
1072 .Case(
"vectorize",
true)
1073 .Case(
"interleave",
true)
1075 OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
1076 OptionPipelineDisabled;
1079 bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
1080 !OptionDistribute && !OptionPipelineDisabled;
1083 ConsumeAnnotationToken();
1084 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1086 << (OptionUnroll || OptionUnrollAndJam)
1093 ConsumeAnnotationToken();
1097 bool Valid = StateInfo &&
1098 llvm::StringSwitch<bool>(StateInfo->
getName())
1099 .Case(
"disable",
true)
1100 .Case(
"enable", !OptionPipelineDisabled)
1101 .Case(
"full", OptionUnroll || OptionUnrollAndJam)
1102 .Case(
"assume_safety", AssumeSafetyArg)
1105 if (OptionPipelineDisabled) {
1106 Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
1108 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1109 << (OptionUnroll || OptionUnrollAndJam)
1114 if (Toks.size() > 2)
1120 PP.EnterTokenStream(Toks,
false,
1122 ConsumeAnnotationToken();
1138 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation()))
1146 Info->Toks.back().getLocation());
1151 struct PragmaAttributeInfo {
1152 enum ActionType { Push, Pop, Attribute };
1158 PragmaAttributeInfo(
ParsedAttributes &Attributes) : Attributes(Attributes) {}
1161 #include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc" 1166 if (Tok.
is(tok::identifier))
1175 using namespace attr;
1177 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \ 1180 #include "clang/Basic/AttrSubMatchRulesList.inc" 1182 llvm_unreachable(
"Invalid attribute subject match rule");
1190 PRef.
Diag(SubRuleLoc,
1191 diag::err_pragma_attribute_expected_subject_sub_identifier)
1193 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1204 PRef.
Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1205 << SubRuleName << PrimaryRuleName;
1206 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1212 bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1218 AnyLoc = ConsumeToken();
1228 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1231 std::pair<Optional<attr::SubjectMatchRule>,
1233 Rule = isAttributeSubjectMatchRule(Name);
1235 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1246 if (!SubjectMatchRules
1248 std::make_pair(PrimaryRule,
SourceRange(RuleLoc, RuleLoc)))
1250 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1253 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleLoc));
1254 LastMatchRuleEndLoc = RuleLoc;
1260 if (SubRuleName.empty()) {
1266 if (SubRuleName ==
"unless") {
1272 if (SubRuleName.empty()) {
1277 auto SubRuleOrNone = Rule.second(SubRuleName,
true);
1278 if (!SubRuleOrNone) {
1279 std::string SubRuleUnlessName =
"unless(" + SubRuleName.str() +
")";
1281 SubRuleUnlessName, SubRuleLoc);
1284 SubRule = *SubRuleOrNone;
1289 auto SubRuleOrNone = Rule.second(SubRuleName,
false);
1290 if (!SubRuleOrNone) {
1295 SubRule = *SubRuleOrNone;
1299 LastMatchRuleEndLoc = RuleEndLoc;
1302 if (!SubjectMatchRules
1303 .insert(std::make_pair(SubRule,
SourceRange(RuleLoc, RuleEndLoc)))
1305 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1308 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleEndLoc));
1311 }
while (IsAny && TryConsumeToken(tok::comma));
1332 getAttributeSubjectRulesRecoveryPointForToken(
const Token &Tok) {
1334 if (II->isStr(
"apply_to"))
1335 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1336 if (II->isStr(
"any"))
1337 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1339 if (Tok.
is(tok::equal))
1340 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1356 getAttributeSubjectRulesRecoveryPointForToken(PRef.
getCurToken());
1359 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1360 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1361 FixIt +=
"apply_to";
1362 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1363 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1370 if (SubjectMatchRuleSet.empty()) {
1376 bool NeedsComma =
false;
1377 for (
const auto &I : SubjectMatchRuleSet) {
1403 void Parser::HandlePragmaAttribute() {
1404 assert(Tok.
is(tok::annot_pragma_attribute) &&
1405 "Expected #pragma attribute annotation token");
1408 if (Info->Action == PragmaAttributeInfo::Pop) {
1409 ConsumeAnnotationToken();
1410 Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
1414 assert((Info->Action == PragmaAttributeInfo::Push ||
1415 Info->Action == PragmaAttributeInfo::Attribute) &&
1416 "Unexpected #pragma attribute command");
1418 if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1419 ConsumeAnnotationToken();
1420 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1424 PP.EnterTokenStream(Info->Tokens,
false,
1426 ConsumeAnnotationToken();
1431 auto SkipToEnd = [
this]() {
1432 SkipUntil(
tok::eof, StopBeforeMatch);
1436 if (Tok.
is(tok::l_square) && NextToken().is(tok::l_square)) {
1438 ParseCXX11AttributeSpecifier(Attrs);
1439 }
else if (Tok.
is(tok::kw___attribute)) {
1441 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1444 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"("))
1447 if (Tok.
isNot(tok::identifier)) {
1448 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1455 if (Tok.
isNot(tok::l_paren))
1456 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1459 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs,
nullptr,
1464 if (ExpectAndConsume(tok::r_paren))
1466 if (ExpectAndConsume(tok::r_paren))
1468 }
else if (Tok.
is(tok::kw___declspec)) {
1469 ParseMicrosoftDeclSpecs(Attrs);
1471 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1480 if (Tok.
is(tok::l_paren)) {
1482 SkipUntil(tok::r_paren, StopBeforeMatch);
1483 if (Tok.
isNot(tok::r_paren))
1486 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1495 if (Attrs.
empty() || Attrs.
begin()->isInvalid()) {
1501 if (Attrs.
size() > 1) {
1503 Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1510 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1517 if (!TryConsumeToken(tok::comma)) {
1518 createExpectedAttributeSubjectRulesTokenDiagnostic(
1519 diag::err_expected, Attribute,
1526 if (Tok.
isNot(tok::identifier)) {
1527 createExpectedAttributeSubjectRulesTokenDiagnostic(
1528 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1529 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1534 if (!II->
isStr(
"apply_to")) {
1535 createExpectedAttributeSubjectRulesTokenDiagnostic(
1536 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1537 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1543 if (!TryConsumeToken(tok::equal)) {
1544 createExpectedAttributeSubjectRulesTokenDiagnostic(
1545 diag::err_expected, Attribute,
1546 MissingAttributeSubjectRulesRecoveryPoint::Equals, *
this)
1554 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1555 LastMatchRuleEndLoc)) {
1563 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1572 if (Info->Action == PragmaAttributeInfo::Push)
1573 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1575 Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
1576 std::move(SubjectMatchRules));
1582 void PragmaGCCVisibilityHandler::HandlePragma(
Preprocessor &PP,
1593 if (PushPop && PushPop->
isStr(
"pop")) {
1595 }
else if (PushPop && PushPop->
isStr(
"push")) {
1597 if (Tok.
isNot(tok::l_paren)) {
1610 if (Tok.
isNot(tok::r_paren)) {
1622 if (Tok.
isNot(tok::eod)) {
1628 auto Toks = llvm::make_unique<Token[]>(1);
1629 Toks[0].startToken();
1630 Toks[0].setKind(tok::annot_pragma_vis);
1631 Toks[0].setLocation(VisLoc);
1632 Toks[0].setAnnotationEndLoc(EndLoc);
1633 Toks[0].setAnnotationValue(
1634 const_cast<void *>(static_cast<const void *>(VisType)));
1635 PP.EnterTokenStream(std::move(Toks), 1,
true,
1650 if (Tok.
isNot(tok::l_paren)) {
1651 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"pack";
1656 StringRef SlotLabel;
1660 if (Tok.
is(tok::numeric_constant)) {
1670 }
else if (Tok.
is(tok::identifier)) {
1672 if (II->
isStr(
"show")) {
1676 if (II->
isStr(
"push")) {
1678 }
else if (II->
isStr(
"pop")) {
1681 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_invalid_action) <<
"pack";
1686 if (Tok.
is(tok::comma)) {
1689 if (Tok.
is(tok::numeric_constant)) {
1694 }
else if (Tok.
is(tok::identifier)) {
1698 if (Tok.
is(tok::comma)) {
1701 if (Tok.
isNot(tok::numeric_constant)) {
1724 if (Tok.
isNot(tok::r_paren)) {
1725 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"pack";
1731 if (Tok.
isNot(tok::eod)) {
1732 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"pack";
1736 PragmaPackInfo *Info =
1738 Info->Action = Action;
1739 Info->SlotLabel = SlotLabel;
1740 Info->Alignment = Alignment;
1744 Toks[0].startToken();
1745 Toks[0].setKind(tok::annot_pragma_pack);
1746 Toks[0].setLocation(PackLoc);
1747 Toks[0].setAnnotationEndLoc(RParenLoc);
1748 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1749 PP.EnterTokenStream(Toks,
true,
1755 void PragmaMSStructHandler::HandlePragma(
Preprocessor &PP,
1757 Token &MSStructTok) {
1762 if (Tok.
isNot(tok::identifier)) {
1768 if (II->
isStr(
"on")) {
1772 else if (II->
isStr(
"off") || II->
isStr(
"reset"))
1779 if (Tok.
isNot(tok::eod)) {
1787 Toks[0].startToken();
1788 Toks[0].setKind(tok::annot_pragma_msstruct);
1790 Toks[0].setAnnotationEndLoc(EndLoc);
1791 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1792 static_cast<uintptr_t>(Kind)));
1793 PP.EnterTokenStream(Toks,
true,
1798 void PragmaClangSectionHandler::HandlePragma(
Preprocessor &PP,
1800 Token &FirstToken) {
1803 auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1806 while (Tok.
isNot(tok::eod)) {
1807 if (Tok.
isNot(tok::identifier)) {
1808 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1813 if (SecType->
isStr(
"bss"))
1814 SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1815 else if (SecType->
isStr(
"data"))
1816 SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1817 else if (SecType->
isStr(
"rodata"))
1818 SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1819 else if (SecType->
isStr(
"text"))
1820 SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1822 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1827 if (Tok.
isNot(tok::equal)) {
1828 PP.
Diag(Tok.
getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1832 std::string SecName;
1836 Actions.ActOnPragmaClangSection(Tok.
getLocation(),
1837 (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1838 Sema::PragmaClangSectionAction::PCSA_Clear),
1851 if (Tok.
isNot(tok::identifier) ||
1859 if (Tok.
isNot(tok::equal)) {
1866 if (Tok.
isNot(tok::identifier)) {
1868 << (IsOptions ?
"options" :
"align");
1874 if (II->
isStr(
"native"))
1876 else if (II->
isStr(
"natural"))
1878 else if (II->
isStr(
"packed"))
1880 else if (II->
isStr(
"power"))
1882 else if (II->
isStr(
"mac68k"))
1884 else if (II->
isStr(
"reset"))
1894 if (Tok.
isNot(tok::eod)) {
1896 << (IsOptions ?
"options" :
"align");
1902 Toks[0].startToken();
1903 Toks[0].setKind(tok::annot_pragma_align);
1905 Toks[0].setAnnotationEndLoc(EndLoc);
1906 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1907 static_cast<uintptr_t>(Kind)));
1908 PP.EnterTokenStream(Toks,
true,
1912 void PragmaAlignHandler::HandlePragma(
Preprocessor &PP,
1918 void PragmaOptionsHandler::HandlePragma(
Preprocessor &PP,
1920 Token &OptionsTok) {
1925 void PragmaUnusedHandler::HandlePragma(
Preprocessor &PP,
1934 if (Tok.
isNot(tok::l_paren)) {
1935 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"unused";
1948 if (Tok.
is(tok::identifier)) {
1949 Identifiers.push_back(Tok);
1960 if (Tok.
is(tok::comma)) {
1965 if (Tok.
is(tok::r_paren)) {
1971 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_punc) <<
"unused";
1976 if (Tok.
isNot(tok::eod)) {
1983 assert(RParenLoc.
isValid() &&
"Valid '#pragma unused' must have ')'");
1984 assert(!Identifiers.empty() &&
"Valid '#pragma unused' must have arguments");
1993 2 * Identifiers.size());
1994 for (
unsigned i=0;
i != Identifiers.size();
i++) {
1995 Token &pragmaUnusedTok = Toks[2*
i], &idTok = Toks[2*
i+1];
1997 pragmaUnusedTok.
setKind(tok::annot_pragma_unused);
1999 idTok = Identifiers[
i];
2001 PP.EnterTokenStream(Toks,
true,
2014 if (Tok.
isNot(tok::identifier)) {
2015 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_identifier) <<
"weak";
2020 bool HasAlias =
false;
2024 if (Tok.
is(tok::equal)) {
2027 if (Tok.
isNot(tok::identifier)) {
2036 if (Tok.
isNot(tok::eod)) {
2037 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"weak";
2044 Token &pragmaUnusedTok = Toks[0];
2046 pragmaUnusedTok.
setKind(tok::annot_pragma_weakalias);
2050 Toks[2] = AliasName;
2051 PP.EnterTokenStream(Toks,
true,
2056 Token &pragmaUnusedTok = Toks[0];
2058 pragmaUnusedTok.
setKind(tok::annot_pragma_weak);
2062 PP.EnterTokenStream(Toks,
true,
2068 void PragmaRedefineExtnameHandler::HandlePragma(
Preprocessor &PP,
2070 Token &RedefToken) {
2075 if (Tok.
isNot(tok::identifier)) {
2084 if (Tok.
isNot(tok::identifier)) {
2086 <<
"redefine_extname";
2093 if (Tok.
isNot(tok::eod)) {
2101 Token &pragmaRedefTok = Toks[0];
2103 pragmaRedefTok.
setKind(tok::annot_pragma_redefine_extname);
2106 Toks[1] = RedefName;
2107 Toks[2] = AliasName;
2108 PP.EnterTokenStream(Toks,
true,
2112 void PragmaFPContractHandler::HandlePragma(
Preprocessor &PP,
2121 Toks[0].startToken();
2122 Toks[0].setKind(tok::annot_pragma_fp_contract);
2125 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2126 static_cast<uintptr_t>(OOS)));
2127 PP.EnterTokenStream(Toks,
true,
2131 void PragmaOpenCLExtensionHandler::HandlePragma(
Preprocessor &PP,
2135 if (Tok.
isNot(tok::identifier)) {
2144 if (Tok.
isNot(tok::colon)) {
2150 if (Tok.
isNot(tok::identifier)) {
2151 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_predicate) << 0;
2157 if (Pred->
isStr(
"enable")) {
2159 }
else if (Pred->
isStr(
"disable")) {
2161 }
else if (Pred->
isStr(
"begin"))
2163 else if (Pred->
isStr(
"end"))
2167 << Ext->
isStr(
"all");
2173 if (Tok.
isNot(tok::eod)) {
2181 Info->second =
State;
2184 Toks[0].startToken();
2185 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2186 Toks[0].setLocation(NameLoc);
2187 Toks[0].setAnnotationValue(static_cast<void*>(Info));
2188 Toks[0].setAnnotationEndLoc(StateLoc);
2189 PP.EnterTokenStream(Toks,
true,
2199 void PragmaNoOpenMPHandler::HandlePragma(
Preprocessor &PP,
2204 PP.
Diag(FirstTok, diag::warn_pragma_omp_ignored);
2213 void PragmaOpenMPHandler::HandlePragma(
Preprocessor &PP,
2219 Tok.
setKind(tok::annot_pragma_openmp);
2223 Pragma.push_back(Tok);
2225 if (Tok.
is(tok::annot_pragma_openmp)) {
2226 PP.
Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2227 unsigned InnerPragmaCnt = 1;
2228 while (InnerPragmaCnt != 0) {
2230 if (Tok.
is(tok::annot_pragma_openmp))
2232 else if (Tok.
is(tok::annot_pragma_openmp_end))
2240 Tok.
setKind(tok::annot_pragma_openmp_end);
2242 Pragma.push_back(Tok);
2244 auto Toks = llvm::make_unique<Token[]>(Pragma.size());
2245 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2246 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2258 void PragmaMSPointersToMembers::HandlePragma(
Preprocessor &PP,
2263 if (Tok.
isNot(tok::l_paren)) {
2264 PP.
Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2265 <<
"pointers_to_members";
2272 <<
"pointers_to_members";
2278 if (Arg->
isStr(
"best_case")) {
2281 if (Arg->
isStr(
"full_generality")) {
2282 if (Tok.
is(tok::comma)) {
2288 diag::err_pragma_pointers_to_members_unknown_kind)
2293 }
else if (Tok.
is(tok::r_paren)) {
2300 <<
"full_generality";
2306 if (Arg->
isStr(
"single_inheritance")) {
2307 RepresentationMethod =
2309 }
else if (Arg->
isStr(
"multiple_inheritance")) {
2310 RepresentationMethod =
2312 }
else if (Arg->
isStr(
"virtual_inheritance")) {
2313 RepresentationMethod =
2317 diag::err_pragma_pointers_to_members_unknown_kind)
2324 if (Tok.
isNot(tok::r_paren)) {
2326 << (Arg ? Arg->
getName() :
"full_generality");
2332 if (Tok.
isNot(tok::eod)) {
2334 <<
"pointers_to_members";
2340 AnnotTok.
setKind(tok::annot_pragma_ms_pointers_to_members);
2344 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2360 if (Tok.
isNot(tok::l_paren)) {
2361 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) <<
"vtordisp";
2369 if (II->
isStr(
"push")) {
2372 if (Tok.
isNot(tok::comma)) {
2373 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_punc) <<
"vtordisp";
2379 }
else if (II->
isStr(
"pop")) {
2386 if (Tok.
is(tok::r_paren)) {
2396 if (II && II->
isStr(
"off")) {
2399 }
else if (II && II->
isStr(
"on")) {
2402 }
else if (Tok.
is(tok::numeric_constant) &&
2406 << 0 << 2 <<
"vtordisp";
2417 if (Tok.
isNot(tok::r_paren)) {
2418 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) <<
"vtordisp";
2423 if (Tok.
isNot(tok::eod)) {
2432 AnnotTok.
setKind(tok::annot_pragma_ms_vtordisp);
2436 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2444 Token EoF, AnnotTok;
2448 AnnotTok.
setKind(tok::annot_pragma_ms_pragma);
2453 for (; Tok.
isNot(tok::eod); PP.
Lex(Tok)) {
2454 TokenVector.push_back(Tok);
2458 TokenVector.push_back(EoF);
2461 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
2462 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2464 std::pair<std::unique_ptr<
Token[]>,
size_t>(std::move(TokenArray),
2465 TokenVector.size());
2480 void PragmaDetectMismatchHandler::HandlePragma(
Preprocessor &PP,
2485 if (Tok.
isNot(tok::l_paren)) {
2486 PP.
Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2491 std::string NameString;
2493 "pragma detect_mismatch",
2498 std::string ValueString;
2499 if (Tok.
isNot(tok::comma)) {
2500 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2508 if (Tok.
isNot(tok::r_paren)) {
2514 if (Tok.
isNot(tok::eod)) {
2515 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2524 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2536 void PragmaCommentHandler::HandlePragma(
Preprocessor &PP,
2541 if (Tok.
isNot(tok::l_paren)) {
2542 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2548 if (Tok.
isNot(tok::identifier)) {
2549 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2556 llvm::StringSwitch<PragmaMSCommentKind>(II->
getName())
2584 std::string ArgumentString;
2597 if (Tok.
isNot(tok::r_paren)) {
2603 if (Tok.
isNot(tok::eod)) {
2612 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2617 void PragmaOptimizeHandler::HandlePragma(
Preprocessor &PP,
2619 Token &FirstToken) {
2622 if (Tok.
is(tok::eod)) {
2624 <<
"clang optimize" <<
true <<
"'on' or 'off'";
2627 if (Tok.
isNot(tok::identifier)) {
2628 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2635 if (II->
isStr(
"on")) {
2637 }
else if (!II->
isStr(
"off")) {
2638 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2644 if (Tok.
isNot(tok::eod)) {
2650 Actions.ActOnPragmaOptimize(IsOn, FirstToken.
getLocation());
2655 struct TokFPAnnotValue {
2656 enum FlagKinds { Contract };
2657 enum FlagValues { On, Off, Fast };
2660 FlagValues FlagValue;
2671 if (Tok.
isNot(tok::identifier)) {
2677 while (Tok.
is(tok::identifier)) {
2681 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2683 .Case(
"contract", TokFPAnnotValue::Contract)
2687 <<
false << OptionInfo;
2693 if (Tok.
isNot(tok::l_paren)) {
2699 if (Tok.
isNot(tok::identifier)) {
2707 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2709 .Case(
"on", TokFPAnnotValue::On)
2710 .Case(
"off", TokFPAnnotValue::Off)
2711 .Case(
"fast", TokFPAnnotValue::Fast)
2722 if (Tok.
isNot(tok::r_paren)) {
2729 TokFPAnnotValue{*FlagKind, *FlagValue};
2733 FPTok.
setKind(tok::annot_pragma_fp);
2737 TokenList.push_back(FPTok);
2740 if (Tok.
isNot(tok::eod)) {
2746 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2747 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2749 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2753 void Parser::HandlePragmaFP() {
2754 assert(Tok.
is(tok::annot_pragma_fp));
2759 switch (AnnotValue->FlagValue) {
2760 case TokFPAnnotValue::On:
2763 case TokFPAnnotValue::Fast:
2766 case TokFPAnnotValue::Off:
2771 Actions.ActOnPragmaFPContract(FPC);
2772 ConsumeAnnotationToken();
2777 Token Option,
bool ValueInParens,
2778 PragmaLoopHintInfo &Info) {
2780 int OpenParens = ValueInParens ? 1 : 0;
2782 while (Tok.
isNot(tok::eod)) {
2783 if (Tok.
is(tok::l_paren))
2785 else if (Tok.
is(tok::r_paren)) {
2787 if (OpenParens == 0 && ValueInParens)
2791 ValueList.push_back(Tok);
2795 if (ValueInParens) {
2797 if (Tok.
isNot(tok::r_paren)) {
2808 ValueList.push_back(EOFTok);
2812 Info.PragmaName = PragmaName;
2813 Info.Option = Option;
2864 void PragmaLoopHintHandler::HandlePragma(
Preprocessor &PP,
2873 if (Tok.
isNot(tok::identifier)) {
2879 while (Tok.
is(tok::identifier)) {
2883 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->
getName())
2884 .Case(
"vectorize",
true)
2885 .Case(
"interleave",
true)
2886 .Case(
"unroll",
true)
2887 .Case(
"distribute",
true)
2888 .Case(
"vectorize_width",
true)
2889 .Case(
"interleave_count",
true)
2890 .Case(
"unroll_count",
true)
2891 .Case(
"pipeline",
true)
2892 .Case(
"pipeline_initiation_interval",
true)
2896 <<
false << OptionInfo;
2902 if (Tok.
isNot(tok::l_paren)) {
2916 LoopHintTok.
setKind(tok::annot_pragma_loop_hint);
2920 TokenList.push_back(LoopHintTok);
2923 if (Tok.
isNot(tok::eod)) {
2929 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2930 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2932 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2957 void PragmaUnrollHintHandler::HandlePragma(
Preprocessor &PP,
2965 if (Tok.
is(tok::eod)) {
2967 Info->PragmaName = PragmaName;
2978 bool ValueInParens = Tok.
is(tok::l_paren);
2990 PP.
Diag(Info->Toks[0].getLocation(),
2991 diag::warn_pragma_unroll_cuda_value_in_parens);
2993 if (Tok.
isNot(tok::eod)) {
3001 auto TokenArray = llvm::make_unique<Token[]>(1);
3002 TokenArray[0].startToken();
3003 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
3004 TokenArray[0].setLocation(PragmaName.
getLocation());
3005 TokenArray[0].setAnnotationEndLoc(PragmaName.
getLocation());
3006 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3007 PP.EnterTokenStream(std::move(TokenArray), 1,
3023 void PragmaMSIntrinsicHandler::HandlePragma(
Preprocessor &PP,
3028 if (Tok.
isNot(tok::l_paren)) {
3037 while (Tok.
is(tok::identifier)) {
3041 << II << SuggestIntrinH;
3044 if (Tok.
isNot(tok::comma))
3049 if (Tok.
isNot(tok::r_paren)) {
3056 if (Tok.
isNot(tok::eod))
3062 void PragmaMSOptimizeHandler::HandlePragma(
Preprocessor &PP,
3068 if (Tok.
isNot(tok::l_paren)) {
3069 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"optimize";
3074 if (Tok.
isNot(tok::string_literal)) {
3075 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_string) <<
"optimize";
3081 if (Tok.
isNot(tok::comma)) {
3082 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_comma) <<
"optimize";
3087 if (Tok.
is(tok::eod) || Tok.
is(tok::r_paren)) {
3089 <<
"optimize" <<
true <<
"'on' or 'off'";
3093 if (!II || (!II->
isStr(
"on") && !II->
isStr(
"off"))) {
3101 if (Tok.
isNot(tok::r_paren)) {
3102 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"optimize";
3107 if (Tok.
isNot(tok::eod)) {
3112 PP.
Diag(StartLoc, diag::warn_pragma_optimize);
3115 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3121 if (!Info || (!Info->
isStr(
"begin") && !Info->
isStr(
"end"))) {
3123 diag::warn_pragma_force_cuda_host_device_bad_arg);
3127 if (Info->
isStr(
"begin"))
3128 Actions.PushForceCUDAHostDevice();
3129 else if (!Actions.PopForceCUDAHostDevice())
3131 diag::err_pragma_cannot_end_force_cuda_host_device);
3134 if (!Tok.
is(tok::eod))
3136 diag::warn_pragma_force_cuda_host_device_bad_arg);
3166 void PragmaAttributeHandler::HandlePragma(
Preprocessor &PP,
3168 Token &FirstToken) {
3172 PragmaAttributeInfo(AttributesForPragmaAttribute);
3175 if (Tok.
is(tok::identifier)) {
3177 if (!II->
isStr(
"push") && !II->
isStr(
"pop")) {
3178 Info->Namespace = II;
3181 if (!Tok.
is(tok::period)) {
3182 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_period)
3190 if (!Tok.
isOneOf(tok::identifier, tok::l_paren)) {
3192 diag::err_pragma_attribute_expected_push_pop_paren);
3197 if (Tok.
is(tok::l_paren)) {
3198 if (Info->Namespace) {
3200 diag::err_pragma_attribute_namespace_on_attribute);
3202 diag::note_pragma_attribute_namespace_on_attribute);
3205 Info->Action = PragmaAttributeInfo::Attribute;
3208 if (II->
isStr(
"push"))
3209 Info->Action = PragmaAttributeInfo::Push;
3211 Info->Action = PragmaAttributeInfo::Pop;
3213 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_invalid_argument)
3222 if ((Info->Action == PragmaAttributeInfo::Push && Tok.
isNot(tok::eod)) ||
3223 Info->Action == PragmaAttributeInfo::Attribute) {
3224 if (Tok.
isNot(tok::l_paren)) {
3233 while (Tok.
isNot(tok::eod)) {
3234 if (Tok.
is(tok::l_paren))
3236 else if (Tok.
is(tok::r_paren)) {
3238 if (OpenParens == 0)
3242 AttributeTokens.push_back(Tok);
3246 if (AttributeTokens.empty()) {
3247 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_attribute);
3250 if (Tok.
isNot(tok::r_paren)) {
3262 AttributeTokens.push_back(EOFTok);
3268 if (Tok.
isNot(tok::eod))
3270 <<
"clang attribute";
3273 auto TokenArray = llvm::make_unique<Token[]>(1);
3274 TokenArray[0].startToken();
3275 TokenArray[0].setKind(tok::annot_pragma_attribute);
3276 TokenArray[0].setLocation(FirstToken.
getLocation());
3277 TokenArray[0].setAnnotationEndLoc(FirstToken.
getLocation());
3278 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3279 PP.EnterTokenStream(std::move(TokenArray), 1,
Defines the clang::ASTContext interface.
IdentifierLoc * PragmaNameLoc
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.
ActionResult< Stmt * > StmtResult
static void diagnoseUnknownAttributeSubjectSubRule(Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, StringRef SubRuleName, SourceLocation SubRuleLoc)
static std::string PragmaLoopHintString(Token PragmaName, Token Option)
IdentifierLoc * OptionLoc
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
Parse and apply any fixits to the source.
tok::TokenKind getKind() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
One of these records is kept for each identifier that is lexed.
SubjectMatchRule
A list of all the recognized kinds of attributes.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
const TargetInfo & getTargetInfo() const
Token - This structure provides full information about a lexed token.
void setKind(tok::TokenKind K)
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
unsigned getCharByteWidth() const
const LangOptions & getLangOpts() const
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
MissingAttributeSubjectRulesRecoveryPoint
Describes the stage at which attribute subject rule parsing was interrupted.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
unsigned getLength() const
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
Sema - This implements semantic analysis and AST building for C.
A little helper class used to produce diagnostics.
EmptyPragmaHandler - A pragma handler which takes no action, which can be used to ignore particular p...
void setAnnotationValue(void *val)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
const Token & getCurToken() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Remove the specific pragma handler from this preprocessor.
This is a compound statement scope.
static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule)
SourceLocation getEnd() const
PPCallbacks * getPPCallbacks() const
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, StringRef Str)
Callback invoked when a #pragma comment directive is read.
static StringRef getIdentifier(const Token &Tok)
const LangOptions & getLangOpts() const
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
static CharSourceRange getCharRange(SourceRange R)
static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, bool IsOptions)
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
const char * getSubjectMatchRuleSpelling(SubjectMatchRule Rule)
void setLength(unsigned Len)
IdentifierInfo * getIdentifierInfo() const
void setAnnotationEndLoc(SourceLocation L)
ParsedAttr - Represents a syntactic attribute.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
void Lex(Token &Result)
Lex the next token for this preprocessor.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
PragmaMSPointersToMembersKind
StringRef getName() const
Return the actual identifier string.
bool isMacroDefined(StringRef Id)
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool expectAndConsume(unsigned DiagID=diag::err_expected, const char *Msg="", tok::TokenKind SkipToTok=tok::unknown)
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, StringRef Value)
Callback invoked when a #pragma detect_mismatch directive is read.
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
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
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Describes how and where the pragma was introduced.
Loop optimization hint for loop and unroll pragmas.
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