1 //===--- ParsePragma.cpp - Language specific pragma parsing ---------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the language specific #pragma handlers. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "RAIIObjectsForParser.h" 15 #include "clang/Lex/Preprocessor.h" 16 #include "clang/Parse/ParseDiagnostic.h" 17 #include "clang/Parse/Parser.h" 18 #include "clang/Sema/LoopHint.h" 19 #include "clang/Sema/Scope.h" 20 #include "llvm/ADT/StringSwitch.h" 21 using namespace clang; 22 23 namespace { 24 25 struct PragmaAlignHandler : public PragmaHandler { 26 explicit PragmaAlignHandler() : PragmaHandler("align") {} 27 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 28 Token &FirstToken) override; 29 }; 30 31 struct PragmaGCCVisibilityHandler : public PragmaHandler { 32 explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {} 33 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 34 Token &FirstToken) override; 35 }; 36 37 struct PragmaOptionsHandler : public PragmaHandler { 38 explicit PragmaOptionsHandler() : PragmaHandler("options") {} 39 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 40 Token &FirstToken) override; 41 }; 42 43 struct PragmaPackHandler : public PragmaHandler { 44 explicit PragmaPackHandler() : PragmaHandler("pack") {} 45 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 46 Token &FirstToken) override; 47 }; 48 49 struct PragmaMSStructHandler : public PragmaHandler { 50 explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {} 51 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 52 Token &FirstToken) override; 53 }; 54 55 struct PragmaUnusedHandler : public PragmaHandler { 56 PragmaUnusedHandler() : PragmaHandler("unused") {} 57 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 58 Token &FirstToken) override; 59 }; 60 61 struct PragmaWeakHandler : public PragmaHandler { 62 explicit PragmaWeakHandler() : PragmaHandler("weak") {} 63 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 64 Token &FirstToken) override; 65 }; 66 67 struct PragmaRedefineExtnameHandler : public PragmaHandler { 68 explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {} 69 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 70 Token &FirstToken) override; 71 }; 72 73 struct PragmaOpenCLExtensionHandler : public PragmaHandler { 74 PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {} 75 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 76 Token &FirstToken) override; 77 }; 78 79 80 struct PragmaFPContractHandler : public PragmaHandler { 81 PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {} 82 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 83 Token &FirstToken) override; 84 }; 85 86 struct PragmaNoOpenMPHandler : public PragmaHandler { 87 PragmaNoOpenMPHandler() : PragmaHandler("omp") { } 88 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 89 Token &FirstToken) override; 90 }; 91 92 struct PragmaOpenMPHandler : public PragmaHandler { 93 PragmaOpenMPHandler() : PragmaHandler("omp") { } 94 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 95 Token &FirstToken) override; 96 }; 97 98 /// PragmaCommentHandler - "\#pragma comment ...". 99 struct PragmaCommentHandler : public PragmaHandler { 100 PragmaCommentHandler(Sema &Actions) 101 : PragmaHandler("comment"), Actions(Actions) {} 102 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 103 Token &FirstToken) override; 104 private: 105 Sema &Actions; 106 }; 107 108 struct PragmaDetectMismatchHandler : public PragmaHandler { 109 PragmaDetectMismatchHandler(Sema &Actions) 110 : PragmaHandler("detect_mismatch"), Actions(Actions) {} 111 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 112 Token &FirstToken) override; 113 private: 114 Sema &Actions; 115 }; 116 117 struct PragmaMSPointersToMembers : public PragmaHandler { 118 explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {} 119 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 120 Token &FirstToken) override; 121 }; 122 123 struct PragmaMSVtorDisp : public PragmaHandler { 124 explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {} 125 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 126 Token &FirstToken) override; 127 }; 128 129 struct PragmaMSPragma : public PragmaHandler { 130 explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {} 131 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 132 Token &FirstToken) override; 133 }; 134 135 /// PragmaOptimizeHandler - "\#pragma clang optimize on/off". 136 struct PragmaOptimizeHandler : public PragmaHandler { 137 PragmaOptimizeHandler(Sema &S) 138 : PragmaHandler("optimize"), Actions(S) {} 139 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 140 Token &FirstToken) override; 141 private: 142 Sema &Actions; 143 }; 144 145 struct PragmaLoopHintHandler : public PragmaHandler { 146 PragmaLoopHintHandler() : PragmaHandler("loop") {} 147 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 148 Token &FirstToken) override; 149 }; 150 151 } // end namespace 152 153 void Parser::initializePragmaHandlers() { 154 AlignHandler.reset(new PragmaAlignHandler()); 155 PP.AddPragmaHandler(AlignHandler.get()); 156 157 GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler()); 158 PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get()); 159 160 OptionsHandler.reset(new PragmaOptionsHandler()); 161 PP.AddPragmaHandler(OptionsHandler.get()); 162 163 PackHandler.reset(new PragmaPackHandler()); 164 PP.AddPragmaHandler(PackHandler.get()); 165 166 MSStructHandler.reset(new PragmaMSStructHandler()); 167 PP.AddPragmaHandler(MSStructHandler.get()); 168 169 UnusedHandler.reset(new PragmaUnusedHandler()); 170 PP.AddPragmaHandler(UnusedHandler.get()); 171 172 WeakHandler.reset(new PragmaWeakHandler()); 173 PP.AddPragmaHandler(WeakHandler.get()); 174 175 RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler()); 176 PP.AddPragmaHandler(RedefineExtnameHandler.get()); 177 178 FPContractHandler.reset(new PragmaFPContractHandler()); 179 PP.AddPragmaHandler("STDC", FPContractHandler.get()); 180 181 if (getLangOpts().OpenCL) { 182 OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler()); 183 PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get()); 184 185 PP.AddPragmaHandler("OPENCL", FPContractHandler.get()); 186 } 187 if (getLangOpts().OpenMP) 188 OpenMPHandler.reset(new PragmaOpenMPHandler()); 189 else 190 OpenMPHandler.reset(new PragmaNoOpenMPHandler()); 191 PP.AddPragmaHandler(OpenMPHandler.get()); 192 193 if (getLangOpts().MicrosoftExt) { 194 MSCommentHandler.reset(new PragmaCommentHandler(Actions)); 195 PP.AddPragmaHandler(MSCommentHandler.get()); 196 MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions)); 197 PP.AddPragmaHandler(MSDetectMismatchHandler.get()); 198 MSPointersToMembers.reset(new PragmaMSPointersToMembers()); 199 PP.AddPragmaHandler(MSPointersToMembers.get()); 200 MSVtorDisp.reset(new PragmaMSVtorDisp()); 201 PP.AddPragmaHandler(MSVtorDisp.get()); 202 MSInitSeg.reset(new PragmaMSPragma("init_seg")); 203 PP.AddPragmaHandler(MSInitSeg.get()); 204 MSDataSeg.reset(new PragmaMSPragma("data_seg")); 205 PP.AddPragmaHandler(MSDataSeg.get()); 206 MSBSSSeg.reset(new PragmaMSPragma("bss_seg")); 207 PP.AddPragmaHandler(MSBSSSeg.get()); 208 MSConstSeg.reset(new PragmaMSPragma("const_seg")); 209 PP.AddPragmaHandler(MSConstSeg.get()); 210 MSCodeSeg.reset(new PragmaMSPragma("code_seg")); 211 PP.AddPragmaHandler(MSCodeSeg.get()); 212 MSSection.reset(new PragmaMSPragma("section")); 213 PP.AddPragmaHandler(MSSection.get()); 214 } 215 216 OptimizeHandler.reset(new PragmaOptimizeHandler(Actions)); 217 PP.AddPragmaHandler("clang", OptimizeHandler.get()); 218 219 LoopHintHandler.reset(new PragmaLoopHintHandler()); 220 PP.AddPragmaHandler("clang", LoopHintHandler.get()); 221 } 222 223 void Parser::resetPragmaHandlers() { 224 // Remove the pragma handlers we installed. 225 PP.RemovePragmaHandler(AlignHandler.get()); 226 AlignHandler.reset(); 227 PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get()); 228 GCCVisibilityHandler.reset(); 229 PP.RemovePragmaHandler(OptionsHandler.get()); 230 OptionsHandler.reset(); 231 PP.RemovePragmaHandler(PackHandler.get()); 232 PackHandler.reset(); 233 PP.RemovePragmaHandler(MSStructHandler.get()); 234 MSStructHandler.reset(); 235 PP.RemovePragmaHandler(UnusedHandler.get()); 236 UnusedHandler.reset(); 237 PP.RemovePragmaHandler(WeakHandler.get()); 238 WeakHandler.reset(); 239 PP.RemovePragmaHandler(RedefineExtnameHandler.get()); 240 RedefineExtnameHandler.reset(); 241 242 if (getLangOpts().OpenCL) { 243 PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get()); 244 OpenCLExtensionHandler.reset(); 245 PP.RemovePragmaHandler("OPENCL", FPContractHandler.get()); 246 } 247 PP.RemovePragmaHandler(OpenMPHandler.get()); 248 OpenMPHandler.reset(); 249 250 if (getLangOpts().MicrosoftExt) { 251 PP.RemovePragmaHandler(MSCommentHandler.get()); 252 MSCommentHandler.reset(); 253 PP.RemovePragmaHandler(MSDetectMismatchHandler.get()); 254 MSDetectMismatchHandler.reset(); 255 PP.RemovePragmaHandler(MSPointersToMembers.get()); 256 MSPointersToMembers.reset(); 257 PP.RemovePragmaHandler(MSVtorDisp.get()); 258 MSVtorDisp.reset(); 259 PP.RemovePragmaHandler(MSInitSeg.get()); 260 MSInitSeg.reset(); 261 PP.RemovePragmaHandler(MSDataSeg.get()); 262 MSDataSeg.reset(); 263 PP.RemovePragmaHandler(MSBSSSeg.get()); 264 MSBSSSeg.reset(); 265 PP.RemovePragmaHandler(MSConstSeg.get()); 266 MSConstSeg.reset(); 267 PP.RemovePragmaHandler(MSCodeSeg.get()); 268 MSCodeSeg.reset(); 269 PP.RemovePragmaHandler(MSSection.get()); 270 MSSection.reset(); 271 } 272 273 PP.RemovePragmaHandler("STDC", FPContractHandler.get()); 274 FPContractHandler.reset(); 275 276 PP.RemovePragmaHandler("clang", OptimizeHandler.get()); 277 OptimizeHandler.reset(); 278 279 PP.RemovePragmaHandler("clang", LoopHintHandler.get()); 280 LoopHintHandler.reset(); 281 } 282 283 /// \brief Handle the annotation token produced for #pragma unused(...) 284 /// 285 /// Each annot_pragma_unused is followed by the argument token so e.g. 286 /// "#pragma unused(x,y)" becomes: 287 /// annot_pragma_unused 'x' annot_pragma_unused 'y' 288 void Parser::HandlePragmaUnused() { 289 assert(Tok.is(tok::annot_pragma_unused)); 290 SourceLocation UnusedLoc = ConsumeToken(); 291 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc); 292 ConsumeToken(); // The argument token. 293 } 294 295 void Parser::HandlePragmaVisibility() { 296 assert(Tok.is(tok::annot_pragma_vis)); 297 const IdentifierInfo *VisType = 298 static_cast<IdentifierInfo *>(Tok.getAnnotationValue()); 299 SourceLocation VisLoc = ConsumeToken(); 300 Actions.ActOnPragmaVisibility(VisType, VisLoc); 301 } 302 303 struct PragmaPackInfo { 304 Sema::PragmaPackKind Kind; 305 IdentifierInfo *Name; 306 Token Alignment; 307 SourceLocation LParenLoc; 308 SourceLocation RParenLoc; 309 }; 310 311 void Parser::HandlePragmaPack() { 312 assert(Tok.is(tok::annot_pragma_pack)); 313 PragmaPackInfo *Info = 314 static_cast<PragmaPackInfo *>(Tok.getAnnotationValue()); 315 SourceLocation PragmaLoc = ConsumeToken(); 316 ExprResult Alignment; 317 if (Info->Alignment.is(tok::numeric_constant)) { 318 Alignment = Actions.ActOnNumericConstant(Info->Alignment); 319 if (Alignment.isInvalid()) 320 return; 321 } 322 Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc, 323 Info->LParenLoc, Info->RParenLoc); 324 } 325 326 void Parser::HandlePragmaMSStruct() { 327 assert(Tok.is(tok::annot_pragma_msstruct)); 328 Sema::PragmaMSStructKind Kind = 329 static_cast<Sema::PragmaMSStructKind>( 330 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 331 Actions.ActOnPragmaMSStruct(Kind); 332 ConsumeToken(); // The annotation token. 333 } 334 335 void Parser::HandlePragmaAlign() { 336 assert(Tok.is(tok::annot_pragma_align)); 337 Sema::PragmaOptionsAlignKind Kind = 338 static_cast<Sema::PragmaOptionsAlignKind>( 339 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 340 SourceLocation PragmaLoc = ConsumeToken(); 341 Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc); 342 } 343 344 void Parser::HandlePragmaWeak() { 345 assert(Tok.is(tok::annot_pragma_weak)); 346 SourceLocation PragmaLoc = ConsumeToken(); 347 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc, 348 Tok.getLocation()); 349 ConsumeToken(); // The weak name. 350 } 351 352 void Parser::HandlePragmaWeakAlias() { 353 assert(Tok.is(tok::annot_pragma_weakalias)); 354 SourceLocation PragmaLoc = ConsumeToken(); 355 IdentifierInfo *WeakName = Tok.getIdentifierInfo(); 356 SourceLocation WeakNameLoc = Tok.getLocation(); 357 ConsumeToken(); 358 IdentifierInfo *AliasName = Tok.getIdentifierInfo(); 359 SourceLocation AliasNameLoc = Tok.getLocation(); 360 ConsumeToken(); 361 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc, 362 WeakNameLoc, AliasNameLoc); 363 364 } 365 366 void Parser::HandlePragmaRedefineExtname() { 367 assert(Tok.is(tok::annot_pragma_redefine_extname)); 368 SourceLocation RedefLoc = ConsumeToken(); 369 IdentifierInfo *RedefName = Tok.getIdentifierInfo(); 370 SourceLocation RedefNameLoc = Tok.getLocation(); 371 ConsumeToken(); 372 IdentifierInfo *AliasName = Tok.getIdentifierInfo(); 373 SourceLocation AliasNameLoc = Tok.getLocation(); 374 ConsumeToken(); 375 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc, 376 RedefNameLoc, AliasNameLoc); 377 } 378 379 void Parser::HandlePragmaFPContract() { 380 assert(Tok.is(tok::annot_pragma_fp_contract)); 381 tok::OnOffSwitch OOS = 382 static_cast<tok::OnOffSwitch>( 383 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 384 Actions.ActOnPragmaFPContract(OOS); 385 ConsumeToken(); // The annotation token. 386 } 387 388 StmtResult Parser::HandlePragmaCaptured() 389 { 390 assert(Tok.is(tok::annot_pragma_captured)); 391 ConsumeToken(); 392 393 if (Tok.isNot(tok::l_brace)) { 394 PP.Diag(Tok, diag::err_expected) << tok::l_brace; 395 return StmtError(); 396 } 397 398 SourceLocation Loc = Tok.getLocation(); 399 400 ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope); 401 Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default, 402 /*NumParams=*/1); 403 404 StmtResult R = ParseCompoundStatement(); 405 CapturedRegionScope.Exit(); 406 407 if (R.isInvalid()) { 408 Actions.ActOnCapturedRegionError(); 409 return StmtError(); 410 } 411 412 return Actions.ActOnCapturedRegionEnd(R.get()); 413 } 414 415 namespace { 416 typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData; 417 } 418 419 void Parser::HandlePragmaOpenCLExtension() { 420 assert(Tok.is(tok::annot_pragma_opencl_extension)); 421 OpenCLExtData data = 422 OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue()); 423 unsigned state = data.getInt(); 424 IdentifierInfo *ename = data.getPointer(); 425 SourceLocation NameLoc = Tok.getLocation(); 426 ConsumeToken(); // The annotation token. 427 428 OpenCLOptions &f = Actions.getOpenCLOptions(); 429 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions, 430 // overriding all previously issued extension directives, but only if the 431 // behavior is set to disable." 432 if (state == 0 && ename->isStr("all")) { 433 #define OPENCLEXT(nm) f.nm = 0; 434 #include "clang/Basic/OpenCLExtensions.def" 435 } 436 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; } 437 #include "clang/Basic/OpenCLExtensions.def" 438 else { 439 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename; 440 return; 441 } 442 } 443 444 void Parser::HandlePragmaMSPointersToMembers() { 445 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members)); 446 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod = 447 static_cast<LangOptions::PragmaMSPointersToMembersKind>( 448 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 449 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token. 450 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc); 451 } 452 453 void Parser::HandlePragmaMSVtorDisp() { 454 assert(Tok.is(tok::annot_pragma_ms_vtordisp)); 455 uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()); 456 Sema::PragmaVtorDispKind Kind = 457 static_cast<Sema::PragmaVtorDispKind>((Value >> 16) & 0xFFFF); 458 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF); 459 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token. 460 Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode); 461 } 462 463 void Parser::HandlePragmaMSPragma() { 464 assert(Tok.is(tok::annot_pragma_ms_pragma)); 465 // Grab the tokens out of the annotation and enter them into the stream. 466 auto TheTokens = (std::pair<Token*, size_t> *)Tok.getAnnotationValue(); 467 PP.EnterTokenStream(TheTokens->first, TheTokens->second, true, true); 468 SourceLocation PragmaLocation = ConsumeToken(); // The annotation token. 469 assert(Tok.isAnyIdentifier()); 470 llvm::StringRef PragmaName = Tok.getIdentifierInfo()->getName(); 471 PP.Lex(Tok); // pragma kind 472 // Figure out which #pragma we're dealing with. The switch has no default 473 // because lex shouldn't emit the annotation token for unrecognized pragmas. 474 typedef unsigned (Parser::*PragmaHandler)(llvm::StringRef, SourceLocation); 475 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName) 476 .Case("data_seg", &Parser::HandlePragmaMSSegment) 477 .Case("bss_seg", &Parser::HandlePragmaMSSegment) 478 .Case("const_seg", &Parser::HandlePragmaMSSegment) 479 .Case("code_seg", &Parser::HandlePragmaMSSegment) 480 .Case("section", &Parser::HandlePragmaMSSection) 481 .Case("init_seg", &Parser::HandlePragmaMSInitSeg); 482 if (auto DiagID = (this->*Handler)(PragmaName, PragmaLocation)) { 483 PP.Diag(PragmaLocation, DiagID) << PragmaName; 484 while (Tok.isNot(tok::eof)) 485 PP.Lex(Tok); 486 PP.Lex(Tok); 487 } 488 } 489 490 unsigned Parser::HandlePragmaMSSection(llvm::StringRef PragmaName, 491 SourceLocation PragmaLocation) { 492 if (Tok.isNot(tok::l_paren)) 493 return diag::warn_pragma_expected_lparen; 494 PP.Lex(Tok); // ( 495 // Parsing code for pragma section 496 if (Tok.isNot(tok::string_literal)) 497 return diag::warn_pragma_expected_section_name; 498 StringLiteral *SegmentName = 499 cast<StringLiteral>(ParseStringLiteralExpression().get()); 500 int SectionFlags = 0; 501 while (Tok.is(tok::comma)) { 502 PP.Lex(Tok); // , 503 if (!Tok.isAnyIdentifier()) 504 return diag::warn_pragma_expected_action_or_r_paren; 505 Sema::PragmaSectionFlag Flag = 506 llvm::StringSwitch<Sema::PragmaSectionFlag>( 507 Tok.getIdentifierInfo()->getName()) 508 .Case("read", Sema::PSF_Read) 509 .Case("write", Sema::PSF_Write) 510 .Case("execute", Sema::PSF_Execute) 511 .Case("shared", Sema::PSF_Invalid) 512 .Case("nopage", Sema::PSF_Invalid) 513 .Case("nocache", Sema::PSF_Invalid) 514 .Case("discard", Sema::PSF_Invalid) 515 .Case("remove", Sema::PSF_Invalid) 516 .Default(Sema::PSF_None); 517 if (Flag == Sema::PSF_None || Flag == Sema::PSF_Invalid) { 518 PP.Diag(PragmaLocation, Flag == Sema::PSF_None ? 519 diag::warn_pragma_invalid_specific_action : 520 diag::warn_pragma_unsupported_action) 521 << PragmaName << Tok.getIdentifierInfo()->getName(); 522 while (Tok.isNot(tok::eof)) 523 PP.Lex(Tok); 524 PP.Lex(Tok); 525 return 0; 526 } 527 SectionFlags |= Flag; 528 PP.Lex(Tok); // Identifier 529 } 530 if (Tok.isNot(tok::r_paren)) 531 return diag::warn_pragma_expected_rparen; 532 PP.Lex(Tok); // ) 533 if (Tok.isNot(tok::eof)) 534 return diag::warn_pragma_extra_tokens_at_eol; 535 PP.Lex(Tok); // eof 536 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName); 537 return 0; 538 } 539 540 unsigned Parser::HandlePragmaMSSegment(llvm::StringRef PragmaName, 541 SourceLocation PragmaLocation) { 542 if (Tok.isNot(tok::l_paren)) 543 return diag::warn_pragma_expected_lparen; 544 PP.Lex(Tok); // ( 545 Sema::PragmaMsStackAction Action = Sema::PSK_Reset; 546 llvm::StringRef SlotLabel; 547 if (Tok.isAnyIdentifier()) { 548 llvm::StringRef PushPop = Tok.getIdentifierInfo()->getName(); 549 if (PushPop == "push") 550 Action = Sema::PSK_Push; 551 else if (PushPop == "pop") 552 Action = Sema::PSK_Pop; 553 else 554 return diag::warn_pragma_expected_section_push_pop_or_name; 555 if (Action != Sema::PSK_Reset) { 556 PP.Lex(Tok); // push | pop 557 if (Tok.is(tok::comma)) { 558 PP.Lex(Tok); // , 559 // If we've got a comma, we either need a label or a string. 560 if (Tok.isAnyIdentifier()) { 561 SlotLabel = Tok.getIdentifierInfo()->getName(); 562 PP.Lex(Tok); // identifier 563 if (Tok.is(tok::comma)) 564 PP.Lex(Tok); 565 else if (Tok.isNot(tok::r_paren)) 566 return diag::warn_pragma_expected_punc; 567 } 568 } else if (Tok.isNot(tok::r_paren)) 569 return diag::warn_pragma_expected_punc; 570 } 571 } 572 // Grab the string literal for our section name. 573 StringLiteral *SegmentName = nullptr; 574 if (Tok.isNot(tok::r_paren)) { 575 if (Tok.isNot(tok::string_literal)) 576 return Action != Sema::PSK_Reset ? !SlotLabel.empty() ? 577 diag::warn_pragma_expected_section_name : 578 diag::warn_pragma_expected_section_label_or_name : 579 diag::warn_pragma_expected_section_push_pop_or_name; 580 SegmentName = cast<StringLiteral>(ParseStringLiteralExpression().get()); 581 // Setting section "" has no effect 582 if (SegmentName->getLength()) 583 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set); 584 } 585 if (Tok.isNot(tok::r_paren)) 586 return diag::warn_pragma_expected_rparen; 587 PP.Lex(Tok); // ) 588 if (Tok.isNot(tok::eof)) 589 return diag::warn_pragma_extra_tokens_at_eol; 590 PP.Lex(Tok); // eof 591 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel, 592 SegmentName, PragmaName); 593 return 0; 594 } 595 596 unsigned Parser::HandlePragmaMSInitSeg(llvm::StringRef PragmaName, 597 SourceLocation PragmaLocation) { 598 return PP.getDiagnostics().getCustomDiagID( 599 DiagnosticsEngine::Error, "'#pragma %0' not implemented."); 600 } 601 602 struct PragmaLoopHintInfo { 603 Token Loop; 604 Token Value; 605 Token Option; 606 }; 607 608 LoopHint Parser::HandlePragmaLoopHint() { 609 assert(Tok.is(tok::annot_pragma_loop_hint)); 610 PragmaLoopHintInfo *Info = 611 static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue()); 612 613 LoopHint Hint; 614 Hint.LoopLoc = 615 IdentifierLoc::create(Actions.Context, Info->Loop.getLocation(), 616 Info->Loop.getIdentifierInfo()); 617 Hint.OptionLoc = 618 IdentifierLoc::create(Actions.Context, Info->Option.getLocation(), 619 Info->Option.getIdentifierInfo()); 620 Hint.ValueLoc = 621 IdentifierLoc::create(Actions.Context, Info->Value.getLocation(), 622 Info->Value.getIdentifierInfo()); 623 Hint.Range = 624 SourceRange(Info->Option.getLocation(), Info->Value.getLocation()); 625 626 // FIXME: We should allow non-type template parameters for the loop hint 627 // value. See bug report #19610 628 if (Info->Value.is(tok::numeric_constant)) 629 Hint.ValueExpr = Actions.ActOnNumericConstant(Info->Value).get(); 630 else 631 Hint.ValueExpr = nullptr; 632 633 return Hint; 634 } 635 636 // #pragma GCC visibility comes in two variants: 637 // 'push' '(' [visibility] ')' 638 // 'pop' 639 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, 640 PragmaIntroducerKind Introducer, 641 Token &VisTok) { 642 SourceLocation VisLoc = VisTok.getLocation(); 643 644 Token Tok; 645 PP.LexUnexpandedToken(Tok); 646 647 const IdentifierInfo *PushPop = Tok.getIdentifierInfo(); 648 649 const IdentifierInfo *VisType; 650 if (PushPop && PushPop->isStr("pop")) { 651 VisType = nullptr; 652 } else if (PushPop && PushPop->isStr("push")) { 653 PP.LexUnexpandedToken(Tok); 654 if (Tok.isNot(tok::l_paren)) { 655 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) 656 << "visibility"; 657 return; 658 } 659 PP.LexUnexpandedToken(Tok); 660 VisType = Tok.getIdentifierInfo(); 661 if (!VisType) { 662 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 663 << "visibility"; 664 return; 665 } 666 PP.LexUnexpandedToken(Tok); 667 if (Tok.isNot(tok::r_paren)) { 668 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) 669 << "visibility"; 670 return; 671 } 672 } else { 673 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 674 << "visibility"; 675 return; 676 } 677 PP.LexUnexpandedToken(Tok); 678 if (Tok.isNot(tok::eod)) { 679 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 680 << "visibility"; 681 return; 682 } 683 684 Token *Toks = new Token[1]; 685 Toks[0].startToken(); 686 Toks[0].setKind(tok::annot_pragma_vis); 687 Toks[0].setLocation(VisLoc); 688 Toks[0].setAnnotationValue( 689 const_cast<void*>(static_cast<const void*>(VisType))); 690 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 691 /*OwnsTokens=*/true); 692 } 693 694 // #pragma pack(...) comes in the following delicious flavors: 695 // pack '(' [integer] ')' 696 // pack '(' 'show' ')' 697 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')' 698 void PragmaPackHandler::HandlePragma(Preprocessor &PP, 699 PragmaIntroducerKind Introducer, 700 Token &PackTok) { 701 SourceLocation PackLoc = PackTok.getLocation(); 702 703 Token Tok; 704 PP.Lex(Tok); 705 if (Tok.isNot(tok::l_paren)) { 706 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack"; 707 return; 708 } 709 710 Sema::PragmaPackKind Kind = Sema::PPK_Default; 711 IdentifierInfo *Name = nullptr; 712 Token Alignment; 713 Alignment.startToken(); 714 SourceLocation LParenLoc = Tok.getLocation(); 715 PP.Lex(Tok); 716 if (Tok.is(tok::numeric_constant)) { 717 Alignment = Tok; 718 719 PP.Lex(Tok); 720 721 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting 722 // the push/pop stack. 723 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4) 724 if (PP.getLangOpts().ApplePragmaPack) 725 Kind = Sema::PPK_Push; 726 } else if (Tok.is(tok::identifier)) { 727 const IdentifierInfo *II = Tok.getIdentifierInfo(); 728 if (II->isStr("show")) { 729 Kind = Sema::PPK_Show; 730 PP.Lex(Tok); 731 } else { 732 if (II->isStr("push")) { 733 Kind = Sema::PPK_Push; 734 } else if (II->isStr("pop")) { 735 Kind = Sema::PPK_Pop; 736 } else { 737 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack"; 738 return; 739 } 740 PP.Lex(Tok); 741 742 if (Tok.is(tok::comma)) { 743 PP.Lex(Tok); 744 745 if (Tok.is(tok::numeric_constant)) { 746 Alignment = Tok; 747 748 PP.Lex(Tok); 749 } else if (Tok.is(tok::identifier)) { 750 Name = Tok.getIdentifierInfo(); 751 PP.Lex(Tok); 752 753 if (Tok.is(tok::comma)) { 754 PP.Lex(Tok); 755 756 if (Tok.isNot(tok::numeric_constant)) { 757 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed); 758 return; 759 } 760 761 Alignment = Tok; 762 763 PP.Lex(Tok); 764 } 765 } else { 766 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed); 767 return; 768 } 769 } 770 } 771 } else if (PP.getLangOpts().ApplePragmaPack) { 772 // In MSVC/gcc, #pragma pack() resets the alignment without affecting 773 // the push/pop stack. 774 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop). 775 Kind = Sema::PPK_Pop; 776 } 777 778 if (Tok.isNot(tok::r_paren)) { 779 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack"; 780 return; 781 } 782 783 SourceLocation RParenLoc = Tok.getLocation(); 784 PP.Lex(Tok); 785 if (Tok.isNot(tok::eod)) { 786 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack"; 787 return; 788 } 789 790 PragmaPackInfo *Info = 791 (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate( 792 sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>()); 793 new (Info) PragmaPackInfo(); 794 Info->Kind = Kind; 795 Info->Name = Name; 796 Info->Alignment = Alignment; 797 Info->LParenLoc = LParenLoc; 798 Info->RParenLoc = RParenLoc; 799 800 Token *Toks = 801 (Token*) PP.getPreprocessorAllocator().Allocate( 802 sizeof(Token) * 1, llvm::alignOf<Token>()); 803 new (Toks) Token(); 804 Toks[0].startToken(); 805 Toks[0].setKind(tok::annot_pragma_pack); 806 Toks[0].setLocation(PackLoc); 807 Toks[0].setAnnotationValue(static_cast<void*>(Info)); 808 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 809 /*OwnsTokens=*/false); 810 } 811 812 // #pragma ms_struct on 813 // #pragma ms_struct off 814 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, 815 PragmaIntroducerKind Introducer, 816 Token &MSStructTok) { 817 Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF; 818 819 Token Tok; 820 PP.Lex(Tok); 821 if (Tok.isNot(tok::identifier)) { 822 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); 823 return; 824 } 825 const IdentifierInfo *II = Tok.getIdentifierInfo(); 826 if (II->isStr("on")) { 827 Kind = Sema::PMSST_ON; 828 PP.Lex(Tok); 829 } 830 else if (II->isStr("off") || II->isStr("reset")) 831 PP.Lex(Tok); 832 else { 833 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); 834 return; 835 } 836 837 if (Tok.isNot(tok::eod)) { 838 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 839 << "ms_struct"; 840 return; 841 } 842 843 Token *Toks = 844 (Token*) PP.getPreprocessorAllocator().Allocate( 845 sizeof(Token) * 1, llvm::alignOf<Token>()); 846 new (Toks) Token(); 847 Toks[0].startToken(); 848 Toks[0].setKind(tok::annot_pragma_msstruct); 849 Toks[0].setLocation(MSStructTok.getLocation()); 850 Toks[0].setAnnotationValue(reinterpret_cast<void*>( 851 static_cast<uintptr_t>(Kind))); 852 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 853 /*OwnsTokens=*/false); 854 } 855 856 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'} 857 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'} 858 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, 859 bool IsOptions) { 860 Token Tok; 861 862 if (IsOptions) { 863 PP.Lex(Tok); 864 if (Tok.isNot(tok::identifier) || 865 !Tok.getIdentifierInfo()->isStr("align")) { 866 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align); 867 return; 868 } 869 } 870 871 PP.Lex(Tok); 872 if (Tok.isNot(tok::equal)) { 873 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal) 874 << IsOptions; 875 return; 876 } 877 878 PP.Lex(Tok); 879 if (Tok.isNot(tok::identifier)) { 880 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 881 << (IsOptions ? "options" : "align"); 882 return; 883 } 884 885 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural; 886 const IdentifierInfo *II = Tok.getIdentifierInfo(); 887 if (II->isStr("native")) 888 Kind = Sema::POAK_Native; 889 else if (II->isStr("natural")) 890 Kind = Sema::POAK_Natural; 891 else if (II->isStr("packed")) 892 Kind = Sema::POAK_Packed; 893 else if (II->isStr("power")) 894 Kind = Sema::POAK_Power; 895 else if (II->isStr("mac68k")) 896 Kind = Sema::POAK_Mac68k; 897 else if (II->isStr("reset")) 898 Kind = Sema::POAK_Reset; 899 else { 900 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option) 901 << IsOptions; 902 return; 903 } 904 905 PP.Lex(Tok); 906 if (Tok.isNot(tok::eod)) { 907 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 908 << (IsOptions ? "options" : "align"); 909 return; 910 } 911 912 Token *Toks = 913 (Token*) PP.getPreprocessorAllocator().Allocate( 914 sizeof(Token) * 1, llvm::alignOf<Token>()); 915 new (Toks) Token(); 916 Toks[0].startToken(); 917 Toks[0].setKind(tok::annot_pragma_align); 918 Toks[0].setLocation(FirstTok.getLocation()); 919 Toks[0].setAnnotationValue(reinterpret_cast<void*>( 920 static_cast<uintptr_t>(Kind))); 921 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 922 /*OwnsTokens=*/false); 923 } 924 925 void PragmaAlignHandler::HandlePragma(Preprocessor &PP, 926 PragmaIntroducerKind Introducer, 927 Token &AlignTok) { 928 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false); 929 } 930 931 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, 932 PragmaIntroducerKind Introducer, 933 Token &OptionsTok) { 934 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true); 935 } 936 937 // #pragma unused(identifier) 938 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, 939 PragmaIntroducerKind Introducer, 940 Token &UnusedTok) { 941 // FIXME: Should we be expanding macros here? My guess is no. 942 SourceLocation UnusedLoc = UnusedTok.getLocation(); 943 944 // Lex the left '('. 945 Token Tok; 946 PP.Lex(Tok); 947 if (Tok.isNot(tok::l_paren)) { 948 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused"; 949 return; 950 } 951 952 // Lex the declaration reference(s). 953 SmallVector<Token, 5> Identifiers; 954 SourceLocation RParenLoc; 955 bool LexID = true; 956 957 while (true) { 958 PP.Lex(Tok); 959 960 if (LexID) { 961 if (Tok.is(tok::identifier)) { 962 Identifiers.push_back(Tok); 963 LexID = false; 964 continue; 965 } 966 967 // Illegal token! 968 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var); 969 return; 970 } 971 972 // We are execting a ')' or a ','. 973 if (Tok.is(tok::comma)) { 974 LexID = true; 975 continue; 976 } 977 978 if (Tok.is(tok::r_paren)) { 979 RParenLoc = Tok.getLocation(); 980 break; 981 } 982 983 // Illegal token! 984 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused"; 985 return; 986 } 987 988 PP.Lex(Tok); 989 if (Tok.isNot(tok::eod)) { 990 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << 991 "unused"; 992 return; 993 } 994 995 // Verify that we have a location for the right parenthesis. 996 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'"); 997 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments"); 998 999 // For each identifier token, insert into the token stream a 1000 // annot_pragma_unused token followed by the identifier token. 1001 // This allows us to cache a "#pragma unused" that occurs inside an inline 1002 // C++ member function. 1003 1004 Token *Toks = 1005 (Token*) PP.getPreprocessorAllocator().Allocate( 1006 sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>()); 1007 for (unsigned i=0; i != Identifiers.size(); i++) { 1008 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1]; 1009 pragmaUnusedTok.startToken(); 1010 pragmaUnusedTok.setKind(tok::annot_pragma_unused); 1011 pragmaUnusedTok.setLocation(UnusedLoc); 1012 idTok = Identifiers[i]; 1013 } 1014 PP.EnterTokenStream(Toks, 2*Identifiers.size(), 1015 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); 1016 } 1017 1018 // #pragma weak identifier 1019 // #pragma weak identifier '=' identifier 1020 void PragmaWeakHandler::HandlePragma(Preprocessor &PP, 1021 PragmaIntroducerKind Introducer, 1022 Token &WeakTok) { 1023 SourceLocation WeakLoc = WeakTok.getLocation(); 1024 1025 Token Tok; 1026 PP.Lex(Tok); 1027 if (Tok.isNot(tok::identifier)) { 1028 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak"; 1029 return; 1030 } 1031 1032 Token WeakName = Tok; 1033 bool HasAlias = false; 1034 Token AliasName; 1035 1036 PP.Lex(Tok); 1037 if (Tok.is(tok::equal)) { 1038 HasAlias = true; 1039 PP.Lex(Tok); 1040 if (Tok.isNot(tok::identifier)) { 1041 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 1042 << "weak"; 1043 return; 1044 } 1045 AliasName = Tok; 1046 PP.Lex(Tok); 1047 } 1048 1049 if (Tok.isNot(tok::eod)) { 1050 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak"; 1051 return; 1052 } 1053 1054 if (HasAlias) { 1055 Token *Toks = 1056 (Token*) PP.getPreprocessorAllocator().Allocate( 1057 sizeof(Token) * 3, llvm::alignOf<Token>()); 1058 Token &pragmaUnusedTok = Toks[0]; 1059 pragmaUnusedTok.startToken(); 1060 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias); 1061 pragmaUnusedTok.setLocation(WeakLoc); 1062 Toks[1] = WeakName; 1063 Toks[2] = AliasName; 1064 PP.EnterTokenStream(Toks, 3, 1065 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); 1066 } else { 1067 Token *Toks = 1068 (Token*) PP.getPreprocessorAllocator().Allocate( 1069 sizeof(Token) * 2, llvm::alignOf<Token>()); 1070 Token &pragmaUnusedTok = Toks[0]; 1071 pragmaUnusedTok.startToken(); 1072 pragmaUnusedTok.setKind(tok::annot_pragma_weak); 1073 pragmaUnusedTok.setLocation(WeakLoc); 1074 Toks[1] = WeakName; 1075 PP.EnterTokenStream(Toks, 2, 1076 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); 1077 } 1078 } 1079 1080 // #pragma redefine_extname identifier identifier 1081 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP, 1082 PragmaIntroducerKind Introducer, 1083 Token &RedefToken) { 1084 SourceLocation RedefLoc = RedefToken.getLocation(); 1085 1086 Token Tok; 1087 PP.Lex(Tok); 1088 if (Tok.isNot(tok::identifier)) { 1089 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << 1090 "redefine_extname"; 1091 return; 1092 } 1093 1094 Token RedefName = Tok; 1095 PP.Lex(Tok); 1096 1097 if (Tok.isNot(tok::identifier)) { 1098 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 1099 << "redefine_extname"; 1100 return; 1101 } 1102 1103 Token AliasName = Tok; 1104 PP.Lex(Tok); 1105 1106 if (Tok.isNot(tok::eod)) { 1107 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << 1108 "redefine_extname"; 1109 return; 1110 } 1111 1112 Token *Toks = 1113 (Token*) PP.getPreprocessorAllocator().Allocate( 1114 sizeof(Token) * 3, llvm::alignOf<Token>()); 1115 Token &pragmaRedefTok = Toks[0]; 1116 pragmaRedefTok.startToken(); 1117 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname); 1118 pragmaRedefTok.setLocation(RedefLoc); 1119 Toks[1] = RedefName; 1120 Toks[2] = AliasName; 1121 PP.EnterTokenStream(Toks, 3, 1122 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); 1123 } 1124 1125 1126 void 1127 PragmaFPContractHandler::HandlePragma(Preprocessor &PP, 1128 PragmaIntroducerKind Introducer, 1129 Token &Tok) { 1130 tok::OnOffSwitch OOS; 1131 if (PP.LexOnOffSwitch(OOS)) 1132 return; 1133 1134 Token *Toks = 1135 (Token*) PP.getPreprocessorAllocator().Allocate( 1136 sizeof(Token) * 1, llvm::alignOf<Token>()); 1137 new (Toks) Token(); 1138 Toks[0].startToken(); 1139 Toks[0].setKind(tok::annot_pragma_fp_contract); 1140 Toks[0].setLocation(Tok.getLocation()); 1141 Toks[0].setAnnotationValue(reinterpret_cast<void*>( 1142 static_cast<uintptr_t>(OOS))); 1143 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 1144 /*OwnsTokens=*/false); 1145 } 1146 1147 void 1148 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP, 1149 PragmaIntroducerKind Introducer, 1150 Token &Tok) { 1151 PP.LexUnexpandedToken(Tok); 1152 if (Tok.isNot(tok::identifier)) { 1153 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << 1154 "OPENCL"; 1155 return; 1156 } 1157 IdentifierInfo *ename = Tok.getIdentifierInfo(); 1158 SourceLocation NameLoc = Tok.getLocation(); 1159 1160 PP.Lex(Tok); 1161 if (Tok.isNot(tok::colon)) { 1162 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename; 1163 return; 1164 } 1165 1166 PP.Lex(Tok); 1167 if (Tok.isNot(tok::identifier)) { 1168 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); 1169 return; 1170 } 1171 IdentifierInfo *op = Tok.getIdentifierInfo(); 1172 1173 unsigned state; 1174 if (op->isStr("enable")) { 1175 state = 1; 1176 } else if (op->isStr("disable")) { 1177 state = 0; 1178 } else { 1179 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); 1180 return; 1181 } 1182 SourceLocation StateLoc = Tok.getLocation(); 1183 1184 PP.Lex(Tok); 1185 if (Tok.isNot(tok::eod)) { 1186 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << 1187 "OPENCL EXTENSION"; 1188 return; 1189 } 1190 1191 OpenCLExtData data(ename, state); 1192 Token *Toks = 1193 (Token*) PP.getPreprocessorAllocator().Allocate( 1194 sizeof(Token) * 1, llvm::alignOf<Token>()); 1195 new (Toks) Token(); 1196 Toks[0].startToken(); 1197 Toks[0].setKind(tok::annot_pragma_opencl_extension); 1198 Toks[0].setLocation(NameLoc); 1199 Toks[0].setAnnotationValue(data.getOpaqueValue()); 1200 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 1201 /*OwnsTokens=*/false); 1202 1203 if (PP.getPPCallbacks()) 1204 PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename, 1205 StateLoc, state); 1206 } 1207 1208 /// \brief Handle '#pragma omp ...' when OpenMP is disabled. 1209 /// 1210 void 1211 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP, 1212 PragmaIntroducerKind Introducer, 1213 Token &FirstTok) { 1214 if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored, 1215 FirstTok.getLocation())) { 1216 PP.Diag(FirstTok, diag::warn_pragma_omp_ignored); 1217 PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored, 1218 diag::Severity::Ignored, SourceLocation()); 1219 } 1220 PP.DiscardUntilEndOfDirective(); 1221 } 1222 1223 /// \brief Handle '#pragma omp ...' when OpenMP is enabled. 1224 /// 1225 void 1226 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP, 1227 PragmaIntroducerKind Introducer, 1228 Token &FirstTok) { 1229 SmallVector<Token, 16> Pragma; 1230 Token Tok; 1231 Tok.startToken(); 1232 Tok.setKind(tok::annot_pragma_openmp); 1233 Tok.setLocation(FirstTok.getLocation()); 1234 1235 while (Tok.isNot(tok::eod)) { 1236 Pragma.push_back(Tok); 1237 PP.Lex(Tok); 1238 } 1239 SourceLocation EodLoc = Tok.getLocation(); 1240 Tok.startToken(); 1241 Tok.setKind(tok::annot_pragma_openmp_end); 1242 Tok.setLocation(EodLoc); 1243 Pragma.push_back(Tok); 1244 1245 Token *Toks = new Token[Pragma.size()]; 1246 std::copy(Pragma.begin(), Pragma.end(), Toks); 1247 PP.EnterTokenStream(Toks, Pragma.size(), 1248 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true); 1249 } 1250 1251 /// \brief Handle '#pragma pointers_to_members' 1252 // The grammar for this pragma is as follows: 1253 // 1254 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance' 1255 // 1256 // #pragma pointers_to_members '(' 'best_case' ')' 1257 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')' 1258 // #pragma pointers_to_members '(' inheritance-model ')' 1259 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP, 1260 PragmaIntroducerKind Introducer, 1261 Token &Tok) { 1262 SourceLocation PointersToMembersLoc = Tok.getLocation(); 1263 PP.Lex(Tok); 1264 if (Tok.isNot(tok::l_paren)) { 1265 PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen) 1266 << "pointers_to_members"; 1267 return; 1268 } 1269 PP.Lex(Tok); 1270 const IdentifierInfo *Arg = Tok.getIdentifierInfo(); 1271 if (!Arg) { 1272 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 1273 << "pointers_to_members"; 1274 return; 1275 } 1276 PP.Lex(Tok); 1277 1278 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod; 1279 if (Arg->isStr("best_case")) { 1280 RepresentationMethod = LangOptions::PPTMK_BestCase; 1281 } else { 1282 if (Arg->isStr("full_generality")) { 1283 if (Tok.is(tok::comma)) { 1284 PP.Lex(Tok); 1285 1286 Arg = Tok.getIdentifierInfo(); 1287 if (!Arg) { 1288 PP.Diag(Tok.getLocation(), 1289 diag::err_pragma_pointers_to_members_unknown_kind) 1290 << Tok.getKind() << /*OnlyInheritanceModels*/ 0; 1291 return; 1292 } 1293 PP.Lex(Tok); 1294 } else if (Tok.is(tok::r_paren)) { 1295 // #pragma pointers_to_members(full_generality) implicitly specifies 1296 // virtual_inheritance. 1297 Arg = nullptr; 1298 RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance; 1299 } else { 1300 PP.Diag(Tok.getLocation(), diag::err_expected_punc) 1301 << "full_generality"; 1302 return; 1303 } 1304 } 1305 1306 if (Arg) { 1307 if (Arg->isStr("single_inheritance")) { 1308 RepresentationMethod = 1309 LangOptions::PPTMK_FullGeneralitySingleInheritance; 1310 } else if (Arg->isStr("multiple_inheritance")) { 1311 RepresentationMethod = 1312 LangOptions::PPTMK_FullGeneralityMultipleInheritance; 1313 } else if (Arg->isStr("virtual_inheritance")) { 1314 RepresentationMethod = 1315 LangOptions::PPTMK_FullGeneralityVirtualInheritance; 1316 } else { 1317 PP.Diag(Tok.getLocation(), 1318 diag::err_pragma_pointers_to_members_unknown_kind) 1319 << Arg << /*HasPointerDeclaration*/ 1; 1320 return; 1321 } 1322 } 1323 } 1324 1325 if (Tok.isNot(tok::r_paren)) { 1326 PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after) 1327 << (Arg ? Arg->getName() : "full_generality"); 1328 return; 1329 } 1330 1331 PP.Lex(Tok); 1332 if (Tok.isNot(tok::eod)) { 1333 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 1334 << "pointers_to_members"; 1335 return; 1336 } 1337 1338 Token AnnotTok; 1339 AnnotTok.startToken(); 1340 AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members); 1341 AnnotTok.setLocation(PointersToMembersLoc); 1342 AnnotTok.setAnnotationValue( 1343 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod))); 1344 PP.EnterToken(AnnotTok); 1345 } 1346 1347 /// \brief Handle '#pragma vtordisp' 1348 // The grammar for this pragma is as follows: 1349 // 1350 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' ) 1351 // 1352 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')' 1353 // #pragma vtordisp '(' 'pop' ')' 1354 // #pragma vtordisp '(' ')' 1355 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP, 1356 PragmaIntroducerKind Introducer, 1357 Token &Tok) { 1358 SourceLocation VtorDispLoc = Tok.getLocation(); 1359 PP.Lex(Tok); 1360 if (Tok.isNot(tok::l_paren)) { 1361 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp"; 1362 return; 1363 } 1364 PP.Lex(Tok); 1365 1366 Sema::PragmaVtorDispKind Kind = Sema::PVDK_Set; 1367 const IdentifierInfo *II = Tok.getIdentifierInfo(); 1368 if (II) { 1369 if (II->isStr("push")) { 1370 // #pragma vtordisp(push, mode) 1371 PP.Lex(Tok); 1372 if (Tok.isNot(tok::comma)) { 1373 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp"; 1374 return; 1375 } 1376 PP.Lex(Tok); 1377 Kind = Sema::PVDK_Push; 1378 // not push, could be on/off 1379 } else if (II->isStr("pop")) { 1380 // #pragma vtordisp(pop) 1381 PP.Lex(Tok); 1382 Kind = Sema::PVDK_Pop; 1383 } 1384 // not push or pop, could be on/off 1385 } else { 1386 if (Tok.is(tok::r_paren)) { 1387 // #pragma vtordisp() 1388 Kind = Sema::PVDK_Reset; 1389 } 1390 } 1391 1392 1393 uint64_t Value = 0; 1394 if (Kind == Sema::PVDK_Push || Kind == Sema::PVDK_Set) { 1395 const IdentifierInfo *II = Tok.getIdentifierInfo(); 1396 if (II && II->isStr("off")) { 1397 PP.Lex(Tok); 1398 Value = 0; 1399 } else if (II && II->isStr("on")) { 1400 PP.Lex(Tok); 1401 Value = 1; 1402 } else if (Tok.is(tok::numeric_constant) && 1403 PP.parseSimpleIntegerLiteral(Tok, Value)) { 1404 if (Value > 2) { 1405 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer) 1406 << 0 << 2 << "vtordisp"; 1407 return; 1408 } 1409 } else { 1410 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) 1411 << "vtordisp"; 1412 return; 1413 } 1414 } 1415 1416 // Finish the pragma: ')' $ 1417 if (Tok.isNot(tok::r_paren)) { 1418 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp"; 1419 return; 1420 } 1421 PP.Lex(Tok); 1422 if (Tok.isNot(tok::eod)) { 1423 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 1424 << "vtordisp"; 1425 return; 1426 } 1427 1428 // Enter the annotation. 1429 Token AnnotTok; 1430 AnnotTok.startToken(); 1431 AnnotTok.setKind(tok::annot_pragma_ms_vtordisp); 1432 AnnotTok.setLocation(VtorDispLoc); 1433 AnnotTok.setAnnotationValue(reinterpret_cast<void *>( 1434 static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF)))); 1435 PP.EnterToken(AnnotTok); 1436 } 1437 1438 /// \brief Handle all MS pragmas. Simply forwards the tokens after inserting 1439 /// an annotation token. 1440 void PragmaMSPragma::HandlePragma(Preprocessor &PP, 1441 PragmaIntroducerKind Introducer, 1442 Token &Tok) { 1443 Token EoF, AnnotTok; 1444 EoF.startToken(); 1445 EoF.setKind(tok::eof); 1446 AnnotTok.startToken(); 1447 AnnotTok.setKind(tok::annot_pragma_ms_pragma); 1448 AnnotTok.setLocation(Tok.getLocation()); 1449 SmallVector<Token, 8> TokenVector; 1450 // Suck up all of the tokens before the eod. 1451 for (; Tok.isNot(tok::eod); PP.Lex(Tok)) 1452 TokenVector.push_back(Tok); 1453 // Add a sentinal EoF token to the end of the list. 1454 TokenVector.push_back(EoF); 1455 // We must allocate this array with new because EnterTokenStream is going to 1456 // delete it later. 1457 Token *TokenArray = new Token[TokenVector.size()]; 1458 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray); 1459 auto Value = new (PP.getPreprocessorAllocator()) 1460 std::pair<Token*, size_t>(std::make_pair(TokenArray, TokenVector.size())); 1461 AnnotTok.setAnnotationValue(Value); 1462 PP.EnterToken(AnnotTok); 1463 } 1464 1465 /// \brief Handle the Microsoft \#pragma detect_mismatch extension. 1466 /// 1467 /// The syntax is: 1468 /// \code 1469 /// #pragma detect_mismatch("name", "value") 1470 /// \endcode 1471 /// Where 'name' and 'value' are quoted strings. The values are embedded in 1472 /// the object file and passed along to the linker. If the linker detects a 1473 /// mismatch in the object file's values for the given name, a LNK2038 error 1474 /// is emitted. See MSDN for more details. 1475 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP, 1476 PragmaIntroducerKind Introducer, 1477 Token &Tok) { 1478 SourceLocation CommentLoc = Tok.getLocation(); 1479 PP.Lex(Tok); 1480 if (Tok.isNot(tok::l_paren)) { 1481 PP.Diag(CommentLoc, diag::err_expected) << tok::l_paren; 1482 return; 1483 } 1484 1485 // Read the name to embed, which must be a string literal. 1486 std::string NameString; 1487 if (!PP.LexStringLiteral(Tok, NameString, 1488 "pragma detect_mismatch", 1489 /*MacroExpansion=*/true)) 1490 return; 1491 1492 // Read the comma followed by a second string literal. 1493 std::string ValueString; 1494 if (Tok.isNot(tok::comma)) { 1495 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed); 1496 return; 1497 } 1498 1499 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch", 1500 /*MacroExpansion=*/true)) 1501 return; 1502 1503 if (Tok.isNot(tok::r_paren)) { 1504 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren; 1505 return; 1506 } 1507 PP.Lex(Tok); // Eat the r_paren. 1508 1509 if (Tok.isNot(tok::eod)) { 1510 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed); 1511 return; 1512 } 1513 1514 // If the pragma is lexically sound, notify any interested PPCallbacks. 1515 if (PP.getPPCallbacks()) 1516 PP.getPPCallbacks()->PragmaDetectMismatch(CommentLoc, NameString, 1517 ValueString); 1518 1519 Actions.ActOnPragmaDetectMismatch(NameString, ValueString); 1520 } 1521 1522 /// \brief Handle the microsoft \#pragma comment extension. 1523 /// 1524 /// The syntax is: 1525 /// \code 1526 /// #pragma comment(linker, "foo") 1527 /// \endcode 1528 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user. 1529 /// "foo" is a string, which is fully macro expanded, and permits string 1530 /// concatenation, embedded escape characters etc. See MSDN for more details. 1531 void PragmaCommentHandler::HandlePragma(Preprocessor &PP, 1532 PragmaIntroducerKind Introducer, 1533 Token &Tok) { 1534 SourceLocation CommentLoc = Tok.getLocation(); 1535 PP.Lex(Tok); 1536 if (Tok.isNot(tok::l_paren)) { 1537 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed); 1538 return; 1539 } 1540 1541 // Read the identifier. 1542 PP.Lex(Tok); 1543 if (Tok.isNot(tok::identifier)) { 1544 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed); 1545 return; 1546 } 1547 1548 // Verify that this is one of the 5 whitelisted options. 1549 IdentifierInfo *II = Tok.getIdentifierInfo(); 1550 Sema::PragmaMSCommentKind Kind = 1551 llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName()) 1552 .Case("linker", Sema::PCK_Linker) 1553 .Case("lib", Sema::PCK_Lib) 1554 .Case("compiler", Sema::PCK_Compiler) 1555 .Case("exestr", Sema::PCK_ExeStr) 1556 .Case("user", Sema::PCK_User) 1557 .Default(Sema::PCK_Unknown); 1558 if (Kind == Sema::PCK_Unknown) { 1559 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind); 1560 return; 1561 } 1562 1563 // Read the optional string if present. 1564 PP.Lex(Tok); 1565 std::string ArgumentString; 1566 if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString, 1567 "pragma comment", 1568 /*MacroExpansion=*/true)) 1569 return; 1570 1571 // FIXME: warn that 'exestr' is deprecated. 1572 // FIXME: If the kind is "compiler" warn if the string is present (it is 1573 // ignored). 1574 // The MSDN docs say that "lib" and "linker" require a string and have a short 1575 // whitelist of linker options they support, but in practice MSVC doesn't 1576 // issue a diagnostic. Therefore neither does clang. 1577 1578 if (Tok.isNot(tok::r_paren)) { 1579 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); 1580 return; 1581 } 1582 PP.Lex(Tok); // eat the r_paren. 1583 1584 if (Tok.isNot(tok::eod)) { 1585 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); 1586 return; 1587 } 1588 1589 // If the pragma is lexically sound, notify any interested PPCallbacks. 1590 if (PP.getPPCallbacks()) 1591 PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString); 1592 1593 Actions.ActOnPragmaMSComment(Kind, ArgumentString); 1594 } 1595 1596 // #pragma clang optimize off 1597 // #pragma clang optimize on 1598 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP, 1599 PragmaIntroducerKind Introducer, 1600 Token &FirstToken) { 1601 Token Tok; 1602 PP.Lex(Tok); 1603 if (Tok.is(tok::eod)) { 1604 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_missing_argument); 1605 return; 1606 } 1607 if (Tok.isNot(tok::identifier)) { 1608 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument) 1609 << PP.getSpelling(Tok); 1610 return; 1611 } 1612 const IdentifierInfo *II = Tok.getIdentifierInfo(); 1613 // The only accepted values are 'on' or 'off'. 1614 bool IsOn = false; 1615 if (II->isStr("on")) { 1616 IsOn = true; 1617 } else if (!II->isStr("off")) { 1618 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument) 1619 << PP.getSpelling(Tok); 1620 return; 1621 } 1622 PP.Lex(Tok); 1623 1624 if (Tok.isNot(tok::eod)) { 1625 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument) 1626 << PP.getSpelling(Tok); 1627 return; 1628 } 1629 1630 Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation()); 1631 } 1632 1633 /// \brief Handle the \#pragma clang loop directive. 1634 /// #pragma clang 'loop' loop-hints 1635 /// 1636 /// loop-hints: 1637 /// loop-hint loop-hints[opt] 1638 /// 1639 /// loop-hint: 1640 /// 'vectorize' '(' loop-hint-keyword ')' 1641 /// 'interleave' '(' loop-hint-keyword ')' 1642 /// 'unroll' '(' loop-hint-keyword ')' 1643 /// 'vectorize_width' '(' loop-hint-value ')' 1644 /// 'interleave_count' '(' loop-hint-value ')' 1645 /// 'unroll_count' '(' loop-hint-value ')' 1646 /// 1647 /// loop-hint-keyword: 1648 /// 'enable' 1649 /// 'disable' 1650 /// 1651 /// loop-hint-value: 1652 /// constant-expression 1653 /// 1654 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to 1655 /// try vectorizing the instructions of the loop it precedes. Specifying 1656 /// interleave(enable) or interleave_count(_value_) instructs llvm to try 1657 /// interleaving multiple iterations of the loop it precedes. The width of the 1658 /// vector instructions is specified by vectorize_width() and the number of 1659 /// interleaved loop iterations is specified by interleave_count(). Specifying a 1660 /// value of 1 effectively disables vectorization/interleaving, even if it is 1661 /// possible and profitable, and 0 is invalid. The loop vectorizer currently 1662 /// only works on inner loops. 1663 /// 1664 /// The unroll and unroll_count directives control the concatenation 1665 /// unroller. Specifying unroll(enable) instructs llvm to try to 1666 /// unroll the loop completely, and unroll(disable) disables unrolling 1667 /// for the loop. Specifying unroll_count(_value_) instructs llvm to 1668 /// try to unroll the loop the number of times indicated by the value. 1669 /// If unroll(enable) and unroll_count are both specified only 1670 /// unroll_count takes effect. 1671 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP, 1672 PragmaIntroducerKind Introducer, 1673 Token &Tok) { 1674 Token Loop = Tok; 1675 SmallVector<Token, 1> TokenList; 1676 1677 // Lex the optimization option and verify it is an identifier. 1678 PP.Lex(Tok); 1679 if (Tok.isNot(tok::identifier)) { 1680 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option) 1681 << /*MissingOption=*/true << ""; 1682 return; 1683 } 1684 1685 while (Tok.is(tok::identifier)) { 1686 Token Option = Tok; 1687 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo(); 1688 1689 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName()) 1690 .Case("vectorize", true) 1691 .Case("interleave", true) 1692 .Case("unroll", true) 1693 .Case("vectorize_width", true) 1694 .Case("interleave_count", true) 1695 .Case("unroll_count", true) 1696 .Default(false); 1697 if (!OptionValid) { 1698 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option) 1699 << /*MissingOption=*/false << OptionInfo; 1700 return; 1701 } 1702 1703 // Read '(' 1704 PP.Lex(Tok); 1705 if (Tok.isNot(tok::l_paren)) { 1706 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren; 1707 return; 1708 } 1709 1710 // FIXME: All tokens between '(' and ')' should be stored and parsed as a 1711 // constant expression. 1712 PP.Lex(Tok); 1713 if (Tok.is(tok::r_paren)) { 1714 // Nothing between the parentheses. 1715 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_missing_argument) 1716 << OptionInfo; 1717 return; 1718 } 1719 Token Value = Tok; 1720 1721 // Read ')' 1722 PP.Lex(Tok); 1723 if (Tok.isNot(tok::r_paren)) { 1724 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren; 1725 return; 1726 } 1727 1728 // Get next optimization option. 1729 PP.Lex(Tok); 1730 1731 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo; 1732 Info->Loop = Loop; 1733 Info->Option = Option; 1734 Info->Value = Value; 1735 1736 // Generate the vectorization hint token. 1737 Token LoopHintTok; 1738 LoopHintTok.startToken(); 1739 LoopHintTok.setKind(tok::annot_pragma_loop_hint); 1740 LoopHintTok.setLocation(Loop.getLocation()); 1741 LoopHintTok.setAnnotationValue(static_cast<void *>(Info)); 1742 TokenList.push_back(LoopHintTok); 1743 } 1744 1745 if (Tok.isNot(tok::eod)) { 1746 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 1747 << "clang loop"; 1748 return; 1749 } 1750 1751 Token *TokenArray = new Token[TokenList.size()]; 1752 std::copy(TokenList.begin(), TokenList.end(), TokenArray); 1753 1754 PP.EnterTokenStream(TokenArray, TokenList.size(), 1755 /*DisableMacroExpansion=*/false, 1756 /*OwnsTokens=*/true); 1757 } 1758