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