1 //===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the language specific #pragma handlers.
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/ASTContext.h"
15 #include "clang/Basic/PragmaKinds.h"
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/Lex/Preprocessor.h"
18 #include "clang/Parse/ParseDiagnostic.h"
19 #include "clang/Parse/Parser.h"
20 #include "clang/Parse/RAIIObjectsForParser.h"
21 #include "clang/Sema/LoopHint.h"
22 #include "clang/Sema/Scope.h"
23 #include "llvm/ADT/StringSwitch.h"
24 using namespace clang;
28 struct PragmaAlignHandler : public PragmaHandler {
29 explicit PragmaAlignHandler() : PragmaHandler("align") {}
30 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
31 Token &FirstToken) override;
34 struct PragmaGCCVisibilityHandler : public PragmaHandler {
35 explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
36 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
37 Token &FirstToken) override;
40 struct PragmaOptionsHandler : public PragmaHandler {
41 explicit PragmaOptionsHandler() : PragmaHandler("options") {}
42 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
43 Token &FirstToken) override;
46 struct PragmaPackHandler : public PragmaHandler {
47 explicit PragmaPackHandler() : PragmaHandler("pack") {}
48 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
49 Token &FirstToken) override;
52 struct PragmaMSStructHandler : public PragmaHandler {
53 explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
54 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
55 Token &FirstToken) override;
58 struct PragmaUnusedHandler : public PragmaHandler {
59 PragmaUnusedHandler() : PragmaHandler("unused") {}
60 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
61 Token &FirstToken) override;
64 struct PragmaWeakHandler : public PragmaHandler {
65 explicit PragmaWeakHandler() : PragmaHandler("weak") {}
66 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
67 Token &FirstToken) override;
70 struct PragmaRedefineExtnameHandler : public PragmaHandler {
71 explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
72 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
73 Token &FirstToken) override;
76 struct PragmaOpenCLExtensionHandler : public PragmaHandler {
77 PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
78 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
79 Token &FirstToken) override;
83 struct PragmaFPContractHandler : public PragmaHandler {
84 PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
85 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
86 Token &FirstToken) override;
89 struct PragmaFPHandler : public PragmaHandler {
90 PragmaFPHandler() : PragmaHandler("fp") {}
91 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
92 Token &FirstToken) override;
95 struct PragmaNoOpenMPHandler : public PragmaHandler {
96 PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
97 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
98 Token &FirstToken) override;
101 struct PragmaOpenMPHandler : public PragmaHandler {
102 PragmaOpenMPHandler() : PragmaHandler("omp") { }
103 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
104 Token &FirstToken) override;
107 /// PragmaCommentHandler - "\#pragma comment ...".
108 struct PragmaCommentHandler : public PragmaHandler {
109 PragmaCommentHandler(Sema &Actions)
110 : PragmaHandler("comment"), Actions(Actions) {}
111 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
112 Token &FirstToken) override;
117 struct PragmaDetectMismatchHandler : public PragmaHandler {
118 PragmaDetectMismatchHandler(Sema &Actions)
119 : PragmaHandler("detect_mismatch"), Actions(Actions) {}
120 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
121 Token &FirstToken) override;
126 struct PragmaMSPointersToMembers : public PragmaHandler {
127 explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
128 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
129 Token &FirstToken) override;
132 struct PragmaMSVtorDisp : public PragmaHandler {
133 explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
134 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
135 Token &FirstToken) override;
138 struct PragmaMSPragma : public PragmaHandler {
139 explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
140 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
141 Token &FirstToken) override;
144 /// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
145 struct PragmaOptimizeHandler : public PragmaHandler {
146 PragmaOptimizeHandler(Sema &S)
147 : PragmaHandler("optimize"), Actions(S) {}
148 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
149 Token &FirstToken) override;
154 struct PragmaLoopHintHandler : public PragmaHandler {
155 PragmaLoopHintHandler() : PragmaHandler("loop") {}
156 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
157 Token &FirstToken) override;
160 struct PragmaUnrollHintHandler : public PragmaHandler {
161 PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
162 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
163 Token &FirstToken) override;
166 struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
167 PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
170 struct PragmaMSIntrinsicHandler : public PragmaHandler {
171 PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {}
172 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
173 Token &FirstToken) override;
176 struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler {
177 PragmaForceCUDAHostDeviceHandler(Sema &Actions)
178 : PragmaHandler("force_cuda_host_device"), Actions(Actions) {}
179 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
180 Token &FirstToken) override;
186 /// PragmaAttributeHandler - "\#pragma clang attribute ...".
187 struct PragmaAttributeHandler : public PragmaHandler {
188 PragmaAttributeHandler(AttributeFactory &AttrFactory)
189 : PragmaHandler("attribute"), AttributesForPragmaAttribute(AttrFactory) {}
190 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
191 Token &FirstToken) override;
193 /// A pool of attributes that were parsed in \#pragma clang attribute.
194 ParsedAttributes AttributesForPragmaAttribute;
199 void Parser::initializePragmaHandlers() {
200 AlignHandler.reset(new PragmaAlignHandler());
201 PP.AddPragmaHandler(AlignHandler.get());
203 GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
204 PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
206 OptionsHandler.reset(new PragmaOptionsHandler());
207 PP.AddPragmaHandler(OptionsHandler.get());
209 PackHandler.reset(new PragmaPackHandler());
210 PP.AddPragmaHandler(PackHandler.get());
212 MSStructHandler.reset(new PragmaMSStructHandler());
213 PP.AddPragmaHandler(MSStructHandler.get());
215 UnusedHandler.reset(new PragmaUnusedHandler());
216 PP.AddPragmaHandler(UnusedHandler.get());
218 WeakHandler.reset(new PragmaWeakHandler());
219 PP.AddPragmaHandler(WeakHandler.get());
221 RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
222 PP.AddPragmaHandler(RedefineExtnameHandler.get());
224 FPContractHandler.reset(new PragmaFPContractHandler());
225 PP.AddPragmaHandler("STDC", FPContractHandler.get());
227 if (getLangOpts().OpenCL) {
228 OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
229 PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
231 PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
233 if (getLangOpts().OpenMP)
234 OpenMPHandler.reset(new PragmaOpenMPHandler());
236 OpenMPHandler.reset(new PragmaNoOpenMPHandler());
237 PP.AddPragmaHandler(OpenMPHandler.get());
239 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
240 MSCommentHandler.reset(new PragmaCommentHandler(Actions));
241 PP.AddPragmaHandler(MSCommentHandler.get());
244 if (getLangOpts().MicrosoftExt) {
245 MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions));
246 PP.AddPragmaHandler(MSDetectMismatchHandler.get());
247 MSPointersToMembers.reset(new PragmaMSPointersToMembers());
248 PP.AddPragmaHandler(MSPointersToMembers.get());
249 MSVtorDisp.reset(new PragmaMSVtorDisp());
250 PP.AddPragmaHandler(MSVtorDisp.get());
251 MSInitSeg.reset(new PragmaMSPragma("init_seg"));
252 PP.AddPragmaHandler(MSInitSeg.get());
253 MSDataSeg.reset(new PragmaMSPragma("data_seg"));
254 PP.AddPragmaHandler(MSDataSeg.get());
255 MSBSSSeg.reset(new PragmaMSPragma("bss_seg"));
256 PP.AddPragmaHandler(MSBSSSeg.get());
257 MSConstSeg.reset(new PragmaMSPragma("const_seg"));
258 PP.AddPragmaHandler(MSConstSeg.get());
259 MSCodeSeg.reset(new PragmaMSPragma("code_seg"));
260 PP.AddPragmaHandler(MSCodeSeg.get());
261 MSSection.reset(new PragmaMSPragma("section"));
262 PP.AddPragmaHandler(MSSection.get());
263 MSRuntimeChecks.reset(new PragmaMSRuntimeChecksHandler());
264 PP.AddPragmaHandler(MSRuntimeChecks.get());
265 MSIntrinsic.reset(new PragmaMSIntrinsicHandler());
266 PP.AddPragmaHandler(MSIntrinsic.get());
269 if (getLangOpts().CUDA) {
270 CUDAForceHostDeviceHandler.reset(
271 new PragmaForceCUDAHostDeviceHandler(Actions));
272 PP.AddPragmaHandler("clang", CUDAForceHostDeviceHandler.get());
275 OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
276 PP.AddPragmaHandler("clang", OptimizeHandler.get());
278 LoopHintHandler.reset(new PragmaLoopHintHandler());
279 PP.AddPragmaHandler("clang", LoopHintHandler.get());
281 UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll"));
282 PP.AddPragmaHandler(UnrollHintHandler.get());
284 NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll"));
285 PP.AddPragmaHandler(NoUnrollHintHandler.get());
287 FPHandler.reset(new PragmaFPHandler());
288 PP.AddPragmaHandler("clang", FPHandler.get());
290 AttributePragmaHandler.reset(new PragmaAttributeHandler(AttrFactory));
291 PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
294 void Parser::resetPragmaHandlers() {
295 // Remove the pragma handlers we installed.
296 PP.RemovePragmaHandler(AlignHandler.get());
297 AlignHandler.reset();
298 PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
299 GCCVisibilityHandler.reset();
300 PP.RemovePragmaHandler(OptionsHandler.get());
301 OptionsHandler.reset();
302 PP.RemovePragmaHandler(PackHandler.get());
304 PP.RemovePragmaHandler(MSStructHandler.get());
305 MSStructHandler.reset();
306 PP.RemovePragmaHandler(UnusedHandler.get());
307 UnusedHandler.reset();
308 PP.RemovePragmaHandler(WeakHandler.get());
310 PP.RemovePragmaHandler(RedefineExtnameHandler.get());
311 RedefineExtnameHandler.reset();
313 if (getLangOpts().OpenCL) {
314 PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
315 OpenCLExtensionHandler.reset();
316 PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
318 PP.RemovePragmaHandler(OpenMPHandler.get());
319 OpenMPHandler.reset();
321 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
322 PP.RemovePragmaHandler(MSCommentHandler.get());
323 MSCommentHandler.reset();
326 if (getLangOpts().MicrosoftExt) {
327 PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
328 MSDetectMismatchHandler.reset();
329 PP.RemovePragmaHandler(MSPointersToMembers.get());
330 MSPointersToMembers.reset();
331 PP.RemovePragmaHandler(MSVtorDisp.get());
333 PP.RemovePragmaHandler(MSInitSeg.get());
335 PP.RemovePragmaHandler(MSDataSeg.get());
337 PP.RemovePragmaHandler(MSBSSSeg.get());
339 PP.RemovePragmaHandler(MSConstSeg.get());
341 PP.RemovePragmaHandler(MSCodeSeg.get());
343 PP.RemovePragmaHandler(MSSection.get());
345 PP.RemovePragmaHandler(MSRuntimeChecks.get());
346 MSRuntimeChecks.reset();
347 PP.RemovePragmaHandler(MSIntrinsic.get());
351 if (getLangOpts().CUDA) {
352 PP.RemovePragmaHandler("clang", CUDAForceHostDeviceHandler.get());
353 CUDAForceHostDeviceHandler.reset();
356 PP.RemovePragmaHandler("STDC", FPContractHandler.get());
357 FPContractHandler.reset();
359 PP.RemovePragmaHandler("clang", OptimizeHandler.get());
360 OptimizeHandler.reset();
362 PP.RemovePragmaHandler("clang", LoopHintHandler.get());
363 LoopHintHandler.reset();
365 PP.RemovePragmaHandler(UnrollHintHandler.get());
366 UnrollHintHandler.reset();
368 PP.RemovePragmaHandler(NoUnrollHintHandler.get());
369 NoUnrollHintHandler.reset();
371 PP.RemovePragmaHandler("clang", FPHandler.get());
374 PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
375 AttributePragmaHandler.reset();
378 /// \brief Handle the annotation token produced for #pragma unused(...)
380 /// Each annot_pragma_unused is followed by the argument token so e.g.
381 /// "#pragma unused(x,y)" becomes:
382 /// annot_pragma_unused 'x' annot_pragma_unused 'y'
383 void Parser::HandlePragmaUnused() {
384 assert(Tok.is(tok::annot_pragma_unused));
385 SourceLocation UnusedLoc = ConsumeAnnotationToken();
386 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
387 ConsumeToken(); // The argument token.
390 void Parser::HandlePragmaVisibility() {
391 assert(Tok.is(tok::annot_pragma_vis));
392 const IdentifierInfo *VisType =
393 static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
394 SourceLocation VisLoc = ConsumeAnnotationToken();
395 Actions.ActOnPragmaVisibility(VisType, VisLoc);
399 struct PragmaPackInfo {
400 Sema::PragmaMsStackAction Action;
404 } // end anonymous namespace
406 void Parser::HandlePragmaPack() {
407 assert(Tok.is(tok::annot_pragma_pack));
408 PragmaPackInfo *Info =
409 static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
410 SourceLocation PragmaLoc = ConsumeAnnotationToken();
411 ExprResult Alignment;
412 if (Info->Alignment.is(tok::numeric_constant)) {
413 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
414 if (Alignment.isInvalid())
417 Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
421 void Parser::HandlePragmaMSStruct() {
422 assert(Tok.is(tok::annot_pragma_msstruct));
423 PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>(
424 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
425 Actions.ActOnPragmaMSStruct(Kind);
426 ConsumeAnnotationToken();
429 void Parser::HandlePragmaAlign() {
430 assert(Tok.is(tok::annot_pragma_align));
431 Sema::PragmaOptionsAlignKind Kind =
432 static_cast<Sema::PragmaOptionsAlignKind>(
433 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
434 SourceLocation PragmaLoc = ConsumeAnnotationToken();
435 Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
438 void Parser::HandlePragmaDump() {
439 assert(Tok.is(tok::annot_pragma_dump));
441 reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue());
442 Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II);
443 ConsumeAnnotationToken();
446 void Parser::HandlePragmaWeak() {
447 assert(Tok.is(tok::annot_pragma_weak));
448 SourceLocation PragmaLoc = ConsumeAnnotationToken();
449 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
451 ConsumeToken(); // The weak name.
454 void Parser::HandlePragmaWeakAlias() {
455 assert(Tok.is(tok::annot_pragma_weakalias));
456 SourceLocation PragmaLoc = ConsumeAnnotationToken();
457 IdentifierInfo *WeakName = Tok.getIdentifierInfo();
458 SourceLocation WeakNameLoc = Tok.getLocation();
460 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
461 SourceLocation AliasNameLoc = Tok.getLocation();
463 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
464 WeakNameLoc, AliasNameLoc);
468 void Parser::HandlePragmaRedefineExtname() {
469 assert(Tok.is(tok::annot_pragma_redefine_extname));
470 SourceLocation RedefLoc = ConsumeAnnotationToken();
471 IdentifierInfo *RedefName = Tok.getIdentifierInfo();
472 SourceLocation RedefNameLoc = Tok.getLocation();
474 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
475 SourceLocation AliasNameLoc = Tok.getLocation();
477 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
478 RedefNameLoc, AliasNameLoc);
481 void Parser::HandlePragmaFPContract() {
482 assert(Tok.is(tok::annot_pragma_fp_contract));
483 tok::OnOffSwitch OOS =
484 static_cast<tok::OnOffSwitch>(
485 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
487 LangOptions::FPContractModeKind FPC;
490 FPC = LangOptions::FPC_On;
493 FPC = LangOptions::FPC_Off;
495 case tok::OOS_DEFAULT:
496 FPC = getLangOpts().getDefaultFPContractMode();
500 Actions.ActOnPragmaFPContract(FPC);
501 ConsumeAnnotationToken();
504 StmtResult Parser::HandlePragmaCaptured()
506 assert(Tok.is(tok::annot_pragma_captured));
507 ConsumeAnnotationToken();
509 if (Tok.isNot(tok::l_brace)) {
510 PP.Diag(Tok, diag::err_expected) << tok::l_brace;
514 SourceLocation Loc = Tok.getLocation();
516 ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope);
517 Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
520 StmtResult R = ParseCompoundStatement();
521 CapturedRegionScope.Exit();
524 Actions.ActOnCapturedRegionError();
528 return Actions.ActOnCapturedRegionEnd(R.get());
532 enum OpenCLExtState : char {
533 Disable, Enable, Begin, End
535 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
538 void Parser::HandlePragmaOpenCLExtension() {
539 assert(Tok.is(tok::annot_pragma_opencl_extension));
540 OpenCLExtData *Data = static_cast<OpenCLExtData*>(Tok.getAnnotationValue());
541 auto State = Data->second;
542 auto Ident = Data->first;
543 SourceLocation NameLoc = Tok.getLocation();
544 ConsumeAnnotationToken();
546 auto &Opt = Actions.getOpenCLOptions();
547 auto Name = Ident->getName();
548 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
549 // overriding all previously issued extension directives, but only if the
550 // behavior is set to disable."
552 if (State == Disable) {
554 Opt.enableSupportedCore(getLangOpts().OpenCLVersion);
556 PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
558 } else if (State == Begin) {
559 if (!Opt.isKnown(Name) ||
560 !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
563 Actions.setCurrentOpenCLExtension(Name);
564 } else if (State == End) {
565 if (Name != Actions.getCurrentOpenCLExtension())
566 PP.Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
567 Actions.setCurrentOpenCLExtension("");
568 } else if (!Opt.isKnown(Name))
569 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
570 else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
571 Opt.enable(Name, State == Enable);
572 else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
573 PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
575 PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
578 void Parser::HandlePragmaMSPointersToMembers() {
579 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
580 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
581 static_cast<LangOptions::PragmaMSPointersToMembersKind>(
582 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
583 SourceLocation PragmaLoc = ConsumeAnnotationToken();
584 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
587 void Parser::HandlePragmaMSVtorDisp() {
588 assert(Tok.is(tok::annot_pragma_ms_vtordisp));
589 uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
590 Sema::PragmaMsStackAction Action =
591 static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
592 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
593 SourceLocation PragmaLoc = ConsumeAnnotationToken();
594 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
597 void Parser::HandlePragmaMSPragma() {
598 assert(Tok.is(tok::annot_pragma_ms_pragma));
599 // Grab the tokens out of the annotation and enter them into the stream.
601 (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue();
602 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true);
603 SourceLocation PragmaLocation = ConsumeAnnotationToken();
604 assert(Tok.isAnyIdentifier());
605 StringRef PragmaName = Tok.getIdentifierInfo()->getName();
606 PP.Lex(Tok); // pragma kind
608 // Figure out which #pragma we're dealing with. The switch has no default
609 // because lex shouldn't emit the annotation token for unrecognized pragmas.
610 typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
611 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
612 .Case("data_seg", &Parser::HandlePragmaMSSegment)
613 .Case("bss_seg", &Parser::HandlePragmaMSSegment)
614 .Case("const_seg", &Parser::HandlePragmaMSSegment)
615 .Case("code_seg", &Parser::HandlePragmaMSSegment)
616 .Case("section", &Parser::HandlePragmaMSSection)
617 .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
619 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
620 // Pragma handling failed, and has been diagnosed. Slurp up the tokens
621 // until eof (really end of line) to prevent follow-on errors.
622 while (Tok.isNot(tok::eof))
628 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
629 SourceLocation PragmaLocation) {
630 if (Tok.isNot(tok::l_paren)) {
631 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
635 // Parsing code for pragma section
636 if (Tok.isNot(tok::string_literal)) {
637 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
641 ExprResult StringResult = ParseStringLiteralExpression();
642 if (StringResult.isInvalid())
643 return false; // Already diagnosed.
644 StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
645 if (SegmentName->getCharByteWidth() != 1) {
646 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
650 int SectionFlags = ASTContext::PSF_Read;
651 bool SectionFlagsAreDefault = true;
652 while (Tok.is(tok::comma)) {
654 // Ignore "long" and "short".
655 // They are undocumented, but widely used, section attributes which appear
657 if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
658 PP.Lex(Tok); // long/short
662 if (!Tok.isAnyIdentifier()) {
663 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
667 ASTContext::PragmaSectionFlag Flag =
668 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
669 Tok.getIdentifierInfo()->getName())
670 .Case("read", ASTContext::PSF_Read)
671 .Case("write", ASTContext::PSF_Write)
672 .Case("execute", ASTContext::PSF_Execute)
673 .Case("shared", ASTContext::PSF_Invalid)
674 .Case("nopage", ASTContext::PSF_Invalid)
675 .Case("nocache", ASTContext::PSF_Invalid)
676 .Case("discard", ASTContext::PSF_Invalid)
677 .Case("remove", ASTContext::PSF_Invalid)
678 .Default(ASTContext::PSF_None);
679 if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
680 PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
681 ? diag::warn_pragma_invalid_specific_action
682 : diag::warn_pragma_unsupported_action)
683 << PragmaName << Tok.getIdentifierInfo()->getName();
686 SectionFlags |= Flag;
687 SectionFlagsAreDefault = false;
688 PP.Lex(Tok); // Identifier
690 // If no section attributes are specified, the section will be marked as
692 if (SectionFlagsAreDefault)
693 SectionFlags |= ASTContext::PSF_Write;
694 if (Tok.isNot(tok::r_paren)) {
695 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
699 if (Tok.isNot(tok::eof)) {
700 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
705 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
709 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
710 SourceLocation PragmaLocation) {
711 if (Tok.isNot(tok::l_paren)) {
712 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
716 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
718 if (Tok.isAnyIdentifier()) {
719 StringRef PushPop = Tok.getIdentifierInfo()->getName();
720 if (PushPop == "push")
721 Action = Sema::PSK_Push;
722 else if (PushPop == "pop")
723 Action = Sema::PSK_Pop;
725 PP.Diag(PragmaLocation,
726 diag::warn_pragma_expected_section_push_pop_or_name)
730 if (Action != Sema::PSK_Reset) {
731 PP.Lex(Tok); // push | pop
732 if (Tok.is(tok::comma)) {
734 // If we've got a comma, we either need a label or a string.
735 if (Tok.isAnyIdentifier()) {
736 SlotLabel = Tok.getIdentifierInfo()->getName();
737 PP.Lex(Tok); // identifier
738 if (Tok.is(tok::comma))
740 else if (Tok.isNot(tok::r_paren)) {
741 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
746 } else if (Tok.isNot(tok::r_paren)) {
747 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
752 // Grab the string literal for our section name.
753 StringLiteral *SegmentName = nullptr;
754 if (Tok.isNot(tok::r_paren)) {
755 if (Tok.isNot(tok::string_literal)) {
756 unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
757 diag::warn_pragma_expected_section_name :
758 diag::warn_pragma_expected_section_label_or_name :
759 diag::warn_pragma_expected_section_push_pop_or_name;
760 PP.Diag(PragmaLocation, DiagID) << PragmaName;
763 ExprResult StringResult = ParseStringLiteralExpression();
764 if (StringResult.isInvalid())
765 return false; // Already diagnosed.
766 SegmentName = cast<StringLiteral>(StringResult.get());
767 if (SegmentName->getCharByteWidth() != 1) {
768 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
772 // Setting section "" has no effect
773 if (SegmentName->getLength())
774 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
776 if (Tok.isNot(tok::r_paren)) {
777 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
781 if (Tok.isNot(tok::eof)) {
782 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
787 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
788 SegmentName, PragmaName);
792 // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
793 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
794 SourceLocation PragmaLocation) {
795 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
796 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
800 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
804 // Parse either the known section names or the string section name.
805 StringLiteral *SegmentName = nullptr;
806 if (Tok.isAnyIdentifier()) {
807 auto *II = Tok.getIdentifierInfo();
808 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
809 .Case("compiler", "\".CRT$XCC\"")
810 .Case("lib", "\".CRT$XCL\"")
811 .Case("user", "\".CRT$XCU\"")
814 if (!Section.empty()) {
815 // Pretend the user wrote the appropriate string literal here.
817 Toks[0].startToken();
818 Toks[0].setKind(tok::string_literal);
819 Toks[0].setLocation(Tok.getLocation());
820 Toks[0].setLiteralData(Section.data());
821 Toks[0].setLength(Section.size());
823 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
826 } else if (Tok.is(tok::string_literal)) {
827 ExprResult StringResult = ParseStringLiteralExpression();
828 if (StringResult.isInvalid())
830 SegmentName = cast<StringLiteral>(StringResult.get());
831 if (SegmentName->getCharByteWidth() != 1) {
832 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
836 // FIXME: Add support for the '[, func-name]' part of the pragma.
840 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
844 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
846 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
850 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
855 struct PragmaLoopHintInfo {
858 ArrayRef<Token> Toks;
860 } // end anonymous namespace
862 static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
863 std::string PragmaString;
864 if (PragmaName.getIdentifierInfo()->getName() == "loop") {
865 PragmaString = "clang loop ";
866 PragmaString += Option.getIdentifierInfo()->getName();
868 assert(PragmaName.getIdentifierInfo()->getName() == "unroll" &&
869 "Unexpected pragma name");
870 PragmaString = "unroll";
875 bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
876 assert(Tok.is(tok::annot_pragma_loop_hint));
877 PragmaLoopHintInfo *Info =
878 static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
880 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
881 Hint.PragmaNameLoc = IdentifierLoc::create(
882 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
884 // It is possible that the loop hint has no option identifier, such as
885 // #pragma unroll(4).
886 IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
887 ? Info->Option.getIdentifierInfo()
889 Hint.OptionLoc = IdentifierLoc::create(
890 Actions.Context, Info->Option.getLocation(), OptionInfo);
892 llvm::ArrayRef<Token> Toks = Info->Toks;
894 // Return a valid hint if pragma unroll or nounroll were specified
895 // without an argument.
896 bool PragmaUnroll = PragmaNameInfo->getName() == "unroll";
897 bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll";
898 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll)) {
899 ConsumeAnnotationToken();
900 Hint.Range = Info->PragmaName.getLocation();
904 // The constant expression is always followed by an eof token, which increases
906 assert(!Toks.empty() &&
907 "PragmaLoopHintInfo::Toks must contain at least one token.");
909 // If no option is specified the argument is assumed to be a constant expr.
910 bool OptionUnroll = false;
911 bool OptionDistribute = false;
912 bool StateOption = false;
913 if (OptionInfo) { // Pragma Unroll does not specify an option.
914 OptionUnroll = OptionInfo->isStr("unroll");
915 OptionDistribute = OptionInfo->isStr("distribute");
916 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
917 .Case("vectorize", true)
918 .Case("interleave", true)
920 OptionUnroll || OptionDistribute;
923 bool AssumeSafetyArg = !OptionUnroll && !OptionDistribute;
924 // Verify loop hint has an argument.
925 if (Toks[0].is(tok::eof)) {
926 ConsumeAnnotationToken();
927 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
928 << /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll
929 << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
933 // Validate the argument.
935 ConsumeAnnotationToken();
936 SourceLocation StateLoc = Toks[0].getLocation();
937 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
939 bool Valid = StateInfo &&
940 llvm::StringSwitch<bool>(StateInfo->getName())
941 .Cases("enable", "disable", true)
942 .Case("full", OptionUnroll)
943 .Case("assume_safety", AssumeSafetyArg)
946 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
947 << /*FullKeyword=*/OptionUnroll
948 << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
952 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
953 << PragmaLoopHintString(Info->PragmaName, Info->Option);
954 Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
956 // Enter constant expression including eof terminator into token stream.
957 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false);
958 ConsumeAnnotationToken();
960 ExprResult R = ParseConstantExpression();
962 // Tokens following an error in an ill-formed constant expression will
963 // remain in the token stream and must be removed.
964 if (Tok.isNot(tok::eof)) {
965 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
966 << PragmaLoopHintString(Info->PragmaName, Info->Option);
967 while (Tok.isNot(tok::eof))
971 ConsumeToken(); // Consume the constant expression eof terminator.
974 Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
977 // Argument is a constant expression with an integer type.
978 Hint.ValueExpr = R.get();
981 Hint.Range = SourceRange(Info->PragmaName.getLocation(),
982 Info->Toks.back().getLocation());
987 struct PragmaAttributeInfo {
988 enum ActionType { Push, Pop };
989 ParsedAttributes &Attributes;
991 ArrayRef<Token> Tokens;
993 PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
996 #include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
998 } // end anonymous namespace
1000 static StringRef getIdentifier(const Token &Tok) {
1001 if (Tok.is(tok::identifier))
1002 return Tok.getIdentifierInfo()->getName();
1003 const char *S = tok::getKeywordSpelling(Tok.getKind());
1009 static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule) {
1010 using namespace attr;
1012 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \
1015 #include "clang/Basic/AttrSubMatchRulesList.inc"
1017 llvm_unreachable("Invalid attribute subject match rule");
1021 static void diagnoseExpectedAttributeSubjectSubRule(
1022 Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1023 SourceLocation SubRuleLoc) {
1025 PRef.Diag(SubRuleLoc,
1026 diag::err_pragma_attribute_expected_subject_sub_identifier)
1028 if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1029 Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1031 Diagnostic << /*SubRulesSupported=*/0;
1034 static void diagnoseUnknownAttributeSubjectSubRule(
1035 Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1036 StringRef SubRuleName, SourceLocation SubRuleLoc) {
1039 PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1040 << SubRuleName << PrimaryRuleName;
1041 if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1042 Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1044 Diagnostic << /*SubRulesSupported=*/0;
1047 bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1048 attr::ParsedSubjectMatchRuleSet &SubjectMatchRules, SourceLocation &AnyLoc,
1049 SourceLocation &LastMatchRuleEndLoc) {
1051 BalancedDelimiterTracker AnyParens(*this, tok::l_paren);
1052 if (getIdentifier(Tok) == "any") {
1053 AnyLoc = ConsumeToken();
1055 if (AnyParens.expectAndConsume())
1060 // Parse the subject matcher rule.
1061 StringRef Name = getIdentifier(Tok);
1063 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1066 std::pair<Optional<attr::SubjectMatchRule>,
1067 Optional<attr::SubjectMatchRule> (*)(StringRef, bool)>
1068 Rule = isAttributeSubjectMatchRule(Name);
1070 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1073 attr::SubjectMatchRule PrimaryRule = *Rule.first;
1074 SourceLocation RuleLoc = ConsumeToken();
1076 BalancedDelimiterTracker Parens(*this, tok::l_paren);
1077 if (isAbstractAttrMatcherRule(PrimaryRule)) {
1078 if (Parens.expectAndConsume())
1080 } else if (Parens.consumeOpen()) {
1081 if (!SubjectMatchRules
1083 std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
1085 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1087 << FixItHint::CreateRemoval(SourceRange(
1088 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
1089 LastMatchRuleEndLoc = RuleLoc;
1093 // Parse the sub-rules.
1094 StringRef SubRuleName = getIdentifier(Tok);
1095 if (SubRuleName.empty()) {
1096 diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1100 attr::SubjectMatchRule SubRule;
1101 if (SubRuleName == "unless") {
1102 SourceLocation SubRuleLoc = ConsumeToken();
1103 BalancedDelimiterTracker Parens(*this, tok::l_paren);
1104 if (Parens.expectAndConsume())
1106 SubRuleName = getIdentifier(Tok);
1107 if (SubRuleName.empty()) {
1108 diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1112 auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/true);
1113 if (!SubRuleOrNone) {
1114 std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")";
1115 diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1116 SubRuleUnlessName, SubRuleLoc);
1119 SubRule = *SubRuleOrNone;
1121 if (Parens.consumeClose())
1124 auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/false);
1125 if (!SubRuleOrNone) {
1126 diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1127 SubRuleName, Tok.getLocation());
1130 SubRule = *SubRuleOrNone;
1133 SourceLocation RuleEndLoc = Tok.getLocation();
1134 LastMatchRuleEndLoc = RuleEndLoc;
1135 if (Parens.consumeClose())
1137 if (!SubjectMatchRules
1138 .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
1140 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1141 << attr::getSubjectMatchRuleSpelling(SubRule)
1142 << FixItHint::CreateRemoval(SourceRange(
1143 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
1146 } while (IsAny && TryConsumeToken(tok::comma));
1149 if (AnyParens.consumeClose())
1157 /// Describes the stage at which attribute subject rule parsing was interruped.
1158 enum class MissingAttributeSubjectRulesRecoveryPoint {
1166 MissingAttributeSubjectRulesRecoveryPoint
1167 getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
1168 if (const auto *II = Tok.getIdentifierInfo()) {
1169 if (II->isStr("apply_to"))
1170 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1171 if (II->isStr("any"))
1172 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1174 if (Tok.is(tok::equal))
1175 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1176 return MissingAttributeSubjectRulesRecoveryPoint::None;
1179 /// Creates a diagnostic for the attribute subject rule parsing diagnostic that
1180 /// suggests the possible attribute subject rules in a fix-it together with
1181 /// any other missing tokens.
1182 DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
1183 unsigned DiagID, AttributeList &Attribute,
1184 MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
1185 SourceLocation Loc = PRef.getEndOfPreviousToken();
1186 if (Loc.isInvalid())
1187 Loc = PRef.getCurToken().getLocation();
1188 auto Diagnostic = PRef.Diag(Loc, DiagID);
1190 MissingAttributeSubjectRulesRecoveryPoint EndPoint =
1191 getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken());
1192 if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
1194 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1195 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1196 FixIt += "apply_to";
1197 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1198 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1200 SourceRange FixItRange(Loc);
1201 if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
1202 // Gather the subject match rules that are supported by the attribute.
1203 SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> SubjectMatchRuleSet;
1204 Attribute.getMatchRules(PRef.getLangOpts(), SubjectMatchRuleSet);
1205 if (SubjectMatchRuleSet.empty()) {
1206 // FIXME: We can emit a "fix-it" with a subject list placeholder when
1207 // placeholders will be supported by the fix-its.
1211 bool NeedsComma = false;
1212 for (const auto &I : SubjectMatchRuleSet) {
1213 // Ensure that the missing rule is reported in the fix-it only when it's
1214 // supported in the current language mode.
1221 FixIt += attr::getSubjectMatchRuleSpelling(I.first);
1224 // Check if we need to remove the range
1225 PRef.SkipUntil(tok::eof, Parser::StopBeforeMatch);
1226 FixItRange.setEnd(PRef.getCurToken().getLocation());
1228 if (FixItRange.getBegin() == FixItRange.getEnd())
1229 Diagnostic << FixItHint::CreateInsertion(FixItRange.getBegin(), FixIt);
1231 Diagnostic << FixItHint::CreateReplacement(
1232 CharSourceRange::getCharRange(FixItRange), FixIt);
1236 } // end anonymous namespace
1238 void Parser::HandlePragmaAttribute() {
1239 assert(Tok.is(tok::annot_pragma_attribute) &&
1240 "Expected #pragma attribute annotation token");
1241 SourceLocation PragmaLoc = Tok.getLocation();
1242 auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
1243 if (Info->Action == PragmaAttributeInfo::Pop) {
1244 ConsumeAnnotationToken();
1245 Actions.ActOnPragmaAttributePop(PragmaLoc);
1248 // Parse the actual attribute with its arguments.
1249 assert(Info->Action == PragmaAttributeInfo::Push &&
1250 "Unexpected #pragma attribute command");
1251 PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false);
1252 ConsumeAnnotationToken();
1254 ParsedAttributes &Attrs = Info->Attributes;
1255 Attrs.clearListOnly();
1257 auto SkipToEnd = [this]() {
1258 SkipUntil(tok::eof, StopBeforeMatch);
1262 if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
1263 // Parse the CXX11 style attribute.
1264 ParseCXX11AttributeSpecifier(Attrs);
1265 } else if (Tok.is(tok::kw___attribute)) {
1267 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1270 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "("))
1273 if (Tok.isNot(tok::identifier)) {
1274 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1278 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1279 SourceLocation AttrNameLoc = ConsumeToken();
1281 if (Tok.isNot(tok::l_paren))
1282 Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
1283 AttributeList::AS_GNU);
1285 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
1286 /*ScopeName=*/nullptr,
1287 /*ScopeLoc=*/SourceLocation(),
1288 AttributeList::AS_GNU,
1289 /*Declarator=*/nullptr);
1291 if (ExpectAndConsume(tok::r_paren))
1293 if (ExpectAndConsume(tok::r_paren))
1295 } else if (Tok.is(tok::kw___declspec)) {
1296 ParseMicrosoftDeclSpecs(Attrs);
1298 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1299 if (Tok.getIdentifierInfo()) {
1300 // If we suspect that this is an attribute suggest the use of
1302 if (AttributeList::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
1303 AttributeList::AS_GNU) !=
1304 AttributeList::UnknownAttribute) {
1305 SourceLocation InsertStartLoc = Tok.getLocation();
1307 if (Tok.is(tok::l_paren)) {
1309 SkipUntil(tok::r_paren, StopBeforeMatch);
1310 if (Tok.isNot(tok::r_paren))
1313 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1314 << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((")
1315 << FixItHint::CreateInsertion(Tok.getEndLoc(), "))");
1322 if (!Attrs.getList() || Attrs.getList()->isInvalid()) {
1327 // Ensure that we don't have more than one attribute.
1328 if (Attrs.getList()->getNext()) {
1329 SourceLocation Loc = Attrs.getList()->getNext()->getLoc();
1330 Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1335 if (!Attrs.getList()->isSupportedByPragmaAttribute()) {
1336 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1337 << Attrs.getList()->getName();
1341 AttributeList &Attribute = *Attrs.getList();
1343 // Parse the subject-list.
1344 if (!TryConsumeToken(tok::comma)) {
1345 createExpectedAttributeSubjectRulesTokenDiagnostic(
1346 diag::err_expected, Attribute,
1347 MissingAttributeSubjectRulesRecoveryPoint::Comma, *this)
1353 if (Tok.isNot(tok::identifier)) {
1354 createExpectedAttributeSubjectRulesTokenDiagnostic(
1355 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1356 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1360 const IdentifierInfo *II = Tok.getIdentifierInfo();
1361 if (!II->isStr("apply_to")) {
1362 createExpectedAttributeSubjectRulesTokenDiagnostic(
1363 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1364 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1370 if (!TryConsumeToken(tok::equal)) {
1371 createExpectedAttributeSubjectRulesTokenDiagnostic(
1372 diag::err_expected, Attribute,
1373 MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
1379 attr::ParsedSubjectMatchRuleSet SubjectMatchRules;
1380 SourceLocation AnyLoc, LastMatchRuleEndLoc;
1381 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1382 LastMatchRuleEndLoc)) {
1387 // Tokens following an ill-formed attribute will remain in the token stream
1388 // and must be removed.
1389 if (Tok.isNot(tok::eof)) {
1390 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1395 // Consume the eof terminator token.
1398 Actions.ActOnPragmaAttributePush(Attribute, PragmaLoc,
1399 std::move(SubjectMatchRules));
1402 // #pragma GCC visibility comes in two variants:
1403 // 'push' '(' [visibility] ')'
1405 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
1406 PragmaIntroducerKind Introducer,
1408 SourceLocation VisLoc = VisTok.getLocation();
1411 PP.LexUnexpandedToken(Tok);
1413 const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
1415 const IdentifierInfo *VisType;
1416 if (PushPop && PushPop->isStr("pop")) {
1418 } else if (PushPop && PushPop->isStr("push")) {
1419 PP.LexUnexpandedToken(Tok);
1420 if (Tok.isNot(tok::l_paren)) {
1421 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
1425 PP.LexUnexpandedToken(Tok);
1426 VisType = Tok.getIdentifierInfo();
1428 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1432 PP.LexUnexpandedToken(Tok);
1433 if (Tok.isNot(tok::r_paren)) {
1434 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
1439 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1443 SourceLocation EndLoc = Tok.getLocation();
1444 PP.LexUnexpandedToken(Tok);
1445 if (Tok.isNot(tok::eod)) {
1446 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1451 auto Toks = llvm::make_unique<Token[]>(1);
1452 Toks[0].startToken();
1453 Toks[0].setKind(tok::annot_pragma_vis);
1454 Toks[0].setLocation(VisLoc);
1455 Toks[0].setAnnotationEndLoc(EndLoc);
1456 Toks[0].setAnnotationValue(
1457 const_cast<void*>(static_cast<const void*>(VisType)));
1458 PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true);
1461 // #pragma pack(...) comes in the following delicious flavors:
1462 // pack '(' [integer] ')'
1463 // pack '(' 'show' ')'
1464 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
1465 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
1466 PragmaIntroducerKind Introducer,
1468 SourceLocation PackLoc = PackTok.getLocation();
1472 if (Tok.isNot(tok::l_paren)) {
1473 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
1477 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
1478 StringRef SlotLabel;
1480 Alignment.startToken();
1482 if (Tok.is(tok::numeric_constant)) {
1487 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
1488 // the push/pop stack.
1489 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
1491 PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set;
1492 } else if (Tok.is(tok::identifier)) {
1493 const IdentifierInfo *II = Tok.getIdentifierInfo();
1494 if (II->isStr("show")) {
1495 Action = Sema::PSK_Show;
1498 if (II->isStr("push")) {
1499 Action = Sema::PSK_Push;
1500 } else if (II->isStr("pop")) {
1501 Action = Sema::PSK_Pop;
1503 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
1508 if (Tok.is(tok::comma)) {
1511 if (Tok.is(tok::numeric_constant)) {
1512 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1516 } else if (Tok.is(tok::identifier)) {
1517 SlotLabel = Tok.getIdentifierInfo()->getName();
1520 if (Tok.is(tok::comma)) {
1523 if (Tok.isNot(tok::numeric_constant)) {
1524 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1528 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1534 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1539 } else if (PP.getLangOpts().ApplePragmaPack) {
1540 // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1541 // the push/pop stack.
1542 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
1543 Action = Sema::PSK_Pop;
1546 if (Tok.isNot(tok::r_paren)) {
1547 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1551 SourceLocation RParenLoc = Tok.getLocation();
1553 if (Tok.isNot(tok::eod)) {
1554 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1558 PragmaPackInfo *Info =
1559 PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1);
1560 Info->Action = Action;
1561 Info->SlotLabel = SlotLabel;
1562 Info->Alignment = Alignment;
1564 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1566 Toks[0].startToken();
1567 Toks[0].setKind(tok::annot_pragma_pack);
1568 Toks[0].setLocation(PackLoc);
1569 Toks[0].setAnnotationEndLoc(RParenLoc);
1570 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1571 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1574 // #pragma ms_struct on
1575 // #pragma ms_struct off
1576 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
1577 PragmaIntroducerKind Introducer,
1578 Token &MSStructTok) {
1579 PragmaMSStructKind Kind = PMSST_OFF;
1583 if (Tok.isNot(tok::identifier)) {
1584 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1587 SourceLocation EndLoc = Tok.getLocation();
1588 const IdentifierInfo *II = Tok.getIdentifierInfo();
1589 if (II->isStr("on")) {
1593 else if (II->isStr("off") || II->isStr("reset"))
1596 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1600 if (Tok.isNot(tok::eod)) {
1601 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1606 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1608 Toks[0].startToken();
1609 Toks[0].setKind(tok::annot_pragma_msstruct);
1610 Toks[0].setLocation(MSStructTok.getLocation());
1611 Toks[0].setAnnotationEndLoc(EndLoc);
1612 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1613 static_cast<uintptr_t>(Kind)));
1614 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1617 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
1618 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
1619 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
1625 if (Tok.isNot(tok::identifier) ||
1626 !Tok.getIdentifierInfo()->isStr("align")) {
1627 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
1633 if (Tok.isNot(tok::equal)) {
1634 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1640 if (Tok.isNot(tok::identifier)) {
1641 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1642 << (IsOptions ? "options" : "align");
1646 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
1647 const IdentifierInfo *II = Tok.getIdentifierInfo();
1648 if (II->isStr("native"))
1649 Kind = Sema::POAK_Native;
1650 else if (II->isStr("natural"))
1651 Kind = Sema::POAK_Natural;
1652 else if (II->isStr("packed"))
1653 Kind = Sema::POAK_Packed;
1654 else if (II->isStr("power"))
1655 Kind = Sema::POAK_Power;
1656 else if (II->isStr("mac68k"))
1657 Kind = Sema::POAK_Mac68k;
1658 else if (II->isStr("reset"))
1659 Kind = Sema::POAK_Reset;
1661 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1666 SourceLocation EndLoc = Tok.getLocation();
1668 if (Tok.isNot(tok::eod)) {
1669 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1670 << (IsOptions ? "options" : "align");
1674 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1676 Toks[0].startToken();
1677 Toks[0].setKind(tok::annot_pragma_align);
1678 Toks[0].setLocation(FirstTok.getLocation());
1679 Toks[0].setAnnotationEndLoc(EndLoc);
1680 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1681 static_cast<uintptr_t>(Kind)));
1682 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1685 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
1686 PragmaIntroducerKind Introducer,
1688 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1691 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
1692 PragmaIntroducerKind Introducer,
1693 Token &OptionsTok) {
1694 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1697 // #pragma unused(identifier)
1698 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
1699 PragmaIntroducerKind Introducer,
1701 // FIXME: Should we be expanding macros here? My guess is no.
1702 SourceLocation UnusedLoc = UnusedTok.getLocation();
1704 // Lex the left '('.
1707 if (Tok.isNot(tok::l_paren)) {
1708 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1712 // Lex the declaration reference(s).
1713 SmallVector<Token, 5> Identifiers;
1714 SourceLocation RParenLoc;
1721 if (Tok.is(tok::identifier)) {
1722 Identifiers.push_back(Tok);
1728 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1732 // We are execting a ')' or a ','.
1733 if (Tok.is(tok::comma)) {
1738 if (Tok.is(tok::r_paren)) {
1739 RParenLoc = Tok.getLocation();
1744 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1749 if (Tok.isNot(tok::eod)) {
1750 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1755 // Verify that we have a location for the right parenthesis.
1756 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
1757 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
1759 // For each identifier token, insert into the token stream a
1760 // annot_pragma_unused token followed by the identifier token.
1761 // This allows us to cache a "#pragma unused" that occurs inside an inline
1762 // C++ member function.
1764 MutableArrayRef<Token> Toks(
1765 PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()),
1766 2 * Identifiers.size());
1767 for (unsigned i=0; i != Identifiers.size(); i++) {
1768 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1769 pragmaUnusedTok.startToken();
1770 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1771 pragmaUnusedTok.setLocation(UnusedLoc);
1772 idTok = Identifiers[i];
1774 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1777 // #pragma weak identifier
1778 // #pragma weak identifier '=' identifier
1779 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
1780 PragmaIntroducerKind Introducer,
1782 SourceLocation WeakLoc = WeakTok.getLocation();
1786 if (Tok.isNot(tok::identifier)) {
1787 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
1791 Token WeakName = Tok;
1792 bool HasAlias = false;
1796 if (Tok.is(tok::equal)) {
1799 if (Tok.isNot(tok::identifier)) {
1800 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1808 if (Tok.isNot(tok::eod)) {
1809 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
1814 MutableArrayRef<Token> Toks(
1815 PP.getPreprocessorAllocator().Allocate<Token>(3), 3);
1816 Token &pragmaUnusedTok = Toks[0];
1817 pragmaUnusedTok.startToken();
1818 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
1819 pragmaUnusedTok.setLocation(WeakLoc);
1820 pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
1822 Toks[2] = AliasName;
1823 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1825 MutableArrayRef<Token> Toks(
1826 PP.getPreprocessorAllocator().Allocate<Token>(2), 2);
1827 Token &pragmaUnusedTok = Toks[0];
1828 pragmaUnusedTok.startToken();
1829 pragmaUnusedTok.setKind(tok::annot_pragma_weak);
1830 pragmaUnusedTok.setLocation(WeakLoc);
1831 pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
1833 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1837 // #pragma redefine_extname identifier identifier
1838 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
1839 PragmaIntroducerKind Introducer,
1840 Token &RedefToken) {
1841 SourceLocation RedefLoc = RedefToken.getLocation();
1845 if (Tok.isNot(tok::identifier)) {
1846 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1851 Token RedefName = Tok;
1854 if (Tok.isNot(tok::identifier)) {
1855 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1856 << "redefine_extname";
1860 Token AliasName = Tok;
1863 if (Tok.isNot(tok::eod)) {
1864 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1869 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3),
1871 Token &pragmaRedefTok = Toks[0];
1872 pragmaRedefTok.startToken();
1873 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
1874 pragmaRedefTok.setLocation(RedefLoc);
1875 pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
1876 Toks[1] = RedefName;
1877 Toks[2] = AliasName;
1878 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1883 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
1884 PragmaIntroducerKind Introducer,
1886 tok::OnOffSwitch OOS;
1887 if (PP.LexOnOffSwitch(OOS))
1890 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1892 Toks[0].startToken();
1893 Toks[0].setKind(tok::annot_pragma_fp_contract);
1894 Toks[0].setLocation(Tok.getLocation());
1895 Toks[0].setAnnotationEndLoc(Tok.getLocation());
1896 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1897 static_cast<uintptr_t>(OOS)));
1898 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1902 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
1903 PragmaIntroducerKind Introducer,
1905 PP.LexUnexpandedToken(Tok);
1906 if (Tok.isNot(tok::identifier)) {
1907 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1911 IdentifierInfo *Ext = Tok.getIdentifierInfo();
1912 SourceLocation NameLoc = Tok.getLocation();
1915 if (Tok.isNot(tok::colon)) {
1916 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
1921 if (Tok.isNot(tok::identifier)) {
1922 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
1925 IdentifierInfo *Pred = Tok.getIdentifierInfo();
1927 OpenCLExtState State;
1928 if (Pred->isStr("enable")) {
1930 } else if (Pred->isStr("disable")) {
1932 } else if (Pred->isStr("begin"))
1934 else if (Pred->isStr("end"))
1937 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
1938 << Ext->isStr("all");
1941 SourceLocation StateLoc = Tok.getLocation();
1944 if (Tok.isNot(tok::eod)) {
1945 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1950 auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
1952 Info->second = State;
1953 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1955 Toks[0].startToken();
1956 Toks[0].setKind(tok::annot_pragma_opencl_extension);
1957 Toks[0].setLocation(NameLoc);
1958 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1959 Toks[0].setAnnotationEndLoc(StateLoc);
1960 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1962 if (PP.getPPCallbacks())
1963 PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext,
1967 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
1970 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
1971 PragmaIntroducerKind Introducer,
1973 if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
1974 FirstTok.getLocation())) {
1975 PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
1976 PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
1977 diag::Severity::Ignored, SourceLocation());
1979 PP.DiscardUntilEndOfDirective();
1982 /// \brief Handle '#pragma omp ...' when OpenMP is enabled.
1985 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
1986 PragmaIntroducerKind Introducer,
1988 SmallVector<Token, 16> Pragma;
1991 Tok.setKind(tok::annot_pragma_openmp);
1992 Tok.setLocation(FirstTok.getLocation());
1994 while (Tok.isNot(tok::eod)) {
1995 Pragma.push_back(Tok);
1998 SourceLocation EodLoc = Tok.getLocation();
2000 Tok.setKind(tok::annot_pragma_openmp_end);
2001 Tok.setLocation(EodLoc);
2002 Pragma.push_back(Tok);
2004 auto Toks = llvm::make_unique<Token[]>(Pragma.size());
2005 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2006 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2007 /*DisableMacroExpansion=*/false);
2010 /// \brief Handle '#pragma pointers_to_members'
2011 // The grammar for this pragma is as follows:
2013 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
2015 // #pragma pointers_to_members '(' 'best_case' ')'
2016 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
2017 // #pragma pointers_to_members '(' inheritance-model ')'
2018 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
2019 PragmaIntroducerKind Introducer,
2021 SourceLocation PointersToMembersLoc = Tok.getLocation();
2023 if (Tok.isNot(tok::l_paren)) {
2024 PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2025 << "pointers_to_members";
2029 const IdentifierInfo *Arg = Tok.getIdentifierInfo();
2031 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2032 << "pointers_to_members";
2037 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
2038 if (Arg->isStr("best_case")) {
2039 RepresentationMethod = LangOptions::PPTMK_BestCase;
2041 if (Arg->isStr("full_generality")) {
2042 if (Tok.is(tok::comma)) {
2045 Arg = Tok.getIdentifierInfo();
2047 PP.Diag(Tok.getLocation(),
2048 diag::err_pragma_pointers_to_members_unknown_kind)
2049 << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
2053 } else if (Tok.is(tok::r_paren)) {
2054 // #pragma pointers_to_members(full_generality) implicitly specifies
2055 // virtual_inheritance.
2057 RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
2059 PP.Diag(Tok.getLocation(), diag::err_expected_punc)
2060 << "full_generality";
2066 if (Arg->isStr("single_inheritance")) {
2067 RepresentationMethod =
2068 LangOptions::PPTMK_FullGeneralitySingleInheritance;
2069 } else if (Arg->isStr("multiple_inheritance")) {
2070 RepresentationMethod =
2071 LangOptions::PPTMK_FullGeneralityMultipleInheritance;
2072 } else if (Arg->isStr("virtual_inheritance")) {
2073 RepresentationMethod =
2074 LangOptions::PPTMK_FullGeneralityVirtualInheritance;
2076 PP.Diag(Tok.getLocation(),
2077 diag::err_pragma_pointers_to_members_unknown_kind)
2078 << Arg << /*HasPointerDeclaration*/ 1;
2084 if (Tok.isNot(tok::r_paren)) {
2085 PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
2086 << (Arg ? Arg->getName() : "full_generality");
2090 SourceLocation EndLoc = Tok.getLocation();
2092 if (Tok.isNot(tok::eod)) {
2093 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2094 << "pointers_to_members";
2099 AnnotTok.startToken();
2100 AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
2101 AnnotTok.setLocation(PointersToMembersLoc);
2102 AnnotTok.setAnnotationEndLoc(EndLoc);
2103 AnnotTok.setAnnotationValue(
2104 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2105 PP.EnterToken(AnnotTok);
2108 /// \brief Handle '#pragma vtordisp'
2109 // The grammar for this pragma is as follows:
2111 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
2113 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
2114 // #pragma vtordisp '(' 'pop' ')'
2115 // #pragma vtordisp '(' ')'
2116 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
2117 PragmaIntroducerKind Introducer,
2119 SourceLocation VtorDispLoc = Tok.getLocation();
2121 if (Tok.isNot(tok::l_paren)) {
2122 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
2127 Sema::PragmaMsStackAction Action = Sema::PSK_Set;
2128 const IdentifierInfo *II = Tok.getIdentifierInfo();
2130 if (II->isStr("push")) {
2131 // #pragma vtordisp(push, mode)
2133 if (Tok.isNot(tok::comma)) {
2134 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
2138 Action = Sema::PSK_Push_Set;
2139 // not push, could be on/off
2140 } else if (II->isStr("pop")) {
2141 // #pragma vtordisp(pop)
2143 Action = Sema::PSK_Pop;
2145 // not push or pop, could be on/off
2147 if (Tok.is(tok::r_paren)) {
2148 // #pragma vtordisp()
2149 Action = Sema::PSK_Reset;
2155 if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
2156 const IdentifierInfo *II = Tok.getIdentifierInfo();
2157 if (II && II->isStr("off")) {
2160 } else if (II && II->isStr("on")) {
2163 } else if (Tok.is(tok::numeric_constant) &&
2164 PP.parseSimpleIntegerLiteral(Tok, Value)) {
2166 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
2167 << 0 << 2 << "vtordisp";
2171 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
2177 // Finish the pragma: ')' $
2178 if (Tok.isNot(tok::r_paren)) {
2179 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
2182 SourceLocation EndLoc = Tok.getLocation();
2184 if (Tok.isNot(tok::eod)) {
2185 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2190 // Enter the annotation.
2192 AnnotTok.startToken();
2193 AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
2194 AnnotTok.setLocation(VtorDispLoc);
2195 AnnotTok.setAnnotationEndLoc(EndLoc);
2196 AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
2197 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2198 PP.EnterToken(AnnotTok);
2201 /// \brief Handle all MS pragmas. Simply forwards the tokens after inserting
2202 /// an annotation token.
2203 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
2204 PragmaIntroducerKind Introducer,
2206 Token EoF, AnnotTok;
2208 EoF.setKind(tok::eof);
2209 AnnotTok.startToken();
2210 AnnotTok.setKind(tok::annot_pragma_ms_pragma);
2211 AnnotTok.setLocation(Tok.getLocation());
2212 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2213 SmallVector<Token, 8> TokenVector;
2214 // Suck up all of the tokens before the eod.
2215 for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
2216 TokenVector.push_back(Tok);
2217 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2219 // Add a sentinal EoF token to the end of the list.
2220 TokenVector.push_back(EoF);
2221 // We must allocate this array with new because EnterTokenStream is going to
2223 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
2224 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2225 auto Value = new (PP.getPreprocessorAllocator())
2226 std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
2227 TokenVector.size());
2228 AnnotTok.setAnnotationValue(Value);
2229 PP.EnterToken(AnnotTok);
2232 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
2236 /// #pragma detect_mismatch("name", "value")
2238 /// Where 'name' and 'value' are quoted strings. The values are embedded in
2239 /// the object file and passed along to the linker. If the linker detects a
2240 /// mismatch in the object file's values for the given name, a LNK2038 error
2241 /// is emitted. See MSDN for more details.
2242 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
2243 PragmaIntroducerKind Introducer,
2245 SourceLocation DetectMismatchLoc = Tok.getLocation();
2247 if (Tok.isNot(tok::l_paren)) {
2248 PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2252 // Read the name to embed, which must be a string literal.
2253 std::string NameString;
2254 if (!PP.LexStringLiteral(Tok, NameString,
2255 "pragma detect_mismatch",
2256 /*MacroExpansion=*/true))
2259 // Read the comma followed by a second string literal.
2260 std::string ValueString;
2261 if (Tok.isNot(tok::comma)) {
2262 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2266 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
2267 /*MacroExpansion=*/true))
2270 if (Tok.isNot(tok::r_paren)) {
2271 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2274 PP.Lex(Tok); // Eat the r_paren.
2276 if (Tok.isNot(tok::eod)) {
2277 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2281 // If the pragma is lexically sound, notify any interested PPCallbacks.
2282 if (PP.getPPCallbacks())
2283 PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString,
2286 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2289 /// \brief Handle the microsoft \#pragma comment extension.
2293 /// #pragma comment(linker, "foo")
2295 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
2296 /// "foo" is a string, which is fully macro expanded, and permits string
2297 /// concatenation, embedded escape characters etc. See MSDN for more details.
2298 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
2299 PragmaIntroducerKind Introducer,
2301 SourceLocation CommentLoc = Tok.getLocation();
2303 if (Tok.isNot(tok::l_paren)) {
2304 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2308 // Read the identifier.
2310 if (Tok.isNot(tok::identifier)) {
2311 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2315 // Verify that this is one of the 5 whitelisted options.
2316 IdentifierInfo *II = Tok.getIdentifierInfo();
2317 PragmaMSCommentKind Kind =
2318 llvm::StringSwitch<PragmaMSCommentKind>(II->getName())
2319 .Case("linker", PCK_Linker)
2320 .Case("lib", PCK_Lib)
2321 .Case("compiler", PCK_Compiler)
2322 .Case("exestr", PCK_ExeStr)
2323 .Case("user", PCK_User)
2324 .Default(PCK_Unknown);
2325 if (Kind == PCK_Unknown) {
2326 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
2330 // On PS4, issue a warning about any pragma comments other than
2331 // #pragma comment lib.
2332 if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
2333 PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2338 // Read the optional string if present.
2340 std::string ArgumentString;
2341 if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
2343 /*MacroExpansion=*/true))
2346 // FIXME: warn that 'exestr' is deprecated.
2347 // FIXME: If the kind is "compiler" warn if the string is present (it is
2349 // The MSDN docs say that "lib" and "linker" require a string and have a short
2350 // whitelist of linker options they support, but in practice MSVC doesn't
2351 // issue a diagnostic. Therefore neither does clang.
2353 if (Tok.isNot(tok::r_paren)) {
2354 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2357 PP.Lex(Tok); // eat the r_paren.
2359 if (Tok.isNot(tok::eod)) {
2360 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2364 // If the pragma is lexically sound, notify any interested PPCallbacks.
2365 if (PP.getPPCallbacks())
2366 PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
2368 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2371 // #pragma clang optimize off
2372 // #pragma clang optimize on
2373 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
2374 PragmaIntroducerKind Introducer,
2375 Token &FirstToken) {
2378 if (Tok.is(tok::eod)) {
2379 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
2380 << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
2383 if (Tok.isNot(tok::identifier)) {
2384 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2385 << PP.getSpelling(Tok);
2388 const IdentifierInfo *II = Tok.getIdentifierInfo();
2389 // The only accepted values are 'on' or 'off'.
2391 if (II->isStr("on")) {
2393 } else if (!II->isStr("off")) {
2394 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2395 << PP.getSpelling(Tok);
2400 if (Tok.isNot(tok::eod)) {
2401 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
2402 << PP.getSpelling(Tok);
2406 Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
2410 /// Used as the annotation value for tok::annot_pragma_fp.
2411 struct TokFPAnnotValue {
2412 enum FlagKinds { Contract };
2413 enum FlagValues { On, Off, Fast };
2416 FlagValues FlagValue;
2418 } // end anonymous namespace
2420 void PragmaFPHandler::HandlePragma(Preprocessor &PP,
2421 PragmaIntroducerKind Introducer,
2424 Token PragmaName = Tok;
2425 SmallVector<Token, 1> TokenList;
2428 if (Tok.isNot(tok::identifier)) {
2429 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2430 << /*MissingOption=*/true << "";
2434 while (Tok.is(tok::identifier)) {
2435 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2438 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2439 OptionInfo->getName())
2440 .Case("contract", TokFPAnnotValue::Contract)
2443 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2444 << /*MissingOption=*/false << OptionInfo;
2450 if (Tok.isNot(tok::l_paren)) {
2451 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2456 if (Tok.isNot(tok::identifier)) {
2457 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2458 << PP.getSpelling(Tok) << OptionInfo->getName();
2461 const IdentifierInfo *II = Tok.getIdentifierInfo();
2464 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2466 .Case("on", TokFPAnnotValue::On)
2467 .Case("off", TokFPAnnotValue::Off)
2468 .Case("fast", TokFPAnnotValue::Fast)
2469 .Default(llvm::None);
2472 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2473 << PP.getSpelling(Tok) << OptionInfo->getName();
2479 if (Tok.isNot(tok::r_paren)) {
2480 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2485 auto *AnnotValue = new (PP.getPreprocessorAllocator())
2486 TokFPAnnotValue{*FlagKind, *FlagValue};
2487 // Generate the loop hint token.
2490 FPTok.setKind(tok::annot_pragma_fp);
2491 FPTok.setLocation(PragmaName.getLocation());
2492 FPTok.setAnnotationEndLoc(PragmaName.getLocation());
2493 FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue));
2494 TokenList.push_back(FPTok);
2497 if (Tok.isNot(tok::eod)) {
2498 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2503 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2504 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2506 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2507 /*DisableMacroExpansion=*/false);
2510 void Parser::HandlePragmaFP() {
2511 assert(Tok.is(tok::annot_pragma_fp));
2513 reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
2515 LangOptions::FPContractModeKind FPC;
2516 switch (AnnotValue->FlagValue) {
2517 case TokFPAnnotValue::On:
2518 FPC = LangOptions::FPC_On;
2520 case TokFPAnnotValue::Fast:
2521 FPC = LangOptions::FPC_Fast;
2523 case TokFPAnnotValue::Off:
2524 FPC = LangOptions::FPC_Off;
2528 Actions.ActOnPragmaFPContract(FPC);
2529 ConsumeAnnotationToken();
2532 /// \brief Parses loop or unroll pragma hint value and fills in Info.
2533 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
2534 Token Option, bool ValueInParens,
2535 PragmaLoopHintInfo &Info) {
2536 SmallVector<Token, 1> ValueList;
2537 int OpenParens = ValueInParens ? 1 : 0;
2538 // Read constant expression.
2539 while (Tok.isNot(tok::eod)) {
2540 if (Tok.is(tok::l_paren))
2542 else if (Tok.is(tok::r_paren)) {
2544 if (OpenParens == 0 && ValueInParens)
2548 ValueList.push_back(Tok);
2552 if (ValueInParens) {
2554 if (Tok.isNot(tok::r_paren)) {
2555 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2562 EOFTok.startToken();
2563 EOFTok.setKind(tok::eof);
2564 EOFTok.setLocation(Tok.getLocation());
2565 ValueList.push_back(EOFTok); // Terminates expression for parsing.
2567 Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
2569 Info.PragmaName = PragmaName;
2570 Info.Option = Option;
2574 /// \brief Handle the \#pragma clang loop directive.
2575 /// #pragma clang 'loop' loop-hints
2578 /// loop-hint loop-hints[opt]
2581 /// 'vectorize' '(' loop-hint-keyword ')'
2582 /// 'interleave' '(' loop-hint-keyword ')'
2583 /// 'unroll' '(' unroll-hint-keyword ')'
2584 /// 'vectorize_width' '(' loop-hint-value ')'
2585 /// 'interleave_count' '(' loop-hint-value ')'
2586 /// 'unroll_count' '(' loop-hint-value ')'
2588 /// loop-hint-keyword:
2593 /// unroll-hint-keyword:
2598 /// loop-hint-value:
2599 /// constant-expression
2601 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
2602 /// try vectorizing the instructions of the loop it precedes. Specifying
2603 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
2604 /// interleaving multiple iterations of the loop it precedes. The width of the
2605 /// vector instructions is specified by vectorize_width() and the number of
2606 /// interleaved loop iterations is specified by interleave_count(). Specifying a
2607 /// value of 1 effectively disables vectorization/interleaving, even if it is
2608 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
2609 /// only works on inner loops.
2611 /// The unroll and unroll_count directives control the concatenation
2612 /// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
2613 /// completely if the trip count is known at compile time and unroll partially
2614 /// if the trip count is not known. Specifying unroll(full) is similar to
2615 /// unroll(enable) but will unroll the loop only if the trip count is known at
2616 /// compile time. Specifying unroll(disable) disables unrolling for the
2617 /// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
2618 /// loop the number of times indicated by the value.
2619 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
2620 PragmaIntroducerKind Introducer,
2622 // Incoming token is "loop" from "#pragma clang loop".
2623 Token PragmaName = Tok;
2624 SmallVector<Token, 1> TokenList;
2626 // Lex the optimization option and verify it is an identifier.
2628 if (Tok.isNot(tok::identifier)) {
2629 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2630 << /*MissingOption=*/true << "";
2634 while (Tok.is(tok::identifier)) {
2636 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2638 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
2639 .Case("vectorize", true)
2640 .Case("interleave", true)
2641 .Case("unroll", true)
2642 .Case("distribute", true)
2643 .Case("vectorize_width", true)
2644 .Case("interleave_count", true)
2645 .Case("unroll_count", true)
2648 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2649 << /*MissingOption=*/false << OptionInfo;
2655 if (Tok.isNot(tok::l_paren)) {
2656 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2661 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2662 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
2666 // Generate the loop hint token.
2668 LoopHintTok.startToken();
2669 LoopHintTok.setKind(tok::annot_pragma_loop_hint);
2670 LoopHintTok.setLocation(PragmaName.getLocation());
2671 LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
2672 LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
2673 TokenList.push_back(LoopHintTok);
2676 if (Tok.isNot(tok::eod)) {
2677 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2682 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2683 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2685 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2686 /*DisableMacroExpansion=*/false);
2689 /// \brief Handle the loop unroll optimization pragmas.
2691 /// #pragma unroll unroll-hint-value
2692 /// #pragma unroll '(' unroll-hint-value ')'
2693 /// #pragma nounroll
2695 /// unroll-hint-value:
2696 /// constant-expression
2698 /// Loop unrolling hints can be specified with '#pragma unroll' or
2699 /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
2700 /// contained in parentheses. With no argument the directive instructs llvm to
2701 /// try to unroll the loop completely. A positive integer argument can be
2702 /// specified to indicate the number of times the loop should be unrolled. To
2703 /// maximize compatibility with other compilers the unroll count argument can be
2704 /// specified with or without parentheses. Specifying, '#pragma nounroll'
2705 /// disables unrolling of the loop.
2706 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
2707 PragmaIntroducerKind Introducer,
2709 // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
2710 // "#pragma nounroll".
2711 Token PragmaName = Tok;
2713 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2714 if (Tok.is(tok::eod)) {
2715 // nounroll or unroll pragma without an argument.
2716 Info->PragmaName = PragmaName;
2717 Info->Option.startToken();
2718 } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") {
2719 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2723 // Unroll pragma with an argument: "#pragma unroll N" or
2724 // "#pragma unroll(N)".
2725 // Read '(' if it exists.
2726 bool ValueInParens = Tok.is(tok::l_paren);
2731 Option.startToken();
2732 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
2735 // In CUDA, the argument to '#pragma unroll' should not be contained in
2737 if (PP.getLangOpts().CUDA && ValueInParens)
2738 PP.Diag(Info->Toks[0].getLocation(),
2739 diag::warn_pragma_unroll_cuda_value_in_parens);
2741 if (Tok.isNot(tok::eod)) {
2742 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2748 // Generate the hint token.
2749 auto TokenArray = llvm::make_unique<Token[]>(1);
2750 TokenArray[0].startToken();
2751 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2752 TokenArray[0].setLocation(PragmaName.getLocation());
2753 TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
2754 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2755 PP.EnterTokenStream(std::move(TokenArray), 1,
2756 /*DisableMacroExpansion=*/false);
2759 /// \brief Handle the Microsoft \#pragma intrinsic extension.
2763 /// #pragma intrinsic(memset)
2764 /// #pragma intrinsic(strlen, memcpy)
2767 /// Pragma intrisic tells the compiler to use a builtin version of the
2768 /// function. Clang does it anyway, so the pragma doesn't really do anything.
2769 /// Anyway, we emit a warning if the function specified in \#pragma intrinsic
2770 /// isn't an intrinsic in clang and suggest to include intrin.h.
2771 void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
2772 PragmaIntroducerKind Introducer,
2776 if (Tok.isNot(tok::l_paren)) {
2777 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
2783 bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
2785 while (Tok.is(tok::identifier)) {
2786 IdentifierInfo *II = Tok.getIdentifierInfo();
2787 if (!II->getBuiltinID())
2788 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
2789 << II << SuggestIntrinH;
2792 if (Tok.isNot(tok::comma))
2797 if (Tok.isNot(tok::r_paren)) {
2798 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
2804 if (Tok.isNot(tok::eod))
2805 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2808 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
2809 Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) {
2810 Token FirstTok = Tok;
2813 IdentifierInfo *Info = Tok.getIdentifierInfo();
2814 if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) {
2815 PP.Diag(FirstTok.getLocation(),
2816 diag::warn_pragma_force_cuda_host_device_bad_arg);
2820 if (Info->isStr("begin"))
2821 Actions.PushForceCUDAHostDevice();
2822 else if (!Actions.PopForceCUDAHostDevice())
2823 PP.Diag(FirstTok.getLocation(),
2824 diag::err_pragma_cannot_end_force_cuda_host_device);
2827 if (!Tok.is(tok::eod))
2828 PP.Diag(FirstTok.getLocation(),
2829 diag::warn_pragma_force_cuda_host_device_bad_arg);
2832 /// \brief Handle the #pragma clang attribute directive.
2836 /// #pragma clang attribute push(attribute, subject-set)
2837 /// #pragma clang attribute pop
2840 /// The subject-set clause defines the set of declarations which receive the
2841 /// attribute. Its exact syntax is described in the LanguageExtensions document
2842 /// in Clang's documentation.
2844 /// This directive instructs the compiler to begin/finish applying the specified
2845 /// attribute to the set of attribute-specific declarations in the active range
2847 void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
2848 PragmaIntroducerKind Introducer,
2849 Token &FirstToken) {
2852 auto *Info = new (PP.getPreprocessorAllocator())
2853 PragmaAttributeInfo(AttributesForPragmaAttribute);
2855 // Parse the 'push' or 'pop'.
2856 if (Tok.isNot(tok::identifier)) {
2857 PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_push_pop);
2860 const auto *II = Tok.getIdentifierInfo();
2861 if (II->isStr("push"))
2862 Info->Action = PragmaAttributeInfo::Push;
2863 else if (II->isStr("pop"))
2864 Info->Action = PragmaAttributeInfo::Pop;
2866 PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
2867 << PP.getSpelling(Tok);
2872 // Parse the actual attribute.
2873 if (Info->Action == PragmaAttributeInfo::Push) {
2874 if (Tok.isNot(tok::l_paren)) {
2875 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2880 // Lex the attribute tokens.
2881 SmallVector<Token, 16> AttributeTokens;
2883 while (Tok.isNot(tok::eod)) {
2884 if (Tok.is(tok::l_paren))
2886 else if (Tok.is(tok::r_paren)) {
2888 if (OpenParens == 0)
2892 AttributeTokens.push_back(Tok);
2896 if (AttributeTokens.empty()) {
2897 PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
2900 if (Tok.isNot(tok::r_paren)) {
2901 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2904 SourceLocation EndLoc = Tok.getLocation();
2907 // Terminate the attribute for parsing.
2909 EOFTok.startToken();
2910 EOFTok.setKind(tok::eof);
2911 EOFTok.setLocation(EndLoc);
2912 AttributeTokens.push_back(EOFTok);
2915 llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator());
2918 if (Tok.isNot(tok::eod))
2919 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2920 << "clang attribute";
2922 // Generate the annotated pragma token.
2923 auto TokenArray = llvm::make_unique<Token[]>(1);
2924 TokenArray[0].startToken();
2925 TokenArray[0].setKind(tok::annot_pragma_attribute);
2926 TokenArray[0].setLocation(FirstToken.getLocation());
2927 TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
2928 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2929 PP.EnterTokenStream(std::move(TokenArray), 1,
2930 /*DisableMacroExpansion=*/false);