23 #include "llvm/ADT/StringSwitch.h" 24 using namespace clang;
31 Token &FirstToken)
override;
35 explicit PragmaGCCVisibilityHandler() :
PragmaHandler(
"visibility") {}
37 Token &FirstToken)
override;
43 Token &FirstToken)
override;
49 Token &FirstToken)
override;
53 explicit PragmaClangSectionHandler(
Sema &S)
56 Token &FirstToken)
override;
62 explicit PragmaMSStructHandler() :
PragmaHandler(
"ms_struct") {}
64 Token &FirstToken)
override;
70 Token &FirstToken)
override;
76 Token &FirstToken)
override;
80 explicit PragmaRedefineExtnameHandler() :
PragmaHandler(
"redefine_extname") {}
82 Token &FirstToken)
override;
86 PragmaOpenCLExtensionHandler() :
PragmaHandler(
"EXTENSION") {}
88 Token &FirstToken)
override;
95 Token &FirstToken)
override;
101 struct PragmaSTDC_FENV_ACCESSHandler :
public PragmaHandler {
102 PragmaSTDC_FENV_ACCESSHandler() :
PragmaHandler(
"FENV_ACCESS") {}
110 PP.
Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
115 struct PragmaSTDC_CX_LIMITED_RANGEHandler :
public PragmaHandler {
116 PragmaSTDC_CX_LIMITED_RANGEHandler() :
PragmaHandler(
"CX_LIMITED_RANGE") {}
119 Token &Tok)
override {
127 PragmaSTDC_UnknownHandler() =
default;
130 Token &UnknownTok)
override {
132 PP.
Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
139 Token &FirstToken)
override;
145 Token &FirstToken)
override;
151 Token &FirstToken)
override;
156 PragmaCommentHandler(
Sema &Actions)
159 Token &FirstToken)
override;
165 PragmaDetectMismatchHandler(
Sema &Actions)
168 Token &FirstToken)
override;
174 explicit PragmaMSPointersToMembers() :
PragmaHandler(
"pointers_to_members") {}
176 Token &FirstToken)
override;
182 Token &FirstToken)
override;
186 explicit PragmaMSPragma(
const char *name) :
PragmaHandler(name) {}
188 Token &FirstToken)
override;
193 PragmaOptimizeHandler(
Sema &S)
196 Token &FirstToken)
override;
204 Token &FirstToken)
override;
208 PragmaUnrollHintHandler(
const char *name) :
PragmaHandler(name) {}
210 Token &FirstToken)
override;
220 Token &FirstToken)
override;
226 Token &FirstToken)
override;
229 struct PragmaForceCUDAHostDeviceHandler :
public PragmaHandler {
230 PragmaForceCUDAHostDeviceHandler(
Sema &Actions)
231 :
PragmaHandler(
"force_cuda_host_device"), Actions(Actions) {}
233 Token &FirstToken)
override;
242 :
PragmaHandler(
"attribute"), AttributesForPragmaAttribute(AttrFactory) {}
244 Token &FirstToken)
override;
252 void Parser::initializePragmaHandlers() {
253 AlignHandler.reset(
new PragmaAlignHandler());
256 GCCVisibilityHandler.reset(
new PragmaGCCVisibilityHandler());
259 OptionsHandler.reset(
new PragmaOptionsHandler());
262 PackHandler.reset(
new PragmaPackHandler());
265 MSStructHandler.reset(
new PragmaMSStructHandler());
268 UnusedHandler.reset(
new PragmaUnusedHandler());
271 WeakHandler.reset(
new PragmaWeakHandler());
274 RedefineExtnameHandler.reset(
new PragmaRedefineExtnameHandler());
277 FPContractHandler.reset(
new PragmaFPContractHandler());
280 STDCFENVHandler.reset(
new PragmaSTDC_FENV_ACCESSHandler());
283 STDCCXLIMITHandler.reset(
new PragmaSTDC_CX_LIMITED_RANGEHandler());
286 STDCUnknownHandler.reset(
new PragmaSTDC_UnknownHandler());
289 PCSectionHandler.reset(
new PragmaClangSectionHandler(Actions));
292 if (getLangOpts().OpenCL) {
293 OpenCLExtensionHandler.reset(
new PragmaOpenCLExtensionHandler());
298 if (getLangOpts().OpenMP)
299 OpenMPHandler.reset(
new PragmaOpenMPHandler());
301 OpenMPHandler.reset(
new PragmaNoOpenMPHandler());
304 if (getLangOpts().MicrosoftExt ||
305 getTargetInfo().getTriple().isOSBinFormatELF()) {
306 MSCommentHandler.reset(
new PragmaCommentHandler(Actions));
310 if (getLangOpts().MicrosoftExt) {
311 MSDetectMismatchHandler.reset(
new PragmaDetectMismatchHandler(Actions));
313 MSPointersToMembers.reset(
new PragmaMSPointersToMembers());
315 MSVtorDisp.reset(
new PragmaMSVtorDisp());
317 MSInitSeg.reset(
new PragmaMSPragma(
"init_seg"));
319 MSDataSeg.reset(
new PragmaMSPragma(
"data_seg"));
321 MSBSSSeg.reset(
new PragmaMSPragma(
"bss_seg"));
323 MSConstSeg.reset(
new PragmaMSPragma(
"const_seg"));
325 MSCodeSeg.reset(
new PragmaMSPragma(
"code_seg"));
327 MSSection.reset(
new PragmaMSPragma(
"section"));
329 MSRuntimeChecks.reset(
new PragmaMSRuntimeChecksHandler());
331 MSIntrinsic.reset(
new PragmaMSIntrinsicHandler());
333 MSOptimize.reset(
new PragmaMSOptimizeHandler());
337 if (getLangOpts().CUDA) {
338 CUDAForceHostDeviceHandler.reset(
339 new PragmaForceCUDAHostDeviceHandler(Actions));
343 OptimizeHandler.reset(
new PragmaOptimizeHandler(Actions));
346 LoopHintHandler.reset(
new PragmaLoopHintHandler());
349 UnrollHintHandler.reset(
new PragmaUnrollHintHandler(
"unroll"));
352 NoUnrollHintHandler.reset(
new PragmaUnrollHintHandler(
"nounroll"));
355 FPHandler.reset(
new PragmaFPHandler());
358 AttributePragmaHandler.reset(
new PragmaAttributeHandler(AttrFactory));
362 void Parser::resetPragmaHandlers() {
365 AlignHandler.reset();
367 GCCVisibilityHandler.reset();
369 OptionsHandler.reset();
373 MSStructHandler.reset();
375 UnusedHandler.reset();
379 RedefineExtnameHandler.reset();
381 if (getLangOpts().
OpenCL) {
383 OpenCLExtensionHandler.reset();
387 OpenMPHandler.reset();
389 if (getLangOpts().MicrosoftExt ||
390 getTargetInfo().getTriple().isOSBinFormatELF()) {
392 MSCommentHandler.reset();
396 PCSectionHandler.reset();
398 if (getLangOpts().MicrosoftExt) {
400 MSDetectMismatchHandler.reset();
402 MSPointersToMembers.reset();
418 MSRuntimeChecks.reset();
425 if (getLangOpts().CUDA) {
427 CUDAForceHostDeviceHandler.reset();
431 FPContractHandler.reset();
434 STDCFENVHandler.reset();
437 STDCCXLIMITHandler.reset();
440 STDCUnknownHandler.reset();
443 OptimizeHandler.reset();
446 LoopHintHandler.reset();
449 UnrollHintHandler.reset();
452 NoUnrollHintHandler.reset();
458 AttributePragmaHandler.reset();
466 void Parser::HandlePragmaUnused() {
467 assert(Tok.
is(tok::annot_pragma_unused));
469 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
473 void Parser::HandlePragmaVisibility() {
474 assert(Tok.
is(tok::annot_pragma_vis));
478 Actions.ActOnPragmaVisibility(VisType, VisLoc);
482 struct PragmaPackInfo {
489 void Parser::HandlePragmaPack() {
490 assert(Tok.
is(tok::annot_pragma_pack));
491 PragmaPackInfo *Info =
495 if (Info->Alignment.is(tok::numeric_constant)) {
496 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
498 ConsumeAnnotationToken();
502 Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
506 ConsumeAnnotationToken();
509 void Parser::HandlePragmaMSStruct() {
510 assert(Tok.
is(tok::annot_pragma_msstruct));
513 Actions.ActOnPragmaMSStruct(Kind);
514 ConsumeAnnotationToken();
517 void Parser::HandlePragmaAlign() {
518 assert(Tok.
is(tok::annot_pragma_align));
522 Actions.ActOnPragmaOptionsAlign(Kind, Tok.
getLocation());
525 ConsumeAnnotationToken();
528 void Parser::HandlePragmaDump() {
529 assert(Tok.
is(tok::annot_pragma_dump));
532 Actions.ActOnPragmaDump(getCurScope(), Tok.
getLocation(), II);
533 ConsumeAnnotationToken();
536 void Parser::HandlePragmaWeak() {
537 assert(Tok.
is(tok::annot_pragma_weak));
544 void Parser::HandlePragmaWeakAlias() {
545 assert(Tok.
is(tok::annot_pragma_weakalias));
553 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
554 WeakNameLoc, AliasNameLoc);
558 void Parser::HandlePragmaRedefineExtname() {
559 assert(Tok.
is(tok::annot_pragma_redefine_extname));
567 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
568 RedefNameLoc, AliasNameLoc);
571 void Parser::HandlePragmaFPContract() {
572 assert(Tok.
is(tok::annot_pragma_fp_contract));
586 FPC = getLangOpts().getDefaultFPContractMode();
590 Actions.ActOnPragmaFPContract(FPC);
591 ConsumeAnnotationToken();
596 assert(Tok.
is(tok::annot_pragma_captured));
597 ConsumeAnnotationToken();
599 if (Tok.
isNot(tok::l_brace)) {
600 PP.
Diag(Tok, diag::err_expected) << tok::l_brace;
608 Actions.ActOnCapturedRegionStart(Loc, getCurScope(),
CR_Default,
612 CapturedRegionScope.Exit();
615 Actions.ActOnCapturedRegionError();
619 return Actions.ActOnCapturedRegionEnd(R.get());
626 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
629 void Parser::HandlePragmaOpenCLExtension() {
630 assert(Tok.
is(tok::annot_pragma_opencl_extension));
632 auto State = Data->second;
633 auto Ident = Data->first;
635 ConsumeAnnotationToken();
637 auto &Opt = Actions.getOpenCLOptions();
638 auto Name = Ident->getName();
643 if (
State == Disable) {
645 Opt.enableSupportedCore(getLangOpts().OpenCLVersion);
647 PP.
Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
650 if (!Opt.isKnown(Name) ||
651 !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
654 Actions.setCurrentOpenCLExtension(Name);
656 if (Name != Actions.getCurrentOpenCLExtension())
657 PP.
Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
658 Actions.setCurrentOpenCLExtension(
"");
659 }
else if (!Opt.isKnown(Name))
660 PP.
Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
661 else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
662 Opt.enable(Name,
State == Enable);
663 else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
664 PP.
Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
666 PP.
Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
669 void Parser::HandlePragmaMSPointersToMembers() {
670 assert(Tok.
is(tok::annot_pragma_ms_pointers_to_members));
675 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
678 void Parser::HandlePragmaMSVtorDisp() {
679 assert(Tok.
is(tok::annot_pragma_ms_vtordisp));
683 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
685 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
688 void Parser::HandlePragmaMSPragma() {
689 assert(Tok.
is(tok::annot_pragma_ms_pragma));
693 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second,
true);
702 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
703 .Case(
"data_seg", &Parser::HandlePragmaMSSegment)
704 .Case(
"bss_seg", &Parser::HandlePragmaMSSegment)
705 .Case(
"const_seg", &Parser::HandlePragmaMSSegment)
706 .Case(
"code_seg", &Parser::HandlePragmaMSSegment)
707 .Case(
"section", &Parser::HandlePragmaMSSection)
708 .Case(
"init_seg", &Parser::HandlePragmaMSInitSeg);
710 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
719 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
721 if (Tok.
isNot(tok::l_paren)) {
722 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
727 if (Tok.
isNot(tok::string_literal)) {
728 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
732 ExprResult StringResult = ParseStringLiteralExpression();
737 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
742 bool SectionFlagsAreDefault =
true;
743 while (Tok.
is(tok::comma)) {
748 if (Tok.
is(tok::kw_long) || Tok.
is(tok::kw_short)) {
754 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
759 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
772 ? diag::warn_pragma_invalid_specific_action
773 : diag::warn_pragma_unsupported_action)
777 SectionFlags |= Flag;
778 SectionFlagsAreDefault =
false;
783 if (SectionFlagsAreDefault)
785 if (Tok.
isNot(tok::r_paren)) {
786 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
791 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
796 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
800 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
802 if (Tok.
isNot(tok::l_paren)) {
803 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
811 if (PushPop ==
"push")
813 else if (PushPop ==
"pop")
816 PP.
Diag(PragmaLocation,
817 diag::warn_pragma_expected_section_push_pop_or_name)
823 if (Tok.
is(tok::comma)) {
829 if (Tok.
is(tok::comma))
831 else if (Tok.
isNot(tok::r_paren)) {
832 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc)
837 }
else if (Tok.
isNot(tok::r_paren)) {
838 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
845 if (Tok.
isNot(tok::r_paren)) {
846 if (Tok.
isNot(tok::string_literal)) {
848 diag::warn_pragma_expected_section_name :
849 diag::warn_pragma_expected_section_label_or_name :
850 diag::warn_pragma_expected_section_push_pop_or_name;
851 PP.
Diag(PragmaLocation, DiagID) << PragmaName;
854 ExprResult StringResult = ParseStringLiteralExpression();
857 SegmentName = cast<StringLiteral>(StringResult.
get());
859 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
867 if (Tok.
isNot(tok::r_paren)) {
868 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
873 PP.
Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
878 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
879 SegmentName, PragmaName);
884 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
886 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
887 PP.
Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
891 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
899 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
900 .Case(
"compiler",
"\".CRT$XCC\"")
901 .Case(
"lib",
"\".CRT$XCL\"")
902 .Case(
"user",
"\".CRT$XCU\"")
905 if (!Section.empty()) {
909 Toks[0].
setKind(tok::string_literal);
914 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks,
nullptr).get());
917 }
else if (Tok.
is(tok::string_literal)) {
918 ExprResult StringResult = ParseStringLiteralExpression();
921 SegmentName = cast<StringLiteral>(StringResult.
get());
923 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
931 PP.
Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
935 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
937 ExpectAndConsume(
tok::eof, diag::warn_pragma_extra_tokens_at_eol,
941 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
946 struct PragmaLoopHintInfo {
954 std::string PragmaString;
956 PragmaString =
"clang loop ";
960 "Unexpected pragma name");
961 PragmaString =
"unroll";
966 bool Parser::HandlePragmaLoopHint(
LoopHint &Hint) {
967 assert(Tok.
is(tok::annot_pragma_loop_hint));
968 PragmaLoopHintInfo *Info =
971 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
973 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
978 ? Info->Option.getIdentifierInfo()
981 Actions.Context, Info->Option.getLocation(), OptionInfo);
987 bool PragmaUnroll = PragmaNameInfo->
getName() ==
"unroll";
988 bool PragmaNoUnroll = PragmaNameInfo->
getName() ==
"nounroll";
989 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll)) {
990 ConsumeAnnotationToken();
991 Hint.
Range = Info->PragmaName.getLocation();
997 assert(!Toks.empty() &&
998 "PragmaLoopHintInfo::Toks must contain at least one token.");
1001 bool OptionUnroll =
false;
1002 bool OptionDistribute =
false;
1003 bool StateOption =
false;
1005 OptionUnroll = OptionInfo->isStr(
"unroll");
1006 OptionDistribute = OptionInfo->isStr(
"distribute");
1007 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
1008 .Case(
"vectorize",
true)
1009 .Case(
"interleave",
true)
1011 OptionUnroll || OptionDistribute;
1014 bool AssumeSafetyArg = !OptionUnroll && !OptionDistribute;
1017 ConsumeAnnotationToken();
1018 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1019 << StateOption << OptionUnroll
1026 ConsumeAnnotationToken();
1030 bool Valid = StateInfo &&
1031 llvm::StringSwitch<bool>(StateInfo->
getName())
1032 .Cases(
"enable",
"disable",
true)
1033 .Case(
"full", OptionUnroll)
1034 .Case(
"assume_safety", AssumeSafetyArg)
1037 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1042 if (Toks.size() > 2)
1048 PP.EnterTokenStream(Toks,
false);
1049 ConsumeAnnotationToken();
1065 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation()))
1073 Info->Toks.back().getLocation());
1078 struct PragmaAttributeInfo {
1079 enum ActionType { Push, Pop };
1084 PragmaAttributeInfo(
ParsedAttributes &Attributes) : Attributes(Attributes) {}
1087 #include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc" 1092 if (Tok.
is(tok::identifier))
1101 using namespace attr;
1103 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \ 1106 #include "clang/Basic/AttrSubMatchRulesList.inc" 1108 llvm_unreachable(
"Invalid attribute subject match rule");
1116 PRef.
Diag(SubRuleLoc,
1117 diag::err_pragma_attribute_expected_subject_sub_identifier)
1119 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1130 PRef.
Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1131 << SubRuleName << PrimaryRuleName;
1132 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1138 bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1144 AnyLoc = ConsumeToken();
1154 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1157 std::pair<Optional<attr::SubjectMatchRule>,
1159 Rule = isAttributeSubjectMatchRule(Name);
1161 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1172 if (!SubjectMatchRules
1174 std::make_pair(PrimaryRule,
SourceRange(RuleLoc, RuleLoc)))
1176 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1179 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleLoc));
1180 LastMatchRuleEndLoc = RuleLoc;
1186 if (SubRuleName.empty()) {
1192 if (SubRuleName ==
"unless") {
1198 if (SubRuleName.empty()) {
1203 auto SubRuleOrNone = Rule.second(SubRuleName,
true);
1204 if (!SubRuleOrNone) {
1205 std::string SubRuleUnlessName =
"unless(" + SubRuleName.str() +
")";
1207 SubRuleUnlessName, SubRuleLoc);
1210 SubRule = *SubRuleOrNone;
1215 auto SubRuleOrNone = Rule.second(SubRuleName,
false);
1216 if (!SubRuleOrNone) {
1221 SubRule = *SubRuleOrNone;
1225 LastMatchRuleEndLoc = RuleEndLoc;
1228 if (!SubjectMatchRules
1229 .insert(std::make_pair(SubRule,
SourceRange(RuleLoc, RuleEndLoc)))
1231 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1234 RuleLoc, Tok.
is(tok::comma) ? Tok.
getLocation() : RuleEndLoc));
1237 }
while (IsAny && TryConsumeToken(tok::comma));
1258 getAttributeSubjectRulesRecoveryPointForToken(
const Token &Tok) {
1260 if (II->isStr(
"apply_to"))
1261 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1262 if (II->isStr(
"any"))
1263 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1265 if (Tok.
is(tok::equal))
1266 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1282 getAttributeSubjectRulesRecoveryPointForToken(PRef.
getCurToken());
1285 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1286 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1287 FixIt +=
"apply_to";
1288 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1289 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1296 if (SubjectMatchRuleSet.empty()) {
1302 bool NeedsComma =
false;
1303 for (
const auto &I : SubjectMatchRuleSet) {
1329 void Parser::HandlePragmaAttribute() {
1330 assert(Tok.
is(tok::annot_pragma_attribute) &&
1331 "Expected #pragma attribute annotation token");
1334 if (Info->Action == PragmaAttributeInfo::Pop) {
1335 ConsumeAnnotationToken();
1336 Actions.ActOnPragmaAttributePop(PragmaLoc);
1340 assert(Info->Action == PragmaAttributeInfo::Push &&
1341 "Unexpected #pragma attribute command");
1342 PP.EnterTokenStream(Info->Tokens,
false);
1343 ConsumeAnnotationToken();
1348 auto SkipToEnd = [
this]() {
1349 SkipUntil(
tok::eof, StopBeforeMatch);
1353 if (Tok.
is(tok::l_square) && NextToken().is(tok::l_square)) {
1355 ParseCXX11AttributeSpecifier(Attrs);
1356 }
else if (Tok.
is(tok::kw___attribute)) {
1358 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1361 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"("))
1364 if (Tok.
isNot(tok::identifier)) {
1365 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1372 if (Tok.
isNot(tok::l_paren))
1373 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1376 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs,
nullptr,
1381 if (ExpectAndConsume(tok::r_paren))
1383 if (ExpectAndConsume(tok::r_paren))
1385 }
else if (Tok.
is(tok::kw___declspec)) {
1386 ParseMicrosoftDeclSpecs(Attrs);
1388 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1397 if (Tok.
is(tok::l_paren)) {
1399 SkipUntil(tok::r_paren, StopBeforeMatch);
1400 if (Tok.
isNot(tok::r_paren))
1403 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1412 if (Attrs.
empty() || Attrs.
begin()->isInvalid()) {
1418 if (Attrs.
size() > 1) {
1420 Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1427 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1434 if (!TryConsumeToken(tok::comma)) {
1435 createExpectedAttributeSubjectRulesTokenDiagnostic(
1436 diag::err_expected, Attribute,
1443 if (Tok.
isNot(tok::identifier)) {
1444 createExpectedAttributeSubjectRulesTokenDiagnostic(
1445 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1446 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1451 if (!II->
isStr(
"apply_to")) {
1452 createExpectedAttributeSubjectRulesTokenDiagnostic(
1453 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1454 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
1460 if (!TryConsumeToken(tok::equal)) {
1461 createExpectedAttributeSubjectRulesTokenDiagnostic(
1462 diag::err_expected, Attribute,
1463 MissingAttributeSubjectRulesRecoveryPoint::Equals, *
this)
1471 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1472 LastMatchRuleEndLoc)) {
1480 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1488 Actions.ActOnPragmaAttributePush(Attribute, PragmaLoc,
1489 std::move(SubjectMatchRules));
1495 void PragmaGCCVisibilityHandler::HandlePragma(
Preprocessor &PP,
1506 if (PushPop && PushPop->
isStr(
"pop")) {
1508 }
else if (PushPop && PushPop->
isStr(
"push")) {
1510 if (Tok.
isNot(tok::l_paren)) {
1523 if (Tok.
isNot(tok::r_paren)) {
1535 if (Tok.
isNot(tok::eod)) {
1541 auto Toks = llvm::make_unique<Token[]>(1);
1542 Toks[0].startToken();
1543 Toks[0].setKind(tok::annot_pragma_vis);
1544 Toks[0].setLocation(VisLoc);
1545 Toks[0].setAnnotationEndLoc(EndLoc);
1546 Toks[0].setAnnotationValue(
1547 const_cast<void*>(static_cast<const void*>(VisType)));
1548 PP.EnterTokenStream(std::move(Toks), 1,
true);
1562 if (Tok.
isNot(tok::l_paren)) {
1563 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"pack";
1568 StringRef SlotLabel;
1572 if (Tok.
is(tok::numeric_constant)) {
1582 }
else if (Tok.
is(tok::identifier)) {
1584 if (II->
isStr(
"show")) {
1588 if (II->
isStr(
"push")) {
1590 }
else if (II->
isStr(
"pop")) {
1593 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_invalid_action) <<
"pack";
1598 if (Tok.
is(tok::comma)) {
1601 if (Tok.
is(tok::numeric_constant)) {
1606 }
else if (Tok.
is(tok::identifier)) {
1610 if (Tok.
is(tok::comma)) {
1613 if (Tok.
isNot(tok::numeric_constant)) {
1636 if (Tok.
isNot(tok::r_paren)) {
1637 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"pack";
1643 if (Tok.
isNot(tok::eod)) {
1644 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"pack";
1648 PragmaPackInfo *Info =
1650 Info->Action = Action;
1651 Info->SlotLabel = SlotLabel;
1652 Info->Alignment = Alignment;
1656 Toks[0].startToken();
1657 Toks[0].setKind(tok::annot_pragma_pack);
1658 Toks[0].setLocation(PackLoc);
1659 Toks[0].setAnnotationEndLoc(RParenLoc);
1660 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1661 PP.EnterTokenStream(Toks,
true);
1666 void PragmaMSStructHandler::HandlePragma(
Preprocessor &PP,
1668 Token &MSStructTok) {
1673 if (Tok.
isNot(tok::identifier)) {
1679 if (II->
isStr(
"on")) {
1683 else if (II->
isStr(
"off") || II->
isStr(
"reset"))
1690 if (Tok.
isNot(tok::eod)) {
1698 Toks[0].startToken();
1699 Toks[0].setKind(tok::annot_pragma_msstruct);
1701 Toks[0].setAnnotationEndLoc(EndLoc);
1702 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1703 static_cast<uintptr_t>(Kind)));
1704 PP.EnterTokenStream(Toks,
true);
1708 void PragmaClangSectionHandler::HandlePragma(
Preprocessor &PP,
1712 auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1715 while (Tok.
isNot(tok::eod)) {
1716 if (Tok.
isNot(tok::identifier)) {
1717 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1722 if (SecType->
isStr(
"bss"))
1723 SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1724 else if (SecType->
isStr(
"data"))
1725 SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1726 else if (SecType->
isStr(
"rodata"))
1727 SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1728 else if (SecType->
isStr(
"text"))
1729 SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1731 PP.
Diag(Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
1736 if (Tok.
isNot(tok::equal)) {
1737 PP.
Diag(Tok.
getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1741 std::string SecName;
1745 Actions.ActOnPragmaClangSection(Tok.
getLocation(),
1746 (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1747 Sema::PragmaClangSectionAction::PCSA_Clear),
1760 if (Tok.
isNot(tok::identifier) ||
1768 if (Tok.
isNot(tok::equal)) {
1775 if (Tok.
isNot(tok::identifier)) {
1777 << (IsOptions ?
"options" :
"align");
1783 if (II->
isStr(
"native"))
1785 else if (II->
isStr(
"natural"))
1787 else if (II->
isStr(
"packed"))
1789 else if (II->
isStr(
"power"))
1791 else if (II->
isStr(
"mac68k"))
1793 else if (II->
isStr(
"reset"))
1803 if (Tok.
isNot(tok::eod)) {
1805 << (IsOptions ?
"options" :
"align");
1811 Toks[0].startToken();
1812 Toks[0].setKind(tok::annot_pragma_align);
1814 Toks[0].setAnnotationEndLoc(EndLoc);
1815 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1816 static_cast<uintptr_t>(Kind)));
1817 PP.EnterTokenStream(Toks,
true);
1820 void PragmaAlignHandler::HandlePragma(
Preprocessor &PP,
1826 void PragmaOptionsHandler::HandlePragma(
Preprocessor &PP,
1828 Token &OptionsTok) {
1833 void PragmaUnusedHandler::HandlePragma(
Preprocessor &PP,
1842 if (Tok.
isNot(tok::l_paren)) {
1843 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"unused";
1856 if (Tok.
is(tok::identifier)) {
1857 Identifiers.push_back(Tok);
1868 if (Tok.
is(tok::comma)) {
1873 if (Tok.
is(tok::r_paren)) {
1879 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_punc) <<
"unused";
1884 if (Tok.
isNot(tok::eod)) {
1891 assert(RParenLoc.
isValid() &&
"Valid '#pragma unused' must have ')'");
1892 assert(!Identifiers.empty() &&
"Valid '#pragma unused' must have arguments");
1901 2 * Identifiers.size());
1902 for (
unsigned i=0; i != Identifiers.size(); i++) {
1903 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1905 pragmaUnusedTok.
setKind(tok::annot_pragma_unused);
1907 idTok = Identifiers[i];
1909 PP.EnterTokenStream(Toks,
true);
1921 if (Tok.
isNot(tok::identifier)) {
1922 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_identifier) <<
"weak";
1927 bool HasAlias =
false;
1931 if (Tok.
is(tok::equal)) {
1934 if (Tok.
isNot(tok::identifier)) {
1943 if (Tok.
isNot(tok::eod)) {
1944 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"weak";
1951 Token &pragmaUnusedTok = Toks[0];
1953 pragmaUnusedTok.
setKind(tok::annot_pragma_weakalias);
1957 Toks[2] = AliasName;
1958 PP.EnterTokenStream(Toks,
true);
1962 Token &pragmaUnusedTok = Toks[0];
1964 pragmaUnusedTok.
setKind(tok::annot_pragma_weak);
1968 PP.EnterTokenStream(Toks,
true);
1973 void PragmaRedefineExtnameHandler::HandlePragma(
Preprocessor &PP,
1975 Token &RedefToken) {
1980 if (Tok.
isNot(tok::identifier)) {
1989 if (Tok.
isNot(tok::identifier)) {
1991 <<
"redefine_extname";
1998 if (Tok.
isNot(tok::eod)) {
2006 Token &pragmaRedefTok = Toks[0];
2008 pragmaRedefTok.
setKind(tok::annot_pragma_redefine_extname);
2011 Toks[1] = RedefName;
2012 Toks[2] = AliasName;
2013 PP.EnterTokenStream(Toks,
true);
2018 PragmaFPContractHandler::HandlePragma(
Preprocessor &PP,
2027 Toks[0].startToken();
2028 Toks[0].setKind(tok::annot_pragma_fp_contract);
2031 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2032 static_cast<uintptr_t>(OOS)));
2033 PP.EnterTokenStream(Toks,
true);
2037 PragmaOpenCLExtensionHandler::HandlePragma(
Preprocessor &PP,
2041 if (Tok.
isNot(tok::identifier)) {
2050 if (Tok.
isNot(tok::colon)) {
2056 if (Tok.
isNot(tok::identifier)) {
2057 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_predicate) << 0;
2063 if (Pred->
isStr(
"enable")) {
2065 }
else if (Pred->
isStr(
"disable")) {
2067 }
else if (Pred->
isStr(
"begin"))
2069 else if (Pred->
isStr(
"end"))
2073 << Ext->
isStr(
"all");
2079 if (Tok.
isNot(tok::eod)) {
2087 Info->second =
State;
2090 Toks[0].startToken();
2091 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2092 Toks[0].setLocation(NameLoc);
2093 Toks[0].setAnnotationValue(static_cast<void*>(Info));
2094 Toks[0].setAnnotationEndLoc(StateLoc);
2095 PP.EnterTokenStream(Toks,
true);
2110 PP.
Diag(FirstTok, diag::warn_pragma_omp_ignored);
2126 Tok.
setKind(tok::annot_pragma_openmp);
2130 Pragma.push_back(Tok);
2132 if (Tok.
is(tok::annot_pragma_openmp)) {
2133 PP.
Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2134 unsigned InnerPragmaCnt = 1;
2135 while (InnerPragmaCnt != 0) {
2137 if (Tok.
is(tok::annot_pragma_openmp))
2139 else if (Tok.
is(tok::annot_pragma_openmp_end))
2147 Tok.
setKind(tok::annot_pragma_openmp_end);
2149 Pragma.push_back(Tok);
2151 auto Toks = llvm::make_unique<Token[]>(Pragma.size());
2152 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2153 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2165 void PragmaMSPointersToMembers::HandlePragma(
Preprocessor &PP,
2170 if (Tok.
isNot(tok::l_paren)) {
2171 PP.
Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2172 <<
"pointers_to_members";
2179 <<
"pointers_to_members";
2185 if (Arg->
isStr(
"best_case")) {
2188 if (Arg->
isStr(
"full_generality")) {
2189 if (Tok.
is(tok::comma)) {
2195 diag::err_pragma_pointers_to_members_unknown_kind)
2200 }
else if (Tok.
is(tok::r_paren)) {
2207 <<
"full_generality";
2213 if (Arg->
isStr(
"single_inheritance")) {
2214 RepresentationMethod =
2216 }
else if (Arg->
isStr(
"multiple_inheritance")) {
2217 RepresentationMethod =
2219 }
else if (Arg->
isStr(
"virtual_inheritance")) {
2220 RepresentationMethod =
2224 diag::err_pragma_pointers_to_members_unknown_kind)
2231 if (Tok.
isNot(tok::r_paren)) {
2233 << (Arg ? Arg->
getName() :
"full_generality");
2239 if (Tok.
isNot(tok::eod)) {
2241 <<
"pointers_to_members";
2247 AnnotTok.
setKind(tok::annot_pragma_ms_pointers_to_members);
2251 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2268 if (Tok.
isNot(tok::l_paren)) {
2269 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) <<
"vtordisp";
2277 if (II->
isStr(
"push")) {
2280 if (Tok.
isNot(tok::comma)) {
2281 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_punc) <<
"vtordisp";
2287 }
else if (II->
isStr(
"pop")) {
2294 if (Tok.
is(tok::r_paren)) {
2304 if (II && II->
isStr(
"off")) {
2307 }
else if (II && II->
isStr(
"on")) {
2310 }
else if (Tok.
is(tok::numeric_constant) &&
2314 << 0 << 2 <<
"vtordisp";
2325 if (Tok.
isNot(tok::r_paren)) {
2326 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) <<
"vtordisp";
2331 if (Tok.
isNot(tok::eod)) {
2340 AnnotTok.
setKind(tok::annot_pragma_ms_vtordisp);
2344 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2353 Token EoF, AnnotTok;
2357 AnnotTok.
setKind(tok::annot_pragma_ms_pragma);
2362 for (; Tok.
isNot(tok::eod); PP.
Lex(Tok)) {
2363 TokenVector.push_back(Tok);
2367 TokenVector.push_back(EoF);
2370 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
2371 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2373 std::pair<std::unique_ptr<
Token[]>,
size_t>(std::move(TokenArray),
2374 TokenVector.size());
2389 void PragmaDetectMismatchHandler::HandlePragma(
Preprocessor &PP,
2394 if (Tok.
isNot(tok::l_paren)) {
2395 PP.
Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2400 std::string NameString;
2402 "pragma detect_mismatch",
2407 std::string ValueString;
2408 if (Tok.
isNot(tok::comma)) {
2409 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2417 if (Tok.
isNot(tok::r_paren)) {
2423 if (Tok.
isNot(tok::eod)) {
2424 PP.
Diag(Tok.
getLocation(), diag::err_pragma_detect_mismatch_malformed);
2433 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2445 void PragmaCommentHandler::HandlePragma(
Preprocessor &PP,
2450 if (Tok.
isNot(tok::l_paren)) {
2451 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2457 if (Tok.
isNot(tok::identifier)) {
2458 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
2465 llvm::StringSwitch<PragmaMSCommentKind>(II->
getName())
2493 std::string ArgumentString;
2506 if (Tok.
isNot(tok::r_paren)) {
2512 if (Tok.
isNot(tok::eod)) {
2521 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2526 void PragmaOptimizeHandler::HandlePragma(
Preprocessor &PP,
2528 Token &FirstToken) {
2531 if (Tok.
is(tok::eod)) {
2533 <<
"clang optimize" <<
true <<
"'on' or 'off'";
2536 if (Tok.
isNot(tok::identifier)) {
2537 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2544 if (II->
isStr(
"on")) {
2546 }
else if (!II->
isStr(
"off")) {
2547 PP.
Diag(Tok.
getLocation(), diag::err_pragma_optimize_invalid_argument)
2553 if (Tok.
isNot(tok::eod)) {
2559 Actions.ActOnPragmaOptimize(IsOn, FirstToken.
getLocation());
2564 struct TokFPAnnotValue {
2565 enum FlagKinds { Contract };
2566 enum FlagValues { On, Off, Fast };
2569 FlagValues FlagValue;
2581 if (Tok.
isNot(tok::identifier)) {
2587 while (Tok.
is(tok::identifier)) {
2591 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2593 .Case(
"contract", TokFPAnnotValue::Contract)
2597 <<
false << OptionInfo;
2603 if (Tok.
isNot(tok::l_paren)) {
2609 if (Tok.
isNot(tok::identifier)) {
2617 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2619 .Case(
"on", TokFPAnnotValue::On)
2620 .Case(
"off", TokFPAnnotValue::Off)
2621 .Case(
"fast", TokFPAnnotValue::Fast)
2632 if (Tok.
isNot(tok::r_paren)) {
2639 TokFPAnnotValue{*FlagKind, *FlagValue};
2643 FPTok.
setKind(tok::annot_pragma_fp);
2647 TokenList.push_back(FPTok);
2650 if (Tok.
isNot(tok::eod)) {
2656 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2657 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2659 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2663 void Parser::HandlePragmaFP() {
2664 assert(Tok.
is(tok::annot_pragma_fp));
2669 switch (AnnotValue->FlagValue) {
2670 case TokFPAnnotValue::On:
2673 case TokFPAnnotValue::Fast:
2676 case TokFPAnnotValue::Off:
2681 Actions.ActOnPragmaFPContract(FPC);
2682 ConsumeAnnotationToken();
2687 Token Option,
bool ValueInParens,
2688 PragmaLoopHintInfo &Info) {
2690 int OpenParens = ValueInParens ? 1 : 0;
2692 while (Tok.
isNot(tok::eod)) {
2693 if (Tok.
is(tok::l_paren))
2695 else if (Tok.
is(tok::r_paren)) {
2697 if (OpenParens == 0 && ValueInParens)
2701 ValueList.push_back(Tok);
2705 if (ValueInParens) {
2707 if (Tok.
isNot(tok::r_paren)) {
2718 ValueList.push_back(EOFTok);
2722 Info.PragmaName = PragmaName;
2723 Info.Option = Option;
2772 void PragmaLoopHintHandler::HandlePragma(
Preprocessor &PP,
2781 if (Tok.
isNot(tok::identifier)) {
2787 while (Tok.
is(tok::identifier)) {
2791 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->
getName())
2792 .Case(
"vectorize",
true)
2793 .Case(
"interleave",
true)
2794 .Case(
"unroll",
true)
2795 .Case(
"distribute",
true)
2796 .Case(
"vectorize_width",
true)
2797 .Case(
"interleave_count",
true)
2798 .Case(
"unroll_count",
true)
2802 <<
false << OptionInfo;
2808 if (Tok.
isNot(tok::l_paren)) {
2822 LoopHintTok.
setKind(tok::annot_pragma_loop_hint);
2826 TokenList.push_back(LoopHintTok);
2829 if (Tok.
isNot(tok::eod)) {
2835 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2836 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2838 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2859 void PragmaUnrollHintHandler::HandlePragma(
Preprocessor &PP,
2867 if (Tok.
is(tok::eod)) {
2869 Info->PragmaName = PragmaName;
2879 bool ValueInParens = Tok.
is(tok::l_paren);
2891 PP.
Diag(Info->Toks[0].getLocation(),
2892 diag::warn_pragma_unroll_cuda_value_in_parens);
2894 if (Tok.
isNot(tok::eod)) {
2902 auto TokenArray = llvm::make_unique<Token[]>(1);
2903 TokenArray[0].startToken();
2904 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2905 TokenArray[0].setLocation(PragmaName.
getLocation());
2906 TokenArray[0].setAnnotationEndLoc(PragmaName.
getLocation());
2907 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2908 PP.EnterTokenStream(std::move(TokenArray), 1,
2924 void PragmaMSIntrinsicHandler::HandlePragma(
Preprocessor &PP,
2929 if (Tok.
isNot(tok::l_paren)) {
2938 while (Tok.
is(tok::identifier)) {
2942 << II << SuggestIntrinH;
2945 if (Tok.
isNot(tok::comma))
2950 if (Tok.
isNot(tok::r_paren)) {
2957 if (Tok.
isNot(tok::eod))
2963 void PragmaMSOptimizeHandler::HandlePragma(
Preprocessor &PP,
2969 if (Tok.
isNot(tok::l_paren)) {
2970 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_lparen) <<
"optimize";
2975 if (Tok.
isNot(tok::string_literal)) {
2976 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_string) <<
"optimize";
2982 if (Tok.
isNot(tok::comma)) {
2983 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_comma) <<
"optimize";
2988 if (Tok.
is(tok::eod) || Tok.
is(tok::r_paren)) {
2990 <<
"optimize" <<
true <<
"'on' or 'off'";
2994 if (!II || (!II->
isStr(
"on") && !II->
isStr(
"off"))) {
3002 if (Tok.
isNot(tok::r_paren)) {
3003 PP.
Diag(Tok.
getLocation(), diag::warn_pragma_expected_rparen) <<
"optimize";
3008 if (Tok.
isNot(tok::eod)) {
3013 PP.
Diag(StartLoc, diag::warn_pragma_optimize);
3016 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3022 if (!Info || (!Info->
isStr(
"begin") && !Info->
isStr(
"end"))) {
3024 diag::warn_pragma_force_cuda_host_device_bad_arg);
3028 if (Info->
isStr(
"begin"))
3029 Actions.PushForceCUDAHostDevice();
3030 else if (!Actions.PopForceCUDAHostDevice())
3032 diag::err_pragma_cannot_end_force_cuda_host_device);
3035 if (!Tok.
is(tok::eod))
3037 diag::warn_pragma_force_cuda_host_device_bad_arg);
3055 void PragmaAttributeHandler::HandlePragma(
Preprocessor &PP,
3057 Token &FirstToken) {
3061 PragmaAttributeInfo(AttributesForPragmaAttribute);
3064 if (Tok.
isNot(tok::identifier)) {
3065 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_push_pop);
3069 if (II->isStr(
"push"))
3070 Info->Action = PragmaAttributeInfo::Push;
3071 else if (II->isStr(
"pop"))
3072 Info->Action = PragmaAttributeInfo::Pop;
3074 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_invalid_argument)
3081 if (Info->Action == PragmaAttributeInfo::Push) {
3082 if (Tok.
isNot(tok::l_paren)) {
3091 while (Tok.
isNot(tok::eod)) {
3092 if (Tok.
is(tok::l_paren))
3094 else if (Tok.
is(tok::r_paren)) {
3096 if (OpenParens == 0)
3100 AttributeTokens.push_back(Tok);
3104 if (AttributeTokens.empty()) {
3105 PP.
Diag(Tok.
getLocation(), diag::err_pragma_attribute_expected_attribute);
3108 if (Tok.
isNot(tok::r_paren)) {
3120 AttributeTokens.push_back(EOFTok);
3126 if (Tok.
isNot(tok::eod))
3128 <<
"clang attribute";
3131 auto TokenArray = llvm::make_unique<Token[]>(1);
3132 TokenArray[0].startToken();
3133 TokenArray[0].setKind(tok::annot_pragma_attribute);
3134 TokenArray[0].setLocation(FirstToken.
getLocation());
3135 TokenArray[0].setAnnotationEndLoc(FirstToken.
getLocation());
3136 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3137 PP.EnterTokenStream(std::move(TokenArray), 1,
Defines the clang::ASTContext interface.
IdentifierLoc * PragmaNameLoc
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::BumpPtrAllocator & getPreprocessorAllocator()
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
SourceLocation getEndOfPreviousToken()
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName, Token Option, bool ValueInParens, PragmaLoopHintInfo &Info)
Parses loop or unroll pragma hint value and fills in Info.
virtual void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, SourceLocation StateLoc, unsigned State)
Called when an OpenCL extension is either disabled or enabled with a pragma.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
bool LexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)
Lex a string literal, which may be the concatenation of multiple string literals and may even come fr...
This indicates that the scope corresponds to a function, which means that labels are set here...
Parser - This implements a parser for the C family of languages.
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)
Parses a simple integer literal to get its numeric value.
void EnterToken(const Token &Tok)
Enters a token in the token stream to be lexed next.
ActionResult< Stmt * > StmtResult
static void diagnoseUnknownAttributeSubjectSubRule(Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, StringRef SubRuleName, SourceLocation SubRuleLoc)
static std::string PragmaLoopHintString(Token PragmaName, Token Option)
IdentifierLoc * OptionLoc
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
Parse and apply any fixits to the source.
tok::TokenKind getKind() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
One of these records is kept for each identifier that is lexed.
SubjectMatchRule
A list of all the recognized kinds of attributes.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
const TargetInfo & getTargetInfo() const
Token - This structure provides full information about a lexed token.
void setKind(tok::TokenKind K)
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
unsigned getCharByteWidth() const
const LangOptions & getLangOpts() const
MissingAttributeSubjectRulesRecoveryPoint
Describes the stage at which attribute subject rule parsing was interrupted.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
unsigned getLength() const
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
PragmaIntroducerKind
Describes how the pragma was introduced, e.g., with #pragma, _Pragma, or __pragma.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
Sema - This implements semantic analysis and AST building for C.
A little helper class used to produce diagnostics.
EmptyPragmaHandler - A pragma handler which takes no action, which can be used to ignore particular p...
void setAnnotationValue(void *val)
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.
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Remove the specific pragma handler from this preprocessor.
This is a compound statement scope.
static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule)
SourceLocation getEnd() const
PPCallbacks * getPPCallbacks() const
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, StringRef Str)
Callback invoked when a #pragma comment directive is read.
static StringRef getIdentifier(const Token &Tok)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
const LangOptions & getLangOpts() const
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
static CharSourceRange getCharRange(SourceRange R)
static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, bool IsOptions)
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
const char * getSubjectMatchRuleSpelling(SubjectMatchRule Rule)
void setLength(unsigned Len)
IdentifierInfo * getIdentifierInfo() const
void setAnnotationEndLoc(SourceLocation L)
ParsedAttr - Represents a syntactic attribute.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
void Lex(Token &Result)
Lex the next token for this preprocessor.
PragmaMSPointersToMembersKind
StringRef getName() const
Return the actual identifier string.
bool isMacroDefined(StringRef Id)
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool expectAndConsume(unsigned DiagID=diag::err_expected, const char *Msg="", tok::TokenKind SkipToTok=tok::unknown)
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, StringRef Value)
Callback invoked when a #pragma detect_mismatch directive is read.
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
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.
void setEnd(SourceLocation e)
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
DiagnosticsEngine & getDiagnostics() const
Do not present this diagnostic, ignore it.
llvm::DenseMap< int, SourceRange > ParsedSubjectMatchRuleSet
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine) ...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
bool isSupportedByPragmaAttribute() const
void DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Loop optimization hint for loop and unroll pragmas.
void setLocation(SourceLocation L)
A trivial tuple used to represent a source range.
void * getAnnotationValue() const
SourceLocation getBegin() const
ParsedAttributes - A collection of parsed attributes.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void startToken()
Reset all flags to cleared.
ArrayRef< SVal > ValueList
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Stop skipping at specified token, but don't skip the token itself.
SourceLocation getEndLoc() const