blob: f32e06bbcdee88a6a5e6c5cd334407213f1826a1 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Pragma.cpp - Pragma registration and handling --------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source 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/PPCallbacks.h"
17#include "clang/Lex/HeaderSearch.h"
18#include "clang/Lex/Preprocessor.h"
19#include "clang/Basic/Diagnostic.h"
20#include "clang/Basic/FileManager.h"
21#include "clang/Basic/SourceManager.h"
22#include "llvm/ADT/SmallVector.h"
23using namespace clang;
24
25// Out-of-line destructor to provide a home for the class.
26PragmaHandler::~PragmaHandler() {
27}
28
29//===----------------------------------------------------------------------===//
30// PragmaNamespace Implementation.
31//===----------------------------------------------------------------------===//
32
33
34PragmaNamespace::~PragmaNamespace() {
35 for (unsigned i = 0, e = Handlers.size(); i != e; ++i)
36 delete Handlers[i];
37}
38
39/// FindHandler - Check to see if there is already a handler for the
40/// specified name. If not, return the handler for the null identifier if it
41/// exists, otherwise return null. If IgnoreNull is true (the default) then
42/// the null handler isn't returned on failure to match.
43PragmaHandler *PragmaNamespace::FindHandler(const IdentifierInfo *Name,
44 bool IgnoreNull) const {
45 PragmaHandler *NullHandler = 0;
46 for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
47 if (Handlers[i]->getName() == Name)
48 return Handlers[i];
49
50 if (Handlers[i]->getName() == 0)
51 NullHandler = Handlers[i];
52 }
53 return IgnoreNull ? 0 : NullHandler;
54}
55
Chris Lattnerd2177732007-07-20 16:59:19 +000056void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) {
Reid Spencer5f016e22007-07-11 17:01:13 +000057 // Read the 'namespace' that the directive is in, e.g. STDC. Do not macro
58 // expand it, the user can have a STDC #define, that should not affect this.
59 PP.LexUnexpandedToken(Tok);
60
61 // Get the handler for this token. If there is no handler, ignore the pragma.
62 PragmaHandler *Handler = FindHandler(Tok.getIdentifierInfo(), false);
63 if (Handler == 0) return;
64
65 // Otherwise, pass it down.
66 Handler->HandlePragma(PP, Tok);
67}
68
69//===----------------------------------------------------------------------===//
70// Preprocessor Pragma Directive Handling.
71//===----------------------------------------------------------------------===//
72
73/// HandlePragmaDirective - The "#pragma" directive has been parsed. Lex the
74/// rest of the pragma, passing it to the registered pragma handlers.
75void Preprocessor::HandlePragmaDirective() {
76 ++NumPragma;
77
78 // Invoke the first level of pragma handlers which reads the namespace id.
Chris Lattnerd2177732007-07-20 16:59:19 +000079 Token Tok;
Reid Spencer5f016e22007-07-11 17:01:13 +000080 PragmaHandlers->HandlePragma(*this, Tok);
81
82 // If the pragma handler didn't read the rest of the line, consume it now.
83 if (CurLexer->ParsingPreprocessorDirective)
84 DiscardUntilEndOfDirective();
85}
86
87/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
88/// return the first token after the directive. The _Pragma token has just
89/// been read into 'Tok'.
Chris Lattnerd2177732007-07-20 16:59:19 +000090void Preprocessor::Handle_Pragma(Token &Tok) {
Reid Spencer5f016e22007-07-11 17:01:13 +000091 // Remember the pragma token location.
92 SourceLocation PragmaLoc = Tok.getLocation();
93
94 // Read the '('.
95 Lex(Tok);
Chris Lattner22f6bbc2007-10-09 18:02:16 +000096 if (Tok.isNot(tok::l_paren))
Reid Spencer5f016e22007-07-11 17:01:13 +000097 return Diag(PragmaLoc, diag::err__Pragma_malformed);
98
99 // Read the '"..."'.
100 Lex(Tok);
Chris Lattner22f6bbc2007-10-09 18:02:16 +0000101 if (Tok.isNot(tok::string_literal) && Tok.isNot(tok::wide_string_literal))
Reid Spencer5f016e22007-07-11 17:01:13 +0000102 return Diag(PragmaLoc, diag::err__Pragma_malformed);
103
104 // Remember the string.
105 std::string StrVal = getSpelling(Tok);
106 SourceLocation StrLoc = Tok.getLocation();
107
108 // Read the ')'.
109 Lex(Tok);
Chris Lattner22f6bbc2007-10-09 18:02:16 +0000110 if (Tok.isNot(tok::r_paren))
Reid Spencer5f016e22007-07-11 17:01:13 +0000111 return Diag(PragmaLoc, diag::err__Pragma_malformed);
112
113 // The _Pragma is lexically sound. Destringize according to C99 6.10.9.1.
114 if (StrVal[0] == 'L') // Remove L prefix.
115 StrVal.erase(StrVal.begin());
116 assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
117 "Invalid string token!");
118
119 // Remove the front quote, replacing it with a space, so that the pragma
120 // contents appear to have a space before them.
121 StrVal[0] = ' ';
122
123 // Replace the terminating quote with a \n\0.
124 StrVal[StrVal.size()-1] = '\n';
125 StrVal += '\0';
126
127 // Remove escaped quotes and escapes.
128 for (unsigned i = 0, e = StrVal.size(); i != e-1; ++i) {
129 if (StrVal[i] == '\\' &&
130 (StrVal[i+1] == '\\' || StrVal[i+1] == '"')) {
131 // \\ -> '\' and \" -> '"'.
132 StrVal.erase(StrVal.begin()+i);
133 --e;
134 }
135 }
136
137 // Plop the string (including the newline and trailing null) into a buffer
138 // where we can lex it.
139 SourceLocation TokLoc = CreateString(&StrVal[0], StrVal.size(), StrLoc);
140 const char *StrData = SourceMgr.getCharacterData(TokLoc);
141
Reid Spencer5f016e22007-07-11 17:01:13 +0000142 // Make and enter a lexer object so that we lex and expand the tokens just
143 // like any others.
Chris Lattner25bdb512007-07-20 16:52:03 +0000144 Lexer *TL = new Lexer(TokLoc, *this,
Reid Spencer5f016e22007-07-11 17:01:13 +0000145 StrData, StrData+StrVal.size()-1 /* no null */);
146
147 // Ensure that the lexer thinks it is inside a directive, so that end \n will
148 // return an EOM token.
149 TL->ParsingPreprocessorDirective = true;
150
151 // This lexer really is for _Pragma.
152 TL->Is_PragmaLexer = true;
153
154 EnterSourceFileWithLexer(TL, 0);
155
156 // With everything set up, lex this as a #pragma directive.
157 HandlePragmaDirective();
158
159 // Finally, return whatever came after the pragma directive.
160 return Lex(Tok);
161}
162
163
164
165/// HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'.
166///
Chris Lattnerd2177732007-07-20 16:59:19 +0000167void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000168 if (isInPrimaryFile()) {
169 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
170 return;
171 }
172
173 // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.
Chris Lattner9dc1f532007-07-20 16:37:10 +0000174 SourceLocation FileLoc = getCurrentFileLexer()->getFileLoc();
Reid Spencer5f016e22007-07-11 17:01:13 +0000175
176 // Mark the file as a once-only file now.
Chris Lattner9dc1f532007-07-20 16:37:10 +0000177 HeaderInfo.MarkFileIncludeOnce(SourceMgr.getFileEntryForLoc(FileLoc));
Reid Spencer5f016e22007-07-11 17:01:13 +0000178}
179
Chris Lattner22434492007-12-19 19:38:36 +0000180void Preprocessor::HandlePragmaMark() {
181 assert(CurLexer && "No current lexer?");
182 CurLexer->ReadToEndOfLine();
183}
184
185
Reid Spencer5f016e22007-07-11 17:01:13 +0000186/// HandlePragmaPoison - Handle #pragma GCC poison. PoisonTok is the 'poison'.
187///
Chris Lattnerd2177732007-07-20 16:59:19 +0000188void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
189 Token Tok;
Reid Spencer5f016e22007-07-11 17:01:13 +0000190
191 while (1) {
192 // Read the next token to poison. While doing this, pretend that we are
193 // skipping while reading the identifier to poison.
194 // This avoids errors on code like:
195 // #pragma GCC poison X
196 // #pragma GCC poison X
197 if (CurLexer) CurLexer->LexingRawMode = true;
198 LexUnexpandedToken(Tok);
199 if (CurLexer) CurLexer->LexingRawMode = false;
200
201 // If we reached the end of line, we're done.
Chris Lattner22f6bbc2007-10-09 18:02:16 +0000202 if (Tok.is(tok::eom)) return;
Reid Spencer5f016e22007-07-11 17:01:13 +0000203
204 // Can only poison identifiers.
Chris Lattner22f6bbc2007-10-09 18:02:16 +0000205 if (Tok.isNot(tok::identifier)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000206 Diag(Tok, diag::err_pp_invalid_poison);
207 return;
208 }
209
210 // Look up the identifier info for the token. We disabled identifier lookup
211 // by saying we're skipping contents, so we need to do this manually.
212 IdentifierInfo *II = LookUpIdentifierInfo(Tok);
213
214 // Already poisoned.
215 if (II->isPoisoned()) continue;
216
217 // If this is a macro identifier, emit a warning.
Chris Lattner0edde552007-10-07 08:04:56 +0000218 if (II->hasMacroDefinition())
Reid Spencer5f016e22007-07-11 17:01:13 +0000219 Diag(Tok, diag::pp_poisoning_existing_macro);
220
221 // Finally, poison it!
222 II->setIsPoisoned();
223 }
224}
225
226/// HandlePragmaSystemHeader - Implement #pragma GCC system_header. We know
227/// that the whole directive has been parsed.
Chris Lattnerd2177732007-07-20 16:59:19 +0000228void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000229 if (isInPrimaryFile()) {
230 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
231 return;
232 }
233
234 // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.
235 Lexer *TheLexer = getCurrentFileLexer();
236
237 // Mark the file as a system header.
Chris Lattner9dc1f532007-07-20 16:37:10 +0000238 const FileEntry *File = SourceMgr.getFileEntryForLoc(TheLexer->getFileLoc());
Reid Spencer5f016e22007-07-11 17:01:13 +0000239 HeaderInfo.MarkFileSystemHeader(File);
240
241 // Notify the client, if desired, that we are in a new source file.
242 if (Callbacks)
243 Callbacks->FileChanged(TheLexer->getSourceLocation(TheLexer->BufferPtr),
244 PPCallbacks::SystemHeaderPragma,
245 DirectoryLookup::SystemHeaderDir);
246}
247
248/// HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
249///
Chris Lattnerd2177732007-07-20 16:59:19 +0000250void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
251 Token FilenameTok;
Reid Spencer5f016e22007-07-11 17:01:13 +0000252 CurLexer->LexIncludeFilename(FilenameTok);
253
254 // If the token kind is EOM, the error has already been diagnosed.
Chris Lattner22f6bbc2007-10-09 18:02:16 +0000255 if (FilenameTok.is(tok::eom))
Reid Spencer5f016e22007-07-11 17:01:13 +0000256 return;
257
258 // Reserve a buffer to get the spelling.
259 llvm::SmallVector<char, 128> FilenameBuffer;
260 FilenameBuffer.resize(FilenameTok.getLength());
261
Chris Lattnerf1c99ac2007-07-23 04:15:27 +0000262 const char *FilenameStart = &FilenameBuffer[0];
263 unsigned Len = getSpelling(FilenameTok, FilenameStart);
264 const char *FilenameEnd = FilenameStart+Len;
265 bool isAngled = GetIncludeFilenameSpelling(FilenameTok.getLocation(),
Reid Spencer5f016e22007-07-11 17:01:13 +0000266 FilenameStart, FilenameEnd);
267 // If GetIncludeFilenameSpelling set the start ptr to null, there was an
268 // error.
269 if (FilenameStart == 0)
270 return;
271
272 // Search include directories for this file.
273 const DirectoryLookup *CurDir;
274 const FileEntry *File = LookupFile(FilenameStart, FilenameEnd,
275 isAngled, 0, CurDir);
276 if (File == 0)
277 return Diag(FilenameTok, diag::err_pp_file_not_found,
278 std::string(FilenameStart, FilenameEnd));
279
Chris Lattner9dc1f532007-07-20 16:37:10 +0000280 SourceLocation FileLoc = getCurrentFileLexer()->getFileLoc();
281 const FileEntry *CurFile = SourceMgr.getFileEntryForLoc(FileLoc);
Reid Spencer5f016e22007-07-11 17:01:13 +0000282
283 // If this file is older than the file it depends on, emit a diagnostic.
284 if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
285 // Lex tokens at the end of the message and include them in the message.
286 std::string Message;
287 Lex(DependencyTok);
Chris Lattner22f6bbc2007-10-09 18:02:16 +0000288 while (DependencyTok.isNot(tok::eom)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000289 Message += getSpelling(DependencyTok) + " ";
290 Lex(DependencyTok);
291 }
292
293 Message.erase(Message.end()-1);
294 Diag(FilenameTok, diag::pp_out_of_date_dependency, Message);
295 }
296}
297
298
299/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
300/// If 'Namespace' is non-null, then it is a token required to exist on the
301/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
302void Preprocessor::AddPragmaHandler(const char *Namespace,
303 PragmaHandler *Handler) {
304 PragmaNamespace *InsertNS = PragmaHandlers;
305
306 // If this is specified to be in a namespace, step down into it.
307 if (Namespace) {
308 IdentifierInfo *NSID = getIdentifierInfo(Namespace);
309
310 // If there is already a pragma handler with the name of this namespace,
311 // we either have an error (directive with the same name as a namespace) or
312 // we already have the namespace to insert into.
313 if (PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID)) {
314 InsertNS = Existing->getIfNamespace();
315 assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma"
316 " handler with the same name!");
317 } else {
318 // Otherwise, this namespace doesn't exist yet, create and insert the
319 // handler for it.
320 InsertNS = new PragmaNamespace(NSID);
321 PragmaHandlers->AddPragma(InsertNS);
322 }
323 }
324
325 // Check to make sure we don't already have a pragma for this identifier.
326 assert(!InsertNS->FindHandler(Handler->getName()) &&
327 "Pragma handler already exists for this identifier!");
328 InsertNS->AddPragma(Handler);
329}
330
331namespace {
Chris Lattner22434492007-12-19 19:38:36 +0000332/// PragmaOnceHandler - "#pragma once" marks the file as atomically included.
Reid Spencer5f016e22007-07-11 17:01:13 +0000333struct PragmaOnceHandler : public PragmaHandler {
334 PragmaOnceHandler(const IdentifierInfo *OnceID) : PragmaHandler(OnceID) {}
Chris Lattnerd2177732007-07-20 16:59:19 +0000335 virtual void HandlePragma(Preprocessor &PP, Token &OnceTok) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000336 PP.CheckEndOfDirective("#pragma once");
337 PP.HandlePragmaOnce(OnceTok);
338 }
339};
340
Chris Lattner22434492007-12-19 19:38:36 +0000341/// PragmaMarkHandler - "#pragma mark ..." is ignored by the compiler, and the
342/// rest of the line is not lexed.
343struct PragmaMarkHandler : public PragmaHandler {
344 PragmaMarkHandler(const IdentifierInfo *MarkID) : PragmaHandler(MarkID) {}
345 virtual void HandlePragma(Preprocessor &PP, Token &MarkTok) {
346 PP.HandlePragmaMark();
347 }
348};
349
350/// PragmaPoisonHandler - "#pragma poison x" marks x as not usable.
Reid Spencer5f016e22007-07-11 17:01:13 +0000351struct PragmaPoisonHandler : public PragmaHandler {
352 PragmaPoisonHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
Chris Lattnerd2177732007-07-20 16:59:19 +0000353 virtual void HandlePragma(Preprocessor &PP, Token &PoisonTok) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000354 PP.HandlePragmaPoison(PoisonTok);
355 }
356};
357
Chris Lattner22434492007-12-19 19:38:36 +0000358/// PragmaSystemHeaderHandler - "#pragma system_header" marks the current file
359/// as a system header, which silences warnings in it.
Reid Spencer5f016e22007-07-11 17:01:13 +0000360struct PragmaSystemHeaderHandler : public PragmaHandler {
361 PragmaSystemHeaderHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
Chris Lattnerd2177732007-07-20 16:59:19 +0000362 virtual void HandlePragma(Preprocessor &PP, Token &SHToken) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000363 PP.HandlePragmaSystemHeader(SHToken);
364 PP.CheckEndOfDirective("#pragma");
365 }
366};
367struct PragmaDependencyHandler : public PragmaHandler {
368 PragmaDependencyHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
Chris Lattnerd2177732007-07-20 16:59:19 +0000369 virtual void HandlePragma(Preprocessor &PP, Token &DepToken) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000370 PP.HandlePragmaDependency(DepToken);
371 }
372};
373} // end anonymous namespace
374
375
376/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
377/// #pragma GCC poison/system_header/dependency and #pragma once.
378void Preprocessor::RegisterBuiltinPragmas() {
379 AddPragmaHandler(0, new PragmaOnceHandler(getIdentifierInfo("once")));
Chris Lattner22434492007-12-19 19:38:36 +0000380 AddPragmaHandler(0, new PragmaMarkHandler(getIdentifierInfo("mark")));
Reid Spencer5f016e22007-07-11 17:01:13 +0000381 AddPragmaHandler("GCC", new PragmaPoisonHandler(getIdentifierInfo("poison")));
382 AddPragmaHandler("GCC", new PragmaSystemHeaderHandler(
383 getIdentifierInfo("system_header")));
384 AddPragmaHandler("GCC", new PragmaDependencyHandler(
385 getIdentifierInfo("dependency")));
386}