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