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)
512 PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
513 } else if (State == Begin) {
514 if (!Opt.isKnown(Name) ||
515 !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
518 Actions.setCurrentOpenCLExtension(Name);
519 } else if (State == End) {
520 if (Name != Actions.getCurrentOpenCLExtension())
521 PP.Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
522 Actions.setCurrentOpenCLExtension("");
523 } else if (!Opt.isKnown(Name))
524 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
525 else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
526 Opt.enable(Name, State == Enable);
527 else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
528 PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
530 PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
533 void Parser::HandlePragmaMSPointersToMembers() {
534 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
535 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
536 static_cast<LangOptions::PragmaMSPointersToMembersKind>(
537 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
538 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
539 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
542 void Parser::HandlePragmaMSVtorDisp() {
543 assert(Tok.is(tok::annot_pragma_ms_vtordisp));
544 uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
545 Sema::PragmaMsStackAction Action =
546 static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
547 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
548 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
549 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
552 void Parser::HandlePragmaMSPragma() {
553 assert(Tok.is(tok::annot_pragma_ms_pragma));
554 // Grab the tokens out of the annotation and enter them into the stream.
556 (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue();
557 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true);
558 SourceLocation PragmaLocation = ConsumeToken(); // The annotation token.
559 assert(Tok.isAnyIdentifier());
560 StringRef PragmaName = Tok.getIdentifierInfo()->getName();
561 PP.Lex(Tok); // pragma kind
563 // Figure out which #pragma we're dealing with. The switch has no default
564 // because lex shouldn't emit the annotation token for unrecognized pragmas.
565 typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
566 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
567 .Case("data_seg", &Parser::HandlePragmaMSSegment)
568 .Case("bss_seg", &Parser::HandlePragmaMSSegment)
569 .Case("const_seg", &Parser::HandlePragmaMSSegment)
570 .Case("code_seg", &Parser::HandlePragmaMSSegment)
571 .Case("section", &Parser::HandlePragmaMSSection)
572 .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
574 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
575 // Pragma handling failed, and has been diagnosed. Slurp up the tokens
576 // until eof (really end of line) to prevent follow-on errors.
577 while (Tok.isNot(tok::eof))
583 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
584 SourceLocation PragmaLocation) {
585 if (Tok.isNot(tok::l_paren)) {
586 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
590 // Parsing code for pragma section
591 if (Tok.isNot(tok::string_literal)) {
592 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
596 ExprResult StringResult = ParseStringLiteralExpression();
597 if (StringResult.isInvalid())
598 return false; // Already diagnosed.
599 StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
600 if (SegmentName->getCharByteWidth() != 1) {
601 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
605 int SectionFlags = ASTContext::PSF_Read;
606 bool SectionFlagsAreDefault = true;
607 while (Tok.is(tok::comma)) {
609 // Ignore "long" and "short".
610 // They are undocumented, but widely used, section attributes which appear
612 if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
613 PP.Lex(Tok); // long/short
617 if (!Tok.isAnyIdentifier()) {
618 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
622 ASTContext::PragmaSectionFlag Flag =
623 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
624 Tok.getIdentifierInfo()->getName())
625 .Case("read", ASTContext::PSF_Read)
626 .Case("write", ASTContext::PSF_Write)
627 .Case("execute", ASTContext::PSF_Execute)
628 .Case("shared", ASTContext::PSF_Invalid)
629 .Case("nopage", ASTContext::PSF_Invalid)
630 .Case("nocache", ASTContext::PSF_Invalid)
631 .Case("discard", ASTContext::PSF_Invalid)
632 .Case("remove", ASTContext::PSF_Invalid)
633 .Default(ASTContext::PSF_None);
634 if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
635 PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
636 ? diag::warn_pragma_invalid_specific_action
637 : diag::warn_pragma_unsupported_action)
638 << PragmaName << Tok.getIdentifierInfo()->getName();
641 SectionFlags |= Flag;
642 SectionFlagsAreDefault = false;
643 PP.Lex(Tok); // Identifier
645 // If no section attributes are specified, the section will be marked as
647 if (SectionFlagsAreDefault)
648 SectionFlags |= ASTContext::PSF_Write;
649 if (Tok.isNot(tok::r_paren)) {
650 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
654 if (Tok.isNot(tok::eof)) {
655 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
660 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
664 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
665 SourceLocation PragmaLocation) {
666 if (Tok.isNot(tok::l_paren)) {
667 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
671 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
673 if (Tok.isAnyIdentifier()) {
674 StringRef PushPop = Tok.getIdentifierInfo()->getName();
675 if (PushPop == "push")
676 Action = Sema::PSK_Push;
677 else if (PushPop == "pop")
678 Action = Sema::PSK_Pop;
680 PP.Diag(PragmaLocation,
681 diag::warn_pragma_expected_section_push_pop_or_name)
685 if (Action != Sema::PSK_Reset) {
686 PP.Lex(Tok); // push | pop
687 if (Tok.is(tok::comma)) {
689 // If we've got a comma, we either need a label or a string.
690 if (Tok.isAnyIdentifier()) {
691 SlotLabel = Tok.getIdentifierInfo()->getName();
692 PP.Lex(Tok); // identifier
693 if (Tok.is(tok::comma))
695 else if (Tok.isNot(tok::r_paren)) {
696 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
701 } else if (Tok.isNot(tok::r_paren)) {
702 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
707 // Grab the string literal for our section name.
708 StringLiteral *SegmentName = nullptr;
709 if (Tok.isNot(tok::r_paren)) {
710 if (Tok.isNot(tok::string_literal)) {
711 unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
712 diag::warn_pragma_expected_section_name :
713 diag::warn_pragma_expected_section_label_or_name :
714 diag::warn_pragma_expected_section_push_pop_or_name;
715 PP.Diag(PragmaLocation, DiagID) << PragmaName;
718 ExprResult StringResult = ParseStringLiteralExpression();
719 if (StringResult.isInvalid())
720 return false; // Already diagnosed.
721 SegmentName = cast<StringLiteral>(StringResult.get());
722 if (SegmentName->getCharByteWidth() != 1) {
723 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
727 // Setting section "" has no effect
728 if (SegmentName->getLength())
729 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
731 if (Tok.isNot(tok::r_paren)) {
732 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
736 if (Tok.isNot(tok::eof)) {
737 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
742 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
743 SegmentName, PragmaName);
747 // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
748 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
749 SourceLocation PragmaLocation) {
750 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
751 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
755 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
759 // Parse either the known section names or the string section name.
760 StringLiteral *SegmentName = nullptr;
761 if (Tok.isAnyIdentifier()) {
762 auto *II = Tok.getIdentifierInfo();
763 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
764 .Case("compiler", "\".CRT$XCC\"")
765 .Case("lib", "\".CRT$XCL\"")
766 .Case("user", "\".CRT$XCU\"")
769 if (!Section.empty()) {
770 // Pretend the user wrote the appropriate string literal here.
772 Toks[0].startToken();
773 Toks[0].setKind(tok::string_literal);
774 Toks[0].setLocation(Tok.getLocation());
775 Toks[0].setLiteralData(Section.data());
776 Toks[0].setLength(Section.size());
778 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
781 } else if (Tok.is(tok::string_literal)) {
782 ExprResult StringResult = ParseStringLiteralExpression();
783 if (StringResult.isInvalid())
785 SegmentName = cast<StringLiteral>(StringResult.get());
786 if (SegmentName->getCharByteWidth() != 1) {
787 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
791 // FIXME: Add support for the '[, func-name]' part of the pragma.
795 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
799 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
801 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
805 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
810 struct PragmaLoopHintInfo {
813 ArrayRef<Token> Toks;
815 } // end anonymous namespace
817 static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
818 std::string PragmaString;
819 if (PragmaName.getIdentifierInfo()->getName() == "loop") {
820 PragmaString = "clang loop ";
821 PragmaString += Option.getIdentifierInfo()->getName();
823 assert(PragmaName.getIdentifierInfo()->getName() == "unroll" &&
824 "Unexpected pragma name");
825 PragmaString = "unroll";
830 bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
831 assert(Tok.is(tok::annot_pragma_loop_hint));
832 PragmaLoopHintInfo *Info =
833 static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
835 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
836 Hint.PragmaNameLoc = IdentifierLoc::create(
837 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
839 // It is possible that the loop hint has no option identifier, such as
840 // #pragma unroll(4).
841 IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
842 ? Info->Option.getIdentifierInfo()
844 Hint.OptionLoc = IdentifierLoc::create(
845 Actions.Context, Info->Option.getLocation(), OptionInfo);
847 llvm::ArrayRef<Token> Toks = Info->Toks;
849 // Return a valid hint if pragma unroll or nounroll were specified
850 // without an argument.
851 bool PragmaUnroll = PragmaNameInfo->getName() == "unroll";
852 bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll";
853 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll)) {
854 ConsumeToken(); // The annotation token.
855 Hint.Range = Info->PragmaName.getLocation();
859 // The constant expression is always followed by an eof token, which increases
861 assert(!Toks.empty() &&
862 "PragmaLoopHintInfo::Toks must contain at least one token.");
864 // If no option is specified the argument is assumed to be a constant expr.
865 bool OptionUnroll = false;
866 bool OptionDistribute = false;
867 bool StateOption = false;
868 if (OptionInfo) { // Pragma Unroll does not specify an option.
869 OptionUnroll = OptionInfo->isStr("unroll");
870 OptionDistribute = OptionInfo->isStr("distribute");
871 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
872 .Case("vectorize", true)
873 .Case("interleave", true)
875 OptionUnroll || OptionDistribute;
878 bool AssumeSafetyArg = !OptionUnroll && !OptionDistribute;
879 // Verify loop hint has an argument.
880 if (Toks[0].is(tok::eof)) {
881 ConsumeToken(); // The annotation token.
882 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
883 << /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll
884 << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
888 // Validate the argument.
890 ConsumeToken(); // The annotation token.
891 SourceLocation StateLoc = Toks[0].getLocation();
892 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
894 bool Valid = StateInfo &&
895 llvm::StringSwitch<bool>(StateInfo->getName())
896 .Cases("enable", "disable", true)
897 .Case("full", OptionUnroll)
898 .Case("assume_safety", AssumeSafetyArg)
901 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
902 << /*FullKeyword=*/OptionUnroll
903 << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
907 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
908 << PragmaLoopHintString(Info->PragmaName, Info->Option);
909 Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
911 // Enter constant expression including eof terminator into token stream.
912 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false);
913 ConsumeToken(); // The annotation token.
915 ExprResult R = ParseConstantExpression();
917 // Tokens following an error in an ill-formed constant expression will
918 // remain in the token stream and must be removed.
919 if (Tok.isNot(tok::eof)) {
920 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
921 << PragmaLoopHintString(Info->PragmaName, Info->Option);
922 while (Tok.isNot(tok::eof))
926 ConsumeToken(); // Consume the constant expression eof terminator.
929 Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
932 // Argument is a constant expression with an integer type.
933 Hint.ValueExpr = R.get();
936 Hint.Range = SourceRange(Info->PragmaName.getLocation(),
937 Info->Toks.back().getLocation());
941 // #pragma GCC visibility comes in two variants:
942 // 'push' '(' [visibility] ')'
944 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
945 PragmaIntroducerKind Introducer,
947 SourceLocation VisLoc = VisTok.getLocation();
950 PP.LexUnexpandedToken(Tok);
952 const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
954 const IdentifierInfo *VisType;
955 if (PushPop && PushPop->isStr("pop")) {
957 } else if (PushPop && PushPop->isStr("push")) {
958 PP.LexUnexpandedToken(Tok);
959 if (Tok.isNot(tok::l_paren)) {
960 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
964 PP.LexUnexpandedToken(Tok);
965 VisType = Tok.getIdentifierInfo();
967 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
971 PP.LexUnexpandedToken(Tok);
972 if (Tok.isNot(tok::r_paren)) {
973 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
978 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
982 SourceLocation EndLoc = Tok.getLocation();
983 PP.LexUnexpandedToken(Tok);
984 if (Tok.isNot(tok::eod)) {
985 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
990 auto Toks = llvm::make_unique<Token[]>(1);
991 Toks[0].startToken();
992 Toks[0].setKind(tok::annot_pragma_vis);
993 Toks[0].setLocation(VisLoc);
994 Toks[0].setAnnotationEndLoc(EndLoc);
995 Toks[0].setAnnotationValue(
996 const_cast<void*>(static_cast<const void*>(VisType)));
997 PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true);
1000 // #pragma pack(...) comes in the following delicious flavors:
1001 // pack '(' [integer] ')'
1002 // pack '(' 'show' ')'
1003 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
1004 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
1005 PragmaIntroducerKind Introducer,
1007 SourceLocation PackLoc = PackTok.getLocation();
1011 if (Tok.isNot(tok::l_paren)) {
1012 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
1016 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
1017 StringRef SlotLabel;
1019 Alignment.startToken();
1021 if (Tok.is(tok::numeric_constant)) {
1026 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
1027 // the push/pop stack.
1028 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
1030 PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set;
1031 } else if (Tok.is(tok::identifier)) {
1032 const IdentifierInfo *II = Tok.getIdentifierInfo();
1033 if (II->isStr("show")) {
1034 Action = Sema::PSK_Show;
1037 if (II->isStr("push")) {
1038 Action = Sema::PSK_Push;
1039 } else if (II->isStr("pop")) {
1040 Action = Sema::PSK_Pop;
1042 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
1047 if (Tok.is(tok::comma)) {
1050 if (Tok.is(tok::numeric_constant)) {
1051 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1055 } else if (Tok.is(tok::identifier)) {
1056 SlotLabel = Tok.getIdentifierInfo()->getName();
1059 if (Tok.is(tok::comma)) {
1062 if (Tok.isNot(tok::numeric_constant)) {
1063 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1067 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1073 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1078 } else if (PP.getLangOpts().ApplePragmaPack) {
1079 // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1080 // the push/pop stack.
1081 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
1082 Action = Sema::PSK_Pop;
1085 if (Tok.isNot(tok::r_paren)) {
1086 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1090 SourceLocation RParenLoc = Tok.getLocation();
1092 if (Tok.isNot(tok::eod)) {
1093 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1097 PragmaPackInfo *Info =
1098 PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1);
1099 Info->Action = Action;
1100 Info->SlotLabel = SlotLabel;
1101 Info->Alignment = Alignment;
1103 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1105 Toks[0].startToken();
1106 Toks[0].setKind(tok::annot_pragma_pack);
1107 Toks[0].setLocation(PackLoc);
1108 Toks[0].setAnnotationEndLoc(RParenLoc);
1109 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1110 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1113 // #pragma ms_struct on
1114 // #pragma ms_struct off
1115 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
1116 PragmaIntroducerKind Introducer,
1117 Token &MSStructTok) {
1118 PragmaMSStructKind Kind = PMSST_OFF;
1122 if (Tok.isNot(tok::identifier)) {
1123 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1126 SourceLocation EndLoc = Tok.getLocation();
1127 const IdentifierInfo *II = Tok.getIdentifierInfo();
1128 if (II->isStr("on")) {
1132 else if (II->isStr("off") || II->isStr("reset"))
1135 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1139 if (Tok.isNot(tok::eod)) {
1140 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1145 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1147 Toks[0].startToken();
1148 Toks[0].setKind(tok::annot_pragma_msstruct);
1149 Toks[0].setLocation(MSStructTok.getLocation());
1150 Toks[0].setAnnotationEndLoc(EndLoc);
1151 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1152 static_cast<uintptr_t>(Kind)));
1153 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1156 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
1157 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
1158 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
1164 if (Tok.isNot(tok::identifier) ||
1165 !Tok.getIdentifierInfo()->isStr("align")) {
1166 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
1172 if (Tok.isNot(tok::equal)) {
1173 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1179 if (Tok.isNot(tok::identifier)) {
1180 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1181 << (IsOptions ? "options" : "align");
1185 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
1186 const IdentifierInfo *II = Tok.getIdentifierInfo();
1187 if (II->isStr("native"))
1188 Kind = Sema::POAK_Native;
1189 else if (II->isStr("natural"))
1190 Kind = Sema::POAK_Natural;
1191 else if (II->isStr("packed"))
1192 Kind = Sema::POAK_Packed;
1193 else if (II->isStr("power"))
1194 Kind = Sema::POAK_Power;
1195 else if (II->isStr("mac68k"))
1196 Kind = Sema::POAK_Mac68k;
1197 else if (II->isStr("reset"))
1198 Kind = Sema::POAK_Reset;
1200 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1205 SourceLocation EndLoc = Tok.getLocation();
1207 if (Tok.isNot(tok::eod)) {
1208 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1209 << (IsOptions ? "options" : "align");
1213 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1215 Toks[0].startToken();
1216 Toks[0].setKind(tok::annot_pragma_align);
1217 Toks[0].setLocation(FirstTok.getLocation());
1218 Toks[0].setAnnotationEndLoc(EndLoc);
1219 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1220 static_cast<uintptr_t>(Kind)));
1221 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1224 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
1225 PragmaIntroducerKind Introducer,
1227 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1230 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
1231 PragmaIntroducerKind Introducer,
1232 Token &OptionsTok) {
1233 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1236 // #pragma unused(identifier)
1237 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
1238 PragmaIntroducerKind Introducer,
1240 // FIXME: Should we be expanding macros here? My guess is no.
1241 SourceLocation UnusedLoc = UnusedTok.getLocation();
1243 // Lex the left '('.
1246 if (Tok.isNot(tok::l_paren)) {
1247 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1251 // Lex the declaration reference(s).
1252 SmallVector<Token, 5> Identifiers;
1253 SourceLocation RParenLoc;
1260 if (Tok.is(tok::identifier)) {
1261 Identifiers.push_back(Tok);
1267 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1271 // We are execting a ')' or a ','.
1272 if (Tok.is(tok::comma)) {
1277 if (Tok.is(tok::r_paren)) {
1278 RParenLoc = Tok.getLocation();
1283 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1288 if (Tok.isNot(tok::eod)) {
1289 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1294 // Verify that we have a location for the right parenthesis.
1295 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
1296 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
1298 // For each identifier token, insert into the token stream a
1299 // annot_pragma_unused token followed by the identifier token.
1300 // This allows us to cache a "#pragma unused" that occurs inside an inline
1301 // C++ member function.
1303 MutableArrayRef<Token> Toks(
1304 PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()),
1305 2 * Identifiers.size());
1306 for (unsigned i=0; i != Identifiers.size(); i++) {
1307 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1308 pragmaUnusedTok.startToken();
1309 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1310 pragmaUnusedTok.setLocation(UnusedLoc);
1311 idTok = Identifiers[i];
1313 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1316 // #pragma weak identifier
1317 // #pragma weak identifier '=' identifier
1318 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
1319 PragmaIntroducerKind Introducer,
1321 SourceLocation WeakLoc = WeakTok.getLocation();
1325 if (Tok.isNot(tok::identifier)) {
1326 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
1330 Token WeakName = Tok;
1331 bool HasAlias = false;
1335 if (Tok.is(tok::equal)) {
1338 if (Tok.isNot(tok::identifier)) {
1339 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1347 if (Tok.isNot(tok::eod)) {
1348 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
1353 MutableArrayRef<Token> Toks(
1354 PP.getPreprocessorAllocator().Allocate<Token>(3), 3);
1355 Token &pragmaUnusedTok = Toks[0];
1356 pragmaUnusedTok.startToken();
1357 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
1358 pragmaUnusedTok.setLocation(WeakLoc);
1359 pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
1361 Toks[2] = AliasName;
1362 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1364 MutableArrayRef<Token> Toks(
1365 PP.getPreprocessorAllocator().Allocate<Token>(2), 2);
1366 Token &pragmaUnusedTok = Toks[0];
1367 pragmaUnusedTok.startToken();
1368 pragmaUnusedTok.setKind(tok::annot_pragma_weak);
1369 pragmaUnusedTok.setLocation(WeakLoc);
1370 pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
1372 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1376 // #pragma redefine_extname identifier identifier
1377 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
1378 PragmaIntroducerKind Introducer,
1379 Token &RedefToken) {
1380 SourceLocation RedefLoc = RedefToken.getLocation();
1384 if (Tok.isNot(tok::identifier)) {
1385 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1390 Token RedefName = Tok;
1393 if (Tok.isNot(tok::identifier)) {
1394 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1395 << "redefine_extname";
1399 Token AliasName = Tok;
1402 if (Tok.isNot(tok::eod)) {
1403 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1408 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3),
1410 Token &pragmaRedefTok = Toks[0];
1411 pragmaRedefTok.startToken();
1412 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
1413 pragmaRedefTok.setLocation(RedefLoc);
1414 pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
1415 Toks[1] = RedefName;
1416 Toks[2] = AliasName;
1417 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1422 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
1423 PragmaIntroducerKind Introducer,
1425 tok::OnOffSwitch OOS;
1426 if (PP.LexOnOffSwitch(OOS))
1429 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1431 Toks[0].startToken();
1432 Toks[0].setKind(tok::annot_pragma_fp_contract);
1433 Toks[0].setLocation(Tok.getLocation());
1434 Toks[0].setAnnotationEndLoc(Tok.getLocation());
1435 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1436 static_cast<uintptr_t>(OOS)));
1437 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1441 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
1442 PragmaIntroducerKind Introducer,
1444 PP.LexUnexpandedToken(Tok);
1445 if (Tok.isNot(tok::identifier)) {
1446 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1450 IdentifierInfo *Ext = Tok.getIdentifierInfo();
1451 SourceLocation NameLoc = Tok.getLocation();
1454 if (Tok.isNot(tok::colon)) {
1455 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
1460 if (Tok.isNot(tok::identifier)) {
1461 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
1464 IdentifierInfo *Pred = Tok.getIdentifierInfo();
1466 OpenCLExtState State;
1467 if (Pred->isStr("enable")) {
1469 } else if (Pred->isStr("disable")) {
1471 } else if (Pred->isStr("begin"))
1473 else if (Pred->isStr("end"))
1476 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
1477 << Ext->isStr("all");
1480 SourceLocation StateLoc = Tok.getLocation();
1483 if (Tok.isNot(tok::eod)) {
1484 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1489 auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
1491 Info->second = State;
1492 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1494 Toks[0].startToken();
1495 Toks[0].setKind(tok::annot_pragma_opencl_extension);
1496 Toks[0].setLocation(NameLoc);
1497 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1498 Toks[0].setAnnotationEndLoc(StateLoc);
1499 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1501 if (PP.getPPCallbacks())
1502 PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext,
1506 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
1509 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
1510 PragmaIntroducerKind Introducer,
1512 if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
1513 FirstTok.getLocation())) {
1514 PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
1515 PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
1516 diag::Severity::Ignored, SourceLocation());
1518 PP.DiscardUntilEndOfDirective();
1521 /// \brief Handle '#pragma omp ...' when OpenMP is enabled.
1524 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
1525 PragmaIntroducerKind Introducer,
1527 SmallVector<Token, 16> Pragma;
1530 Tok.setKind(tok::annot_pragma_openmp);
1531 Tok.setLocation(FirstTok.getLocation());
1533 while (Tok.isNot(tok::eod)) {
1534 Pragma.push_back(Tok);
1537 SourceLocation EodLoc = Tok.getLocation();
1539 Tok.setKind(tok::annot_pragma_openmp_end);
1540 Tok.setLocation(EodLoc);
1541 Pragma.push_back(Tok);
1543 auto Toks = llvm::make_unique<Token[]>(Pragma.size());
1544 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
1545 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
1546 /*DisableMacroExpansion=*/false);
1549 /// \brief Handle '#pragma pointers_to_members'
1550 // The grammar for this pragma is as follows:
1552 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
1554 // #pragma pointers_to_members '(' 'best_case' ')'
1555 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
1556 // #pragma pointers_to_members '(' inheritance-model ')'
1557 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
1558 PragmaIntroducerKind Introducer,
1560 SourceLocation PointersToMembersLoc = Tok.getLocation();
1562 if (Tok.isNot(tok::l_paren)) {
1563 PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
1564 << "pointers_to_members";
1568 const IdentifierInfo *Arg = Tok.getIdentifierInfo();
1570 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1571 << "pointers_to_members";
1576 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
1577 if (Arg->isStr("best_case")) {
1578 RepresentationMethod = LangOptions::PPTMK_BestCase;
1580 if (Arg->isStr("full_generality")) {
1581 if (Tok.is(tok::comma)) {
1584 Arg = Tok.getIdentifierInfo();
1586 PP.Diag(Tok.getLocation(),
1587 diag::err_pragma_pointers_to_members_unknown_kind)
1588 << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
1592 } else if (Tok.is(tok::r_paren)) {
1593 // #pragma pointers_to_members(full_generality) implicitly specifies
1594 // virtual_inheritance.
1596 RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1598 PP.Diag(Tok.getLocation(), diag::err_expected_punc)
1599 << "full_generality";
1605 if (Arg->isStr("single_inheritance")) {
1606 RepresentationMethod =
1607 LangOptions::PPTMK_FullGeneralitySingleInheritance;
1608 } else if (Arg->isStr("multiple_inheritance")) {
1609 RepresentationMethod =
1610 LangOptions::PPTMK_FullGeneralityMultipleInheritance;
1611 } else if (Arg->isStr("virtual_inheritance")) {
1612 RepresentationMethod =
1613 LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1615 PP.Diag(Tok.getLocation(),
1616 diag::err_pragma_pointers_to_members_unknown_kind)
1617 << Arg << /*HasPointerDeclaration*/ 1;
1623 if (Tok.isNot(tok::r_paren)) {
1624 PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
1625 << (Arg ? Arg->getName() : "full_generality");
1629 SourceLocation EndLoc = Tok.getLocation();
1631 if (Tok.isNot(tok::eod)) {
1632 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1633 << "pointers_to_members";
1638 AnnotTok.startToken();
1639 AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
1640 AnnotTok.setLocation(PointersToMembersLoc);
1641 AnnotTok.setAnnotationEndLoc(EndLoc);
1642 AnnotTok.setAnnotationValue(
1643 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
1644 PP.EnterToken(AnnotTok);
1647 /// \brief Handle '#pragma vtordisp'
1648 // The grammar for this pragma is as follows:
1650 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
1652 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
1653 // #pragma vtordisp '(' 'pop' ')'
1654 // #pragma vtordisp '(' ')'
1655 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
1656 PragmaIntroducerKind Introducer,
1658 SourceLocation VtorDispLoc = Tok.getLocation();
1660 if (Tok.isNot(tok::l_paren)) {
1661 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
1666 Sema::PragmaMsStackAction Action = Sema::PSK_Set;
1667 const IdentifierInfo *II = Tok.getIdentifierInfo();
1669 if (II->isStr("push")) {
1670 // #pragma vtordisp(push, mode)
1672 if (Tok.isNot(tok::comma)) {
1673 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
1677 Action = Sema::PSK_Push_Set;
1678 // not push, could be on/off
1679 } else if (II->isStr("pop")) {
1680 // #pragma vtordisp(pop)
1682 Action = Sema::PSK_Pop;
1684 // not push or pop, could be on/off
1686 if (Tok.is(tok::r_paren)) {
1687 // #pragma vtordisp()
1688 Action = Sema::PSK_Reset;
1694 if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
1695 const IdentifierInfo *II = Tok.getIdentifierInfo();
1696 if (II && II->isStr("off")) {
1699 } else if (II && II->isStr("on")) {
1702 } else if (Tok.is(tok::numeric_constant) &&
1703 PP.parseSimpleIntegerLiteral(Tok, Value)) {
1705 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
1706 << 0 << 2 << "vtordisp";
1710 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
1716 // Finish the pragma: ')' $
1717 if (Tok.isNot(tok::r_paren)) {
1718 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
1721 SourceLocation EndLoc = Tok.getLocation();
1723 if (Tok.isNot(tok::eod)) {
1724 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1729 // Enter the annotation.
1731 AnnotTok.startToken();
1732 AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
1733 AnnotTok.setLocation(VtorDispLoc);
1734 AnnotTok.setAnnotationEndLoc(EndLoc);
1735 AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
1736 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
1737 PP.EnterToken(AnnotTok);
1740 /// \brief Handle all MS pragmas. Simply forwards the tokens after inserting
1741 /// an annotation token.
1742 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
1743 PragmaIntroducerKind Introducer,
1745 Token EoF, AnnotTok;
1747 EoF.setKind(tok::eof);
1748 AnnotTok.startToken();
1749 AnnotTok.setKind(tok::annot_pragma_ms_pragma);
1750 AnnotTok.setLocation(Tok.getLocation());
1751 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
1752 SmallVector<Token, 8> TokenVector;
1753 // Suck up all of the tokens before the eod.
1754 for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
1755 TokenVector.push_back(Tok);
1756 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
1758 // Add a sentinal EoF token to the end of the list.
1759 TokenVector.push_back(EoF);
1760 // We must allocate this array with new because EnterTokenStream is going to
1762 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
1763 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
1764 auto Value = new (PP.getPreprocessorAllocator())
1765 std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
1766 TokenVector.size());
1767 AnnotTok.setAnnotationValue(Value);
1768 PP.EnterToken(AnnotTok);
1771 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
1775 /// #pragma detect_mismatch("name", "value")
1777 /// Where 'name' and 'value' are quoted strings. The values are embedded in
1778 /// the object file and passed along to the linker. If the linker detects a
1779 /// mismatch in the object file's values for the given name, a LNK2038 error
1780 /// is emitted. See MSDN for more details.
1781 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
1782 PragmaIntroducerKind Introducer,
1784 SourceLocation DetectMismatchLoc = Tok.getLocation();
1786 if (Tok.isNot(tok::l_paren)) {
1787 PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
1791 // Read the name to embed, which must be a string literal.
1792 std::string NameString;
1793 if (!PP.LexStringLiteral(Tok, NameString,
1794 "pragma detect_mismatch",
1795 /*MacroExpansion=*/true))
1798 // Read the comma followed by a second string literal.
1799 std::string ValueString;
1800 if (Tok.isNot(tok::comma)) {
1801 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1805 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
1806 /*MacroExpansion=*/true))
1809 if (Tok.isNot(tok::r_paren)) {
1810 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1813 PP.Lex(Tok); // Eat the r_paren.
1815 if (Tok.isNot(tok::eod)) {
1816 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1820 // If the pragma is lexically sound, notify any interested PPCallbacks.
1821 if (PP.getPPCallbacks())
1822 PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString,
1825 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
1828 /// \brief Handle the microsoft \#pragma comment extension.
1832 /// #pragma comment(linker, "foo")
1834 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
1835 /// "foo" is a string, which is fully macro expanded, and permits string
1836 /// concatenation, embedded escape characters etc. See MSDN for more details.
1837 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
1838 PragmaIntroducerKind Introducer,
1840 SourceLocation CommentLoc = Tok.getLocation();
1842 if (Tok.isNot(tok::l_paren)) {
1843 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1847 // Read the identifier.
1849 if (Tok.isNot(tok::identifier)) {
1850 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1854 // Verify that this is one of the 5 whitelisted options.
1855 IdentifierInfo *II = Tok.getIdentifierInfo();
1856 PragmaMSCommentKind Kind =
1857 llvm::StringSwitch<PragmaMSCommentKind>(II->getName())
1858 .Case("linker", PCK_Linker)
1859 .Case("lib", PCK_Lib)
1860 .Case("compiler", PCK_Compiler)
1861 .Case("exestr", PCK_ExeStr)
1862 .Case("user", PCK_User)
1863 .Default(PCK_Unknown);
1864 if (Kind == PCK_Unknown) {
1865 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
1869 // On PS4, issue a warning about any pragma comments other than
1870 // #pragma comment lib.
1871 if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
1872 PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
1877 // Read the optional string if present.
1879 std::string ArgumentString;
1880 if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
1882 /*MacroExpansion=*/true))
1885 // FIXME: warn that 'exestr' is deprecated.
1886 // FIXME: If the kind is "compiler" warn if the string is present (it is
1888 // The MSDN docs say that "lib" and "linker" require a string and have a short
1889 // whitelist of linker options they support, but in practice MSVC doesn't
1890 // issue a diagnostic. Therefore neither does clang.
1892 if (Tok.isNot(tok::r_paren)) {
1893 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1896 PP.Lex(Tok); // eat the r_paren.
1898 if (Tok.isNot(tok::eod)) {
1899 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1903 // If the pragma is lexically sound, notify any interested PPCallbacks.
1904 if (PP.getPPCallbacks())
1905 PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
1907 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
1910 // #pragma clang optimize off
1911 // #pragma clang optimize on
1912 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
1913 PragmaIntroducerKind Introducer,
1914 Token &FirstToken) {
1917 if (Tok.is(tok::eod)) {
1918 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
1919 << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
1922 if (Tok.isNot(tok::identifier)) {
1923 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1924 << PP.getSpelling(Tok);
1927 const IdentifierInfo *II = Tok.getIdentifierInfo();
1928 // The only accepted values are 'on' or 'off'.
1930 if (II->isStr("on")) {
1932 } else if (!II->isStr("off")) {
1933 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1934 << PP.getSpelling(Tok);
1939 if (Tok.isNot(tok::eod)) {
1940 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
1941 << PP.getSpelling(Tok);
1945 Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
1948 /// \brief Parses loop or unroll pragma hint value and fills in Info.
1949 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
1950 Token Option, bool ValueInParens,
1951 PragmaLoopHintInfo &Info) {
1952 SmallVector<Token, 1> ValueList;
1953 int OpenParens = ValueInParens ? 1 : 0;
1954 // Read constant expression.
1955 while (Tok.isNot(tok::eod)) {
1956 if (Tok.is(tok::l_paren))
1958 else if (Tok.is(tok::r_paren)) {
1960 if (OpenParens == 0 && ValueInParens)
1964 ValueList.push_back(Tok);
1968 if (ValueInParens) {
1970 if (Tok.isNot(tok::r_paren)) {
1971 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1978 EOFTok.startToken();
1979 EOFTok.setKind(tok::eof);
1980 EOFTok.setLocation(Tok.getLocation());
1981 ValueList.push_back(EOFTok); // Terminates expression for parsing.
1983 Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
1985 Info.PragmaName = PragmaName;
1986 Info.Option = Option;
1990 /// \brief Handle the \#pragma clang loop directive.
1991 /// #pragma clang 'loop' loop-hints
1994 /// loop-hint loop-hints[opt]
1997 /// 'vectorize' '(' loop-hint-keyword ')'
1998 /// 'interleave' '(' loop-hint-keyword ')'
1999 /// 'unroll' '(' unroll-hint-keyword ')'
2000 /// 'vectorize_width' '(' loop-hint-value ')'
2001 /// 'interleave_count' '(' loop-hint-value ')'
2002 /// 'unroll_count' '(' loop-hint-value ')'
2004 /// loop-hint-keyword:
2009 /// unroll-hint-keyword:
2014 /// loop-hint-value:
2015 /// constant-expression
2017 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
2018 /// try vectorizing the instructions of the loop it precedes. Specifying
2019 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
2020 /// interleaving multiple iterations of the loop it precedes. The width of the
2021 /// vector instructions is specified by vectorize_width() and the number of
2022 /// interleaved loop iterations is specified by interleave_count(). Specifying a
2023 /// value of 1 effectively disables vectorization/interleaving, even if it is
2024 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
2025 /// only works on inner loops.
2027 /// The unroll and unroll_count directives control the concatenation
2028 /// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
2029 /// completely if the trip count is known at compile time and unroll partially
2030 /// if the trip count is not known. Specifying unroll(full) is similar to
2031 /// unroll(enable) but will unroll the loop only if the trip count is known at
2032 /// compile time. Specifying unroll(disable) disables unrolling for the
2033 /// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
2034 /// loop the number of times indicated by the value.
2035 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
2036 PragmaIntroducerKind Introducer,
2038 // Incoming token is "loop" from "#pragma clang loop".
2039 Token PragmaName = Tok;
2040 SmallVector<Token, 1> TokenList;
2042 // Lex the optimization option and verify it is an identifier.
2044 if (Tok.isNot(tok::identifier)) {
2045 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2046 << /*MissingOption=*/true << "";
2050 while (Tok.is(tok::identifier)) {
2052 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2054 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
2055 .Case("vectorize", true)
2056 .Case("interleave", true)
2057 .Case("unroll", true)
2058 .Case("distribute", true)
2059 .Case("vectorize_width", true)
2060 .Case("interleave_count", true)
2061 .Case("unroll_count", true)
2064 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2065 << /*MissingOption=*/false << OptionInfo;
2071 if (Tok.isNot(tok::l_paren)) {
2072 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2077 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2078 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
2082 // Generate the loop hint token.
2084 LoopHintTok.startToken();
2085 LoopHintTok.setKind(tok::annot_pragma_loop_hint);
2086 LoopHintTok.setLocation(PragmaName.getLocation());
2087 LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
2088 LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
2089 TokenList.push_back(LoopHintTok);
2092 if (Tok.isNot(tok::eod)) {
2093 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2098 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2099 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2101 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2102 /*DisableMacroExpansion=*/false);
2105 /// \brief Handle the loop unroll optimization pragmas.
2107 /// #pragma unroll unroll-hint-value
2108 /// #pragma unroll '(' unroll-hint-value ')'
2109 /// #pragma nounroll
2111 /// unroll-hint-value:
2112 /// constant-expression
2114 /// Loop unrolling hints can be specified with '#pragma unroll' or
2115 /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
2116 /// contained in parentheses. With no argument the directive instructs llvm to
2117 /// try to unroll the loop completely. A positive integer argument can be
2118 /// specified to indicate the number of times the loop should be unrolled. To
2119 /// maximize compatibility with other compilers the unroll count argument can be
2120 /// specified with or without parentheses. Specifying, '#pragma nounroll'
2121 /// disables unrolling of the loop.
2122 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
2123 PragmaIntroducerKind Introducer,
2125 // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
2126 // "#pragma nounroll".
2127 Token PragmaName = Tok;
2129 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2130 if (Tok.is(tok::eod)) {
2131 // nounroll or unroll pragma without an argument.
2132 Info->PragmaName = PragmaName;
2133 Info->Option.startToken();
2134 } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") {
2135 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2139 // Unroll pragma with an argument: "#pragma unroll N" or
2140 // "#pragma unroll(N)".
2141 // Read '(' if it exists.
2142 bool ValueInParens = Tok.is(tok::l_paren);
2147 Option.startToken();
2148 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
2151 // In CUDA, the argument to '#pragma unroll' should not be contained in
2153 if (PP.getLangOpts().CUDA && ValueInParens)
2154 PP.Diag(Info->Toks[0].getLocation(),
2155 diag::warn_pragma_unroll_cuda_value_in_parens);
2157 if (Tok.isNot(tok::eod)) {
2158 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2164 // Generate the hint token.
2165 auto TokenArray = llvm::make_unique<Token[]>(1);
2166 TokenArray[0].startToken();
2167 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2168 TokenArray[0].setLocation(PragmaName.getLocation());
2169 TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
2170 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2171 PP.EnterTokenStream(std::move(TokenArray), 1,
2172 /*DisableMacroExpansion=*/false);
2175 /// \brief Handle the Microsoft \#pragma intrinsic extension.
2179 /// #pragma intrinsic(memset)
2180 /// #pragma intrinsic(strlen, memcpy)
2183 /// Pragma intrisic tells the compiler to use a builtin version of the
2184 /// function. Clang does it anyway, so the pragma doesn't really do anything.
2185 /// Anyway, we emit a warning if the function specified in \#pragma intrinsic
2186 /// isn't an intrinsic in clang and suggest to include intrin.h.
2187 void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
2188 PragmaIntroducerKind Introducer,
2192 if (Tok.isNot(tok::l_paren)) {
2193 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
2199 bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
2201 while (Tok.is(tok::identifier)) {
2202 IdentifierInfo *II = Tok.getIdentifierInfo();
2203 if (!II->getBuiltinID())
2204 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
2205 << II << SuggestIntrinH;
2208 if (Tok.isNot(tok::comma))
2213 if (Tok.isNot(tok::r_paren)) {
2214 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
2220 if (Tok.isNot(tok::eod))
2221 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2224 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
2225 Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) {
2226 Token FirstTok = Tok;
2229 IdentifierInfo *Info = Tok.getIdentifierInfo();
2230 if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) {
2231 PP.Diag(FirstTok.getLocation(),
2232 diag::warn_pragma_force_cuda_host_device_bad_arg);
2236 if (Info->isStr("begin"))
2237 Actions.PushForceCUDAHostDevice();
2238 else if (!Actions.PopForceCUDAHostDevice())
2239 PP.Diag(FirstTok.getLocation(),
2240 diag::err_pragma_cannot_end_force_cuda_host_device);
2243 if (!Tok.is(tok::eod))
2244 PP.Diag(FirstTok.getLocation(),
2245 diag::warn_pragma_force_cuda_host_device_bad_arg);