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 "ParsePragma.h" 15 #include "clang/Lex/Preprocessor.h" 16 #include "clang/Parse/ParseDiagnostic.h" 17 #include "clang/Parse/Parser.h" 18 using namespace clang; 19 20 /// \brief Handle the annotation token produced for #pragma unused(...) 21 /// 22 /// Each annot_pragma_unused is followed by the argument token so e.g. 23 /// "#pragma unused(x,y)" becomes: 24 /// annot_pragma_unused 'x' annot_pragma_unused 'y' 25 void Parser::HandlePragmaUnused() { 26 assert(Tok.is(tok::annot_pragma_unused)); 27 SourceLocation UnusedLoc = ConsumeToken(); 28 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc); 29 ConsumeToken(); // The argument token. 30 } 31 32 void Parser::HandlePragmaVisibility() { 33 assert(Tok.is(tok::annot_pragma_vis)); 34 const IdentifierInfo *VisType = 35 static_cast<IdentifierInfo *>(Tok.getAnnotationValue()); 36 SourceLocation VisLoc = ConsumeToken(); 37 Actions.ActOnPragmaVisibility(VisType, VisLoc); 38 } 39 40 struct PragmaPackInfo { 41 Sema::PragmaPackKind Kind; 42 IdentifierInfo *Name; 43 Token Alignment; 44 SourceLocation LParenLoc; 45 SourceLocation RParenLoc; 46 }; 47 48 void Parser::HandlePragmaPack() { 49 assert(Tok.is(tok::annot_pragma_pack)); 50 PragmaPackInfo *Info = 51 static_cast<PragmaPackInfo *>(Tok.getAnnotationValue()); 52 SourceLocation PragmaLoc = ConsumeToken(); 53 ExprResult Alignment; 54 if (Info->Alignment.is(tok::numeric_constant)) { 55 Alignment = Actions.ActOnNumericConstant(Info->Alignment); 56 if (Alignment.isInvalid()) 57 return; 58 } 59 Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc, 60 Info->LParenLoc, Info->RParenLoc); 61 } 62 63 void Parser::HandlePragmaMSStruct() { 64 assert(Tok.is(tok::annot_pragma_msstruct)); 65 Sema::PragmaMSStructKind Kind = 66 static_cast<Sema::PragmaMSStructKind>( 67 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 68 Actions.ActOnPragmaMSStruct(Kind); 69 ConsumeToken(); // The annotation token. 70 } 71 72 void Parser::HandlePragmaAlign() { 73 assert(Tok.is(tok::annot_pragma_align)); 74 Sema::PragmaOptionsAlignKind Kind = 75 static_cast<Sema::PragmaOptionsAlignKind>( 76 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 77 SourceLocation PragmaLoc = ConsumeToken(); 78 Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc); 79 } 80 81 void Parser::HandlePragmaWeak() { 82 assert(Tok.is(tok::annot_pragma_weak)); 83 SourceLocation PragmaLoc = ConsumeToken(); 84 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc, 85 Tok.getLocation()); 86 ConsumeToken(); // The weak name. 87 } 88 89 void Parser::HandlePragmaWeakAlias() { 90 assert(Tok.is(tok::annot_pragma_weakalias)); 91 SourceLocation PragmaLoc = ConsumeToken(); 92 IdentifierInfo *WeakName = Tok.getIdentifierInfo(); 93 SourceLocation WeakNameLoc = Tok.getLocation(); 94 ConsumeToken(); 95 IdentifierInfo *AliasName = Tok.getIdentifierInfo(); 96 SourceLocation AliasNameLoc = Tok.getLocation(); 97 ConsumeToken(); 98 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc, 99 WeakNameLoc, AliasNameLoc); 100 101 } 102 103 void Parser::HandlePragmaRedefineExtname() { 104 assert(Tok.is(tok::annot_pragma_redefine_extname)); 105 SourceLocation RedefLoc = ConsumeToken(); 106 IdentifierInfo *RedefName = Tok.getIdentifierInfo(); 107 SourceLocation RedefNameLoc = Tok.getLocation(); 108 ConsumeToken(); 109 IdentifierInfo *AliasName = Tok.getIdentifierInfo(); 110 SourceLocation AliasNameLoc = Tok.getLocation(); 111 ConsumeToken(); 112 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc, 113 RedefNameLoc, AliasNameLoc); 114 } 115 116 void Parser::HandlePragmaFPContract() { 117 assert(Tok.is(tok::annot_pragma_fp_contract)); 118 tok::OnOffSwitch OOS = 119 static_cast<tok::OnOffSwitch>( 120 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); 121 Actions.ActOnPragmaFPContract(OOS); 122 ConsumeToken(); // The annotation token. 123 } 124 125 namespace { 126 typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData; 127 } 128 129 void Parser::HandlePragmaOpenCLExtension() { 130 assert(Tok.is(tok::annot_pragma_opencl_extension)); 131 OpenCLExtData data = 132 OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue()); 133 unsigned state = data.getInt(); 134 IdentifierInfo *ename = data.getPointer(); 135 SourceLocation NameLoc = Tok.getLocation(); 136 ConsumeToken(); // The annotation token. 137 138 OpenCLOptions &f = Actions.getOpenCLOptions(); 139 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions, 140 // overriding all previously issued extension directives, but only if the 141 // behavior is set to disable." 142 if (state == 0 && ename->isStr("all")) { 143 #define OPENCLEXT(nm) f.nm = 0; 144 #include "clang/Basic/OpenCLExtensions.def" 145 } 146 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; } 147 #include "clang/Basic/OpenCLExtensions.def" 148 else { 149 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename; 150 return; 151 } 152 } 153 154 // #pragma GCC visibility comes in two variants: 155 // 'push' '(' [visibility] ')' 156 // 'pop' 157 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, 158 PragmaIntroducerKind Introducer, 159 Token &VisTok) { 160 SourceLocation VisLoc = VisTok.getLocation(); 161 162 Token Tok; 163 PP.LexUnexpandedToken(Tok); 164 165 const IdentifierInfo *PushPop = Tok.getIdentifierInfo(); 166 167 const IdentifierInfo *VisType; 168 if (PushPop && PushPop->isStr("pop")) { 169 VisType = 0; 170 } else if (PushPop && PushPop->isStr("push")) { 171 PP.LexUnexpandedToken(Tok); 172 if (Tok.isNot(tok::l_paren)) { 173 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) 174 << "visibility"; 175 return; 176 } 177 PP.LexUnexpandedToken(Tok); 178 VisType = Tok.getIdentifierInfo(); 179 if (!VisType) { 180 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 181 << "visibility"; 182 return; 183 } 184 PP.LexUnexpandedToken(Tok); 185 if (Tok.isNot(tok::r_paren)) { 186 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) 187 << "visibility"; 188 return; 189 } 190 } else { 191 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 192 << "visibility"; 193 return; 194 } 195 PP.LexUnexpandedToken(Tok); 196 if (Tok.isNot(tok::eod)) { 197 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 198 << "visibility"; 199 return; 200 } 201 202 Token *Toks = new Token[1]; 203 Toks[0].startToken(); 204 Toks[0].setKind(tok::annot_pragma_vis); 205 Toks[0].setLocation(VisLoc); 206 Toks[0].setAnnotationValue( 207 const_cast<void*>(static_cast<const void*>(VisType))); 208 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 209 /*OwnsTokens=*/true); 210 } 211 212 // #pragma pack(...) comes in the following delicious flavors: 213 // pack '(' [integer] ')' 214 // pack '(' 'show' ')' 215 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')' 216 void PragmaPackHandler::HandlePragma(Preprocessor &PP, 217 PragmaIntroducerKind Introducer, 218 Token &PackTok) { 219 SourceLocation PackLoc = PackTok.getLocation(); 220 221 Token Tok; 222 PP.Lex(Tok); 223 if (Tok.isNot(tok::l_paren)) { 224 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack"; 225 return; 226 } 227 228 Sema::PragmaPackKind Kind = Sema::PPK_Default; 229 IdentifierInfo *Name = 0; 230 Token Alignment; 231 Alignment.startToken(); 232 SourceLocation LParenLoc = Tok.getLocation(); 233 PP.Lex(Tok); 234 if (Tok.is(tok::numeric_constant)) { 235 Alignment = Tok; 236 237 PP.Lex(Tok); 238 239 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting 240 // the push/pop stack. 241 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4) 242 if (PP.getLangOpts().ApplePragmaPack) 243 Kind = Sema::PPK_Push; 244 } else if (Tok.is(tok::identifier)) { 245 const IdentifierInfo *II = Tok.getIdentifierInfo(); 246 if (II->isStr("show")) { 247 Kind = Sema::PPK_Show; 248 PP.Lex(Tok); 249 } else { 250 if (II->isStr("push")) { 251 Kind = Sema::PPK_Push; 252 } else if (II->isStr("pop")) { 253 Kind = Sema::PPK_Pop; 254 } else { 255 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action); 256 return; 257 } 258 PP.Lex(Tok); 259 260 if (Tok.is(tok::comma)) { 261 PP.Lex(Tok); 262 263 if (Tok.is(tok::numeric_constant)) { 264 Alignment = Tok; 265 266 PP.Lex(Tok); 267 } else if (Tok.is(tok::identifier)) { 268 Name = Tok.getIdentifierInfo(); 269 PP.Lex(Tok); 270 271 if (Tok.is(tok::comma)) { 272 PP.Lex(Tok); 273 274 if (Tok.isNot(tok::numeric_constant)) { 275 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed); 276 return; 277 } 278 279 Alignment = Tok; 280 281 PP.Lex(Tok); 282 } 283 } else { 284 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed); 285 return; 286 } 287 } 288 } 289 } else if (PP.getLangOpts().ApplePragmaPack) { 290 // In MSVC/gcc, #pragma pack() resets the alignment without affecting 291 // the push/pop stack. 292 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop). 293 Kind = Sema::PPK_Pop; 294 } 295 296 if (Tok.isNot(tok::r_paren)) { 297 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack"; 298 return; 299 } 300 301 SourceLocation RParenLoc = Tok.getLocation(); 302 PP.Lex(Tok); 303 if (Tok.isNot(tok::eod)) { 304 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack"; 305 return; 306 } 307 308 PragmaPackInfo *Info = 309 (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate( 310 sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>()); 311 new (Info) PragmaPackInfo(); 312 Info->Kind = Kind; 313 Info->Name = Name; 314 Info->Alignment = Alignment; 315 Info->LParenLoc = LParenLoc; 316 Info->RParenLoc = RParenLoc; 317 318 Token *Toks = 319 (Token*) PP.getPreprocessorAllocator().Allocate( 320 sizeof(Token) * 1, llvm::alignOf<Token>()); 321 new (Toks) Token(); 322 Toks[0].startToken(); 323 Toks[0].setKind(tok::annot_pragma_pack); 324 Toks[0].setLocation(PackLoc); 325 Toks[0].setAnnotationValue(static_cast<void*>(Info)); 326 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 327 /*OwnsTokens=*/false); 328 } 329 330 // #pragma ms_struct on 331 // #pragma ms_struct off 332 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, 333 PragmaIntroducerKind Introducer, 334 Token &MSStructTok) { 335 Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF; 336 337 Token Tok; 338 PP.Lex(Tok); 339 if (Tok.isNot(tok::identifier)) { 340 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); 341 return; 342 } 343 const IdentifierInfo *II = Tok.getIdentifierInfo(); 344 if (II->isStr("on")) { 345 Kind = Sema::PMSST_ON; 346 PP.Lex(Tok); 347 } 348 else if (II->isStr("off") || II->isStr("reset")) 349 PP.Lex(Tok); 350 else { 351 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); 352 return; 353 } 354 355 if (Tok.isNot(tok::eod)) { 356 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 357 << "ms_struct"; 358 return; 359 } 360 361 Token *Toks = 362 (Token*) PP.getPreprocessorAllocator().Allocate( 363 sizeof(Token) * 1, llvm::alignOf<Token>()); 364 new (Toks) Token(); 365 Toks[0].startToken(); 366 Toks[0].setKind(tok::annot_pragma_msstruct); 367 Toks[0].setLocation(MSStructTok.getLocation()); 368 Toks[0].setAnnotationValue(reinterpret_cast<void*>( 369 static_cast<uintptr_t>(Kind))); 370 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 371 /*OwnsTokens=*/false); 372 } 373 374 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'} 375 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'} 376 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, 377 bool IsOptions) { 378 Token Tok; 379 380 if (IsOptions) { 381 PP.Lex(Tok); 382 if (Tok.isNot(tok::identifier) || 383 !Tok.getIdentifierInfo()->isStr("align")) { 384 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align); 385 return; 386 } 387 } 388 389 PP.Lex(Tok); 390 if (Tok.isNot(tok::equal)) { 391 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal) 392 << IsOptions; 393 return; 394 } 395 396 PP.Lex(Tok); 397 if (Tok.isNot(tok::identifier)) { 398 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 399 << (IsOptions ? "options" : "align"); 400 return; 401 } 402 403 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural; 404 const IdentifierInfo *II = Tok.getIdentifierInfo(); 405 if (II->isStr("native")) 406 Kind = Sema::POAK_Native; 407 else if (II->isStr("natural")) 408 Kind = Sema::POAK_Natural; 409 else if (II->isStr("packed")) 410 Kind = Sema::POAK_Packed; 411 else if (II->isStr("power")) 412 Kind = Sema::POAK_Power; 413 else if (II->isStr("mac68k")) 414 Kind = Sema::POAK_Mac68k; 415 else if (II->isStr("reset")) 416 Kind = Sema::POAK_Reset; 417 else { 418 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option) 419 << IsOptions; 420 return; 421 } 422 423 PP.Lex(Tok); 424 if (Tok.isNot(tok::eod)) { 425 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) 426 << (IsOptions ? "options" : "align"); 427 return; 428 } 429 430 Token *Toks = 431 (Token*) PP.getPreprocessorAllocator().Allocate( 432 sizeof(Token) * 1, llvm::alignOf<Token>()); 433 new (Toks) Token(); 434 Toks[0].startToken(); 435 Toks[0].setKind(tok::annot_pragma_align); 436 Toks[0].setLocation(FirstTok.getLocation()); 437 Toks[0].setAnnotationValue(reinterpret_cast<void*>( 438 static_cast<uintptr_t>(Kind))); 439 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 440 /*OwnsTokens=*/false); 441 } 442 443 void PragmaAlignHandler::HandlePragma(Preprocessor &PP, 444 PragmaIntroducerKind Introducer, 445 Token &AlignTok) { 446 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false); 447 } 448 449 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, 450 PragmaIntroducerKind Introducer, 451 Token &OptionsTok) { 452 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true); 453 } 454 455 // #pragma unused(identifier) 456 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, 457 PragmaIntroducerKind Introducer, 458 Token &UnusedTok) { 459 // FIXME: Should we be expanding macros here? My guess is no. 460 SourceLocation UnusedLoc = UnusedTok.getLocation(); 461 462 // Lex the left '('. 463 Token Tok; 464 PP.Lex(Tok); 465 if (Tok.isNot(tok::l_paren)) { 466 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused"; 467 return; 468 } 469 470 // Lex the declaration reference(s). 471 SmallVector<Token, 5> Identifiers; 472 SourceLocation RParenLoc; 473 bool LexID = true; 474 475 while (true) { 476 PP.Lex(Tok); 477 478 if (LexID) { 479 if (Tok.is(tok::identifier)) { 480 Identifiers.push_back(Tok); 481 LexID = false; 482 continue; 483 } 484 485 // Illegal token! 486 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var); 487 return; 488 } 489 490 // We are execting a ')' or a ','. 491 if (Tok.is(tok::comma)) { 492 LexID = true; 493 continue; 494 } 495 496 if (Tok.is(tok::r_paren)) { 497 RParenLoc = Tok.getLocation(); 498 break; 499 } 500 501 // Illegal token! 502 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc); 503 return; 504 } 505 506 PP.Lex(Tok); 507 if (Tok.isNot(tok::eod)) { 508 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << 509 "unused"; 510 return; 511 } 512 513 // Verify that we have a location for the right parenthesis. 514 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'"); 515 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments"); 516 517 // For each identifier token, insert into the token stream a 518 // annot_pragma_unused token followed by the identifier token. 519 // This allows us to cache a "#pragma unused" that occurs inside an inline 520 // C++ member function. 521 522 Token *Toks = 523 (Token*) PP.getPreprocessorAllocator().Allocate( 524 sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>()); 525 for (unsigned i=0; i != Identifiers.size(); i++) { 526 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1]; 527 pragmaUnusedTok.startToken(); 528 pragmaUnusedTok.setKind(tok::annot_pragma_unused); 529 pragmaUnusedTok.setLocation(UnusedLoc); 530 idTok = Identifiers[i]; 531 } 532 PP.EnterTokenStream(Toks, 2*Identifiers.size(), 533 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); 534 } 535 536 // #pragma weak identifier 537 // #pragma weak identifier '=' identifier 538 void PragmaWeakHandler::HandlePragma(Preprocessor &PP, 539 PragmaIntroducerKind Introducer, 540 Token &WeakTok) { 541 SourceLocation WeakLoc = WeakTok.getLocation(); 542 543 Token Tok; 544 PP.Lex(Tok); 545 if (Tok.isNot(tok::identifier)) { 546 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak"; 547 return; 548 } 549 550 Token WeakName = Tok; 551 bool HasAlias = false; 552 Token AliasName; 553 554 PP.Lex(Tok); 555 if (Tok.is(tok::equal)) { 556 HasAlias = true; 557 PP.Lex(Tok); 558 if (Tok.isNot(tok::identifier)) { 559 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 560 << "weak"; 561 return; 562 } 563 AliasName = Tok; 564 PP.Lex(Tok); 565 } 566 567 if (Tok.isNot(tok::eod)) { 568 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak"; 569 return; 570 } 571 572 if (HasAlias) { 573 Token *Toks = 574 (Token*) PP.getPreprocessorAllocator().Allocate( 575 sizeof(Token) * 3, llvm::alignOf<Token>()); 576 Token &pragmaUnusedTok = Toks[0]; 577 pragmaUnusedTok.startToken(); 578 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias); 579 pragmaUnusedTok.setLocation(WeakLoc); 580 Toks[1] = WeakName; 581 Toks[2] = AliasName; 582 PP.EnterTokenStream(Toks, 3, 583 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); 584 } else { 585 Token *Toks = 586 (Token*) PP.getPreprocessorAllocator().Allocate( 587 sizeof(Token) * 2, llvm::alignOf<Token>()); 588 Token &pragmaUnusedTok = Toks[0]; 589 pragmaUnusedTok.startToken(); 590 pragmaUnusedTok.setKind(tok::annot_pragma_weak); 591 pragmaUnusedTok.setLocation(WeakLoc); 592 Toks[1] = WeakName; 593 PP.EnterTokenStream(Toks, 2, 594 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); 595 } 596 } 597 598 // #pragma redefine_extname identifier identifier 599 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP, 600 PragmaIntroducerKind Introducer, 601 Token &RedefToken) { 602 SourceLocation RedefLoc = RedefToken.getLocation(); 603 604 Token Tok; 605 PP.Lex(Tok); 606 if (Tok.isNot(tok::identifier)) { 607 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << 608 "redefine_extname"; 609 return; 610 } 611 612 Token RedefName = Tok; 613 PP.Lex(Tok); 614 615 if (Tok.isNot(tok::identifier)) { 616 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) 617 << "redefine_extname"; 618 return; 619 } 620 621 Token AliasName = Tok; 622 PP.Lex(Tok); 623 624 if (Tok.isNot(tok::eod)) { 625 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << 626 "redefine_extname"; 627 return; 628 } 629 630 Token *Toks = 631 (Token*) PP.getPreprocessorAllocator().Allocate( 632 sizeof(Token) * 3, llvm::alignOf<Token>()); 633 Token &pragmaRedefTok = Toks[0]; 634 pragmaRedefTok.startToken(); 635 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname); 636 pragmaRedefTok.setLocation(RedefLoc); 637 Toks[1] = RedefName; 638 Toks[2] = AliasName; 639 PP.EnterTokenStream(Toks, 3, 640 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); 641 } 642 643 644 void 645 PragmaFPContractHandler::HandlePragma(Preprocessor &PP, 646 PragmaIntroducerKind Introducer, 647 Token &Tok) { 648 tok::OnOffSwitch OOS; 649 if (PP.LexOnOffSwitch(OOS)) 650 return; 651 652 Token *Toks = 653 (Token*) PP.getPreprocessorAllocator().Allocate( 654 sizeof(Token) * 1, llvm::alignOf<Token>()); 655 new (Toks) Token(); 656 Toks[0].startToken(); 657 Toks[0].setKind(tok::annot_pragma_fp_contract); 658 Toks[0].setLocation(Tok.getLocation()); 659 Toks[0].setAnnotationValue(reinterpret_cast<void*>( 660 static_cast<uintptr_t>(OOS))); 661 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 662 /*OwnsTokens=*/false); 663 } 664 665 void 666 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP, 667 PragmaIntroducerKind Introducer, 668 Token &Tok) { 669 PP.LexUnexpandedToken(Tok); 670 if (Tok.isNot(tok::identifier)) { 671 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << 672 "OPENCL"; 673 return; 674 } 675 IdentifierInfo *ename = Tok.getIdentifierInfo(); 676 SourceLocation NameLoc = Tok.getLocation(); 677 678 PP.Lex(Tok); 679 if (Tok.isNot(tok::colon)) { 680 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename; 681 return; 682 } 683 684 PP.Lex(Tok); 685 if (Tok.isNot(tok::identifier)) { 686 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); 687 return; 688 } 689 IdentifierInfo *op = Tok.getIdentifierInfo(); 690 691 unsigned state; 692 if (op->isStr("enable")) { 693 state = 1; 694 } else if (op->isStr("disable")) { 695 state = 0; 696 } else { 697 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); 698 return; 699 } 700 701 PP.Lex(Tok); 702 if (Tok.isNot(tok::eod)) { 703 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << 704 "OPENCL EXTENSION"; 705 return; 706 } 707 708 OpenCLExtData data(ename, state); 709 Token *Toks = 710 (Token*) PP.getPreprocessorAllocator().Allocate( 711 sizeof(Token) * 1, llvm::alignOf<Token>()); 712 new (Toks) Token(); 713 Toks[0].startToken(); 714 Toks[0].setKind(tok::annot_pragma_opencl_extension); 715 Toks[0].setLocation(NameLoc); 716 Toks[0].setAnnotationValue(data.getOpaqueValue()); 717 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, 718 /*OwnsTokens=*/false); 719 } 720 721