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 "RAIIObjectsForParser.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/Basic/PragmaKinds.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "clang/Lex/Preprocessor.h"
19 #include "clang/Parse/ParseDiagnostic.h"
20 #include "clang/Parse/Parser.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 PragmaNoOpenMPHandler : public PragmaHandler {
90 PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
91 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
92 Token &FirstToken) override;
95 struct PragmaOpenMPHandler : public PragmaHandler {
96 PragmaOpenMPHandler() : PragmaHandler("omp") { }
97 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
98 Token &FirstToken) override;
101 /// PragmaCommentHandler - "\#pragma comment ...".
102 struct PragmaCommentHandler : public PragmaHandler {
103 PragmaCommentHandler(Sema &Actions)
104 : PragmaHandler("comment"), Actions(Actions) {}
105 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
106 Token &FirstToken) override;
111 struct PragmaDetectMismatchHandler : public PragmaHandler {
112 PragmaDetectMismatchHandler(Sema &Actions)
113 : PragmaHandler("detect_mismatch"), Actions(Actions) {}
114 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
115 Token &FirstToken) override;
120 struct PragmaMSPointersToMembers : public PragmaHandler {
121 explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
122 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
123 Token &FirstToken) override;
126 struct PragmaMSVtorDisp : public PragmaHandler {
127 explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
128 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
129 Token &FirstToken) override;
132 struct PragmaMSPragma : public PragmaHandler {
133 explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
134 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
135 Token &FirstToken) override;
138 /// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
139 struct PragmaOptimizeHandler : public PragmaHandler {
140 PragmaOptimizeHandler(Sema &S)
141 : PragmaHandler("optimize"), Actions(S) {}
142 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
143 Token &FirstToken) override;
148 struct PragmaLoopHintHandler : public PragmaHandler {
149 PragmaLoopHintHandler() : PragmaHandler("loop") {}
150 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
151 Token &FirstToken) override;
154 struct PragmaUnrollHintHandler : public PragmaHandler {
155 PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
156 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
157 Token &FirstToken) override;
160 struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
161 PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
164 struct PragmaMSIntrinsicHandler : public PragmaHandler {
165 PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {}
166 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
167 Token &FirstToken) override;
170 struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler {
171 PragmaForceCUDAHostDeviceHandler(Sema &Actions)
172 : PragmaHandler("force_cuda_host_device"), Actions(Actions) {}
173 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
174 Token &FirstToken) override;
182 void Parser::initializePragmaHandlers() {
183 AlignHandler.reset(new PragmaAlignHandler());
184 PP.AddPragmaHandler(AlignHandler.get());
186 GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
187 PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
189 OptionsHandler.reset(new PragmaOptionsHandler());
190 PP.AddPragmaHandler(OptionsHandler.get());
192 PackHandler.reset(new PragmaPackHandler());
193 PP.AddPragmaHandler(PackHandler.get());
195 MSStructHandler.reset(new PragmaMSStructHandler());
196 PP.AddPragmaHandler(MSStructHandler.get());
198 UnusedHandler.reset(new PragmaUnusedHandler());
199 PP.AddPragmaHandler(UnusedHandler.get());
201 WeakHandler.reset(new PragmaWeakHandler());
202 PP.AddPragmaHandler(WeakHandler.get());
204 RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
205 PP.AddPragmaHandler(RedefineExtnameHandler.get());
207 FPContractHandler.reset(new PragmaFPContractHandler());
208 PP.AddPragmaHandler("STDC", FPContractHandler.get());
210 if (getLangOpts().OpenCL) {
211 OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
212 PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
214 PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
216 if (getLangOpts().OpenMP)
217 OpenMPHandler.reset(new PragmaOpenMPHandler());
219 OpenMPHandler.reset(new PragmaNoOpenMPHandler());
220 PP.AddPragmaHandler(OpenMPHandler.get());
222 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
223 MSCommentHandler.reset(new PragmaCommentHandler(Actions));
224 PP.AddPragmaHandler(MSCommentHandler.get());
227 if (getLangOpts().MicrosoftExt) {
228 MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions));
229 PP.AddPragmaHandler(MSDetectMismatchHandler.get());
230 MSPointersToMembers.reset(new PragmaMSPointersToMembers());
231 PP.AddPragmaHandler(MSPointersToMembers.get());
232 MSVtorDisp.reset(new PragmaMSVtorDisp());
233 PP.AddPragmaHandler(MSVtorDisp.get());
234 MSInitSeg.reset(new PragmaMSPragma("init_seg"));
235 PP.AddPragmaHandler(MSInitSeg.get());
236 MSDataSeg.reset(new PragmaMSPragma("data_seg"));
237 PP.AddPragmaHandler(MSDataSeg.get());
238 MSBSSSeg.reset(new PragmaMSPragma("bss_seg"));
239 PP.AddPragmaHandler(MSBSSSeg.get());
240 MSConstSeg.reset(new PragmaMSPragma("const_seg"));
241 PP.AddPragmaHandler(MSConstSeg.get());
242 MSCodeSeg.reset(new PragmaMSPragma("code_seg"));
243 PP.AddPragmaHandler(MSCodeSeg.get());
244 MSSection.reset(new PragmaMSPragma("section"));
245 PP.AddPragmaHandler(MSSection.get());
246 MSRuntimeChecks.reset(new PragmaMSRuntimeChecksHandler());
247 PP.AddPragmaHandler(MSRuntimeChecks.get());
248 MSIntrinsic.reset(new PragmaMSIntrinsicHandler());
249 PP.AddPragmaHandler(MSIntrinsic.get());
252 if (getLangOpts().CUDA) {
253 CUDAForceHostDeviceHandler.reset(
254 new PragmaForceCUDAHostDeviceHandler(Actions));
255 PP.AddPragmaHandler("clang", CUDAForceHostDeviceHandler.get());
258 OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
259 PP.AddPragmaHandler("clang", OptimizeHandler.get());
261 LoopHintHandler.reset(new PragmaLoopHintHandler());
262 PP.AddPragmaHandler("clang", LoopHintHandler.get());
264 UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll"));
265 PP.AddPragmaHandler(UnrollHintHandler.get());
267 NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll"));
268 PP.AddPragmaHandler(NoUnrollHintHandler.get());
271 void Parser::resetPragmaHandlers() {
272 // Remove the pragma handlers we installed.
273 PP.RemovePragmaHandler(AlignHandler.get());
274 AlignHandler.reset();
275 PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
276 GCCVisibilityHandler.reset();
277 PP.RemovePragmaHandler(OptionsHandler.get());
278 OptionsHandler.reset();
279 PP.RemovePragmaHandler(PackHandler.get());
281 PP.RemovePragmaHandler(MSStructHandler.get());
282 MSStructHandler.reset();
283 PP.RemovePragmaHandler(UnusedHandler.get());
284 UnusedHandler.reset();
285 PP.RemovePragmaHandler(WeakHandler.get());
287 PP.RemovePragmaHandler(RedefineExtnameHandler.get());
288 RedefineExtnameHandler.reset();
290 if (getLangOpts().OpenCL) {
291 PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
292 OpenCLExtensionHandler.reset();
293 PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
295 PP.RemovePragmaHandler(OpenMPHandler.get());
296 OpenMPHandler.reset();
298 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
299 PP.RemovePragmaHandler(MSCommentHandler.get());
300 MSCommentHandler.reset();
303 if (getLangOpts().MicrosoftExt) {
304 PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
305 MSDetectMismatchHandler.reset();
306 PP.RemovePragmaHandler(MSPointersToMembers.get());
307 MSPointersToMembers.reset();
308 PP.RemovePragmaHandler(MSVtorDisp.get());
310 PP.RemovePragmaHandler(MSInitSeg.get());
312 PP.RemovePragmaHandler(MSDataSeg.get());
314 PP.RemovePragmaHandler(MSBSSSeg.get());
316 PP.RemovePragmaHandler(MSConstSeg.get());
318 PP.RemovePragmaHandler(MSCodeSeg.get());
320 PP.RemovePragmaHandler(MSSection.get());
322 PP.RemovePragmaHandler(MSRuntimeChecks.get());
323 MSRuntimeChecks.reset();
324 PP.RemovePragmaHandler(MSIntrinsic.get());
328 if (getLangOpts().CUDA) {
329 PP.RemovePragmaHandler("clang", CUDAForceHostDeviceHandler.get());
330 CUDAForceHostDeviceHandler.reset();
333 PP.RemovePragmaHandler("STDC", FPContractHandler.get());
334 FPContractHandler.reset();
336 PP.RemovePragmaHandler("clang", OptimizeHandler.get());
337 OptimizeHandler.reset();
339 PP.RemovePragmaHandler("clang", LoopHintHandler.get());
340 LoopHintHandler.reset();
342 PP.RemovePragmaHandler(UnrollHintHandler.get());
343 UnrollHintHandler.reset();
345 PP.RemovePragmaHandler(NoUnrollHintHandler.get());
346 NoUnrollHintHandler.reset();
349 /// \brief Handle the annotation token produced for #pragma unused(...)
351 /// Each annot_pragma_unused is followed by the argument token so e.g.
352 /// "#pragma unused(x,y)" becomes:
353 /// annot_pragma_unused 'x' annot_pragma_unused 'y'
354 void Parser::HandlePragmaUnused() {
355 assert(Tok.is(tok::annot_pragma_unused));
356 SourceLocation UnusedLoc = ConsumeToken();
357 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
358 ConsumeToken(); // The argument token.
361 void Parser::HandlePragmaVisibility() {
362 assert(Tok.is(tok::annot_pragma_vis));
363 const IdentifierInfo *VisType =
364 static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
365 SourceLocation VisLoc = ConsumeToken();
366 Actions.ActOnPragmaVisibility(VisType, VisLoc);
370 struct PragmaPackInfo {
371 Sema::PragmaMsStackAction Action;
375 } // end anonymous namespace
377 void Parser::HandlePragmaPack() {
378 assert(Tok.is(tok::annot_pragma_pack));
379 PragmaPackInfo *Info =
380 static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
381 SourceLocation PragmaLoc = ConsumeToken();
382 ExprResult Alignment;
383 if (Info->Alignment.is(tok::numeric_constant)) {
384 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
385 if (Alignment.isInvalid())
388 Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
392 void Parser::HandlePragmaMSStruct() {
393 assert(Tok.is(tok::annot_pragma_msstruct));
394 PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>(
395 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
396 Actions.ActOnPragmaMSStruct(Kind);
397 ConsumeToken(); // The annotation token.
400 void Parser::HandlePragmaAlign() {
401 assert(Tok.is(tok::annot_pragma_align));
402 Sema::PragmaOptionsAlignKind Kind =
403 static_cast<Sema::PragmaOptionsAlignKind>(
404 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
405 SourceLocation PragmaLoc = ConsumeToken();
406 Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
409 void Parser::HandlePragmaDump() {
410 assert(Tok.is(tok::annot_pragma_dump));
412 reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue());
413 Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II);
417 void Parser::HandlePragmaWeak() {
418 assert(Tok.is(tok::annot_pragma_weak));
419 SourceLocation PragmaLoc = ConsumeToken();
420 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
422 ConsumeToken(); // The weak name.
425 void Parser::HandlePragmaWeakAlias() {
426 assert(Tok.is(tok::annot_pragma_weakalias));
427 SourceLocation PragmaLoc = ConsumeToken();
428 IdentifierInfo *WeakName = Tok.getIdentifierInfo();
429 SourceLocation WeakNameLoc = Tok.getLocation();
431 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
432 SourceLocation AliasNameLoc = Tok.getLocation();
434 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
435 WeakNameLoc, AliasNameLoc);
439 void Parser::HandlePragmaRedefineExtname() {
440 assert(Tok.is(tok::annot_pragma_redefine_extname));
441 SourceLocation RedefLoc = ConsumeToken();
442 IdentifierInfo *RedefName = Tok.getIdentifierInfo();
443 SourceLocation RedefNameLoc = Tok.getLocation();
445 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
446 SourceLocation AliasNameLoc = Tok.getLocation();
448 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
449 RedefNameLoc, AliasNameLoc);
452 void Parser::HandlePragmaFPContract() {
453 assert(Tok.is(tok::annot_pragma_fp_contract));
454 tok::OnOffSwitch OOS =
455 static_cast<tok::OnOffSwitch>(
456 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
457 Actions.ActOnPragmaFPContract(OOS);
458 ConsumeToken(); // The annotation token.
461 StmtResult Parser::HandlePragmaCaptured()
463 assert(Tok.is(tok::annot_pragma_captured));
466 if (Tok.isNot(tok::l_brace)) {
467 PP.Diag(Tok, diag::err_expected) << tok::l_brace;
471 SourceLocation Loc = Tok.getLocation();
473 ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope);
474 Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
477 StmtResult R = ParseCompoundStatement();
478 CapturedRegionScope.Exit();
481 Actions.ActOnCapturedRegionError();
485 return Actions.ActOnCapturedRegionEnd(R.get());
489 enum OpenCLExtState : char {
490 Disable, Enable, Begin, End
492 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
495 void Parser::HandlePragmaOpenCLExtension() {
496 assert(Tok.is(tok::annot_pragma_opencl_extension));
497 OpenCLExtData *Data = static_cast<OpenCLExtData*>(Tok.getAnnotationValue());
498 auto State = Data->second;
499 auto Ident = Data->first;
500 SourceLocation NameLoc = Tok.getLocation();
501 ConsumeToken(); // The annotation token.
503 auto &Opt = Actions.getOpenCLOptions();
504 auto Name = Ident->getName();
505 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
506 // overriding all previously issued extension directives, but only if the
507 // behavior is set to disable."
509 if (State == Disable) {
511 Opt.enableSupportedCore(getLangOpts().OpenCLVersion);
513 PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
515 } else if (State == Begin) {
516 if (!Opt.isKnown(Name) ||
517 !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
520 Actions.setCurrentOpenCLExtension(Name);
521 } else if (State == End) {
522 if (Name != Actions.getCurrentOpenCLExtension())
523 PP.Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
524 Actions.setCurrentOpenCLExtension("");
525 } else if (!Opt.isKnown(Name))
526 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
527 else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
528 Opt.enable(Name, State == Enable);
529 else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
530 PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
532 PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
535 void Parser::HandlePragmaMSPointersToMembers() {
536 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
537 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
538 static_cast<LangOptions::PragmaMSPointersToMembersKind>(
539 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
540 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
541 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
544 void Parser::HandlePragmaMSVtorDisp() {
545 assert(Tok.is(tok::annot_pragma_ms_vtordisp));
546 uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
547 Sema::PragmaMsStackAction Action =
548 static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
549 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
550 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
551 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
554 void Parser::HandlePragmaMSPragma() {
555 assert(Tok.is(tok::annot_pragma_ms_pragma));
556 // Grab the tokens out of the annotation and enter them into the stream.
558 (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue();
559 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true);
560 SourceLocation PragmaLocation = ConsumeToken(); // The annotation token.
561 assert(Tok.isAnyIdentifier());
562 StringRef PragmaName = Tok.getIdentifierInfo()->getName();
563 PP.Lex(Tok); // pragma kind
565 // Figure out which #pragma we're dealing with. The switch has no default
566 // because lex shouldn't emit the annotation token for unrecognized pragmas.
567 typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
568 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
569 .Case("data_seg", &Parser::HandlePragmaMSSegment)
570 .Case("bss_seg", &Parser::HandlePragmaMSSegment)
571 .Case("const_seg", &Parser::HandlePragmaMSSegment)
572 .Case("code_seg", &Parser::HandlePragmaMSSegment)
573 .Case("section", &Parser::HandlePragmaMSSection)
574 .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
576 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
577 // Pragma handling failed, and has been diagnosed. Slurp up the tokens
578 // until eof (really end of line) to prevent follow-on errors.
579 while (Tok.isNot(tok::eof))
585 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
586 SourceLocation PragmaLocation) {
587 if (Tok.isNot(tok::l_paren)) {
588 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
592 // Parsing code for pragma section
593 if (Tok.isNot(tok::string_literal)) {
594 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
598 ExprResult StringResult = ParseStringLiteralExpression();
599 if (StringResult.isInvalid())
600 return false; // Already diagnosed.
601 StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
602 if (SegmentName->getCharByteWidth() != 1) {
603 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
607 int SectionFlags = ASTContext::PSF_Read;
608 bool SectionFlagsAreDefault = true;
609 while (Tok.is(tok::comma)) {
611 // Ignore "long" and "short".
612 // They are undocumented, but widely used, section attributes which appear
614 if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
615 PP.Lex(Tok); // long/short
619 if (!Tok.isAnyIdentifier()) {
620 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
624 ASTContext::PragmaSectionFlag Flag =
625 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
626 Tok.getIdentifierInfo()->getName())
627 .Case("read", ASTContext::PSF_Read)
628 .Case("write", ASTContext::PSF_Write)
629 .Case("execute", ASTContext::PSF_Execute)
630 .Case("shared", ASTContext::PSF_Invalid)
631 .Case("nopage", ASTContext::PSF_Invalid)
632 .Case("nocache", ASTContext::PSF_Invalid)
633 .Case("discard", ASTContext::PSF_Invalid)
634 .Case("remove", ASTContext::PSF_Invalid)
635 .Default(ASTContext::PSF_None);
636 if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
637 PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
638 ? diag::warn_pragma_invalid_specific_action
639 : diag::warn_pragma_unsupported_action)
640 << PragmaName << Tok.getIdentifierInfo()->getName();
643 SectionFlags |= Flag;
644 SectionFlagsAreDefault = false;
645 PP.Lex(Tok); // Identifier
647 // If no section attributes are specified, the section will be marked as
649 if (SectionFlagsAreDefault)
650 SectionFlags |= ASTContext::PSF_Write;
651 if (Tok.isNot(tok::r_paren)) {
652 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
656 if (Tok.isNot(tok::eof)) {
657 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
662 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
666 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
667 SourceLocation PragmaLocation) {
668 if (Tok.isNot(tok::l_paren)) {
669 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
673 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
675 if (Tok.isAnyIdentifier()) {
676 StringRef PushPop = Tok.getIdentifierInfo()->getName();
677 if (PushPop == "push")
678 Action = Sema::PSK_Push;
679 else if (PushPop == "pop")
680 Action = Sema::PSK_Pop;
682 PP.Diag(PragmaLocation,
683 diag::warn_pragma_expected_section_push_pop_or_name)
687 if (Action != Sema::PSK_Reset) {
688 PP.Lex(Tok); // push | pop
689 if (Tok.is(tok::comma)) {
691 // If we've got a comma, we either need a label or a string.
692 if (Tok.isAnyIdentifier()) {
693 SlotLabel = Tok.getIdentifierInfo()->getName();
694 PP.Lex(Tok); // identifier
695 if (Tok.is(tok::comma))
697 else if (Tok.isNot(tok::r_paren)) {
698 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
703 } else if (Tok.isNot(tok::r_paren)) {
704 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
709 // Grab the string literal for our section name.
710 StringLiteral *SegmentName = nullptr;
711 if (Tok.isNot(tok::r_paren)) {
712 if (Tok.isNot(tok::string_literal)) {
713 unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
714 diag::warn_pragma_expected_section_name :
715 diag::warn_pragma_expected_section_label_or_name :
716 diag::warn_pragma_expected_section_push_pop_or_name;
717 PP.Diag(PragmaLocation, DiagID) << PragmaName;
720 ExprResult StringResult = ParseStringLiteralExpression();
721 if (StringResult.isInvalid())
722 return false; // Already diagnosed.
723 SegmentName = cast<StringLiteral>(StringResult.get());
724 if (SegmentName->getCharByteWidth() != 1) {
725 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
729 // Setting section "" has no effect
730 if (SegmentName->getLength())
731 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
733 if (Tok.isNot(tok::r_paren)) {
734 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
738 if (Tok.isNot(tok::eof)) {
739 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
744 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
745 SegmentName, PragmaName);
749 // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
750 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
751 SourceLocation PragmaLocation) {
752 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
753 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
757 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
761 // Parse either the known section names or the string section name.
762 StringLiteral *SegmentName = nullptr;
763 if (Tok.isAnyIdentifier()) {
764 auto *II = Tok.getIdentifierInfo();
765 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
766 .Case("compiler", "\".CRT$XCC\"")
767 .Case("lib", "\".CRT$XCL\"")
768 .Case("user", "\".CRT$XCU\"")
771 if (!Section.empty()) {
772 // Pretend the user wrote the appropriate string literal here.
774 Toks[0].startToken();
775 Toks[0].setKind(tok::string_literal);
776 Toks[0].setLocation(Tok.getLocation());
777 Toks[0].setLiteralData(Section.data());
778 Toks[0].setLength(Section.size());
780 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
783 } else if (Tok.is(tok::string_literal)) {
784 ExprResult StringResult = ParseStringLiteralExpression();
785 if (StringResult.isInvalid())
787 SegmentName = cast<StringLiteral>(StringResult.get());
788 if (SegmentName->getCharByteWidth() != 1) {
789 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
793 // FIXME: Add support for the '[, func-name]' part of the pragma.
797 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
801 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
803 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
807 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
812 struct PragmaLoopHintInfo {
815 ArrayRef<Token> Toks;
817 } // end anonymous namespace
819 static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
820 std::string PragmaString;
821 if (PragmaName.getIdentifierInfo()->getName() == "loop") {
822 PragmaString = "clang loop ";
823 PragmaString += Option.getIdentifierInfo()->getName();
825 assert(PragmaName.getIdentifierInfo()->getName() == "unroll" &&
826 "Unexpected pragma name");
827 PragmaString = "unroll";
832 bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
833 assert(Tok.is(tok::annot_pragma_loop_hint));
834 PragmaLoopHintInfo *Info =
835 static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
837 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
838 Hint.PragmaNameLoc = IdentifierLoc::create(
839 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
841 // It is possible that the loop hint has no option identifier, such as
842 // #pragma unroll(4).
843 IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
844 ? Info->Option.getIdentifierInfo()
846 Hint.OptionLoc = IdentifierLoc::create(
847 Actions.Context, Info->Option.getLocation(), OptionInfo);
849 llvm::ArrayRef<Token> Toks = Info->Toks;
851 // Return a valid hint if pragma unroll or nounroll were specified
852 // without an argument.
853 bool PragmaUnroll = PragmaNameInfo->getName() == "unroll";
854 bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll";
855 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll)) {
856 ConsumeToken(); // The annotation token.
857 Hint.Range = Info->PragmaName.getLocation();
861 // The constant expression is always followed by an eof token, which increases
863 assert(!Toks.empty() &&
864 "PragmaLoopHintInfo::Toks must contain at least one token.");
866 // If no option is specified the argument is assumed to be a constant expr.
867 bool OptionUnroll = false;
868 bool OptionDistribute = false;
869 bool StateOption = false;
870 if (OptionInfo) { // Pragma Unroll does not specify an option.
871 OptionUnroll = OptionInfo->isStr("unroll");
872 OptionDistribute = OptionInfo->isStr("distribute");
873 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
874 .Case("vectorize", true)
875 .Case("interleave", true)
877 OptionUnroll || OptionDistribute;
880 bool AssumeSafetyArg = !OptionUnroll && !OptionDistribute;
881 // Verify loop hint has an argument.
882 if (Toks[0].is(tok::eof)) {
883 ConsumeToken(); // The annotation token.
884 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
885 << /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll
886 << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
890 // Validate the argument.
892 ConsumeToken(); // The annotation token.
893 SourceLocation StateLoc = Toks[0].getLocation();
894 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
896 bool Valid = StateInfo &&
897 llvm::StringSwitch<bool>(StateInfo->getName())
898 .Cases("enable", "disable", true)
899 .Case("full", OptionUnroll)
900 .Case("assume_safety", AssumeSafetyArg)
903 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
904 << /*FullKeyword=*/OptionUnroll
905 << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
909 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
910 << PragmaLoopHintString(Info->PragmaName, Info->Option);
911 Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
913 // Enter constant expression including eof terminator into token stream.
914 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false);
915 ConsumeToken(); // The annotation token.
917 ExprResult R = ParseConstantExpression();
919 // Tokens following an error in an ill-formed constant expression will
920 // remain in the token stream and must be removed.
921 if (Tok.isNot(tok::eof)) {
922 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
923 << PragmaLoopHintString(Info->PragmaName, Info->Option);
924 while (Tok.isNot(tok::eof))
928 ConsumeToken(); // Consume the constant expression eof terminator.
931 Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
934 // Argument is a constant expression with an integer type.
935 Hint.ValueExpr = R.get();
938 Hint.Range = SourceRange(Info->PragmaName.getLocation(),
939 Info->Toks.back().getLocation());
943 // #pragma GCC visibility comes in two variants:
944 // 'push' '(' [visibility] ')'
946 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
947 PragmaIntroducerKind Introducer,
949 SourceLocation VisLoc = VisTok.getLocation();
952 PP.LexUnexpandedToken(Tok);
954 const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
956 const IdentifierInfo *VisType;
957 if (PushPop && PushPop->isStr("pop")) {
959 } else if (PushPop && PushPop->isStr("push")) {
960 PP.LexUnexpandedToken(Tok);
961 if (Tok.isNot(tok::l_paren)) {
962 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
966 PP.LexUnexpandedToken(Tok);
967 VisType = Tok.getIdentifierInfo();
969 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
973 PP.LexUnexpandedToken(Tok);
974 if (Tok.isNot(tok::r_paren)) {
975 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
980 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
984 SourceLocation EndLoc = Tok.getLocation();
985 PP.LexUnexpandedToken(Tok);
986 if (Tok.isNot(tok::eod)) {
987 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
992 auto Toks = llvm::make_unique<Token[]>(1);
993 Toks[0].startToken();
994 Toks[0].setKind(tok::annot_pragma_vis);
995 Toks[0].setLocation(VisLoc);
996 Toks[0].setAnnotationEndLoc(EndLoc);
997 Toks[0].setAnnotationValue(
998 const_cast<void*>(static_cast<const void*>(VisType)));
999 PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true);
1002 // #pragma pack(...) comes in the following delicious flavors:
1003 // pack '(' [integer] ')'
1004 // pack '(' 'show' ')'
1005 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
1006 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
1007 PragmaIntroducerKind Introducer,
1009 SourceLocation PackLoc = PackTok.getLocation();
1013 if (Tok.isNot(tok::l_paren)) {
1014 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
1018 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
1019 StringRef SlotLabel;
1021 Alignment.startToken();
1023 if (Tok.is(tok::numeric_constant)) {
1028 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
1029 // the push/pop stack.
1030 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
1032 PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set;
1033 } else if (Tok.is(tok::identifier)) {
1034 const IdentifierInfo *II = Tok.getIdentifierInfo();
1035 if (II->isStr("show")) {
1036 Action = Sema::PSK_Show;
1039 if (II->isStr("push")) {
1040 Action = Sema::PSK_Push;
1041 } else if (II->isStr("pop")) {
1042 Action = Sema::PSK_Pop;
1044 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
1049 if (Tok.is(tok::comma)) {
1052 if (Tok.is(tok::numeric_constant)) {
1053 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1057 } else if (Tok.is(tok::identifier)) {
1058 SlotLabel = Tok.getIdentifierInfo()->getName();
1061 if (Tok.is(tok::comma)) {
1064 if (Tok.isNot(tok::numeric_constant)) {
1065 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1069 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1075 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1080 } else if (PP.getLangOpts().ApplePragmaPack) {
1081 // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1082 // the push/pop stack.
1083 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
1084 Action = Sema::PSK_Pop;
1087 if (Tok.isNot(tok::r_paren)) {
1088 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1092 SourceLocation RParenLoc = Tok.getLocation();
1094 if (Tok.isNot(tok::eod)) {
1095 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1099 PragmaPackInfo *Info =
1100 PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1);
1101 Info->Action = Action;
1102 Info->SlotLabel = SlotLabel;
1103 Info->Alignment = Alignment;
1105 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1107 Toks[0].startToken();
1108 Toks[0].setKind(tok::annot_pragma_pack);
1109 Toks[0].setLocation(PackLoc);
1110 Toks[0].setAnnotationEndLoc(RParenLoc);
1111 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1112 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1115 // #pragma ms_struct on
1116 // #pragma ms_struct off
1117 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
1118 PragmaIntroducerKind Introducer,
1119 Token &MSStructTok) {
1120 PragmaMSStructKind Kind = PMSST_OFF;
1124 if (Tok.isNot(tok::identifier)) {
1125 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1128 SourceLocation EndLoc = Tok.getLocation();
1129 const IdentifierInfo *II = Tok.getIdentifierInfo();
1130 if (II->isStr("on")) {
1134 else if (II->isStr("off") || II->isStr("reset"))
1137 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1141 if (Tok.isNot(tok::eod)) {
1142 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1147 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1149 Toks[0].startToken();
1150 Toks[0].setKind(tok::annot_pragma_msstruct);
1151 Toks[0].setLocation(MSStructTok.getLocation());
1152 Toks[0].setAnnotationEndLoc(EndLoc);
1153 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1154 static_cast<uintptr_t>(Kind)));
1155 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1158 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
1159 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
1160 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
1166 if (Tok.isNot(tok::identifier) ||
1167 !Tok.getIdentifierInfo()->isStr("align")) {
1168 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
1174 if (Tok.isNot(tok::equal)) {
1175 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1181 if (Tok.isNot(tok::identifier)) {
1182 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1183 << (IsOptions ? "options" : "align");
1187 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
1188 const IdentifierInfo *II = Tok.getIdentifierInfo();
1189 if (II->isStr("native"))
1190 Kind = Sema::POAK_Native;
1191 else if (II->isStr("natural"))
1192 Kind = Sema::POAK_Natural;
1193 else if (II->isStr("packed"))
1194 Kind = Sema::POAK_Packed;
1195 else if (II->isStr("power"))
1196 Kind = Sema::POAK_Power;
1197 else if (II->isStr("mac68k"))
1198 Kind = Sema::POAK_Mac68k;
1199 else if (II->isStr("reset"))
1200 Kind = Sema::POAK_Reset;
1202 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1207 SourceLocation EndLoc = Tok.getLocation();
1209 if (Tok.isNot(tok::eod)) {
1210 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1211 << (IsOptions ? "options" : "align");
1215 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1217 Toks[0].startToken();
1218 Toks[0].setKind(tok::annot_pragma_align);
1219 Toks[0].setLocation(FirstTok.getLocation());
1220 Toks[0].setAnnotationEndLoc(EndLoc);
1221 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1222 static_cast<uintptr_t>(Kind)));
1223 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1226 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
1227 PragmaIntroducerKind Introducer,
1229 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1232 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
1233 PragmaIntroducerKind Introducer,
1234 Token &OptionsTok) {
1235 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1238 // #pragma unused(identifier)
1239 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
1240 PragmaIntroducerKind Introducer,
1242 // FIXME: Should we be expanding macros here? My guess is no.
1243 SourceLocation UnusedLoc = UnusedTok.getLocation();
1245 // Lex the left '('.
1248 if (Tok.isNot(tok::l_paren)) {
1249 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1253 // Lex the declaration reference(s).
1254 SmallVector<Token, 5> Identifiers;
1255 SourceLocation RParenLoc;
1262 if (Tok.is(tok::identifier)) {
1263 Identifiers.push_back(Tok);
1269 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1273 // We are execting a ')' or a ','.
1274 if (Tok.is(tok::comma)) {
1279 if (Tok.is(tok::r_paren)) {
1280 RParenLoc = Tok.getLocation();
1285 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1290 if (Tok.isNot(tok::eod)) {
1291 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1296 // Verify that we have a location for the right parenthesis.
1297 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
1298 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
1300 // For each identifier token, insert into the token stream a
1301 // annot_pragma_unused token followed by the identifier token.
1302 // This allows us to cache a "#pragma unused" that occurs inside an inline
1303 // C++ member function.
1305 MutableArrayRef<Token> Toks(
1306 PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()),
1307 2 * Identifiers.size());
1308 for (unsigned i=0; i != Identifiers.size(); i++) {
1309 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1310 pragmaUnusedTok.startToken();
1311 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1312 pragmaUnusedTok.setLocation(UnusedLoc);
1313 idTok = Identifiers[i];
1315 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1318 // #pragma weak identifier
1319 // #pragma weak identifier '=' identifier
1320 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
1321 PragmaIntroducerKind Introducer,
1323 SourceLocation WeakLoc = WeakTok.getLocation();
1327 if (Tok.isNot(tok::identifier)) {
1328 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
1332 Token WeakName = Tok;
1333 bool HasAlias = false;
1337 if (Tok.is(tok::equal)) {
1340 if (Tok.isNot(tok::identifier)) {
1341 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1349 if (Tok.isNot(tok::eod)) {
1350 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
1355 MutableArrayRef<Token> Toks(
1356 PP.getPreprocessorAllocator().Allocate<Token>(3), 3);
1357 Token &pragmaUnusedTok = Toks[0];
1358 pragmaUnusedTok.startToken();
1359 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
1360 pragmaUnusedTok.setLocation(WeakLoc);
1361 pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
1363 Toks[2] = AliasName;
1364 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1366 MutableArrayRef<Token> Toks(
1367 PP.getPreprocessorAllocator().Allocate<Token>(2), 2);
1368 Token &pragmaUnusedTok = Toks[0];
1369 pragmaUnusedTok.startToken();
1370 pragmaUnusedTok.setKind(tok::annot_pragma_weak);
1371 pragmaUnusedTok.setLocation(WeakLoc);
1372 pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
1374 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1378 // #pragma redefine_extname identifier identifier
1379 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
1380 PragmaIntroducerKind Introducer,
1381 Token &RedefToken) {
1382 SourceLocation RedefLoc = RedefToken.getLocation();
1386 if (Tok.isNot(tok::identifier)) {
1387 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1392 Token RedefName = Tok;
1395 if (Tok.isNot(tok::identifier)) {
1396 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1397 << "redefine_extname";
1401 Token AliasName = Tok;
1404 if (Tok.isNot(tok::eod)) {
1405 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1410 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3),
1412 Token &pragmaRedefTok = Toks[0];
1413 pragmaRedefTok.startToken();
1414 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
1415 pragmaRedefTok.setLocation(RedefLoc);
1416 pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
1417 Toks[1] = RedefName;
1418 Toks[2] = AliasName;
1419 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1424 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
1425 PragmaIntroducerKind Introducer,
1427 tok::OnOffSwitch OOS;
1428 if (PP.LexOnOffSwitch(OOS))
1431 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1433 Toks[0].startToken();
1434 Toks[0].setKind(tok::annot_pragma_fp_contract);
1435 Toks[0].setLocation(Tok.getLocation());
1436 Toks[0].setAnnotationEndLoc(Tok.getLocation());
1437 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1438 static_cast<uintptr_t>(OOS)));
1439 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1443 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
1444 PragmaIntroducerKind Introducer,
1446 PP.LexUnexpandedToken(Tok);
1447 if (Tok.isNot(tok::identifier)) {
1448 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1452 IdentifierInfo *Ext = Tok.getIdentifierInfo();
1453 SourceLocation NameLoc = Tok.getLocation();
1456 if (Tok.isNot(tok::colon)) {
1457 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
1462 if (Tok.isNot(tok::identifier)) {
1463 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
1466 IdentifierInfo *Pred = Tok.getIdentifierInfo();
1468 OpenCLExtState State;
1469 if (Pred->isStr("enable")) {
1471 } else if (Pred->isStr("disable")) {
1473 } else if (Pred->isStr("begin"))
1475 else if (Pred->isStr("end"))
1478 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
1479 << Ext->isStr("all");
1482 SourceLocation StateLoc = Tok.getLocation();
1485 if (Tok.isNot(tok::eod)) {
1486 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1491 auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
1493 Info->second = State;
1494 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1496 Toks[0].startToken();
1497 Toks[0].setKind(tok::annot_pragma_opencl_extension);
1498 Toks[0].setLocation(NameLoc);
1499 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1500 Toks[0].setAnnotationEndLoc(StateLoc);
1501 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1503 if (PP.getPPCallbacks())
1504 PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext,
1508 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
1511 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
1512 PragmaIntroducerKind Introducer,
1514 if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
1515 FirstTok.getLocation())) {
1516 PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
1517 PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
1518 diag::Severity::Ignored, SourceLocation());
1520 PP.DiscardUntilEndOfDirective();
1523 /// \brief Handle '#pragma omp ...' when OpenMP is enabled.
1526 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
1527 PragmaIntroducerKind Introducer,
1529 SmallVector<Token, 16> Pragma;
1532 Tok.setKind(tok::annot_pragma_openmp);
1533 Tok.setLocation(FirstTok.getLocation());
1535 while (Tok.isNot(tok::eod)) {
1536 Pragma.push_back(Tok);
1539 SourceLocation EodLoc = Tok.getLocation();
1541 Tok.setKind(tok::annot_pragma_openmp_end);
1542 Tok.setLocation(EodLoc);
1543 Pragma.push_back(Tok);
1545 auto Toks = llvm::make_unique<Token[]>(Pragma.size());
1546 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
1547 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
1548 /*DisableMacroExpansion=*/false);
1551 /// \brief Handle '#pragma pointers_to_members'
1552 // The grammar for this pragma is as follows:
1554 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
1556 // #pragma pointers_to_members '(' 'best_case' ')'
1557 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
1558 // #pragma pointers_to_members '(' inheritance-model ')'
1559 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
1560 PragmaIntroducerKind Introducer,
1562 SourceLocation PointersToMembersLoc = Tok.getLocation();
1564 if (Tok.isNot(tok::l_paren)) {
1565 PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
1566 << "pointers_to_members";
1570 const IdentifierInfo *Arg = Tok.getIdentifierInfo();
1572 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1573 << "pointers_to_members";
1578 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
1579 if (Arg->isStr("best_case")) {
1580 RepresentationMethod = LangOptions::PPTMK_BestCase;
1582 if (Arg->isStr("full_generality")) {
1583 if (Tok.is(tok::comma)) {
1586 Arg = Tok.getIdentifierInfo();
1588 PP.Diag(Tok.getLocation(),
1589 diag::err_pragma_pointers_to_members_unknown_kind)
1590 << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
1594 } else if (Tok.is(tok::r_paren)) {
1595 // #pragma pointers_to_members(full_generality) implicitly specifies
1596 // virtual_inheritance.
1598 RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1600 PP.Diag(Tok.getLocation(), diag::err_expected_punc)
1601 << "full_generality";
1607 if (Arg->isStr("single_inheritance")) {
1608 RepresentationMethod =
1609 LangOptions::PPTMK_FullGeneralitySingleInheritance;
1610 } else if (Arg->isStr("multiple_inheritance")) {
1611 RepresentationMethod =
1612 LangOptions::PPTMK_FullGeneralityMultipleInheritance;
1613 } else if (Arg->isStr("virtual_inheritance")) {
1614 RepresentationMethod =
1615 LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1617 PP.Diag(Tok.getLocation(),
1618 diag::err_pragma_pointers_to_members_unknown_kind)
1619 << Arg << /*HasPointerDeclaration*/ 1;
1625 if (Tok.isNot(tok::r_paren)) {
1626 PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
1627 << (Arg ? Arg->getName() : "full_generality");
1631 SourceLocation EndLoc = Tok.getLocation();
1633 if (Tok.isNot(tok::eod)) {
1634 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1635 << "pointers_to_members";
1640 AnnotTok.startToken();
1641 AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
1642 AnnotTok.setLocation(PointersToMembersLoc);
1643 AnnotTok.setAnnotationEndLoc(EndLoc);
1644 AnnotTok.setAnnotationValue(
1645 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
1646 PP.EnterToken(AnnotTok);
1649 /// \brief Handle '#pragma vtordisp'
1650 // The grammar for this pragma is as follows:
1652 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
1654 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
1655 // #pragma vtordisp '(' 'pop' ')'
1656 // #pragma vtordisp '(' ')'
1657 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
1658 PragmaIntroducerKind Introducer,
1660 SourceLocation VtorDispLoc = Tok.getLocation();
1662 if (Tok.isNot(tok::l_paren)) {
1663 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
1668 Sema::PragmaMsStackAction Action = Sema::PSK_Set;
1669 const IdentifierInfo *II = Tok.getIdentifierInfo();
1671 if (II->isStr("push")) {
1672 // #pragma vtordisp(push, mode)
1674 if (Tok.isNot(tok::comma)) {
1675 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
1679 Action = Sema::PSK_Push_Set;
1680 // not push, could be on/off
1681 } else if (II->isStr("pop")) {
1682 // #pragma vtordisp(pop)
1684 Action = Sema::PSK_Pop;
1686 // not push or pop, could be on/off
1688 if (Tok.is(tok::r_paren)) {
1689 // #pragma vtordisp()
1690 Action = Sema::PSK_Reset;
1696 if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
1697 const IdentifierInfo *II = Tok.getIdentifierInfo();
1698 if (II && II->isStr("off")) {
1701 } else if (II && II->isStr("on")) {
1704 } else if (Tok.is(tok::numeric_constant) &&
1705 PP.parseSimpleIntegerLiteral(Tok, Value)) {
1707 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
1708 << 0 << 2 << "vtordisp";
1712 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
1718 // Finish the pragma: ')' $
1719 if (Tok.isNot(tok::r_paren)) {
1720 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
1723 SourceLocation EndLoc = Tok.getLocation();
1725 if (Tok.isNot(tok::eod)) {
1726 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1731 // Enter the annotation.
1733 AnnotTok.startToken();
1734 AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
1735 AnnotTok.setLocation(VtorDispLoc);
1736 AnnotTok.setAnnotationEndLoc(EndLoc);
1737 AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
1738 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
1739 PP.EnterToken(AnnotTok);
1742 /// \brief Handle all MS pragmas. Simply forwards the tokens after inserting
1743 /// an annotation token.
1744 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
1745 PragmaIntroducerKind Introducer,
1747 Token EoF, AnnotTok;
1749 EoF.setKind(tok::eof);
1750 AnnotTok.startToken();
1751 AnnotTok.setKind(tok::annot_pragma_ms_pragma);
1752 AnnotTok.setLocation(Tok.getLocation());
1753 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
1754 SmallVector<Token, 8> TokenVector;
1755 // Suck up all of the tokens before the eod.
1756 for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
1757 TokenVector.push_back(Tok);
1758 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
1760 // Add a sentinal EoF token to the end of the list.
1761 TokenVector.push_back(EoF);
1762 // We must allocate this array with new because EnterTokenStream is going to
1764 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
1765 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
1766 auto Value = new (PP.getPreprocessorAllocator())
1767 std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
1768 TokenVector.size());
1769 AnnotTok.setAnnotationValue(Value);
1770 PP.EnterToken(AnnotTok);
1773 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
1777 /// #pragma detect_mismatch("name", "value")
1779 /// Where 'name' and 'value' are quoted strings. The values are embedded in
1780 /// the object file and passed along to the linker. If the linker detects a
1781 /// mismatch in the object file's values for the given name, a LNK2038 error
1782 /// is emitted. See MSDN for more details.
1783 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
1784 PragmaIntroducerKind Introducer,
1786 SourceLocation DetectMismatchLoc = Tok.getLocation();
1788 if (Tok.isNot(tok::l_paren)) {
1789 PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
1793 // Read the name to embed, which must be a string literal.
1794 std::string NameString;
1795 if (!PP.LexStringLiteral(Tok, NameString,
1796 "pragma detect_mismatch",
1797 /*MacroExpansion=*/true))
1800 // Read the comma followed by a second string literal.
1801 std::string ValueString;
1802 if (Tok.isNot(tok::comma)) {
1803 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1807 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
1808 /*MacroExpansion=*/true))
1811 if (Tok.isNot(tok::r_paren)) {
1812 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1815 PP.Lex(Tok); // Eat the r_paren.
1817 if (Tok.isNot(tok::eod)) {
1818 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1822 // If the pragma is lexically sound, notify any interested PPCallbacks.
1823 if (PP.getPPCallbacks())
1824 PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString,
1827 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
1830 /// \brief Handle the microsoft \#pragma comment extension.
1834 /// #pragma comment(linker, "foo")
1836 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
1837 /// "foo" is a string, which is fully macro expanded, and permits string
1838 /// concatenation, embedded escape characters etc. See MSDN for more details.
1839 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
1840 PragmaIntroducerKind Introducer,
1842 SourceLocation CommentLoc = Tok.getLocation();
1844 if (Tok.isNot(tok::l_paren)) {
1845 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1849 // Read the identifier.
1851 if (Tok.isNot(tok::identifier)) {
1852 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1856 // Verify that this is one of the 5 whitelisted options.
1857 IdentifierInfo *II = Tok.getIdentifierInfo();
1858 PragmaMSCommentKind Kind =
1859 llvm::StringSwitch<PragmaMSCommentKind>(II->getName())
1860 .Case("linker", PCK_Linker)
1861 .Case("lib", PCK_Lib)
1862 .Case("compiler", PCK_Compiler)
1863 .Case("exestr", PCK_ExeStr)
1864 .Case("user", PCK_User)
1865 .Default(PCK_Unknown);
1866 if (Kind == PCK_Unknown) {
1867 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
1871 // On PS4, issue a warning about any pragma comments other than
1872 // #pragma comment lib.
1873 if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
1874 PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
1879 // Read the optional string if present.
1881 std::string ArgumentString;
1882 if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
1884 /*MacroExpansion=*/true))
1887 // FIXME: warn that 'exestr' is deprecated.
1888 // FIXME: If the kind is "compiler" warn if the string is present (it is
1890 // The MSDN docs say that "lib" and "linker" require a string and have a short
1891 // whitelist of linker options they support, but in practice MSVC doesn't
1892 // issue a diagnostic. Therefore neither does clang.
1894 if (Tok.isNot(tok::r_paren)) {
1895 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1898 PP.Lex(Tok); // eat the r_paren.
1900 if (Tok.isNot(tok::eod)) {
1901 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1905 // If the pragma is lexically sound, notify any interested PPCallbacks.
1906 if (PP.getPPCallbacks())
1907 PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
1909 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
1912 // #pragma clang optimize off
1913 // #pragma clang optimize on
1914 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
1915 PragmaIntroducerKind Introducer,
1916 Token &FirstToken) {
1919 if (Tok.is(tok::eod)) {
1920 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
1921 << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
1924 if (Tok.isNot(tok::identifier)) {
1925 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1926 << PP.getSpelling(Tok);
1929 const IdentifierInfo *II = Tok.getIdentifierInfo();
1930 // The only accepted values are 'on' or 'off'.
1932 if (II->isStr("on")) {
1934 } else if (!II->isStr("off")) {
1935 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1936 << PP.getSpelling(Tok);
1941 if (Tok.isNot(tok::eod)) {
1942 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
1943 << PP.getSpelling(Tok);
1947 Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
1950 /// \brief Parses loop or unroll pragma hint value and fills in Info.
1951 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
1952 Token Option, bool ValueInParens,
1953 PragmaLoopHintInfo &Info) {
1954 SmallVector<Token, 1> ValueList;
1955 int OpenParens = ValueInParens ? 1 : 0;
1956 // Read constant expression.
1957 while (Tok.isNot(tok::eod)) {
1958 if (Tok.is(tok::l_paren))
1960 else if (Tok.is(tok::r_paren)) {
1962 if (OpenParens == 0 && ValueInParens)
1966 ValueList.push_back(Tok);
1970 if (ValueInParens) {
1972 if (Tok.isNot(tok::r_paren)) {
1973 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1980 EOFTok.startToken();
1981 EOFTok.setKind(tok::eof);
1982 EOFTok.setLocation(Tok.getLocation());
1983 ValueList.push_back(EOFTok); // Terminates expression for parsing.
1985 Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
1987 Info.PragmaName = PragmaName;
1988 Info.Option = Option;
1992 /// \brief Handle the \#pragma clang loop directive.
1993 /// #pragma clang 'loop' loop-hints
1996 /// loop-hint loop-hints[opt]
1999 /// 'vectorize' '(' loop-hint-keyword ')'
2000 /// 'interleave' '(' loop-hint-keyword ')'
2001 /// 'unroll' '(' unroll-hint-keyword ')'
2002 /// 'vectorize_width' '(' loop-hint-value ')'
2003 /// 'interleave_count' '(' loop-hint-value ')'
2004 /// 'unroll_count' '(' loop-hint-value ')'
2006 /// loop-hint-keyword:
2011 /// unroll-hint-keyword:
2016 /// loop-hint-value:
2017 /// constant-expression
2019 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
2020 /// try vectorizing the instructions of the loop it precedes. Specifying
2021 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
2022 /// interleaving multiple iterations of the loop it precedes. The width of the
2023 /// vector instructions is specified by vectorize_width() and the number of
2024 /// interleaved loop iterations is specified by interleave_count(). Specifying a
2025 /// value of 1 effectively disables vectorization/interleaving, even if it is
2026 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
2027 /// only works on inner loops.
2029 /// The unroll and unroll_count directives control the concatenation
2030 /// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
2031 /// completely if the trip count is known at compile time and unroll partially
2032 /// if the trip count is not known. Specifying unroll(full) is similar to
2033 /// unroll(enable) but will unroll the loop only if the trip count is known at
2034 /// compile time. Specifying unroll(disable) disables unrolling for the
2035 /// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
2036 /// loop the number of times indicated by the value.
2037 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
2038 PragmaIntroducerKind Introducer,
2040 // Incoming token is "loop" from "#pragma clang loop".
2041 Token PragmaName = Tok;
2042 SmallVector<Token, 1> TokenList;
2044 // Lex the optimization option and verify it is an identifier.
2046 if (Tok.isNot(tok::identifier)) {
2047 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2048 << /*MissingOption=*/true << "";
2052 while (Tok.is(tok::identifier)) {
2054 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2056 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
2057 .Case("vectorize", true)
2058 .Case("interleave", true)
2059 .Case("unroll", true)
2060 .Case("distribute", true)
2061 .Case("vectorize_width", true)
2062 .Case("interleave_count", true)
2063 .Case("unroll_count", true)
2066 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2067 << /*MissingOption=*/false << OptionInfo;
2073 if (Tok.isNot(tok::l_paren)) {
2074 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2079 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2080 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
2084 // Generate the loop hint token.
2086 LoopHintTok.startToken();
2087 LoopHintTok.setKind(tok::annot_pragma_loop_hint);
2088 LoopHintTok.setLocation(PragmaName.getLocation());
2089 LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
2090 LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
2091 TokenList.push_back(LoopHintTok);
2094 if (Tok.isNot(tok::eod)) {
2095 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2100 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2101 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2103 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2104 /*DisableMacroExpansion=*/false);
2107 /// \brief Handle the loop unroll optimization pragmas.
2109 /// #pragma unroll unroll-hint-value
2110 /// #pragma unroll '(' unroll-hint-value ')'
2111 /// #pragma nounroll
2113 /// unroll-hint-value:
2114 /// constant-expression
2116 /// Loop unrolling hints can be specified with '#pragma unroll' or
2117 /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
2118 /// contained in parentheses. With no argument the directive instructs llvm to
2119 /// try to unroll the loop completely. A positive integer argument can be
2120 /// specified to indicate the number of times the loop should be unrolled. To
2121 /// maximize compatibility with other compilers the unroll count argument can be
2122 /// specified with or without parentheses. Specifying, '#pragma nounroll'
2123 /// disables unrolling of the loop.
2124 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
2125 PragmaIntroducerKind Introducer,
2127 // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
2128 // "#pragma nounroll".
2129 Token PragmaName = Tok;
2131 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2132 if (Tok.is(tok::eod)) {
2133 // nounroll or unroll pragma without an argument.
2134 Info->PragmaName = PragmaName;
2135 Info->Option.startToken();
2136 } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") {
2137 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2141 // Unroll pragma with an argument: "#pragma unroll N" or
2142 // "#pragma unroll(N)".
2143 // Read '(' if it exists.
2144 bool ValueInParens = Tok.is(tok::l_paren);
2149 Option.startToken();
2150 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
2153 // In CUDA, the argument to '#pragma unroll' should not be contained in
2155 if (PP.getLangOpts().CUDA && ValueInParens)
2156 PP.Diag(Info->Toks[0].getLocation(),
2157 diag::warn_pragma_unroll_cuda_value_in_parens);
2159 if (Tok.isNot(tok::eod)) {
2160 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2166 // Generate the hint token.
2167 auto TokenArray = llvm::make_unique<Token[]>(1);
2168 TokenArray[0].startToken();
2169 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2170 TokenArray[0].setLocation(PragmaName.getLocation());
2171 TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
2172 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2173 PP.EnterTokenStream(std::move(TokenArray), 1,
2174 /*DisableMacroExpansion=*/false);
2177 /// \brief Handle the Microsoft \#pragma intrinsic extension.
2181 /// #pragma intrinsic(memset)
2182 /// #pragma intrinsic(strlen, memcpy)
2185 /// Pragma intrisic tells the compiler to use a builtin version of the
2186 /// function. Clang does it anyway, so the pragma doesn't really do anything.
2187 /// Anyway, we emit a warning if the function specified in \#pragma intrinsic
2188 /// isn't an intrinsic in clang and suggest to include intrin.h.
2189 void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
2190 PragmaIntroducerKind Introducer,
2194 if (Tok.isNot(tok::l_paren)) {
2195 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
2201 bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
2203 while (Tok.is(tok::identifier)) {
2204 IdentifierInfo *II = Tok.getIdentifierInfo();
2205 if (!II->getBuiltinID())
2206 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
2207 << II << SuggestIntrinH;
2210 if (Tok.isNot(tok::comma))
2215 if (Tok.isNot(tok::r_paren)) {
2216 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
2222 if (Tok.isNot(tok::eod))
2223 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2226 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
2227 Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) {
2228 Token FirstTok = Tok;
2231 IdentifierInfo *Info = Tok.getIdentifierInfo();
2232 if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) {
2233 PP.Diag(FirstTok.getLocation(),
2234 diag::warn_pragma_force_cuda_host_device_bad_arg);
2238 if (Info->isStr("begin"))
2239 Actions.PushForceCUDAHostDevice();
2240 else if (!Actions.PopForceCUDAHostDevice())
2241 PP.Diag(FirstTok.getLocation(),
2242 diag::err_pragma_cannot_end_force_cuda_host_device);
2245 if (!Tok.is(tok::eod))
2246 PP.Diag(FirstTok.getLocation(),
2247 diag::warn_pragma_force_cuda_host_device_bad_arg);