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 Token &FirstToken)
override;
107 Token &FirstToken)
override;
113 Token &FirstToken)
override;
118 PragmaCommentHandler(
Sema &Actions)
121 Token &FirstToken)
override;
127 PragmaDetectMismatchHandler(
Sema &Actions)
130 Token &FirstToken)
override;
136 explicit PragmaMSPointersToMembers() :
PragmaHandler(
"pointers_to_members") {}
138 Token &FirstToken)
override;
144 Token &FirstToken)
override;
148 explicit PragmaMSPragma(
const char *name) :
PragmaHandler(name) {}
150 Token &FirstToken)
override;
155 PragmaOptimizeHandler(
Sema &S)
158 Token &FirstToken)
override;
166 Token &FirstToken)
override;
170 PragmaUnrollHintHandler(
const char *name) :
PragmaHandler(name) {}
172 Token &FirstToken)
override;
182 Token &FirstToken)
override;
185 struct PragmaForceCUDAHostDeviceHandler :
public PragmaHandler {
186 PragmaForceCUDAHostDeviceHandler(
Sema &Actions)
187 :
PragmaHandler(
"force_cuda_host_device"), Actions(Actions) {}
189 Token &FirstToken)
override;
198 :
PragmaHandler(
"attribute"), AttributesForPragmaAttribute(AttrFactory) {}
200 Token &FirstToken)
override;
208 void Parser::initializePragmaHandlers() {
209 AlignHandler.reset(
new PragmaAlignHandler());
210 PP.AddPragmaHandler(AlignHandler.get());
212 GCCVisibilityHandler.reset(
new PragmaGCCVisibilityHandler());
213 PP.AddPragmaHandler(
"GCC", GCCVisibilityHandler.get());
215 OptionsHandler.reset(
new PragmaOptionsHandler());
216 PP.AddPragmaHandler(OptionsHandler.get());
218 PackHandler.reset(
new PragmaPackHandler());
219 PP.AddPragmaHandler(PackHandler.get());
221 MSStructHandler.reset(
new PragmaMSStructHandler());
222 PP.AddPragmaHandler(MSStructHandler.get());
224 UnusedHandler.reset(
new PragmaUnusedHandler());
225 PP.AddPragmaHandler(UnusedHandler.get());
227 WeakHandler.reset(
new PragmaWeakHandler());
228 PP.AddPragmaHandler(WeakHandler.get());
230 RedefineExtnameHandler.reset(
new PragmaRedefineExtnameHandler());
231 PP.AddPragmaHandler(RedefineExtnameHandler.get());
233 FPContractHandler.reset(
new PragmaFPContractHandler());
234 PP.AddPragmaHandler(
"STDC", FPContractHandler.get());
236 PCSectionHandler.reset(
new PragmaClangSectionHandler(Actions));
237 PP.AddPragmaHandler(
"clang", PCSectionHandler.get());
239 if (getLangOpts().OpenCL) {
240 OpenCLExtensionHandler.reset(
new PragmaOpenCLExtensionHandler());
241 PP.AddPragmaHandler(
"OPENCL", OpenCLExtensionHandler.get());
243 PP.AddPragmaHandler(
"OPENCL", FPContractHandler.get());
245 if (getLangOpts().OpenMP)
246 OpenMPHandler.reset(
new PragmaOpenMPHandler());
248 OpenMPHandler.reset(
new PragmaNoOpenMPHandler());
249 PP.AddPragmaHandler(OpenMPHandler.get());
251 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
252 MSCommentHandler.reset(
new PragmaCommentHandler(Actions));
253 PP.AddPragmaHandler(MSCommentHandler.get());
256 if (getLangOpts().MicrosoftExt) {
257 MSDetectMismatchHandler.reset(
new PragmaDetectMismatchHandler(Actions));
258 PP.AddPragmaHandler(MSDetectMismatchHandler.get());
259 MSPointersToMembers.reset(
new PragmaMSPointersToMembers());
260 PP.AddPragmaHandler(MSPointersToMembers.get());
261 MSVtorDisp.reset(
new PragmaMSVtorDisp());
262 PP.AddPragmaHandler(MSVtorDisp.get());
263 MSInitSeg.reset(
new PragmaMSPragma(
"init_seg"));
264 PP.AddPragmaHandler(MSInitSeg.get());
265 MSDataSeg.reset(
new PragmaMSPragma(
"data_seg"));
266 PP.AddPragmaHandler(MSDataSeg.get());
267 MSBSSSeg.reset(
new PragmaMSPragma(
"bss_seg"));
268 PP.AddPragmaHandler(MSBSSSeg.get());
269 MSConstSeg.reset(
new PragmaMSPragma(
"const_seg"));
270 PP.AddPragmaHandler(MSConstSeg.get());
271 MSCodeSeg.reset(
new PragmaMSPragma(
"code_seg"));
272 PP.AddPragmaHandler(MSCodeSeg.get());
273 MSSection.reset(
new PragmaMSPragma(
"section"));
274 PP.AddPragmaHandler(MSSection.get());
275 MSRuntimeChecks.reset(
new PragmaMSRuntimeChecksHandler());
276 PP.AddPragmaHandler(MSRuntimeChecks.get());
277 MSIntrinsic.reset(
new PragmaMSIntrinsicHandler());
278 PP.AddPragmaHandler(MSIntrinsic.get());
281 if (getLangOpts().CUDA) {
282 CUDAForceHostDeviceHandler.reset(
283 new PragmaForceCUDAHostDeviceHandler(Actions));
284 PP.AddPragmaHandler(
"clang", CUDAForceHostDeviceHandler.get());
287 OptimizeHandler.reset(
new PragmaOptimizeHandler(Actions));
288 PP.AddPragmaHandler(
"clang", OptimizeHandler.get());
290 LoopHintHandler.reset(
new PragmaLoopHintHandler());
291 PP.AddPragmaHandler(
"clang", LoopHintHandler.get());
293 UnrollHintHandler.reset(
new PragmaUnrollHintHandler(
"unroll"));
294 PP.AddPragmaHandler(UnrollHintHandler.get());
296 NoUnrollHintHandler.reset(
new PragmaUnrollHintHandler(
"nounroll"));
297 PP.AddPragmaHandler(NoUnrollHintHandler.get());
299 FPHandler.reset(
new PragmaFPHandler());
300 PP.AddPragmaHandler(
"clang", FPHandler.get());
302 AttributePragmaHandler.reset(
new PragmaAttributeHandler(AttrFactory));
303 PP.AddPragmaHandler(
"clang", AttributePragmaHandler.get());
306 void Parser::resetPragmaHandlers() {
308 PP.RemovePragmaHandler(AlignHandler.get());
309 AlignHandler.reset();
310 PP.RemovePragmaHandler(
"GCC", GCCVisibilityHandler.get());
311 GCCVisibilityHandler.reset();
312 PP.RemovePragmaHandler(OptionsHandler.get());
313 OptionsHandler.reset();
314 PP.RemovePragmaHandler(PackHandler.get());
316 PP.RemovePragmaHandler(MSStructHandler.get());
317 MSStructHandler.reset();
318 PP.RemovePragmaHandler(UnusedHandler.get());
319 UnusedHandler.reset();
320 PP.RemovePragmaHandler(WeakHandler.get());
322 PP.RemovePragmaHandler(RedefineExtnameHandler.get());
323 RedefineExtnameHandler.reset();
325 if (getLangOpts().
OpenCL) {
326 PP.RemovePragmaHandler(
"OPENCL", OpenCLExtensionHandler.get());
327 OpenCLExtensionHandler.reset();
328 PP.RemovePragmaHandler(
"OPENCL", FPContractHandler.get());
330 PP.RemovePragmaHandler(OpenMPHandler.get());
331 OpenMPHandler.reset();
333 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
334 PP.RemovePragmaHandler(MSCommentHandler.get());
335 MSCommentHandler.reset();
338 PP.RemovePragmaHandler(
"clang", PCSectionHandler.get());
339 PCSectionHandler.reset();
341 if (getLangOpts().MicrosoftExt) {
342 PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
343 MSDetectMismatchHandler.reset();
344 PP.RemovePragmaHandler(MSPointersToMembers.get());
345 MSPointersToMembers.reset();
346 PP.RemovePragmaHandler(MSVtorDisp.get());
348 PP.RemovePragmaHandler(MSInitSeg.get());
350 PP.RemovePragmaHandler(MSDataSeg.get());
352 PP.RemovePragmaHandler(MSBSSSeg.get());
354 PP.RemovePragmaHandler(MSConstSeg.get());
356 PP.RemovePragmaHandler(MSCodeSeg.get());
358 PP.RemovePragmaHandler(MSSection.get());
360 PP.RemovePragmaHandler(MSRuntimeChecks.get());
361 MSRuntimeChecks.reset();
362 PP.RemovePragmaHandler(MSIntrinsic.get());
366 if (getLangOpts().CUDA) {
367 PP.RemovePragmaHandler(
"clang", CUDAForceHostDeviceHandler.get());
368 CUDAForceHostDeviceHandler.reset();
371 PP.RemovePragmaHandler(
"STDC", FPContractHandler.get());
372 FPContractHandler.reset();
374 PP.RemovePragmaHandler(
"clang", OptimizeHandler.get());
375 OptimizeHandler.reset();
377 PP.RemovePragmaHandler(
"clang", LoopHintHandler.get());
378 LoopHintHandler.reset();
380 PP.RemovePragmaHandler(UnrollHintHandler.get());
381 UnrollHintHandler.reset();
383 PP.RemovePragmaHandler(NoUnrollHintHandler.get());
384 NoUnrollHintHandler.reset();
386 PP.RemovePragmaHandler(
"clang", FPHandler.get());
389 PP.RemovePragmaHandler(
"clang", AttributePragmaHandler.get());
390 AttributePragmaHandler.reset();
398 void Parser::HandlePragmaUnused() {
399 assert(
Tok.
is(tok::annot_pragma_unused));
401 Actions.ActOnPragmaUnused(
Tok, getCurScope(), UnusedLoc);
405 void Parser::HandlePragmaVisibility() {
406 assert(
Tok.
is(tok::annot_pragma_vis));
410 Actions.ActOnPragmaVisibility(VisType, VisLoc);
414 struct PragmaPackInfo {
421 void Parser::HandlePragmaPack() {
422 assert(
Tok.
is(tok::annot_pragma_pack));
423 PragmaPackInfo *Info =
424 static_cast<PragmaPackInfo *
>(
Tok.getAnnotationValue());
427 if (Info->Alignment.is(tok::numeric_constant)) {
428 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
430 ConsumeAnnotationToken();
434 Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
438 ConsumeAnnotationToken();
441 void Parser::HandlePragmaMSStruct() {
442 assert(
Tok.
is(tok::annot_pragma_msstruct));
445 Actions.ActOnPragmaMSStruct(Kind);
446 ConsumeAnnotationToken();
449 void Parser::HandlePragmaAlign() {
450 assert(
Tok.
is(tok::annot_pragma_align));
455 Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
458 void Parser::HandlePragmaDump() {
459 assert(
Tok.
is(tok::annot_pragma_dump));
462 Actions.ActOnPragmaDump(getCurScope(),
Tok.getLocation(), II);
463 ConsumeAnnotationToken();
466 void Parser::HandlePragmaWeak() {
467 assert(
Tok.
is(tok::annot_pragma_weak));
469 Actions.ActOnPragmaWeakID(
Tok.getIdentifierInfo(), PragmaLoc,
474 void Parser::HandlePragmaWeakAlias() {
475 assert(
Tok.
is(tok::annot_pragma_weakalias));
483 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
484 WeakNameLoc, AliasNameLoc);
488 void Parser::HandlePragmaRedefineExtname() {
489 assert(
Tok.
is(tok::annot_pragma_redefine_extname));
497 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
498 RedefNameLoc, AliasNameLoc);
501 void Parser::HandlePragmaFPContract() {
502 assert(
Tok.
is(tok::annot_pragma_fp_contract));
516 FPC = getLangOpts().getDefaultFPContractMode();
520 Actions.ActOnPragmaFPContract(FPC);
521 ConsumeAnnotationToken();
526 assert(
Tok.
is(tok::annot_pragma_captured));
527 ConsumeAnnotationToken();
530 PP.Diag(
Tok, diag::err_expected) << tok::l_brace;
538 Actions.ActOnCapturedRegionStart(Loc, getCurScope(),
CR_Default,
542 CapturedRegionScope.Exit();
545 Actions.ActOnCapturedRegionError();
549 return Actions.ActOnCapturedRegionEnd(R.get());
556 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
559 void Parser::HandlePragmaOpenCLExtension() {
560 assert(
Tok.
is(tok::annot_pragma_opencl_extension));
561 OpenCLExtData *Data =
static_cast<OpenCLExtData*
>(
Tok.getAnnotationValue());
562 auto State = Data->second;
563 auto Ident = Data->first;
565 ConsumeAnnotationToken();
567 auto &Opt = Actions.getOpenCLOptions();
568 auto Name = Ident->getName();
573 if (
State == Disable) {
575 Opt.enableSupportedCore(getLangOpts().OpenCLVersion);
577 PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
580 if (!Opt.isKnown(Name) ||
581 !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
584 Actions.setCurrentOpenCLExtension(Name);
586 if (Name != Actions.getCurrentOpenCLExtension())
587 PP.Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
588 Actions.setCurrentOpenCLExtension(
"");
589 }
else if (!Opt.isKnown(Name))
590 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
591 else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
592 Opt.enable(Name,
State == Enable);
593 else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
594 PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
596 PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
599 void Parser::HandlePragmaMSPointersToMembers() {
600 assert(
Tok.
is(tok::annot_pragma_ms_pointers_to_members));
605 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
608 void Parser::HandlePragmaMSVtorDisp() {
609 assert(
Tok.
is(tok::annot_pragma_ms_vtordisp));
613 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
615 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
618 void Parser::HandlePragmaMSPragma() {
619 assert(
Tok.
is(tok::annot_pragma_ms_pragma));
622 (std::pair<std::unique_ptr<Token[]>,
size_t> *)
Tok.getAnnotationValue();
623 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second,
true);
625 assert(
Tok.isAnyIdentifier());
626 StringRef PragmaName =
Tok.getIdentifierInfo()->getName();
632 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
633 .Case(
"data_seg", &Parser::HandlePragmaMSSegment)
634 .Case(
"bss_seg", &Parser::HandlePragmaMSSegment)
635 .Case(
"const_seg", &Parser::HandlePragmaMSSegment)
636 .Case(
"code_seg", &Parser::HandlePragmaMSSegment)
637 .Case(
"section", &Parser::HandlePragmaMSSection)
638 .Case(
"init_seg", &Parser::HandlePragmaMSInitSeg);
640 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
649 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
652 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
657 if (
Tok.
isNot(tok::string_literal)) {
658 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
662 ExprResult StringResult = ParseStringLiteralExpression();
667 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
672 bool SectionFlagsAreDefault =
true;
673 while (
Tok.
is(tok::comma)) {
678 if (
Tok.
is(tok::kw_long) ||
Tok.
is(tok::kw_short)) {
683 if (!
Tok.isAnyIdentifier()) {
684 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
689 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
690 Tok.getIdentifierInfo()->getName())
702 ? diag::warn_pragma_invalid_specific_action
703 : diag::warn_pragma_unsupported_action)
704 << PragmaName <<
Tok.getIdentifierInfo()->getName();
707 SectionFlags |= Flag;
708 SectionFlagsAreDefault =
false;
713 if (SectionFlagsAreDefault)
716 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
721 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
726 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
730 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
733 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
739 if (
Tok.isAnyIdentifier()) {
740 StringRef PushPop =
Tok.getIdentifierInfo()->getName();
741 if (PushPop ==
"push")
743 else if (PushPop ==
"pop")
746 PP.Diag(PragmaLocation,
747 diag::warn_pragma_expected_section_push_pop_or_name)
753 if (
Tok.
is(tok::comma)) {
756 if (
Tok.isAnyIdentifier()) {
757 SlotLabel =
Tok.getIdentifierInfo()->getName();
759 if (
Tok.
is(tok::comma))
762 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
767 }
else if (
Tok.
isNot(tok::r_paren)) {
768 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
776 if (
Tok.
isNot(tok::string_literal)) {
778 diag::warn_pragma_expected_section_name :
779 diag::warn_pragma_expected_section_label_or_name :
780 diag::warn_pragma_expected_section_push_pop_or_name;
781 PP.Diag(PragmaLocation, DiagID) << PragmaName;
784 ExprResult StringResult = ParseStringLiteralExpression();
787 SegmentName = cast<StringLiteral>(StringResult.
get());
789 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
798 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
803 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
808 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
809 SegmentName, PragmaName);
814 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
816 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
817 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
821 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
827 if (
Tok.isAnyIdentifier()) {
828 auto *II =
Tok.getIdentifierInfo();
829 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
830 .Case(
"compiler",
"\".CRT$XCC\"")
831 .Case(
"lib",
"\".CRT$XCL\"")
832 .Case(
"user",
"\".CRT$XCU\"")
835 if (!Section.empty()) {
839 Toks[0].
setKind(tok::string_literal);
844 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks,
nullptr).get());
847 }
else if (
Tok.
is(tok::string_literal)) {
848 ExprResult StringResult = ParseStringLiteralExpression();
851 SegmentName = cast<StringLiteral>(StringResult.
get());
853 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
861 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
865 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
867 ExpectAndConsume(
tok::eof, diag::warn_pragma_extra_tokens_at_eol,
871 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
876 struct PragmaLoopHintInfo {
884 std::string PragmaString;
886 PragmaString =
"clang loop ";
890 "Unexpected pragma name");
891 PragmaString =
"unroll";
896 bool Parser::HandlePragmaLoopHint(
LoopHint &Hint) {
897 assert(
Tok.
is(tok::annot_pragma_loop_hint));
898 PragmaLoopHintInfo *Info =
899 static_cast<PragmaLoopHintInfo *
>(
Tok.getAnnotationValue());
901 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
903 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
908 ? Info->Option.getIdentifierInfo()
911 Actions.Context, Info->Option.getLocation(), OptionInfo);
917 bool PragmaUnroll = PragmaNameInfo->
getName() ==
"unroll";
918 bool PragmaNoUnroll = PragmaNameInfo->
getName() ==
"nounroll";
919 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll)) {
920 ConsumeAnnotationToken();
921 Hint.
Range = Info->PragmaName.getLocation();
927 assert(!Toks.empty() &&
928 "PragmaLoopHintInfo::Toks must contain at least one token.");
931 bool OptionUnroll =
false;
932 bool OptionDistribute =
false;
933 bool StateOption =
false;
935 OptionUnroll = OptionInfo->isStr(
"unroll");
936 OptionDistribute = OptionInfo->isStr(
"distribute");
937 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
938 .Case(
"vectorize",
true)
939 .Case(
"interleave",
true)
941 OptionUnroll || OptionDistribute;
944 bool AssumeSafetyArg = !OptionUnroll && !OptionDistribute;
947 ConsumeAnnotationToken();
948 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
949 << StateOption << OptionUnroll
956 ConsumeAnnotationToken();
960 bool Valid = StateInfo &&
961 llvm::StringSwitch<bool>(StateInfo->
getName())
962 .Cases(
"enable",
"disable",
true)
963 .Case(
"full", OptionUnroll)
964 .Case(
"assume_safety", AssumeSafetyArg)
967 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
973 Diag(
Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
978 PP.EnterTokenStream(Toks,
false);
979 ConsumeAnnotationToken();
986 Diag(
Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
995 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation()))
1003 Info->Toks.back().getLocation());
1008 struct PragmaAttributeInfo {
1009 enum ActionType { Push, Pop };
1014 PragmaAttributeInfo(
ParsedAttributes &Attributes) : Attributes(Attributes) {}
1017 #include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc" 1022 if (Tok.
is(tok::identifier))
1031 using namespace attr;
1033 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \ 1036 #include "clang/Basic/AttrSubMatchRulesList.inc" 1038 llvm_unreachable(
"Invalid attribute subject match rule");
1046 PRef.
Diag(SubRuleLoc,
1047 diag::err_pragma_attribute_expected_subject_sub_identifier)
1049 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1060 PRef.
Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1061 << SubRuleName << PrimaryRuleName;
1062 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1068 bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1074 AnyLoc = ConsumeToken();
1084 Diag(
Tok, diag::err_pragma_attribute_expected_subject_identifier);
1087 std::pair<Optional<attr::SubjectMatchRule>,
1089 Rule = isAttributeSubjectMatchRule(Name);
1091 Diag(
Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1102 if (!SubjectMatchRules
1104 std::make_pair(PrimaryRule,
SourceRange(RuleLoc, RuleLoc)))
1106 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1109 RuleLoc,
Tok.
is(tok::comma) ?
Tok.getLocation() : RuleLoc));
1110 LastMatchRuleEndLoc = RuleLoc;
1116 if (SubRuleName.empty()) {
1122 if (SubRuleName ==
"unless") {
1128 if (SubRuleName.empty()) {
1133 auto SubRuleOrNone = Rule.second(SubRuleName,
true);
1134 if (!SubRuleOrNone) {
1135 std::string SubRuleUnlessName =
"unless(" + SubRuleName.str() +
")";
1137 SubRuleUnlessName, SubRuleLoc);
1140 SubRule = *SubRuleOrNone;
1145 auto SubRuleOrNone = Rule.second(SubRuleName,
false);
1146 if (!SubRuleOrNone) {
1148 SubRuleName,
Tok.getLocation());
1151 SubRule = *SubRuleOrNone;
1155 LastMatchRuleEndLoc = RuleEndLoc;
1158 if (!SubjectMatchRules
1159 .insert(std::make_pair(SubRule,
SourceRange(RuleLoc, RuleEndLoc)))
1161 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1164 RuleLoc,
Tok.
is(tok::comma) ?
Tok.getLocation() : RuleEndLoc));
1167 }
while (IsAny && TryConsumeToken(tok::comma));
1188 getAttributeSubjectRulesRecoveryPointForToken(
const Token &
Tok) {
1190 if (II->isStr(
"apply_to"))
1191 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1192 if (II->isStr(
"any"))
1193 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1195 if (Tok.
is(tok::equal))
1196 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1212 getAttributeSubjectRulesRecoveryPointForToken(PRef.
getCurToken());
1215 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1216 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1217 FixIt +=
"apply_to";
1218 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1219 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1226 if (SubjectMatchRuleSet.empty()) {
1232 bool NeedsComma =
false;
1233 for (
const auto &I : SubjectMatchRuleSet) {
1259 void Parser::HandlePragmaAttribute() {
1260 assert(
Tok.
is(tok::annot_pragma_attribute) &&
1261 "Expected #pragma attribute annotation token");
1263 auto *Info =
static_cast<PragmaAttributeInfo *
>(
Tok.getAnnotationValue());
1264 if (Info->Action == PragmaAttributeInfo::Pop) {
1265 ConsumeAnnotationToken();
1266 Actions.ActOnPragmaAttributePop(PragmaLoc);
1270 assert(Info->Action == PragmaAttributeInfo::Push &&
1271 "Unexpected #pragma attribute command");
1272 PP.EnterTokenStream(Info->Tokens,
false);
1273 ConsumeAnnotationToken();
1278 auto SkipToEnd = [
this]() {
1279 SkipUntil(
tok::eof, StopBeforeMatch);
1283 if (
Tok.
is(tok::l_square) && NextToken().is(tok::l_square)) {
1285 ParseCXX11AttributeSpecifier(Attrs);
1286 }
else if (
Tok.
is(tok::kw___attribute)) {
1288 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1291 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"("))
1295 Diag(
Tok, diag::err_pragma_attribute_expected_attribute_name);
1303 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1306 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs,
nullptr,
1312 if (ExpectAndConsume(tok::r_paren))
1314 if (ExpectAndConsume(tok::r_paren))
1316 }
else if (
Tok.
is(tok::kw___declspec)) {
1317 ParseMicrosoftDeclSpecs(Attrs);
1319 Diag(
Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1320 if (
Tok.getIdentifierInfo()) {
1328 if (
Tok.
is(tok::l_paren)) {
1330 SkipUntil(tok::r_paren, StopBeforeMatch);
1334 Diag(
Tok, diag::note_pragma_attribute_use_attribute_kw)
1351 Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1357 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1365 if (!TryConsumeToken(tok::comma)) {
1366 createExpectedAttributeSubjectRulesTokenDiagnostic(
1367 diag::err_expected, Attribute,
1375 createExpectedAttributeSubjectRulesTokenDiagnostic(
1376 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1377 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1382 if (!II->
isStr(
"apply_to")) {
1383 createExpectedAttributeSubjectRulesTokenDiagnostic(
1384 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1385 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1391 if (!TryConsumeToken(tok::equal)) {
1392 createExpectedAttributeSubjectRulesTokenDiagnostic(
1393 diag::err_expected, Attribute,
1394 MissingAttributeSubjectRulesRecoveryPoint::Equals, *
this)
1402 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1403 LastMatchRuleEndLoc)) {
1411 Diag(
Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1419 Actions.ActOnPragmaAttributePush(Attribute, PragmaLoc,
1420 std::move(SubjectMatchRules));
1426 void PragmaGCCVisibilityHandler::HandlePragma(
Preprocessor &PP,
1437 if (PushPop && PushPop->
isStr(
"pop")) {
1439 }
else if (PushPop && PushPop->
isStr(
"push")) {
1441 if (Tok.
isNot(tok::l_paren)) {
1454 if (Tok.
isNot(tok::r_paren)) {
1466 if (Tok.
isNot(tok::eod)) {
1472 auto Toks = llvm::make_unique<Token[]>(1);
1473 Toks[0].startToken();
1474 Toks[0].setKind(tok::annot_pragma_vis);
1475 Toks[0].setLocation(VisLoc);
1476 Toks[0].setAnnotationEndLoc(EndLoc);
1477 Toks[0].setAnnotationValue(
1478 const_cast<void*>(static_cast<const void*>(VisType)));
1479 PP.EnterTokenStream(std::move(Toks), 1,
true);
1493 if (Tok.
isNot(tok::l_paren)) {
1494 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"pack";
1499 StringRef SlotLabel;
1503 if (Tok.
is(tok::numeric_constant)) {
1513 }
else if (Tok.
is(tok::identifier)) {
1515 if (II->
isStr(
"show")) {
1519 if (II->
isStr(
"push")) {
1521 }
else if (II->
isStr(
"pop")) {
1524 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_invalid_action) <<
"pack";
1529 if (Tok.
is(tok::comma)) {
1532 if (Tok.
is(tok::numeric_constant)) {
1537 }
else if (Tok.
is(tok::identifier)) {
1541 if (Tok.
is(tok::comma)) {
1544 if (Tok.
isNot(tok::numeric_constant)) {
1567 if (Tok.
isNot(tok::r_paren)) {
1568 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"pack";
1574 if (Tok.
isNot(tok::eod)) {
1575 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"pack";
1579 PragmaPackInfo *Info =
1581 Info->Action = Action;
1582 Info->SlotLabel = SlotLabel;
1583 Info->Alignment = Alignment;
1587 Toks[0].startToken();
1588 Toks[0].setKind(tok::annot_pragma_pack);
1589 Toks[0].setLocation(PackLoc);
1590 Toks[0].setAnnotationEndLoc(RParenLoc);
1591 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1592 PP.EnterTokenStream(Toks,
true);
1597 void PragmaMSStructHandler::HandlePragma(
Preprocessor &PP,
1599 Token &MSStructTok) {
1604 if (Tok.
isNot(tok::identifier)) {
1610 if (II->
isStr(
"on")) {
1614 else if (II->
isStr(
"off") || II->
isStr(
"reset"))
1621 if (Tok.
isNot(tok::eod)) {
1629 Toks[0].startToken();
1630 Toks[0].setKind(tok::annot_pragma_msstruct);
1632 Toks[0].setAnnotationEndLoc(EndLoc);
1633 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1634 static_cast<uintptr_t>(Kind)));
1635 PP.EnterTokenStream(Toks,
true);
1639 void PragmaClangSectionHandler::HandlePragma(
Preprocessor &PP,
1643 auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1646 while (Tok.
isNot(tok::eod)) {
1647 if (Tok.
isNot(tok::identifier)) {
1648 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1653 if (SecType->
isStr(
"bss"))
1654 SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1655 else if (SecType->
isStr(
"data"))
1656 SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1657 else if (SecType->
isStr(
"rodata"))
1658 SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1659 else if (SecType->
isStr(
"text"))
1660 SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1662 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1667 if (Tok.
isNot(tok::equal)) {
1668 PP.
Diag(Tok.
getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1672 std::string SecName;
1676 Actions.ActOnPragmaClangSection(Tok.
getLocation(),
1677 (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1678 Sema::PragmaClangSectionAction::PCSA_Clear),
1691 if (Tok.
isNot(tok::identifier) ||
1699 if (Tok.
isNot(tok::equal)) {
1706 if (Tok.
isNot(tok::identifier)) {
1708 << (IsOptions ?
"options" :
"align");
1714 if (II->
isStr(
"native"))
1716 else if (II->
isStr(
"natural"))
1718 else if (II->
isStr(
"packed"))
1720 else if (II->
isStr(
"power"))
1722 else if (II->
isStr(
"mac68k"))
1724 else if (II->
isStr(
"reset"))
1734 if (Tok.
isNot(tok::eod)) {
1736 << (IsOptions ?
"options" :
"align");
1742 Toks[0].startToken();
1743 Toks[0].setKind(tok::annot_pragma_align);
1745 Toks[0].setAnnotationEndLoc(EndLoc);
1746 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1747 static_cast<uintptr_t>(Kind)));
1748 PP.EnterTokenStream(Toks,
true);
1751 void PragmaAlignHandler::HandlePragma(
Preprocessor &PP,
1757 void PragmaOptionsHandler::HandlePragma(
Preprocessor &PP,
1759 Token &OptionsTok) {
1764 void PragmaUnusedHandler::HandlePragma(
Preprocessor &PP,
1773 if (Tok.
isNot(tok::l_paren)) {
1774 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"unused";
1787 if (Tok.
is(tok::identifier)) {
1788 Identifiers.push_back(Tok);
1799 if (Tok.
is(tok::comma)) {
1804 if (Tok.
is(tok::r_paren)) {
1810 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_punc) <<
"unused";
1815 if (Tok.
isNot(tok::eod)) {
1822 assert(RParenLoc.
isValid() &&
"Valid '#pragma unused' must have ')'");
1823 assert(!Identifiers.empty() &&
"Valid '#pragma unused' must have arguments");
1832 2 * Identifiers.size());
1833 for (
unsigned i=0; i != Identifiers.size(); i++) {
1834 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1836 pragmaUnusedTok.
setKind(tok::annot_pragma_unused);
1838 idTok = Identifiers[i];
1840 PP.EnterTokenStream(Toks,
true);
1852 if (Tok.
isNot(tok::identifier)) {
1853 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_identifier) <<
"weak";
1858 bool HasAlias =
false;
1862 if (Tok.
is(tok::equal)) {
1865 if (Tok.
isNot(tok::identifier)) {
1874 if (Tok.
isNot(tok::eod)) {
1875 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"weak";
1882 Token &pragmaUnusedTok = Toks[0];
1884 pragmaUnusedTok.
setKind(tok::annot_pragma_weakalias);
1888 Toks[2] = AliasName;
1889 PP.EnterTokenStream(Toks,
true);
1893 Token &pragmaUnusedTok = Toks[0];
1895 pragmaUnusedTok.
setKind(tok::annot_pragma_weak);
1899 PP.EnterTokenStream(Toks,
true);
1904 void PragmaRedefineExtnameHandler::HandlePragma(
Preprocessor &PP,
1906 Token &RedefToken) {
1911 if (Tok.
isNot(tok::identifier)) {
1920 if (Tok.
isNot(tok::identifier)) {
1922 <<
"redefine_extname";
1929 if (Tok.
isNot(tok::eod)) {
1937 Token &pragmaRedefTok = Toks[0];
1939 pragmaRedefTok.
setKind(tok::annot_pragma_redefine_extname);
1942 Toks[1] = RedefName;
1943 Toks[2] = AliasName;
1944 PP.EnterTokenStream(Toks,
true);
1949 PragmaFPContractHandler::HandlePragma(
Preprocessor &PP,
1958 Toks[0].startToken();
1959 Toks[0].setKind(tok::annot_pragma_fp_contract);
1962 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1963 static_cast<uintptr_t>(OOS)));
1964 PP.EnterTokenStream(Toks,
true);
1968 PragmaOpenCLExtensionHandler::HandlePragma(
Preprocessor &PP,
1972 if (Tok.
isNot(tok::identifier)) {
1981 if (Tok.
isNot(tok::colon)) {
1987 if (Tok.
isNot(tok::identifier)) {
1988 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_predicate) << 0;
1994 if (Pred->
isStr(
"enable")) {
1996 }
else if (Pred->
isStr(
"disable")) {
1998 }
else if (Pred->
isStr(
"begin"))
2000 else if (Pred->
isStr(
"end"))
2004 << Ext->
isStr(
"all");
2010 if (Tok.
isNot(tok::eod)) {
2018 Info->second =
State;
2021 Toks[0].startToken();
2022 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2023 Toks[0].setLocation(NameLoc);
2024 Toks[0].setAnnotationValue(static_cast<void*>(Info));
2025 Toks[0].setAnnotationEndLoc(StateLoc);
2026 PP.EnterTokenStream(Toks,
true);
2041 PP.
Diag(FirstTok, diag::warn_pragma_omp_ignored);
2057 Tok.
setKind(tok::annot_pragma_openmp);
2060 while (Tok.
isNot(tok::eod)) {
2061 Pragma.push_back(Tok);
2066 Tok.
setKind(tok::annot_pragma_openmp_end);
2068 Pragma.push_back(Tok);
2070 auto Toks = llvm::make_unique<Token[]>(Pragma.size());
2071 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2072 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2084 void PragmaMSPointersToMembers::HandlePragma(
Preprocessor &PP,
2089 if (Tok.
isNot(tok::l_paren)) {
2090 PP.
Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2091 <<
"pointers_to_members";
2098 <<
"pointers_to_members";
2104 if (Arg->
isStr(
"best_case")) {
2107 if (Arg->
isStr(
"full_generality")) {
2108 if (Tok.
is(tok::comma)) {
2114 diag::err_pragma_pointers_to_members_unknown_kind)
2119 }
else if (Tok.
is(tok::r_paren)) {
2126 <<
"full_generality";
2132 if (Arg->
isStr(
"single_inheritance")) {
2133 RepresentationMethod =
2135 }
else if (Arg->
isStr(
"multiple_inheritance")) {
2136 RepresentationMethod =
2138 }
else if (Arg->
isStr(
"virtual_inheritance")) {
2139 RepresentationMethod =
2143 diag::err_pragma_pointers_to_members_unknown_kind)
2150 if (Tok.
isNot(tok::r_paren)) {
2152 << (Arg ? Arg->
getName() :
"full_generality");
2158 if (Tok.
isNot(tok::eod)) {
2160 <<
"pointers_to_members";
2166 AnnotTok.
setKind(tok::annot_pragma_ms_pointers_to_members);
2170 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2187 if (Tok.
isNot(tok::l_paren)) {
2188 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) <<
"vtordisp";
2196 if (II->
isStr(
"push")) {
2199 if (Tok.
isNot(tok::comma)) {
2200 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_punc) <<
"vtordisp";
2206 }
else if (II->
isStr(
"pop")) {
2213 if (Tok.
is(tok::r_paren)) {
2223 if (II && II->
isStr(
"off")) {
2226 }
else if (II && II->
isStr(
"on")) {
2229 }
else if (Tok.
is(tok::numeric_constant) &&
2233 << 0 << 2 <<
"vtordisp";
2244 if (Tok.
isNot(tok::r_paren)) {
2245 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) <<
"vtordisp";
2250 if (Tok.
isNot(tok::eod)) {
2259 AnnotTok.
setKind(tok::annot_pragma_ms_vtordisp);
2263 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2272 Token EoF, AnnotTok;
2276 AnnotTok.
setKind(tok::annot_pragma_ms_pragma);
2281 for (; Tok.
isNot(tok::eod); PP.
Lex(Tok)) {
2282 TokenVector.push_back(Tok);
2286 TokenVector.push_back(EoF);
2289 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
2290 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2292 std::pair<std::unique_ptr<
Token[]>,
size_t>(std::move(TokenArray),
2293 TokenVector.size());
2308 void PragmaDetectMismatchHandler::HandlePragma(
Preprocessor &PP,
2313 if (Tok.
isNot(tok::l_paren)) {
2314 PP.
Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2319 std::string NameString;
2321 "pragma detect_mismatch",
2326 std::string ValueString;
2327 if (Tok.
isNot(tok::comma)) {
2328 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2336 if (Tok.
isNot(tok::r_paren)) {
2342 if (Tok.
isNot(tok::eod)) {
2343 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2352 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2364 void PragmaCommentHandler::HandlePragma(
Preprocessor &PP,
2369 if (Tok.
isNot(tok::l_paren)) {
2370 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2376 if (Tok.
isNot(tok::identifier)) {
2377 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2384 llvm::StringSwitch<PragmaMSCommentKind>(II->
getName())
2406 std::string ArgumentString;
2419 if (Tok.
isNot(tok::r_paren)) {
2425 if (Tok.
isNot(tok::eod)) {
2434 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2439 void PragmaOptimizeHandler::HandlePragma(
Preprocessor &PP,
2441 Token &FirstToken) {
2444 if (Tok.
is(tok::eod)) {
2446 <<
"clang optimize" <<
true <<
"'on' or 'off'";
2449 if (Tok.
isNot(tok::identifier)) {
2450 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2457 if (II->
isStr(
"on")) {
2459 }
else if (!II->
isStr(
"off")) {
2460 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2466 if (Tok.
isNot(tok::eod)) {
2472 Actions.ActOnPragmaOptimize(IsOn, FirstToken.
getLocation());
2477 struct TokFPAnnotValue {
2478 enum FlagKinds { Contract };
2479 enum FlagValues { On, Off, Fast };
2482 FlagValues FlagValue;
2494 if (Tok.
isNot(tok::identifier)) {
2500 while (Tok.
is(tok::identifier)) {
2504 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2506 .Case(
"contract", TokFPAnnotValue::Contract)
2510 <<
false << OptionInfo;
2516 if (Tok.
isNot(tok::l_paren)) {
2522 if (Tok.
isNot(tok::identifier)) {
2530 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2532 .Case(
"on", TokFPAnnotValue::On)
2533 .Case(
"off", TokFPAnnotValue::Off)
2534 .Case(
"fast", TokFPAnnotValue::Fast)
2545 if (Tok.
isNot(tok::r_paren)) {
2552 TokFPAnnotValue{*FlagKind, *FlagValue};
2556 FPTok.
setKind(tok::annot_pragma_fp);
2560 TokenList.push_back(FPTok);
2563 if (Tok.
isNot(tok::eod)) {
2569 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2570 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2572 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2576 void Parser::HandlePragmaFP() {
2577 assert(Tok.
is(tok::annot_pragma_fp));
2582 switch (AnnotValue->FlagValue) {
2583 case TokFPAnnotValue::On:
2586 case TokFPAnnotValue::Fast:
2589 case TokFPAnnotValue::Off:
2594 Actions.ActOnPragmaFPContract(FPC);
2595 ConsumeAnnotationToken();
2600 Token Option,
bool ValueInParens,
2601 PragmaLoopHintInfo &Info) {
2603 int OpenParens = ValueInParens ? 1 : 0;
2605 while (Tok.
isNot(tok::eod)) {
2606 if (Tok.
is(tok::l_paren))
2608 else if (Tok.
is(tok::r_paren)) {
2610 if (OpenParens == 0 && ValueInParens)
2614 ValueList.push_back(Tok);
2618 if (ValueInParens) {
2620 if (Tok.
isNot(tok::r_paren)) {
2631 ValueList.push_back(EOFTok);
2635 Info.PragmaName = PragmaName;
2636 Info.Option = Option;
2685 void PragmaLoopHintHandler::HandlePragma(
Preprocessor &PP,
2694 if (Tok.
isNot(tok::identifier)) {
2700 while (Tok.
is(tok::identifier)) {
2704 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->
getName())
2705 .Case(
"vectorize",
true)
2706 .Case(
"interleave",
true)
2707 .Case(
"unroll",
true)
2708 .Case(
"distribute",
true)
2709 .Case(
"vectorize_width",
true)
2710 .Case(
"interleave_count",
true)
2711 .Case(
"unroll_count",
true)
2715 <<
false << OptionInfo;
2721 if (Tok.
isNot(tok::l_paren)) {
2735 LoopHintTok.
setKind(tok::annot_pragma_loop_hint);
2739 TokenList.push_back(LoopHintTok);
2742 if (Tok.
isNot(tok::eod)) {
2748 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2749 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2751 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2772 void PragmaUnrollHintHandler::HandlePragma(
Preprocessor &PP,
2780 if (Tok.
is(tok::eod)) {
2782 Info->PragmaName = PragmaName;
2792 bool ValueInParens = Tok.
is(tok::l_paren);
2804 PP.
Diag(Info->Toks[0].getLocation(),
2805 diag::warn_pragma_unroll_cuda_value_in_parens);
2807 if (Tok.
isNot(tok::eod)) {
2815 auto TokenArray = llvm::make_unique<Token[]>(1);
2816 TokenArray[0].startToken();
2817 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2818 TokenArray[0].setLocation(PragmaName.
getLocation());
2819 TokenArray[0].setAnnotationEndLoc(PragmaName.
getLocation());
2820 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2821 PP.EnterTokenStream(std::move(TokenArray), 1,
2837 void PragmaMSIntrinsicHandler::HandlePragma(
Preprocessor &PP,
2842 if (Tok.
isNot(tok::l_paren)) {
2851 while (Tok.
is(tok::identifier)) {
2855 << II << SuggestIntrinH;
2858 if (Tok.
isNot(tok::comma))
2863 if (Tok.
isNot(tok::r_paren)) {
2870 if (Tok.
isNot(tok::eod))
2874 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
2880 if (!Info || (!Info->
isStr(
"begin") && !Info->
isStr(
"end"))) {
2882 diag::warn_pragma_force_cuda_host_device_bad_arg);
2886 if (Info->
isStr(
"begin"))
2887 Actions.PushForceCUDAHostDevice();
2888 else if (!Actions.PopForceCUDAHostDevice())
2890 diag::err_pragma_cannot_end_force_cuda_host_device);
2893 if (!Tok.
is(tok::eod))
2895 diag::warn_pragma_force_cuda_host_device_bad_arg);
2913 void PragmaAttributeHandler::HandlePragma(
Preprocessor &PP,
2915 Token &FirstToken) {
2919 PragmaAttributeInfo(AttributesForPragmaAttribute);
2922 if (Tok.
isNot(tok::identifier)) {
2923 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_push_pop);
2927 if (II->isStr(
"push"))
2928 Info->Action = PragmaAttributeInfo::Push;
2929 else if (II->isStr(
"pop"))
2930 Info->Action = PragmaAttributeInfo::Pop;
2932 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_invalid_argument)
2939 if (Info->Action == PragmaAttributeInfo::Push) {
2940 if (Tok.
isNot(tok::l_paren)) {
2949 while (Tok.
isNot(tok::eod)) {
2950 if (Tok.
is(tok::l_paren))
2952 else if (Tok.
is(tok::r_paren)) {
2954 if (OpenParens == 0)
2958 AttributeTokens.push_back(Tok);
2962 if (AttributeTokens.empty()) {
2963 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_attribute);
2966 if (Tok.
isNot(tok::r_paren)) {
2978 AttributeTokens.push_back(EOFTok);
2984 if (Tok.
isNot(tok::eod))
2986 <<
"clang attribute";
2989 auto TokenArray = llvm::make_unique<Token[]>(1);
2990 TokenArray[0].startToken();
2991 TokenArray[0].setKind(tok::annot_pragma_attribute);
2992 TokenArray[0].setLocation(FirstToken.
getLocation());
2993 TokenArray[0].setAnnotationEndLoc(FirstToken.
getLocation());
2994 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2995 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()
AttributeList * getNext() const
bool isSupportedByPragmaAttribute() const
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.
static void diagnoseUnknownAttributeSubjectSubRule(Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, StringRef SubRuleName, SourceLocation SubRuleLoc)
static std::string PragmaLoopHintString(Token PragmaName, Token Option)
IdentifierLoc * OptionLoc
Parse and apply any fixits to the source.
AttributeList * getList() const
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 ...
SourceLocation getLoc() const
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.
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 interruped.
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 getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
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)
bool LexOnOffSwitch(tok::OnOffSwitch &OOS)
Lex an on-off-switch (C99 6.10.6p2) and verify that it is followed by EOD.
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.
This is a compound statement scope.
static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule)
SourceLocation getEnd() const
PPCallbacks * getPPCallbacks() const
Accessors for preprocessor callbacks.
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)
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...
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.
ActionResult< Stmt * > StmtResult
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.
AttributeList * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
This is a scope that can contain a declaration.
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.
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.
AttributeList - Represents a syntactic attribute.
Stop skipping at specified token, but don't skip the token itself.