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/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; 25 26 namespace { 27 28 struct PragmaAlignHandler : public PragmaHandler { 29 explicit PragmaAlignHandler() : PragmaHandler("align") {} 30 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 31 Token &FirstToken) override; 32 }; 33 34 struct PragmaGCCVisibilityHandler : public PragmaHandler { 35 explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {} 36 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 37 Token &FirstToken) override; 38 }; 39 40 struct PragmaOptionsHandler : public PragmaHandler { 41 explicit PragmaOptionsHandler() : PragmaHandler("options") {} 42 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 43 Token &FirstToken) override; 44 }; 45 46 struct PragmaPackHandler : public PragmaHandler { 47 explicit PragmaPackHandler() : PragmaHandler("pack") {} 48 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 49 Token &FirstToken) override; 50 }; 51 52 struct PragmaMSStructHandler : public PragmaHandler { 53 explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {} 54 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 55 Token &FirstToken) override; 56 }; 57 58 struct PragmaUnusedHandler : public PragmaHandler { 59 PragmaUnusedHandler() : PragmaHandler("unused") {} 60 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 61 Token &FirstToken) override; 62 }; 63 64 struct PragmaWeakHandler : public PragmaHandler { 65 explicit PragmaWeakHandler() : PragmaHandler("weak") {} 66 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 67 Token &FirstToken) override; 68 }; 69 70 struct PragmaRedefineExtnameHandler : public PragmaHandler { 71 explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {} 72 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 73 Token &FirstToken) override; 74 }; 75 76 struct PragmaOpenCLExtensionHandler : public PragmaHandler { 77 PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {} 78 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 79 Token &FirstToken) override; 80 }; 81 82 83 struct PragmaFPContractHandler : public PragmaHandler { 84 PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {} 85 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 86 Token &FirstToken) override; 87 }; 88 89 struct PragmaNoOpenMPHandler : public PragmaHandler { 90 PragmaNoOpenMPHandler() : PragmaHandler("omp") { } 91 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 92 Token &FirstToken) override; 93 }; 94 95 struct PragmaOpenMPHandler : public PragmaHandler { 96 PragmaOpenMPHandler() : PragmaHandler("omp") { } 97 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 98 Token &FirstToken) override; 99 }; 100 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; 107 private: 108 Sema &Actions; 109 }; 110 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; 116 private: 117 Sema &Actions; 118 }; 119 120 struct PragmaMSPointersToMembers : public PragmaHandler { 121 explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {} 122 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 123 Token &FirstToken) override; 124 }; 125 126 struct PragmaMSVtorDisp : public PragmaHandler { 127 explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {} 128 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 129 Token &FirstToken) override; 130 }; 131 132 struct PragmaMSPragma : public PragmaHandler { 133 explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {} 134 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 135 Token &FirstToken) override; 136 }; 137 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; 144 private: 145 Sema &Actions; 146 }; 147 148 struct PragmaLoopHintHandler : public PragmaHandler { 149 PragmaLoopHintHandler() : PragmaHandler("loop") {} 150 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 151 Token &FirstToken) override; 152 }; 153 154 struct PragmaUnrollHintHandler : public PragmaHandler { 155 PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {} 156 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 157 Token &FirstToken) override; 158 }; 159 160 struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler { 161 PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {} 162 }; 163 164 } // end namespace 165 166 void Parser::initializePragmaHandlers() { 167 AlignHandler.reset(new PragmaAlignHandler()); 168 PP.AddPragmaHandler(AlignHandler.get()); 169 170 GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler()); 171 PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get()); 172 173 OptionsHandler.reset(new PragmaOptionsHandler()); 174 PP.AddPragmaHandler(OptionsHandler.get()); 175 176 PackHandler.reset(new PragmaPackHandler()); 177 PP.AddPragmaHandler(PackHandler.get()); 178 179 MSStructHandler.reset(new PragmaMSStructHandler()); 180 PP.AddPragmaHandler(MSStructHandler.get()); 181 182 UnusedHandler.reset(new PragmaUnusedHandler()); 183 PP.AddPragmaHandler(UnusedHandler.get()); 184 185 WeakHandler.reset(new PragmaWeakHandler()); 186 PP.AddPragmaHandler(WeakHandler.get()); 187 188 RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler()); 189 PP.AddPragmaHandler(RedefineExtnameHandler.get()); 190 191 FPContractHandler.reset(new PragmaFPContractHandler()); 192 PP.AddPragmaHandler("STDC", FPContractHandler.get()); 193 194 if (getLangOpts().OpenCL) { 195 OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler()); 196 PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get()); 197 198 PP.AddPragmaHandler("OPENCL", FPContractHandler.get()); 199 } 200 if (getLangOpts().OpenMP) 201 OpenMPHandler.reset(new PragmaOpenMPHandler()); 202 else 203 OpenMPHandler.reset(new PragmaNoOpenMPHandler()); 204 PP.AddPragmaHandler(OpenMPHandler.get()); 205 206 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) { 207 MSCommentHandler.reset(new PragmaCommentHandler(Actions)); 208 PP.AddPragmaHandler(MSCommentHandler.get()); 209 } 210 211 if (getLangOpts().MicrosoftExt) { 212 MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions)); 213 PP.AddPragmaHandler(MSDetectMismatchHandler.get()); 214 MSPointersToMembers.reset(new PragmaMSPointersToMembers()); 215 PP.AddPragmaHandler(MSPointersToMembers.get()); 216 MSVtorDisp.reset(new PragmaMSVtorDisp()); 217 PP.AddPragmaHandler(MSVtorDisp.get()); 218 MSInitSeg.reset(new PragmaMSPragma("init_seg")); 219 PP.AddPragmaHandler(MSInitSeg.get()); 220 MSDataSeg.reset(new PragmaMSPragma("data_seg")); 221 PP.AddPragmaHandler(MSDataSeg.get()); 222 MSBSSSeg.reset(new PragmaMSPragma("bss_seg")); 223 PP.AddPragmaHandler(MSBSSSeg.get()); 224 MSConstSeg.reset(new PragmaMSPragma("const_seg")); 225 PP.AddPragmaHandler(MSConstSeg.get()); 226 MSCodeSeg.reset(new PragmaMSPragma("code_seg")); 227 PP.AddPragmaHandler(MSCodeSeg.get()); 228 MSSection.reset(new PragmaMSPragma("section")); 229 PP.AddPragmaHandler(MSSection.get()); 230 MSRuntimeChecks.reset(new PragmaMSRuntimeChecksHandler()); 231 PP.AddPragmaHandler(MSRuntimeChecks.get()); 232 } 233 234 OptimizeHandler.reset(new PragmaOptimizeHandler(Actions)); 235 PP.AddPragmaHandler("clang", OptimizeHandler.get()); 236 237 LoopHintHandler.reset(new PragmaLoopHintHandler()); 238 PP.AddPragmaHandler("clang", LoopHintHandler.get()); 239 240 UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll")); 241 PP.AddPragmaHandler(UnrollHintHandler.get()); 242 243 NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll")); 244 PP.AddPragmaHandler(NoUnrollHintHandler.get()); 245 } 246 247 void Parser::resetPragmaHandlers() { 248 // Remove the pragma handlers we installed. 249 PP.RemovePragmaHandler(AlignHandler.get()); 250 AlignHandler.reset(); 251 PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get()); 252 GCCVisibilityHandler.reset(); 253 PP.RemovePragmaHandler(OptionsHandler.get()); 254 OptionsHandler.reset(); 255 PP.RemovePragmaHandler(PackHandler.get()); 256 PackHandler.reset(); 257 PP.RemovePragmaHandler(MSStructHandler.get()); 258 MSStructHandler.reset(); 259 PP.RemovePragmaHandler(UnusedHandler.get()); 260 UnusedHandler.reset(); 261 PP.RemovePragmaHandler(WeakHandler.get()); 262 WeakHandler.reset(); 263 PP.RemovePragmaHandler(RedefineExtnameHandler.get()); 264 RedefineExtnameHandler.reset(); 265 266 if (getLangOpts().OpenCL) { 267 PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get()); 268 OpenCLExtensionHandler.reset(); 269 PP.RemovePragmaHandler("OPENCL", FPContractHandler.get()); 270 } 271 PP.RemovePragmaHandler(OpenMPHandler.get()); 272 OpenMPHandler.reset(); 273 274 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) { 275 PP.RemovePragmaHandler(MSCommentHandler.get()); 276 MSCommentHandler.reset(); 277 } 278 279 if (getLangOpts().MicrosoftExt) { 280 PP.RemovePragmaHandler(MSDetectMismatchHandler.get()); 281 MSDetectMismatchHandler.reset(); 282 PP.RemovePragmaHandler(MSPointersToMembers.get()); 283 MSPointersToMembers.reset(); 284 PP.RemovePragmaHandler(MSVtorDisp.get()); 285 MSVtorDisp.reset(); 286 PP.RemovePragmaHandler(MSInitSeg.get()); 287 MSInitSeg.reset(); 288 PP.RemovePragmaHandler(MSDataSeg.get()); 289 MSDataSeg.reset(); 290 PP.RemovePragmaHandler(MSBSSSeg.get()); 291 MSBSSSeg.reset(); 292 PP.RemovePragmaHandler(MSConstSeg.get()); 293 MSConstSeg.reset(); 294 PP.RemovePragmaHandler(MSCodeSeg.get()); 295 MSCodeSeg.reset(); 296 PP.RemovePragmaHandler(MSSection.get()); 297 MSSection.reset(); 298 PP.RemovePragmaHandler(MSRuntimeChecks.get()); 299 MSRuntimeChecks.reset(); 300 } 301 302 PP.RemovePragmaHandler("STDC", FPContractHandler.get()); 303 FPContractHandler.reset(); 304 305 PP.RemovePragmaHandler("clang", OptimizeHandler.get()); 306 OptimizeHandler.reset(); 307 308 PP.RemovePragmaHandler("clang", LoopHintHandler.get()); 309 LoopHintHandler.reset(); 310 311 PP.RemovePragmaHandler(UnrollHintHandler.get()); 312 UnrollHintHandler.reset(); 313 314 PP.RemovePragmaHandler(NoUnrollHintHandler.get()); 315 NoUnrollHintHandler.reset(); 316 } 317 318 /// \brief Handle the annotation token produced for #pragma unused(...) 319 /// 320 /// Each annot_pragma_unused is followed by the argument token so e.g. 321 /// "#pragma unused(x,y)" becomes: 322 /// annot_pragma_unused 'x' annot_pragma_unused 'y' 323 void Parser::HandlePragmaUnused() { 324 assert(Tok.is(tok::annot_pragma_unused)); 325 SourceLocation UnusedLoc = ConsumeToken(); 326 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc); 327 ConsumeToken(); // The argument token. 328 } 329 330 void Parser::HandlePragmaVisibility() { 331 assert(Tok.is(tok::annot_pragma_vis)); 332 const IdentifierInfo *VisType = 333 static_cast<IdentifierInfo *>(Tok.getAnnotationValue()); 334 SourceLocation VisLoc = ConsumeToken(); 335 Actions.ActOnPragmaVisibility(VisType, VisLoc); 336 } 337 338 namespace { 339 struct PragmaPackInfo { 340 Sema::PragmaMsStackAction Action; 341 StringRef SlotLabel; 342 Token Alignment; 343 }; 344 } // end anonymous namespace 345 346 void Parser::HandlePragmaPack() { 347 assert(Tok.is(tok::annot_pragma_pack)); 348 PragmaPackInfo *Info = 349 static_cast<PragmaPackInfo *>(Tok.getAnnotationValue()); 350 SourceLocation PragmaLoc = ConsumeToken(); 351 ExprResult Alignment; 352 if (Info->Alignment.is(tok::numeric_constant)) { 353 Alignment = Actions.ActOnNumericConstant(Info->Alignment); 354 if (Alignment.isInvalid()) 355 return; 356 } 357 Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel, 358 Alignment.get()); 359 } 360 361 void Parser::HandlePragmaMSStruct() { 362 assert(Tok.is(tok::annot_pragma_msstruct)); 363 PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>( 364 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 365 Actions.ActOnPragmaMSStruct(Kind); 366 ConsumeToken(); // The annotation token. 367 } 368 369 void Parser::HandlePragmaAlign() { 370 assert(Tok.is(tok::annot_pragma_align)); 371 Sema::PragmaOptionsAlignKind Kind = 372 static_cast<Sema::PragmaOptionsAlignKind>( 373 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 374 SourceLocation PragmaLoc = ConsumeToken(); 375 Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc); 376 } 377 378 void Parser::HandlePragmaDump() { 379 assert(Tok.is(tok::annot_pragma_dump)); 380 IdentifierInfo *II = 381 reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue()); 382 Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II); 383 ConsumeToken(); 384 } 385 386 void Parser::HandlePragmaWeak() { 387 assert(Tok.is(tok::annot_pragma_weak)); 388 SourceLocation PragmaLoc = ConsumeToken(); 389 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc, 390 Tok.getLocation()); 391 ConsumeToken(); // The weak name. 392 } 393 394 void Parser::HandlePragmaWeakAlias() { 395 assert(Tok.is(tok::annot_pragma_weakalias)); 396 SourceLocation PragmaLoc = ConsumeToken(); 397 IdentifierInfo *WeakName = Tok.getIdentifierInfo(); 398 SourceLocation WeakNameLoc = Tok.getLocation(); 399 ConsumeToken(); 400 IdentifierInfo *AliasName = Tok.getIdentifierInfo(); 401 SourceLocation AliasNameLoc = Tok.getLocation(); 402 ConsumeToken(); 403 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc, 404 WeakNameLoc, AliasNameLoc); 405 406 } 407 408 void Parser::HandlePragmaRedefineExtname() { 409 assert(Tok.is(tok::annot_pragma_redefine_extname)); 410 SourceLocation RedefLoc = ConsumeToken(); 411 IdentifierInfo *RedefName = Tok.getIdentifierInfo(); 412 SourceLocation RedefNameLoc = Tok.getLocation(); 413 ConsumeToken(); 414 IdentifierInfo *AliasName = Tok.getIdentifierInfo(); 415 SourceLocation AliasNameLoc = Tok.getLocation(); 416 ConsumeToken(); 417 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc, 418 RedefNameLoc, AliasNameLoc); 419 } 420 421 void Parser::HandlePragmaFPContract() { 422 assert(Tok.is(tok::annot_pragma_fp_contract)); 423 tok::OnOffSwitch OOS = 424 static_cast<tok::OnOffSwitch>( 425 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 426 Actions.ActOnPragmaFPContract(OOS); 427 ConsumeToken(); // The annotation token. 428 } 429 430 StmtResult Parser::HandlePragmaCaptured() 431 { 432 assert(Tok.is(tok::annot_pragma_captured)); 433 ConsumeToken(); 434 435 if (Tok.isNot(tok::l_brace)) { 436 PP.Diag(Tok, diag::err_expected) << tok::l_brace; 437 return StmtError(); 438 } 439 440 SourceLocation Loc = Tok.getLocation(); 441 442 ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope); 443 Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default, 444 /*NumParams=*/1); 445 446 StmtResult R = ParseCompoundStatement(); 447 CapturedRegionScope.Exit(); 448 449 if (R.isInvalid()) { 450 Actions.ActOnCapturedRegionError(); 451 return StmtError(); 452 } 453 454 return Actions.ActOnCapturedRegionEnd(R.get()); 455 } 456 457 namespace { 458 typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData; 459 } 460 461 void Parser::HandlePragmaOpenCLExtension() { 462 assert(Tok.is(tok::annot_pragma_opencl_extension)); 463 OpenCLExtData data = 464 OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue()); 465 unsigned state = data.getInt(); 466 IdentifierInfo *ename = data.getPointer(); 467 SourceLocation NameLoc = Tok.getLocation(); 468 ConsumeToken(); // The annotation token. 469 470 OpenCLOptions &f = Actions.getOpenCLOptions(); 471 auto CLVer = getLangOpts().OpenCLVersion; 472 auto &Supp = getTargetInfo().getSupportedOpenCLOpts(); 473 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions, 474 // overriding all previously issued extension directives, but only if the 475 // behavior is set to disable." 476 if (state == 0 && ename->isStr("all")) { 477 #define OPENCLEXT(nm) \ 478 if (Supp.is_##nm##_supported_extension(CLVer)) \ 479 f.nm = 0; 480 #include "clang/Basic/OpenCLExtensions.def" 481 } 482 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) \ 483 if (Supp.is_##nm##_supported_extension(CLVer)) \ 484 f.nm = state; \ 485 else if (Supp.is_##nm##_supported_core(CLVer)) \ 486 PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << ename; \ 487 else \ 488 PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << ename; 489 #include "clang/Basic/OpenCLExtensions.def" 490 else { 491 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename; 492 return; 493 } 494 } 495 496 void Parser::HandlePragmaMSPointersToMembers() { 497 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members)); 498 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod = 499 static_cast<LangOptions::PragmaMSPointersToMembersKind>( 500 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 501 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token. 502 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc); 503 } 504 505 void Parser::HandlePragmaMSVtorDisp() { 506 assert(Tok.is(tok::annot_pragma_ms_vtordisp)); 507 uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()); 508 Sema::PragmaMsStackAction Action = 509 static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF); 510 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF); 511 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token. 512 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode); 513 } 514 515 void Parser::HandlePragmaMSPragma() { 516 assert(Tok.is(tok::annot_pragma_ms_pragma)); 517 // Grab the tokens out of the annotation and enter them into the stream. 518 auto TheTokens = 519 (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue(); 520 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true); 521 SourceLocation PragmaLocation = ConsumeToken(); // The annotation token. 522 assert(Tok.isAnyIdentifier()); 523 StringRef PragmaName = Tok.getIdentifierInfo()->getName(); 524 PP.Lex(Tok); // pragma kind 525 526 // Figure out which #pragma we're dealing with. The switch has no default 527 // because lex shouldn't emit the annotation token for unrecognized pragmas. 528 typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation); 529 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName) 530 .Case("data_seg", &Parser::HandlePragmaMSSegment) 531 .Case("bss_seg", &Parser::HandlePragmaMSSegment) 532 .Case("const_seg", &Parser::HandlePragmaMSSegment) 533 .Case("code_seg", &Parser::HandlePragmaMSSegment) 534 .Case("section", &Parser::HandlePragmaMSSection) 535 .Case("init_seg", &Parser::HandlePragmaMSInitSeg); 536 537 if (!(this->*Handler)(PragmaName, PragmaLocation)) { 538 // Pragma handling failed, and has been diagnosed. Slurp up the tokens 539 // until eof (really end of line) to prevent follow-on errors. 540 while (Tok.isNot(tok::eof)) 541 PP.Lex(Tok); 542 PP.Lex(Tok); 543 } 544 } 545 546 bool Parser::HandlePragmaMSSection(StringRef PragmaName, 547 SourceLocation PragmaLocation) { 548 if (Tok.isNot(tok::l_paren)) { 549 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName; 550 return false; 551 } 552 PP.Lex(Tok); // ( 553 // Parsing code for pragma section 554 if (Tok.isNot(tok::string_literal)) { 555 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name) 556 << PragmaName; 557 return false; 558 } 559 ExprResult StringResult = ParseStringLiteralExpression(); 560 if (StringResult.isInvalid()) 561 return false; // Already diagnosed. 562 StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get()); 563 if (SegmentName->getCharByteWidth() != 1) { 564 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string) 565 << PragmaName; 566 return false; 567 } 568 int SectionFlags = ASTContext::PSF_Read; 569 bool SectionFlagsAreDefault = true; 570 while (Tok.is(tok::comma)) { 571 PP.Lex(Tok); // , 572 // Ignore "long" and "short". 573 // They are undocumented, but widely used, section attributes which appear 574 // to do nothing. 575 if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) { 576 PP.Lex(Tok); // long/short 577 continue; 578 } 579 580 if (!Tok.isAnyIdentifier()) { 581 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren) 582 << PragmaName; 583 return false; 584 } 585 ASTContext::PragmaSectionFlag Flag = 586 llvm::StringSwitch<ASTContext::PragmaSectionFlag>( 587 Tok.getIdentifierInfo()->getName()) 588 .Case("read", ASTContext::PSF_Read) 589 .Case("write", ASTContext::PSF_Write) 590 .Case("execute", ASTContext::PSF_Execute) 591 .Case("shared", ASTContext::PSF_Invalid) 592 .Case("nopage", ASTContext::PSF_Invalid) 593 .Case("nocache", ASTContext::PSF_Invalid) 594 .Case("discard", ASTContext::PSF_Invalid) 595 .Case("remove", ASTContext::PSF_Invalid) 596 .Default(ASTContext::PSF_None); 597 if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) { 598 PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None 599 ? diag::warn_pragma_invalid_specific_action 600 : diag::warn_pragma_unsupported_action) 601 << PragmaName << Tok.getIdentifierInfo()->getName(); 602 return false; 603 } 604 SectionFlags |= Flag; 605 SectionFlagsAreDefault = false; 606 PP.Lex(Tok); // Identifier 607 } 608 // If no section attributes are specified, the section will be marked as 609 // read/write. 610 if (SectionFlagsAreDefault) 611 SectionFlags |= ASTContext::PSF_Write; 612 if (Tok.isNot(tok::r_paren)) { 613 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName; 614 return false; 615 } 616 PP.Lex(Tok); // ) 617 if (Tok.isNot(tok::eof)) { 618 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol) 619 << PragmaName; 620 return false; 621 } 622 PP.Lex(Tok); // eof 623 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName); 624 return true; 625 } 626 627 bool Parser::HandlePragmaMSSegment(StringRef PragmaName, 628 SourceLocation PragmaLocation) { 629 if (Tok.isNot(tok::l_paren)) { 630 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName; 631 return false; 632 } 633 PP.Lex(Tok); // ( 634 Sema::PragmaMsStackAction Action = Sema::PSK_Reset; 635 StringRef SlotLabel; 636 if (Tok.isAnyIdentifier()) { 637 StringRef PushPop = Tok.getIdentifierInfo()->getName(); 638 if (PushPop == "push") 639 Action = Sema::PSK_Push; 640 else if (PushPop == "pop") 641 Action = Sema::PSK_Pop; 642 else { 643 PP.Diag(PragmaLocation, 644 diag::warn_pragma_expected_section_push_pop_or_name) 645 << PragmaName; 646 return false; 647 } 648 if (Action != Sema::PSK_Reset) { 649 PP.Lex(Tok); // push | pop 650 if (Tok.is(tok::comma)) { 651 PP.Lex(Tok); // , 652 // If we've got a comma, we either need a label or a string. 653 if (Tok.isAnyIdentifier()) { 654 SlotLabel = Tok.getIdentifierInfo()->getName(); 655 PP.Lex(Tok); // identifier 656 if (Tok.is(tok::comma)) 657 PP.Lex(Tok); 658 else if (Tok.isNot(tok::r_paren)) { 659 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) 660 << PragmaName; 661 return false; 662 } 663 } 664 } else if (Tok.isNot(tok::r_paren)) { 665 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName; 666 return false; 667 } 668 } 669 } 670 // Grab the string literal for our section name. 671 StringLiteral *SegmentName = nullptr; 672 if (Tok.isNot(tok::r_paren)) { 673 if (Tok.isNot(tok::string_literal)) { 674 unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ? 675 diag::warn_pragma_expected_section_name : 676 diag::warn_pragma_expected_section_label_or_name : 677 diag::warn_pragma_expected_section_push_pop_or_name; 678 PP.Diag(PragmaLocation, DiagID) << PragmaName; 679 return false; 680 } 681 ExprResult StringResult = ParseStringLiteralExpression(); 682 if (StringResult.isInvalid()) 683 return false; // Already diagnosed. 684 SegmentName = cast<StringLiteral>(StringResult.get()); 685 if (SegmentName->getCharByteWidth() != 1) { 686 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string) 687 << PragmaName; 688 return false; 689 } 690 // Setting section "" has no effect 691 if (SegmentName->getLength()) 692 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set); 693 } 694 if (Tok.isNot(tok::r_paren)) { 695 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName; 696 return false; 697 } 698 PP.Lex(Tok); // ) 699 if (Tok.isNot(tok::eof)) { 700 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol) 701 << PragmaName; 702 return false; 703 } 704 PP.Lex(Tok); // eof 705 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel, 706 SegmentName, PragmaName); 707 return true; 708 } 709 710 // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} ) 711 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName, 712 SourceLocation PragmaLocation) { 713 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) { 714 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target); 715 return false; 716 } 717 718 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen, 719 PragmaName)) 720 return false; 721 722 // Parse either the known section names or the string section name. 723 StringLiteral *SegmentName = nullptr; 724 if (Tok.isAnyIdentifier()) { 725 auto *II = Tok.getIdentifierInfo(); 726 StringRef Section = llvm::StringSwitch<StringRef>(II->getName()) 727 .Case("compiler", "\".CRT$XCC\"") 728 .Case("lib", "\".CRT$XCL\"") 729 .Case("user", "\".CRT$XCU\"") 730 .Default(""); 731 732 if (!Section.empty()) { 733 // Pretend the user wrote the appropriate string literal here. 734 Token Toks[1]; 735 Toks[0].startToken(); 736 Toks[0].setKind(tok::string_literal); 737 Toks[0].setLocation(Tok.getLocation()); 738 Toks[0].setLiteralData(Section.data()); 739 Toks[0].setLength(Section.size()); 740 SegmentName = 741 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get()); 742 PP.Lex(Tok); 743 } 744 } else if (Tok.is(tok::string_literal)) { 745 ExprResult StringResult = ParseStringLiteralExpression(); 746 if (StringResult.isInvalid()) 747 return false; 748 SegmentName = cast<StringLiteral>(StringResult.get()); 749 if (SegmentName->getCharByteWidth() != 1) { 750 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string) 751 << PragmaName; 752 return false; 753 } 754 // FIXME: Add support for the '[, func-name]' part of the pragma. 755 } 756 757 if (!SegmentName) { 758 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName; 759 return false; 760 } 761 762 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen, 763 PragmaName) || 764 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol, 765 PragmaName)) 766 return false; 767 768 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName); 769 return true; 770 } 771 772 namespace { 773 struct PragmaLoopHintInfo { 774 Token PragmaName; 775 Token Option; 776 ArrayRef<Token> Toks; 777 }; 778 } // end anonymous namespace 779 780 static std::string PragmaLoopHintString(Token PragmaName, Token Option) { 781 std::string PragmaString; 782 if (PragmaName.getIdentifierInfo()->getName() == "loop") { 783 PragmaString = "clang loop "; 784 PragmaString += Option.getIdentifierInfo()->getName(); 785 } else { 786 assert(PragmaName.getIdentifierInfo()->getName() == "unroll" && 787 "Unexpected pragma name"); 788 PragmaString = "unroll"; 789 } 790 return PragmaString; 791 } 792 793 bool Parser::HandlePragmaLoopHint(LoopHint &Hint) { 794 assert(Tok.is(tok::annot_pragma_loop_hint)); 795 PragmaLoopHintInfo *Info = 796 static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue()); 797 798 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo(); 799 Hint.PragmaNameLoc = IdentifierLoc::create( 800 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo); 801 802 // It is possible that the loop hint has no option identifier, such as 803 // #pragma unroll(4). 804 IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier) 805 ? Info->Option.getIdentifierInfo() 806 : nullptr; 807 Hint.OptionLoc = IdentifierLoc::create( 808 Actions.Context, Info->Option.getLocation(), OptionInfo); 809 810 llvm::ArrayRef<Token> Toks = Info->Toks; 811 812 // Return a valid hint if pragma unroll or nounroll were specified 813 // without an argument. 814 bool PragmaUnroll = PragmaNameInfo->getName() == "unroll"; 815 bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll"; 816 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll)) { 817 ConsumeToken(); // The annotation token. 818 Hint.Range = Info->PragmaName.getLocation(); 819 return true; 820 } 821 822 // The constant expression is always followed by an eof token, which increases 823 // the TokSize by 1. 824 assert(!Toks.empty() && 825 "PragmaLoopHintInfo::Toks must contain at least one token."); 826 827 // If no option is specified the argument is assumed to be a constant expr. 828 bool OptionUnroll = false; 829 bool OptionDistribute = false; 830 bool StateOption = false; 831 if (OptionInfo) { // Pragma Unroll does not specify an option. 832 OptionUnroll = OptionInfo->isStr("unroll"); 833 OptionDistribute = OptionInfo->isStr("distribute"); 834 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName()) 835 .Case("vectorize", true) 836 .Case("interleave", true) 837 .Default(false) || 838 OptionUnroll || OptionDistribute; 839 } 840 841 bool AssumeSafetyArg = !OptionUnroll && !OptionDistribute; 842 // Verify loop hint has an argument. 843 if (Toks[0].is(tok::eof)) { 844 ConsumeToken(); // The annotation token. 845 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument) 846 << /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll 847 << /*AssumeSafetyKeyword=*/AssumeSafetyArg; 848 return false; 849 } 850 851 // Validate the argument. 852 if (StateOption) { 853 ConsumeToken(); // The annotation token. 854 SourceLocation StateLoc = Toks[0].getLocation(); 855 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo(); 856 857 bool Valid = StateInfo && 858 llvm::StringSwitch<bool>(StateInfo->getName()) 859 .Cases("enable", "disable", true) 860 .Case("full", OptionUnroll) 861 .Case("assume_safety", AssumeSafetyArg) 862 .Default(false); 863 if (!Valid) { 864 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword) 865 << /*FullKeyword=*/OptionUnroll 866 << /*AssumeSafetyKeyword=*/AssumeSafetyArg; 867 return false; 868 } 869 if (Toks.size() > 2) 870 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 871 << PragmaLoopHintString(Info->PragmaName, Info->Option); 872 Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo); 873 } else { 874 // Enter constant expression including eof terminator into token stream. 875 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false); 876 ConsumeToken(); // The annotation token. 877 878 ExprResult R = ParseConstantExpression(); 879 880 // Tokens following an error in an ill-formed constant expression will 881 // remain in the token stream and must be removed. 882 if (Tok.isNot(tok::eof)) { 883 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 884 << PragmaLoopHintString(Info->PragmaName, Info->Option); 885 while (Tok.isNot(tok::eof)) 886 ConsumeAnyToken(); 887 } 888 889 ConsumeToken(); // Consume the constant expression eof terminator. 890 891 if (R.isInvalid() || 892 Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation())) 893 return false; 894 895 // Argument is a constant expression with an integer type. 896 Hint.ValueExpr = R.get(); 897 } 898 899 Hint.Range = SourceRange(Info->PragmaName.getLocation(), 900 Info->Toks.back().getLocation()); 901 return true; 902 } 903 904 // #pragma GCC visibility comes in two variants: 905 // 'push' '(' [visibility] ')' 906 // 'pop' 907 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, 908 PragmaIntroducerKind Introducer, 909 Token &VisTok) { 910 SourceLocation VisLoc = VisTok.getLocation(); 911 912 Token Tok; 913 PP.LexUnexpandedToken(Tok); 914 915 const IdentifierInfo *PushPop = Tok.getIdentifierInfo(); 916 917 const IdentifierInfo *VisType; 918 if (PushPop && PushPop->isStr("pop")) { 919 VisType = nullptr; 920 } else if (PushPop && PushPop->isStr("push")) { 921 PP.LexUnexpandedToken(Tok); 922 if (Tok.isNot(tok::l_paren)) { 923 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) 924 << "visibility"; 925 return; 926 } 927 PP.LexUnexpandedToken(Tok); 928 VisType = Tok.getIdentifierInfo(); 929 if (!VisType) { 930 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 931 << "visibility"; 932 return; 933 } 934 PP.LexUnexpandedToken(Tok); 935 if (Tok.isNot(tok::r_paren)) { 936 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) 937 << "visibility"; 938 return; 939 } 940 } else { 941 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 942 << "visibility"; 943 return; 944 } 945 SourceLocation EndLoc = Tok.getLocation(); 946 PP.LexUnexpandedToken(Tok); 947 if (Tok.isNot(tok::eod)) { 948 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 949 << "visibility"; 950 return; 951 } 952 953 auto Toks = llvm::make_unique<Token[]>(1); 954 Toks[0].startToken(); 955 Toks[0].setKind(tok::annot_pragma_vis); 956 Toks[0].setLocation(VisLoc); 957 Toks[0].setAnnotationEndLoc(EndLoc); 958 Toks[0].setAnnotationValue( 959 const_cast<void*>(static_cast<const void*>(VisType))); 960 PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true); 961 } 962 963 // #pragma pack(...) comes in the following delicious flavors: 964 // pack '(' [integer] ')' 965 // pack '(' 'show' ')' 966 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')' 967 void PragmaPackHandler::HandlePragma(Preprocessor &PP, 968 PragmaIntroducerKind Introducer, 969 Token &PackTok) { 970 SourceLocation PackLoc = PackTok.getLocation(); 971 972 Token Tok; 973 PP.Lex(Tok); 974 if (Tok.isNot(tok::l_paren)) { 975 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack"; 976 return; 977 } 978 979 Sema::PragmaMsStackAction Action = Sema::PSK_Reset; 980 StringRef SlotLabel; 981 Token Alignment; 982 Alignment.startToken(); 983 PP.Lex(Tok); 984 if (Tok.is(tok::numeric_constant)) { 985 Alignment = Tok; 986 987 PP.Lex(Tok); 988 989 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting 990 // the push/pop stack. 991 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4) 992 Action = 993 PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set; 994 } else if (Tok.is(tok::identifier)) { 995 const IdentifierInfo *II = Tok.getIdentifierInfo(); 996 if (II->isStr("show")) { 997 Action = Sema::PSK_Show; 998 PP.Lex(Tok); 999 } else { 1000 if (II->isStr("push")) { 1001 Action = Sema::PSK_Push; 1002 } else if (II->isStr("pop")) { 1003 Action = Sema::PSK_Pop; 1004 } else { 1005 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack"; 1006 return; 1007 } 1008 PP.Lex(Tok); 1009 1010 if (Tok.is(tok::comma)) { 1011 PP.Lex(Tok); 1012 1013 if (Tok.is(tok::numeric_constant)) { 1014 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set); 1015 Alignment = Tok; 1016 1017 PP.Lex(Tok); 1018 } else if (Tok.is(tok::identifier)) { 1019 SlotLabel = Tok.getIdentifierInfo()->getName(); 1020 PP.Lex(Tok); 1021 1022 if (Tok.is(tok::comma)) { 1023 PP.Lex(Tok); 1024 1025 if (Tok.isNot(tok::numeric_constant)) { 1026 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed); 1027 return; 1028 } 1029 1030 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set); 1031 Alignment = Tok; 1032 1033 PP.Lex(Tok); 1034 } 1035 } else { 1036 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed); 1037 return; 1038 } 1039 } 1040 } 1041 } else if (PP.getLangOpts().ApplePragmaPack) { 1042 // In MSVC/gcc, #pragma pack() resets the alignment without affecting 1043 // the push/pop stack. 1044 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop). 1045 Action = Sema::PSK_Pop; 1046 } 1047 1048 if (Tok.isNot(tok::r_paren)) { 1049 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack"; 1050 return; 1051 } 1052 1053 SourceLocation RParenLoc = Tok.getLocation(); 1054 PP.Lex(Tok); 1055 if (Tok.isNot(tok::eod)) { 1056 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack"; 1057 return; 1058 } 1059 1060 PragmaPackInfo *Info = 1061 PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1); 1062 Info->Action = Action; 1063 Info->SlotLabel = SlotLabel; 1064 Info->Alignment = Alignment; 1065 1066 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), 1067 1); 1068 Toks[0].startToken(); 1069 Toks[0].setKind(tok::annot_pragma_pack); 1070 Toks[0].setLocation(PackLoc); 1071 Toks[0].setAnnotationEndLoc(RParenLoc); 1072 Toks[0].setAnnotationValue(static_cast<void*>(Info)); 1073 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 1074 } 1075 1076 // #pragma ms_struct on 1077 // #pragma ms_struct off 1078 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, 1079 PragmaIntroducerKind Introducer, 1080 Token &MSStructTok) { 1081 PragmaMSStructKind Kind = PMSST_OFF; 1082 1083 Token Tok; 1084 PP.Lex(Tok); 1085 if (Tok.isNot(tok::identifier)) { 1086 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); 1087 return; 1088 } 1089 SourceLocation EndLoc = Tok.getLocation(); 1090 const IdentifierInfo *II = Tok.getIdentifierInfo(); 1091 if (II->isStr("on")) { 1092 Kind = PMSST_ON; 1093 PP.Lex(Tok); 1094 } 1095 else if (II->isStr("off") || II->isStr("reset")) 1096 PP.Lex(Tok); 1097 else { 1098 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); 1099 return; 1100 } 1101 1102 if (Tok.isNot(tok::eod)) { 1103 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 1104 << "ms_struct"; 1105 return; 1106 } 1107 1108 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), 1109 1); 1110 Toks[0].startToken(); 1111 Toks[0].setKind(tok::annot_pragma_msstruct); 1112 Toks[0].setLocation(MSStructTok.getLocation()); 1113 Toks[0].setAnnotationEndLoc(EndLoc); 1114 Toks[0].setAnnotationValue(reinterpret_cast<void*>( 1115 static_cast<uintptr_t>(Kind))); 1116 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 1117 } 1118 1119 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'} 1120 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'} 1121 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, 1122 bool IsOptions) { 1123 Token Tok; 1124 1125 if (IsOptions) { 1126 PP.Lex(Tok); 1127 if (Tok.isNot(tok::identifier) || 1128 !Tok.getIdentifierInfo()->isStr("align")) { 1129 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align); 1130 return; 1131 } 1132 } 1133 1134 PP.Lex(Tok); 1135 if (Tok.isNot(tok::equal)) { 1136 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal) 1137 << IsOptions; 1138 return; 1139 } 1140 1141 PP.Lex(Tok); 1142 if (Tok.isNot(tok::identifier)) { 1143 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 1144 << (IsOptions ? "options" : "align"); 1145 return; 1146 } 1147 1148 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural; 1149 const IdentifierInfo *II = Tok.getIdentifierInfo(); 1150 if (II->isStr("native")) 1151 Kind = Sema::POAK_Native; 1152 else if (II->isStr("natural")) 1153 Kind = Sema::POAK_Natural; 1154 else if (II->isStr("packed")) 1155 Kind = Sema::POAK_Packed; 1156 else if (II->isStr("power")) 1157 Kind = Sema::POAK_Power; 1158 else if (II->isStr("mac68k")) 1159 Kind = Sema::POAK_Mac68k; 1160 else if (II->isStr("reset")) 1161 Kind = Sema::POAK_Reset; 1162 else { 1163 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option) 1164 << IsOptions; 1165 return; 1166 } 1167 1168 SourceLocation EndLoc = Tok.getLocation(); 1169 PP.Lex(Tok); 1170 if (Tok.isNot(tok::eod)) { 1171 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 1172 << (IsOptions ? "options" : "align"); 1173 return; 1174 } 1175 1176 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), 1177 1); 1178 Toks[0].startToken(); 1179 Toks[0].setKind(tok::annot_pragma_align); 1180 Toks[0].setLocation(FirstTok.getLocation()); 1181 Toks[0].setAnnotationEndLoc(EndLoc); 1182 Toks[0].setAnnotationValue(reinterpret_cast<void*>( 1183 static_cast<uintptr_t>(Kind))); 1184 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 1185 } 1186 1187 void PragmaAlignHandler::HandlePragma(Preprocessor &PP, 1188 PragmaIntroducerKind Introducer, 1189 Token &AlignTok) { 1190 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false); 1191 } 1192 1193 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, 1194 PragmaIntroducerKind Introducer, 1195 Token &OptionsTok) { 1196 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true); 1197 } 1198 1199 // #pragma unused(identifier) 1200 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, 1201 PragmaIntroducerKind Introducer, 1202 Token &UnusedTok) { 1203 // FIXME: Should we be expanding macros here? My guess is no. 1204 SourceLocation UnusedLoc = UnusedTok.getLocation(); 1205 1206 // Lex the left '('. 1207 Token Tok; 1208 PP.Lex(Tok); 1209 if (Tok.isNot(tok::l_paren)) { 1210 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused"; 1211 return; 1212 } 1213 1214 // Lex the declaration reference(s). 1215 SmallVector<Token, 5> Identifiers; 1216 SourceLocation RParenLoc; 1217 bool LexID = true; 1218 1219 while (true) { 1220 PP.Lex(Tok); 1221 1222 if (LexID) { 1223 if (Tok.is(tok::identifier)) { 1224 Identifiers.push_back(Tok); 1225 LexID = false; 1226 continue; 1227 } 1228 1229 // Illegal token! 1230 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var); 1231 return; 1232 } 1233 1234 // We are execting a ')' or a ','. 1235 if (Tok.is(tok::comma)) { 1236 LexID = true; 1237 continue; 1238 } 1239 1240 if (Tok.is(tok::r_paren)) { 1241 RParenLoc = Tok.getLocation(); 1242 break; 1243 } 1244 1245 // Illegal token! 1246 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused"; 1247 return; 1248 } 1249 1250 PP.Lex(Tok); 1251 if (Tok.isNot(tok::eod)) { 1252 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << 1253 "unused"; 1254 return; 1255 } 1256 1257 // Verify that we have a location for the right parenthesis. 1258 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'"); 1259 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments"); 1260 1261 // For each identifier token, insert into the token stream a 1262 // annot_pragma_unused token followed by the identifier token. 1263 // This allows us to cache a "#pragma unused" that occurs inside an inline 1264 // C++ member function. 1265 1266 MutableArrayRef<Token> Toks( 1267 PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()), 1268 2 * Identifiers.size()); 1269 for (unsigned i=0; i != Identifiers.size(); i++) { 1270 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1]; 1271 pragmaUnusedTok.startToken(); 1272 pragmaUnusedTok.setKind(tok::annot_pragma_unused); 1273 pragmaUnusedTok.setLocation(UnusedLoc); 1274 idTok = Identifiers[i]; 1275 } 1276 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 1277 } 1278 1279 // #pragma weak identifier 1280 // #pragma weak identifier '=' identifier 1281 void PragmaWeakHandler::HandlePragma(Preprocessor &PP, 1282 PragmaIntroducerKind Introducer, 1283 Token &WeakTok) { 1284 SourceLocation WeakLoc = WeakTok.getLocation(); 1285 1286 Token Tok; 1287 PP.Lex(Tok); 1288 if (Tok.isNot(tok::identifier)) { 1289 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak"; 1290 return; 1291 } 1292 1293 Token WeakName = Tok; 1294 bool HasAlias = false; 1295 Token AliasName; 1296 1297 PP.Lex(Tok); 1298 if (Tok.is(tok::equal)) { 1299 HasAlias = true; 1300 PP.Lex(Tok); 1301 if (Tok.isNot(tok::identifier)) { 1302 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 1303 << "weak"; 1304 return; 1305 } 1306 AliasName = Tok; 1307 PP.Lex(Tok); 1308 } 1309 1310 if (Tok.isNot(tok::eod)) { 1311 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak"; 1312 return; 1313 } 1314 1315 if (HasAlias) { 1316 MutableArrayRef<Token> Toks( 1317 PP.getPreprocessorAllocator().Allocate<Token>(3), 3); 1318 Token &pragmaUnusedTok = Toks[0]; 1319 pragmaUnusedTok.startToken(); 1320 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias); 1321 pragmaUnusedTok.setLocation(WeakLoc); 1322 pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation()); 1323 Toks[1] = WeakName; 1324 Toks[2] = AliasName; 1325 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 1326 } else { 1327 MutableArrayRef<Token> Toks( 1328 PP.getPreprocessorAllocator().Allocate<Token>(2), 2); 1329 Token &pragmaUnusedTok = Toks[0]; 1330 pragmaUnusedTok.startToken(); 1331 pragmaUnusedTok.setKind(tok::annot_pragma_weak); 1332 pragmaUnusedTok.setLocation(WeakLoc); 1333 pragmaUnusedTok.setAnnotationEndLoc(WeakLoc); 1334 Toks[1] = WeakName; 1335 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 1336 } 1337 } 1338 1339 // #pragma redefine_extname identifier identifier 1340 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP, 1341 PragmaIntroducerKind Introducer, 1342 Token &RedefToken) { 1343 SourceLocation RedefLoc = RedefToken.getLocation(); 1344 1345 Token Tok; 1346 PP.Lex(Tok); 1347 if (Tok.isNot(tok::identifier)) { 1348 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << 1349 "redefine_extname"; 1350 return; 1351 } 1352 1353 Token RedefName = Tok; 1354 PP.Lex(Tok); 1355 1356 if (Tok.isNot(tok::identifier)) { 1357 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 1358 << "redefine_extname"; 1359 return; 1360 } 1361 1362 Token AliasName = Tok; 1363 PP.Lex(Tok); 1364 1365 if (Tok.isNot(tok::eod)) { 1366 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << 1367 "redefine_extname"; 1368 return; 1369 } 1370 1371 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3), 1372 3); 1373 Token &pragmaRedefTok = Toks[0]; 1374 pragmaRedefTok.startToken(); 1375 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname); 1376 pragmaRedefTok.setLocation(RedefLoc); 1377 pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation()); 1378 Toks[1] = RedefName; 1379 Toks[2] = AliasName; 1380 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 1381 } 1382 1383 1384 void 1385 PragmaFPContractHandler::HandlePragma(Preprocessor &PP, 1386 PragmaIntroducerKind Introducer, 1387 Token &Tok) { 1388 tok::OnOffSwitch OOS; 1389 if (PP.LexOnOffSwitch(OOS)) 1390 return; 1391 1392 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), 1393 1); 1394 Toks[0].startToken(); 1395 Toks[0].setKind(tok::annot_pragma_fp_contract); 1396 Toks[0].setLocation(Tok.getLocation()); 1397 Toks[0].setAnnotationEndLoc(Tok.getLocation()); 1398 Toks[0].setAnnotationValue(reinterpret_cast<void*>( 1399 static_cast<uintptr_t>(OOS))); 1400 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 1401 } 1402 1403 void 1404 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP, 1405 PragmaIntroducerKind Introducer, 1406 Token &Tok) { 1407 PP.LexUnexpandedToken(Tok); 1408 if (Tok.isNot(tok::identifier)) { 1409 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << 1410 "OPENCL"; 1411 return; 1412 } 1413 IdentifierInfo *ename = Tok.getIdentifierInfo(); 1414 SourceLocation NameLoc = Tok.getLocation(); 1415 1416 PP.Lex(Tok); 1417 if (Tok.isNot(tok::colon)) { 1418 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename; 1419 return; 1420 } 1421 1422 PP.Lex(Tok); 1423 if (Tok.isNot(tok::identifier)) { 1424 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); 1425 return; 1426 } 1427 IdentifierInfo *op = Tok.getIdentifierInfo(); 1428 1429 unsigned state; 1430 if (op->isStr("enable")) { 1431 state = 1; 1432 } else if (op->isStr("disable")) { 1433 state = 0; 1434 } else { 1435 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); 1436 return; 1437 } 1438 SourceLocation StateLoc = Tok.getLocation(); 1439 1440 PP.Lex(Tok); 1441 if (Tok.isNot(tok::eod)) { 1442 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << 1443 "OPENCL EXTENSION"; 1444 return; 1445 } 1446 1447 OpenCLExtData data(ename, state); 1448 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), 1449 1); 1450 Toks[0].startToken(); 1451 Toks[0].setKind(tok::annot_pragma_opencl_extension); 1452 Toks[0].setLocation(NameLoc); 1453 Toks[0].setAnnotationValue(data.getOpaqueValue()); 1454 Toks[0].setAnnotationEndLoc(StateLoc); 1455 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 1456 1457 if (PP.getPPCallbacks()) 1458 PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename, 1459 StateLoc, state); 1460 } 1461 1462 /// \brief Handle '#pragma omp ...' when OpenMP is disabled. 1463 /// 1464 void 1465 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP, 1466 PragmaIntroducerKind Introducer, 1467 Token &FirstTok) { 1468 if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored, 1469 FirstTok.getLocation())) { 1470 PP.Diag(FirstTok, diag::warn_pragma_omp_ignored); 1471 PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored, 1472 diag::Severity::Ignored, SourceLocation()); 1473 } 1474 PP.DiscardUntilEndOfDirective(); 1475 } 1476 1477 /// \brief Handle '#pragma omp ...' when OpenMP is enabled. 1478 /// 1479 void 1480 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP, 1481 PragmaIntroducerKind Introducer, 1482 Token &FirstTok) { 1483 SmallVector<Token, 16> Pragma; 1484 Token Tok; 1485 Tok.startToken(); 1486 Tok.setKind(tok::annot_pragma_openmp); 1487 Tok.setLocation(FirstTok.getLocation()); 1488 1489 while (Tok.isNot(tok::eod)) { 1490 Pragma.push_back(Tok); 1491 PP.Lex(Tok); 1492 } 1493 SourceLocation EodLoc = Tok.getLocation(); 1494 Tok.startToken(); 1495 Tok.setKind(tok::annot_pragma_openmp_end); 1496 Tok.setLocation(EodLoc); 1497 Pragma.push_back(Tok); 1498 1499 auto Toks = llvm::make_unique<Token[]>(Pragma.size()); 1500 std::copy(Pragma.begin(), Pragma.end(), Toks.get()); 1501 PP.EnterTokenStream(std::move(Toks), Pragma.size(), 1502 /*DisableMacroExpansion=*/false); 1503 } 1504 1505 /// \brief Handle '#pragma pointers_to_members' 1506 // The grammar for this pragma is as follows: 1507 // 1508 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance' 1509 // 1510 // #pragma pointers_to_members '(' 'best_case' ')' 1511 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')' 1512 // #pragma pointers_to_members '(' inheritance-model ')' 1513 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP, 1514 PragmaIntroducerKind Introducer, 1515 Token &Tok) { 1516 SourceLocation PointersToMembersLoc = Tok.getLocation(); 1517 PP.Lex(Tok); 1518 if (Tok.isNot(tok::l_paren)) { 1519 PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen) 1520 << "pointers_to_members"; 1521 return; 1522 } 1523 PP.Lex(Tok); 1524 const IdentifierInfo *Arg = Tok.getIdentifierInfo(); 1525 if (!Arg) { 1526 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 1527 << "pointers_to_members"; 1528 return; 1529 } 1530 PP.Lex(Tok); 1531 1532 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod; 1533 if (Arg->isStr("best_case")) { 1534 RepresentationMethod = LangOptions::PPTMK_BestCase; 1535 } else { 1536 if (Arg->isStr("full_generality")) { 1537 if (Tok.is(tok::comma)) { 1538 PP.Lex(Tok); 1539 1540 Arg = Tok.getIdentifierInfo(); 1541 if (!Arg) { 1542 PP.Diag(Tok.getLocation(), 1543 diag::err_pragma_pointers_to_members_unknown_kind) 1544 << Tok.getKind() << /*OnlyInheritanceModels*/ 0; 1545 return; 1546 } 1547 PP.Lex(Tok); 1548 } else if (Tok.is(tok::r_paren)) { 1549 // #pragma pointers_to_members(full_generality) implicitly specifies 1550 // virtual_inheritance. 1551 Arg = nullptr; 1552 RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance; 1553 } else { 1554 PP.Diag(Tok.getLocation(), diag::err_expected_punc) 1555 << "full_generality"; 1556 return; 1557 } 1558 } 1559 1560 if (Arg) { 1561 if (Arg->isStr("single_inheritance")) { 1562 RepresentationMethod = 1563 LangOptions::PPTMK_FullGeneralitySingleInheritance; 1564 } else if (Arg->isStr("multiple_inheritance")) { 1565 RepresentationMethod = 1566 LangOptions::PPTMK_FullGeneralityMultipleInheritance; 1567 } else if (Arg->isStr("virtual_inheritance")) { 1568 RepresentationMethod = 1569 LangOptions::PPTMK_FullGeneralityVirtualInheritance; 1570 } else { 1571 PP.Diag(Tok.getLocation(), 1572 diag::err_pragma_pointers_to_members_unknown_kind) 1573 << Arg << /*HasPointerDeclaration*/ 1; 1574 return; 1575 } 1576 } 1577 } 1578 1579 if (Tok.isNot(tok::r_paren)) { 1580 PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after) 1581 << (Arg ? Arg->getName() : "full_generality"); 1582 return; 1583 } 1584 1585 SourceLocation EndLoc = Tok.getLocation(); 1586 PP.Lex(Tok); 1587 if (Tok.isNot(tok::eod)) { 1588 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 1589 << "pointers_to_members"; 1590 return; 1591 } 1592 1593 Token AnnotTok; 1594 AnnotTok.startToken(); 1595 AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members); 1596 AnnotTok.setLocation(PointersToMembersLoc); 1597 AnnotTok.setAnnotationEndLoc(EndLoc); 1598 AnnotTok.setAnnotationValue( 1599 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod))); 1600 PP.EnterToken(AnnotTok); 1601 } 1602 1603 /// \brief Handle '#pragma vtordisp' 1604 // The grammar for this pragma is as follows: 1605 // 1606 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' ) 1607 // 1608 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')' 1609 // #pragma vtordisp '(' 'pop' ')' 1610 // #pragma vtordisp '(' ')' 1611 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP, 1612 PragmaIntroducerKind Introducer, 1613 Token &Tok) { 1614 SourceLocation VtorDispLoc = Tok.getLocation(); 1615 PP.Lex(Tok); 1616 if (Tok.isNot(tok::l_paren)) { 1617 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp"; 1618 return; 1619 } 1620 PP.Lex(Tok); 1621 1622 Sema::PragmaMsStackAction Action = Sema::PSK_Set; 1623 const IdentifierInfo *II = Tok.getIdentifierInfo(); 1624 if (II) { 1625 if (II->isStr("push")) { 1626 // #pragma vtordisp(push, mode) 1627 PP.Lex(Tok); 1628 if (Tok.isNot(tok::comma)) { 1629 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp"; 1630 return; 1631 } 1632 PP.Lex(Tok); 1633 Action = Sema::PSK_Push_Set; 1634 // not push, could be on/off 1635 } else if (II->isStr("pop")) { 1636 // #pragma vtordisp(pop) 1637 PP.Lex(Tok); 1638 Action = Sema::PSK_Pop; 1639 } 1640 // not push or pop, could be on/off 1641 } else { 1642 if (Tok.is(tok::r_paren)) { 1643 // #pragma vtordisp() 1644 Action = Sema::PSK_Reset; 1645 } 1646 } 1647 1648 1649 uint64_t Value = 0; 1650 if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) { 1651 const IdentifierInfo *II = Tok.getIdentifierInfo(); 1652 if (II && II->isStr("off")) { 1653 PP.Lex(Tok); 1654 Value = 0; 1655 } else if (II && II->isStr("on")) { 1656 PP.Lex(Tok); 1657 Value = 1; 1658 } else if (Tok.is(tok::numeric_constant) && 1659 PP.parseSimpleIntegerLiteral(Tok, Value)) { 1660 if (Value > 2) { 1661 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer) 1662 << 0 << 2 << "vtordisp"; 1663 return; 1664 } 1665 } else { 1666 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) 1667 << "vtordisp"; 1668 return; 1669 } 1670 } 1671 1672 // Finish the pragma: ')' $ 1673 if (Tok.isNot(tok::r_paren)) { 1674 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp"; 1675 return; 1676 } 1677 SourceLocation EndLoc = Tok.getLocation(); 1678 PP.Lex(Tok); 1679 if (Tok.isNot(tok::eod)) { 1680 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 1681 << "vtordisp"; 1682 return; 1683 } 1684 1685 // Enter the annotation. 1686 Token AnnotTok; 1687 AnnotTok.startToken(); 1688 AnnotTok.setKind(tok::annot_pragma_ms_vtordisp); 1689 AnnotTok.setLocation(VtorDispLoc); 1690 AnnotTok.setAnnotationEndLoc(EndLoc); 1691 AnnotTok.setAnnotationValue(reinterpret_cast<void *>( 1692 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF)))); 1693 PP.EnterToken(AnnotTok); 1694 } 1695 1696 /// \brief Handle all MS pragmas. Simply forwards the tokens after inserting 1697 /// an annotation token. 1698 void PragmaMSPragma::HandlePragma(Preprocessor &PP, 1699 PragmaIntroducerKind Introducer, 1700 Token &Tok) { 1701 Token EoF, AnnotTok; 1702 EoF.startToken(); 1703 EoF.setKind(tok::eof); 1704 AnnotTok.startToken(); 1705 AnnotTok.setKind(tok::annot_pragma_ms_pragma); 1706 AnnotTok.setLocation(Tok.getLocation()); 1707 AnnotTok.setAnnotationEndLoc(Tok.getLocation()); 1708 SmallVector<Token, 8> TokenVector; 1709 // Suck up all of the tokens before the eod. 1710 for (; Tok.isNot(tok::eod); PP.Lex(Tok)) { 1711 TokenVector.push_back(Tok); 1712 AnnotTok.setAnnotationEndLoc(Tok.getLocation()); 1713 } 1714 // Add a sentinal EoF token to the end of the list. 1715 TokenVector.push_back(EoF); 1716 // We must allocate this array with new because EnterTokenStream is going to 1717 // delete it later. 1718 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size()); 1719 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get()); 1720 auto Value = new (PP.getPreprocessorAllocator()) 1721 std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray), 1722 TokenVector.size()); 1723 AnnotTok.setAnnotationValue(Value); 1724 PP.EnterToken(AnnotTok); 1725 } 1726 1727 /// \brief Handle the Microsoft \#pragma detect_mismatch extension. 1728 /// 1729 /// The syntax is: 1730 /// \code 1731 /// #pragma detect_mismatch("name", "value") 1732 /// \endcode 1733 /// Where 'name' and 'value' are quoted strings. The values are embedded in 1734 /// the object file and passed along to the linker. If the linker detects a 1735 /// mismatch in the object file's values for the given name, a LNK2038 error 1736 /// is emitted. See MSDN for more details. 1737 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP, 1738 PragmaIntroducerKind Introducer, 1739 Token &Tok) { 1740 SourceLocation DetectMismatchLoc = Tok.getLocation(); 1741 PP.Lex(Tok); 1742 if (Tok.isNot(tok::l_paren)) { 1743 PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren; 1744 return; 1745 } 1746 1747 // Read the name to embed, which must be a string literal. 1748 std::string NameString; 1749 if (!PP.LexStringLiteral(Tok, NameString, 1750 "pragma detect_mismatch", 1751 /*MacroExpansion=*/true)) 1752 return; 1753 1754 // Read the comma followed by a second string literal. 1755 std::string ValueString; 1756 if (Tok.isNot(tok::comma)) { 1757 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed); 1758 return; 1759 } 1760 1761 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch", 1762 /*MacroExpansion=*/true)) 1763 return; 1764 1765 if (Tok.isNot(tok::r_paren)) { 1766 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren; 1767 return; 1768 } 1769 PP.Lex(Tok); // Eat the r_paren. 1770 1771 if (Tok.isNot(tok::eod)) { 1772 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed); 1773 return; 1774 } 1775 1776 // If the pragma is lexically sound, notify any interested PPCallbacks. 1777 if (PP.getPPCallbacks()) 1778 PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString, 1779 ValueString); 1780 1781 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString); 1782 } 1783 1784 /// \brief Handle the microsoft \#pragma comment extension. 1785 /// 1786 /// The syntax is: 1787 /// \code 1788 /// #pragma comment(linker, "foo") 1789 /// \endcode 1790 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user. 1791 /// "foo" is a string, which is fully macro expanded, and permits string 1792 /// concatenation, embedded escape characters etc. See MSDN for more details. 1793 void PragmaCommentHandler::HandlePragma(Preprocessor &PP, 1794 PragmaIntroducerKind Introducer, 1795 Token &Tok) { 1796 SourceLocation CommentLoc = Tok.getLocation(); 1797 PP.Lex(Tok); 1798 if (Tok.isNot(tok::l_paren)) { 1799 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed); 1800 return; 1801 } 1802 1803 // Read the identifier. 1804 PP.Lex(Tok); 1805 if (Tok.isNot(tok::identifier)) { 1806 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed); 1807 return; 1808 } 1809 1810 // Verify that this is one of the 5 whitelisted options. 1811 IdentifierInfo *II = Tok.getIdentifierInfo(); 1812 PragmaMSCommentKind Kind = 1813 llvm::StringSwitch<PragmaMSCommentKind>(II->getName()) 1814 .Case("linker", PCK_Linker) 1815 .Case("lib", PCK_Lib) 1816 .Case("compiler", PCK_Compiler) 1817 .Case("exestr", PCK_ExeStr) 1818 .Case("user", PCK_User) 1819 .Default(PCK_Unknown); 1820 if (Kind == PCK_Unknown) { 1821 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind); 1822 return; 1823 } 1824 1825 // On PS4, issue a warning about any pragma comments other than 1826 // #pragma comment lib. 1827 if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) { 1828 PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored) 1829 << II->getName(); 1830 return; 1831 } 1832 1833 // Read the optional string if present. 1834 PP.Lex(Tok); 1835 std::string ArgumentString; 1836 if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString, 1837 "pragma comment", 1838 /*MacroExpansion=*/true)) 1839 return; 1840 1841 // FIXME: warn that 'exestr' is deprecated. 1842 // FIXME: If the kind is "compiler" warn if the string is present (it is 1843 // ignored). 1844 // The MSDN docs say that "lib" and "linker" require a string and have a short 1845 // whitelist of linker options they support, but in practice MSVC doesn't 1846 // issue a diagnostic. Therefore neither does clang. 1847 1848 if (Tok.isNot(tok::r_paren)) { 1849 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); 1850 return; 1851 } 1852 PP.Lex(Tok); // eat the r_paren. 1853 1854 if (Tok.isNot(tok::eod)) { 1855 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); 1856 return; 1857 } 1858 1859 // If the pragma is lexically sound, notify any interested PPCallbacks. 1860 if (PP.getPPCallbacks()) 1861 PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString); 1862 1863 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString); 1864 } 1865 1866 // #pragma clang optimize off 1867 // #pragma clang optimize on 1868 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP, 1869 PragmaIntroducerKind Introducer, 1870 Token &FirstToken) { 1871 Token Tok; 1872 PP.Lex(Tok); 1873 if (Tok.is(tok::eod)) { 1874 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument) 1875 << "clang optimize" << /*Expected=*/true << "'on' or 'off'"; 1876 return; 1877 } 1878 if (Tok.isNot(tok::identifier)) { 1879 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument) 1880 << PP.getSpelling(Tok); 1881 return; 1882 } 1883 const IdentifierInfo *II = Tok.getIdentifierInfo(); 1884 // The only accepted values are 'on' or 'off'. 1885 bool IsOn = false; 1886 if (II->isStr("on")) { 1887 IsOn = true; 1888 } else if (!II->isStr("off")) { 1889 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument) 1890 << PP.getSpelling(Tok); 1891 return; 1892 } 1893 PP.Lex(Tok); 1894 1895 if (Tok.isNot(tok::eod)) { 1896 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument) 1897 << PP.getSpelling(Tok); 1898 return; 1899 } 1900 1901 Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation()); 1902 } 1903 1904 /// \brief Parses loop or unroll pragma hint value and fills in Info. 1905 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName, 1906 Token Option, bool ValueInParens, 1907 PragmaLoopHintInfo &Info) { 1908 SmallVector<Token, 1> ValueList; 1909 int OpenParens = ValueInParens ? 1 : 0; 1910 // Read constant expression. 1911 while (Tok.isNot(tok::eod)) { 1912 if (Tok.is(tok::l_paren)) 1913 OpenParens++; 1914 else if (Tok.is(tok::r_paren)) { 1915 OpenParens--; 1916 if (OpenParens == 0 && ValueInParens) 1917 break; 1918 } 1919 1920 ValueList.push_back(Tok); 1921 PP.Lex(Tok); 1922 } 1923 1924 if (ValueInParens) { 1925 // Read ')' 1926 if (Tok.isNot(tok::r_paren)) { 1927 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren; 1928 return true; 1929 } 1930 PP.Lex(Tok); 1931 } 1932 1933 Token EOFTok; 1934 EOFTok.startToken(); 1935 EOFTok.setKind(tok::eof); 1936 EOFTok.setLocation(Tok.getLocation()); 1937 ValueList.push_back(EOFTok); // Terminates expression for parsing. 1938 1939 Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator()); 1940 1941 Info.PragmaName = PragmaName; 1942 Info.Option = Option; 1943 return false; 1944 } 1945 1946 /// \brief Handle the \#pragma clang loop directive. 1947 /// #pragma clang 'loop' loop-hints 1948 /// 1949 /// loop-hints: 1950 /// loop-hint loop-hints[opt] 1951 /// 1952 /// loop-hint: 1953 /// 'vectorize' '(' loop-hint-keyword ')' 1954 /// 'interleave' '(' loop-hint-keyword ')' 1955 /// 'unroll' '(' unroll-hint-keyword ')' 1956 /// 'vectorize_width' '(' loop-hint-value ')' 1957 /// 'interleave_count' '(' loop-hint-value ')' 1958 /// 'unroll_count' '(' loop-hint-value ')' 1959 /// 1960 /// loop-hint-keyword: 1961 /// 'enable' 1962 /// 'disable' 1963 /// 'assume_safety' 1964 /// 1965 /// unroll-hint-keyword: 1966 /// 'enable' 1967 /// 'disable' 1968 /// 'full' 1969 /// 1970 /// loop-hint-value: 1971 /// constant-expression 1972 /// 1973 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to 1974 /// try vectorizing the instructions of the loop it precedes. Specifying 1975 /// interleave(enable) or interleave_count(_value_) instructs llvm to try 1976 /// interleaving multiple iterations of the loop it precedes. The width of the 1977 /// vector instructions is specified by vectorize_width() and the number of 1978 /// interleaved loop iterations is specified by interleave_count(). Specifying a 1979 /// value of 1 effectively disables vectorization/interleaving, even if it is 1980 /// possible and profitable, and 0 is invalid. The loop vectorizer currently 1981 /// only works on inner loops. 1982 /// 1983 /// The unroll and unroll_count directives control the concatenation 1984 /// unroller. Specifying unroll(enable) instructs llvm to unroll the loop 1985 /// completely if the trip count is known at compile time and unroll partially 1986 /// if the trip count is not known. Specifying unroll(full) is similar to 1987 /// unroll(enable) but will unroll the loop only if the trip count is known at 1988 /// compile time. Specifying unroll(disable) disables unrolling for the 1989 /// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the 1990 /// loop the number of times indicated by the value. 1991 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP, 1992 PragmaIntroducerKind Introducer, 1993 Token &Tok) { 1994 // Incoming token is "loop" from "#pragma clang loop". 1995 Token PragmaName = Tok; 1996 SmallVector<Token, 1> TokenList; 1997 1998 // Lex the optimization option and verify it is an identifier. 1999 PP.Lex(Tok); 2000 if (Tok.isNot(tok::identifier)) { 2001 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option) 2002 << /*MissingOption=*/true << ""; 2003 return; 2004 } 2005 2006 while (Tok.is(tok::identifier)) { 2007 Token Option = Tok; 2008 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo(); 2009 2010 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName()) 2011 .Case("vectorize", true) 2012 .Case("interleave", true) 2013 .Case("unroll", true) 2014 .Case("distribute", true) 2015 .Case("vectorize_width", true) 2016 .Case("interleave_count", true) 2017 .Case("unroll_count", true) 2018 .Default(false); 2019 if (!OptionValid) { 2020 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option) 2021 << /*MissingOption=*/false << OptionInfo; 2022 return; 2023 } 2024 PP.Lex(Tok); 2025 2026 // Read '(' 2027 if (Tok.isNot(tok::l_paren)) { 2028 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren; 2029 return; 2030 } 2031 PP.Lex(Tok); 2032 2033 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo; 2034 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true, 2035 *Info)) 2036 return; 2037 2038 // Generate the loop hint token. 2039 Token LoopHintTok; 2040 LoopHintTok.startToken(); 2041 LoopHintTok.setKind(tok::annot_pragma_loop_hint); 2042 LoopHintTok.setLocation(PragmaName.getLocation()); 2043 LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation()); 2044 LoopHintTok.setAnnotationValue(static_cast<void *>(Info)); 2045 TokenList.push_back(LoopHintTok); 2046 } 2047 2048 if (Tok.isNot(tok::eod)) { 2049 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 2050 << "clang loop"; 2051 return; 2052 } 2053 2054 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size()); 2055 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get()); 2056 2057 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(), 2058 /*DisableMacroExpansion=*/false); 2059 } 2060 2061 /// \brief Handle the loop unroll optimization pragmas. 2062 /// #pragma unroll 2063 /// #pragma unroll unroll-hint-value 2064 /// #pragma unroll '(' unroll-hint-value ')' 2065 /// #pragma nounroll 2066 /// 2067 /// unroll-hint-value: 2068 /// constant-expression 2069 /// 2070 /// Loop unrolling hints can be specified with '#pragma unroll' or 2071 /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally 2072 /// contained in parentheses. With no argument the directive instructs llvm to 2073 /// try to unroll the loop completely. A positive integer argument can be 2074 /// specified to indicate the number of times the loop should be unrolled. To 2075 /// maximize compatibility with other compilers the unroll count argument can be 2076 /// specified with or without parentheses. Specifying, '#pragma nounroll' 2077 /// disables unrolling of the loop. 2078 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP, 2079 PragmaIntroducerKind Introducer, 2080 Token &Tok) { 2081 // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for 2082 // "#pragma nounroll". 2083 Token PragmaName = Tok; 2084 PP.Lex(Tok); 2085 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo; 2086 if (Tok.is(tok::eod)) { 2087 // nounroll or unroll pragma without an argument. 2088 Info->PragmaName = PragmaName; 2089 Info->Option.startToken(); 2090 } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") { 2091 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 2092 << "nounroll"; 2093 return; 2094 } else { 2095 // Unroll pragma with an argument: "#pragma unroll N" or 2096 // "#pragma unroll(N)". 2097 // Read '(' if it exists. 2098 bool ValueInParens = Tok.is(tok::l_paren); 2099 if (ValueInParens) 2100 PP.Lex(Tok); 2101 2102 Token Option; 2103 Option.startToken(); 2104 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info)) 2105 return; 2106 2107 // In CUDA, the argument to '#pragma unroll' should not be contained in 2108 // parentheses. 2109 if (PP.getLangOpts().CUDA && ValueInParens) 2110 PP.Diag(Info->Toks[0].getLocation(), 2111 diag::warn_pragma_unroll_cuda_value_in_parens); 2112 2113 if (Tok.isNot(tok::eod)) { 2114 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 2115 << "unroll"; 2116 return; 2117 } 2118 } 2119 2120 // Generate the hint token. 2121 auto TokenArray = llvm::make_unique<Token[]>(1); 2122 TokenArray[0].startToken(); 2123 TokenArray[0].setKind(tok::annot_pragma_loop_hint); 2124 TokenArray[0].setLocation(PragmaName.getLocation()); 2125 TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation()); 2126 TokenArray[0].setAnnotationValue(static_cast<void *>(Info)); 2127 PP.EnterTokenStream(std::move(TokenArray), 1, 2128 /*DisableMacroExpansion=*/false); 2129 } 2130