Pragma.cpp revision 56b05c8829efd13b7e5b333f8f587c71d025c67d
1//===--- Pragma.cpp - Pragma registration and handling --------------------===//
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 PragmaHandler/PragmaTable interfaces and implements
11// pragma related methods of the Preprocessor class.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Lex/Pragma.h"
16#include "clang/Lex/HeaderSearch.h"
17#include "clang/Lex/Preprocessor.h"
18#include "clang/Basic/Diagnostic.h"
19#include "clang/Basic/FileManager.h"
20#include "clang/Basic/SourceManager.h"
21using namespace clang;
22
23// Out-of-line destructor to provide a home for the class.
24PragmaHandler::~PragmaHandler() {
25}
26
27//===----------------------------------------------------------------------===//
28// PragmaNamespace Implementation.
29//===----------------------------------------------------------------------===//
30
31
32PragmaNamespace::~PragmaNamespace() {
33  for (unsigned i = 0, e = Handlers.size(); i != e; ++i)
34    delete Handlers[i];
35}
36
37/// FindHandler - Check to see if there is already a handler for the
38/// specified name.  If not, return the handler for the null identifier if it
39/// exists, otherwise return null.  If IgnoreNull is true (the default) then
40/// the null handler isn't returned on failure to match.
41PragmaHandler *PragmaNamespace::FindHandler(const IdentifierInfo *Name,
42                                            bool IgnoreNull) const {
43  PragmaHandler *NullHandler = 0;
44  for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
45    if (Handlers[i]->getName() == Name)
46      return Handlers[i];
47
48    if (Handlers[i]->getName() == 0)
49      NullHandler = Handlers[i];
50  }
51  return IgnoreNull ? 0 : NullHandler;
52}
53
54void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
55  for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
56    if (Handlers[i] == Handler) {
57      Handlers[i] = Handlers.back();
58      Handlers.pop_back();
59      return;
60    }
61  }
62  assert(0 && "Handler not registered in this namespace");
63}
64
65void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) {
66  // Read the 'namespace' that the directive is in, e.g. STDC.  Do not macro
67  // expand it, the user can have a STDC #define, that should not affect this.
68  PP.LexUnexpandedToken(Tok);
69
70  // Get the handler for this token.  If there is no handler, ignore the pragma.
71  PragmaHandler *Handler = FindHandler(Tok.getIdentifierInfo(), false);
72  if (Handler == 0) return;
73
74  // Otherwise, pass it down.
75  Handler->HandlePragma(PP, Tok);
76}
77
78//===----------------------------------------------------------------------===//
79// Preprocessor Pragma Directive Handling.
80//===----------------------------------------------------------------------===//
81
82/// HandlePragmaDirective - The "#pragma" directive has been parsed.  Lex the
83/// rest of the pragma, passing it to the registered pragma handlers.
84void Preprocessor::HandlePragmaDirective() {
85  ++NumPragma;
86
87  // Invoke the first level of pragma handlers which reads the namespace id.
88  Token Tok;
89  PragmaHandlers->HandlePragma(*this, Tok);
90
91  // If the pragma handler didn't read the rest of the line, consume it now.
92  if (CurPPLexer->ParsingPreprocessorDirective)
93    DiscardUntilEndOfDirective();
94}
95
96/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
97/// return the first token after the directive.  The _Pragma token has just
98/// been read into 'Tok'.
99void Preprocessor::Handle_Pragma(Token &Tok) {
100  // Remember the pragma token location.
101  SourceLocation PragmaLoc = Tok.getLocation();
102
103  // Read the '('.
104  Lex(Tok);
105  if (Tok.isNot(tok::l_paren)) {
106    Diag(PragmaLoc, diag::err__Pragma_malformed);
107    return;
108  }
109
110  // Read the '"..."'.
111  Lex(Tok);
112  if (Tok.isNot(tok::string_literal) && Tok.isNot(tok::wide_string_literal)) {
113    Diag(PragmaLoc, diag::err__Pragma_malformed);
114    return;
115  }
116
117  // Remember the string.
118  std::string StrVal = getSpelling(Tok);
119  SourceLocation StrLoc = Tok.getLocation();
120
121  // Read the ')'.
122  Lex(Tok);
123  if (Tok.isNot(tok::r_paren)) {
124    Diag(PragmaLoc, diag::err__Pragma_malformed);
125    return;
126  }
127
128  // The _Pragma is lexically sound.  Destringize according to C99 6.10.9.1.
129  if (StrVal[0] == 'L')  // Remove L prefix.
130    StrVal.erase(StrVal.begin());
131  assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
132         "Invalid string token!");
133
134  // Remove the front quote, replacing it with a space, so that the pragma
135  // contents appear to have a space before them.
136  StrVal[0] = ' ';
137
138  // Replace the terminating quote with a \n\0.
139  StrVal[StrVal.size()-1] = '\n';
140  StrVal += '\0';
141
142  // Remove escaped quotes and escapes.
143  for (unsigned i = 0, e = StrVal.size(); i != e-1; ++i) {
144    if (StrVal[i] == '\\' &&
145        (StrVal[i+1] == '\\' || StrVal[i+1] == '"')) {
146      // \\ -> '\' and \" -> '"'.
147      StrVal.erase(StrVal.begin()+i);
148      --e;
149    }
150  }
151
152  // Plop the string (including the newline and trailing null) into a buffer
153  // where we can lex it.
154  SourceLocation TokLoc = CreateString(&StrVal[0], StrVal.size(), StrLoc);
155  const char *StrData = SourceMgr.getCharacterData(TokLoc);
156
157  // Make and enter a lexer object so that we lex and expand the tokens just
158  // like any others.
159  Lexer *TL = new Lexer(TokLoc, *this,
160                        StrData, StrData+StrVal.size()-1 /* no null */);
161
162  // Ensure that the lexer thinks it is inside a directive, so that end \n will
163  // return an EOM token.
164  TL->ParsingPreprocessorDirective = true;
165
166  // This lexer really is for _Pragma.
167  TL->Is_PragmaLexer = true;
168
169  EnterSourceFileWithLexer(TL, 0);
170
171  // With everything set up, lex this as a #pragma directive.
172  HandlePragmaDirective();
173
174  // Finally, return whatever came after the pragma directive.
175  return Lex(Tok);
176}
177
178
179
180/// HandlePragmaOnce - Handle #pragma once.  OnceTok is the 'once'.
181///
182void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
183  if (isInPrimaryFile()) {
184    Diag(OnceTok, diag::pp_pragma_once_in_main_file);
185    return;
186  }
187
188  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
189  SourceLocation FileLoc = getCurrentFileLexer()->getFileLoc();
190
191  // Mark the file as a once-only file now.
192  HeaderInfo.MarkFileIncludeOnce(SourceMgr.getFileEntryForLoc(FileLoc));
193}
194
195void Preprocessor::HandlePragmaMark() {
196  assert(CurLexer && "No current lexer?");
197  CurLexer->ReadToEndOfLine();
198}
199
200
201/// HandlePragmaPoison - Handle #pragma GCC poison.  PoisonTok is the 'poison'.
202///
203void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
204  Token Tok;
205
206  while (1) {
207    // Read the next token to poison.  While doing this, pretend that we are
208    // skipping while reading the identifier to poison.
209    // This avoids errors on code like:
210    //   #pragma GCC poison X
211    //   #pragma GCC poison X
212    if (CurPPLexer) CurPPLexer->LexingRawMode = true;
213    LexUnexpandedToken(Tok);
214    if (CurPPLexer) CurPPLexer->LexingRawMode = false;
215
216    // If we reached the end of line, we're done.
217    if (Tok.is(tok::eom)) return;
218
219    // Can only poison identifiers.
220    if (Tok.isNot(tok::identifier)) {
221      Diag(Tok, diag::err_pp_invalid_poison);
222      return;
223    }
224
225    // Look up the identifier info for the token.  We disabled identifier lookup
226    // by saying we're skipping contents, so we need to do this manually.
227    IdentifierInfo *II = LookUpIdentifierInfo(Tok);
228
229    // Already poisoned.
230    if (II->isPoisoned()) continue;
231
232    // If this is a macro identifier, emit a warning.
233    if (II->hasMacroDefinition())
234      Diag(Tok, diag::pp_poisoning_existing_macro);
235
236    // Finally, poison it!
237    II->setIsPoisoned();
238  }
239}
240
241/// HandlePragmaSystemHeader - Implement #pragma GCC system_header.  We know
242/// that the whole directive has been parsed.
243void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
244  if (isInPrimaryFile()) {
245    Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
246    return;
247  }
248
249  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
250  Lexer *TheLexer = getCurrentFileLexer();
251
252  // Mark the file as a system header.
253  const FileEntry *File = SourceMgr.getFileEntryForLoc(TheLexer->getFileLoc());
254  HeaderInfo.MarkFileSystemHeader(File);
255
256  // Notify the client, if desired, that we are in a new source file.
257  if (Callbacks)
258    Callbacks->FileChanged(TheLexer->getSourceLocation(TheLexer->BufferPtr),
259                           PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
260}
261
262/// HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
263///
264void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
265  Token FilenameTok;
266  CurPPLexer->LexIncludeFilename(FilenameTok);
267
268  // If the token kind is EOM, the error has already been diagnosed.
269  if (FilenameTok.is(tok::eom))
270    return;
271
272  // Reserve a buffer to get the spelling.
273  llvm::SmallVector<char, 128> FilenameBuffer;
274  FilenameBuffer.resize(FilenameTok.getLength());
275
276  const char *FilenameStart = &FilenameBuffer[0];
277  unsigned Len = getSpelling(FilenameTok, FilenameStart);
278  const char *FilenameEnd = FilenameStart+Len;
279  bool isAngled = GetIncludeFilenameSpelling(FilenameTok.getLocation(),
280                                             FilenameStart, FilenameEnd);
281  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
282  // error.
283  if (FilenameStart == 0)
284    return;
285
286  // Search include directories for this file.
287  const DirectoryLookup *CurDir;
288  const FileEntry *File = LookupFile(FilenameStart, FilenameEnd,
289                                     isAngled, 0, CurDir);
290  if (File == 0) {
291    Diag(FilenameTok, diag::err_pp_file_not_found)
292      << std::string(FilenameStart, FilenameEnd);
293    return;
294  }
295
296  SourceLocation FileLoc = getCurrentFileLexer()->getFileLoc();
297  const FileEntry *CurFile = SourceMgr.getFileEntryForLoc(FileLoc);
298
299  // If this file is older than the file it depends on, emit a diagnostic.
300  if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
301    // Lex tokens at the end of the message and include them in the message.
302    std::string Message;
303    Lex(DependencyTok);
304    while (DependencyTok.isNot(tok::eom)) {
305      Message += getSpelling(DependencyTok) + " ";
306      Lex(DependencyTok);
307    }
308
309    Message.erase(Message.end()-1);
310    Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
311  }
312}
313
314
315/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
316/// If 'Namespace' is non-null, then it is a token required to exist on the
317/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
318void Preprocessor::AddPragmaHandler(const char *Namespace,
319                                    PragmaHandler *Handler) {
320  PragmaNamespace *InsertNS = PragmaHandlers;
321
322  // If this is specified to be in a namespace, step down into it.
323  if (Namespace) {
324    IdentifierInfo *NSID = getIdentifierInfo(Namespace);
325
326    // If there is already a pragma handler with the name of this namespace,
327    // we either have an error (directive with the same name as a namespace) or
328    // we already have the namespace to insert into.
329    if (PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID)) {
330      InsertNS = Existing->getIfNamespace();
331      assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma"
332             " handler with the same name!");
333    } else {
334      // Otherwise, this namespace doesn't exist yet, create and insert the
335      // handler for it.
336      InsertNS = new PragmaNamespace(NSID);
337      PragmaHandlers->AddPragma(InsertNS);
338    }
339  }
340
341  // Check to make sure we don't already have a pragma for this identifier.
342  assert(!InsertNS->FindHandler(Handler->getName()) &&
343         "Pragma handler already exists for this identifier!");
344  InsertNS->AddPragma(Handler);
345}
346
347/// RemovePragmaHandler - Remove the specific pragma handler from the
348/// preprocessor. If \arg Namespace is non-null, then it should be the
349/// namespace that \arg Handler was added to. It is an error to remove
350/// a handler that has not been registered.
351void Preprocessor::RemovePragmaHandler(const char *Namespace,
352                                       PragmaHandler *Handler) {
353  PragmaNamespace *NS = PragmaHandlers;
354
355  // If this is specified to be in a namespace, step down into it.
356  if (Namespace) {
357    IdentifierInfo *NSID = getIdentifierInfo(Namespace);
358    PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID);
359    assert(Existing && "Namespace containing handler does not exist!");
360
361    NS = Existing->getIfNamespace();
362    assert(NS && "Invalid namespace, registered as a regular pragma handler!");
363  }
364
365  NS->RemovePragmaHandler(Handler);
366
367  // If this is a non-default namespace and it is now empty, remove
368  // it.
369  if (NS != PragmaHandlers && NS->IsEmpty())
370    PragmaHandlers->RemovePragmaHandler(NS);
371}
372
373namespace {
374/// PragmaOnceHandler - "#pragma once" marks the file as atomically included.
375struct PragmaOnceHandler : public PragmaHandler {
376  PragmaOnceHandler(const IdentifierInfo *OnceID) : PragmaHandler(OnceID) {}
377  virtual void HandlePragma(Preprocessor &PP, Token &OnceTok) {
378    PP.CheckEndOfDirective("#pragma once");
379    PP.HandlePragmaOnce(OnceTok);
380  }
381};
382
383/// PragmaMarkHandler - "#pragma mark ..." is ignored by the compiler, and the
384/// rest of the line is not lexed.
385struct PragmaMarkHandler : public PragmaHandler {
386  PragmaMarkHandler(const IdentifierInfo *MarkID) : PragmaHandler(MarkID) {}
387  virtual void HandlePragma(Preprocessor &PP, Token &MarkTok) {
388    PP.HandlePragmaMark();
389  }
390};
391
392/// PragmaPoisonHandler - "#pragma poison x" marks x as not usable.
393struct PragmaPoisonHandler : public PragmaHandler {
394  PragmaPoisonHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
395  virtual void HandlePragma(Preprocessor &PP, Token &PoisonTok) {
396    PP.HandlePragmaPoison(PoisonTok);
397  }
398};
399
400/// PragmaSystemHeaderHandler - "#pragma system_header" marks the current file
401/// as a system header, which silences warnings in it.
402struct PragmaSystemHeaderHandler : public PragmaHandler {
403  PragmaSystemHeaderHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
404  virtual void HandlePragma(Preprocessor &PP, Token &SHToken) {
405    PP.HandlePragmaSystemHeader(SHToken);
406    PP.CheckEndOfDirective("#pragma");
407  }
408};
409struct PragmaDependencyHandler : public PragmaHandler {
410  PragmaDependencyHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
411  virtual void HandlePragma(Preprocessor &PP, Token &DepToken) {
412    PP.HandlePragmaDependency(DepToken);
413  }
414};
415}  // end anonymous namespace
416
417
418/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
419/// #pragma GCC poison/system_header/dependency and #pragma once.
420void Preprocessor::RegisterBuiltinPragmas() {
421  AddPragmaHandler(0, new PragmaOnceHandler(getIdentifierInfo("once")));
422  AddPragmaHandler(0, new PragmaMarkHandler(getIdentifierInfo("mark")));
423  AddPragmaHandler("GCC", new PragmaPoisonHandler(getIdentifierInfo("poison")));
424  AddPragmaHandler("GCC", new PragmaSystemHeaderHandler(
425                                          getIdentifierInfo("system_header")));
426  AddPragmaHandler("GCC", new PragmaDependencyHandler(
427                                          getIdentifierInfo("dependency")));
428}
429