[cfe-commits] r38568 - in /cfe/cfe/trunk: Lex/IdentifierTable.cpp Lex/Lexer.cpp Lex/Pragma.cpp Lex/Preprocessor.cpp README.txt include/clang/Basic/DiagnosticKinds.def include/clang/Lex/IdentifierTable.h include/clang/Lex/Preprocessor.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:22:46 PDT 2007
Author: sabre
Date: Wed Jul 11 11:22:45 2007
New Revision: 38568
URL: http://llvm.org/viewvc/llvm-project?rev=38568&view=rev
Log:
Finish implementation of #pragma once. Implement #pragma GCC poison.
Modified:
cfe/cfe/trunk/Lex/IdentifierTable.cpp
cfe/cfe/trunk/Lex/Lexer.cpp
cfe/cfe/trunk/Lex/Pragma.cpp
cfe/cfe/trunk/Lex/Preprocessor.cpp
cfe/cfe/trunk/README.txt
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h
cfe/cfe/trunk/include/clang/Lex/Preprocessor.h
Modified: cfe/cfe/trunk/Lex/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/IdentifierTable.cpp?rev=38568&r1=38567&r2=38568&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/IdentifierTable.cpp (original)
+++ cfe/cfe/trunk/Lex/IdentifierTable.cpp Wed Jul 11 11:22:45 2007
@@ -191,6 +191,7 @@
Identifier->TokInfo.Macro = 0;
Identifier->TokInfo.TokenID = tok::identifier;
Identifier->TokInfo.IsExtension = false;
+ Identifier->TokInfo.IsPoisoned = false;
Identifier->TokInfo.FETokenInfo = 0;
// Copy the string information.
Modified: cfe/cfe/trunk/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Lexer.cpp?rev=38568&r1=38567&r2=38568&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Lexer.cpp (original)
+++ cfe/cfe/trunk/Lex/Lexer.cpp Wed Jul 11 11:22:45 2007
@@ -19,8 +19,6 @@
// WARNING: `%.*s' is not in NFC
//
// Other:
-// ERROR : attempt to use poisoned \"%s\"
-//
// TODO: Options to support:
// -fexec-charset,-fwide-exec-charset
//
Modified: cfe/cfe/trunk/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Pragma.cpp?rev=38568&r1=38567&r2=38568&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Pragma.cpp (original)
+++ cfe/cfe/trunk/Lex/Pragma.cpp Wed Jul 11 11:22:45 2007
@@ -32,4 +32,3 @@
// Otherwise, pass it down.
Handler->HandlePragma(PP, Tok);
}
-
Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=38568&r1=38567&r2=38568&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:22:45 2007
@@ -416,8 +416,9 @@
return;
}
IdentifierTokenInfo &ITI = *Identifier.getIdentifierInfo();
-
- // FIXME: Check for poisoning in ITI?
+
+ if (ITI.isPoisoned())
+ Diag(Identifier, diag::err_pp_used_poisoned_id);
if (MacroInfo *MI = ITI.getMacroInfo()) {
if (MI->isEnabled() && !DisableMacroExpansion) {
@@ -1260,21 +1261,67 @@
PragmaHandlers->HandlePragma(*this, Tok);
// If the pragma handler didn't read the rest of the line, consume it now.
- if (CurLexer->ParsingPreprocessorDirective) {
- do {
- LexUnexpandedToken(Tok);
- } while (Tok.getKind() != tok::eom);
- }
+ if (CurLexer->ParsingPreprocessorDirective)
+ DiscardUntilEndOfDirective();
}
/// HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'.
+///
void Preprocessor::HandlePragmaOnce(LexerToken &OnceTok) {
if (IncludeStack.empty()) {
Diag(OnceTok, diag::pp_pragma_once_in_main_file);
return;
}
+
+ // FIXME: implement the _Pragma thing.
+ assert(CurLexer && "Cannot have a pragma in a macro expansion yet!");
+
+ // Mark the file as a once-only file now.
+ const FileEntry *File =
+ SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID());
+ getFileInfo(File).isImport = true;
}
+/// HandlePragmaPoison - Handle #pragma GCC poison. PoisonTok is the 'poison'.
+///
+void Preprocessor::HandlePragmaPoison(LexerToken &PoisonTok) {
+ LexerToken Tok;
+ assert(!SkippingContents && "Why are we handling pragmas while skipping?");
+ while (1) {
+ // Read the next token to poison. While doing this, pretend that we are
+ // skipping while reading the identifier to poison.
+ // This avoids errors on code like:
+ // #pragma GCC poison X
+ // #pragma GCC poison X
+ SkippingContents = true;
+ LexUnexpandedToken(Tok);
+ SkippingContents = false;
+
+ // If we reached the end of line, we're done.
+ if (Tok.getKind() == tok::eom) return;
+
+ // Can only poison identifiers.
+ if (Tok.getKind() != tok::identifier) {
+ Diag(Tok, diag::err_pp_invalid_poison);
+ return;
+ }
+
+ // Look up the identifier info for the token.
+ std::string TokStr = getSpelling(Tok);
+ IdentifierTokenInfo *II =
+ getIdentifierInfo(&TokStr[0], &TokStr[0]+TokStr.size());
+
+ // Already poisoned.
+ if (II->isPoisoned()) continue;
+
+ // If this is a macro identifier, emit a warning.
+ if (II->getMacroInfo())
+ Diag(Tok, diag::pp_poisoning_existing_macro);
+
+ // Finally, poison it!
+ II->setIsPoisoned();
+ }
+}
/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
/// If 'Namespace' is non-null, then it is a token required to exist on the
@@ -1308,6 +1355,7 @@
InsertNS->AddPragma(Handler);
}
+namespace {
class PragmaOnceHandler : public PragmaHandler {
public:
PragmaOnceHandler(const IdentifierTokenInfo *OnceID) : PragmaHandler(OnceID){}
@@ -1317,10 +1365,19 @@
}
};
+class PragmaPoisonHandler : public PragmaHandler {
+public:
+ PragmaPoisonHandler(const IdentifierTokenInfo *ID) : PragmaHandler(ID) {}
+ virtual void HandlePragma(Preprocessor &PP, LexerToken &PoisonTok) {
+ PP.HandlePragmaPoison(PoisonTok);
+ }
+};
+}
+
/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
/// #pragma GCC poison/system_header/dependency and #pragma once.
void Preprocessor::RegisterBuiltinPragmas() {
AddPragmaHandler(0, new PragmaOnceHandler(getIdentifierInfo("once")));
-
+ AddPragmaHandler("GCC", new PragmaPoisonHandler(getIdentifierInfo("poison")));
}
Modified: cfe/cfe/trunk/README.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/README.txt?rev=38568&r1=38567&r2=38568&view=diff
==============================================================================
--- cfe/cfe/trunk/README.txt (original)
+++ cfe/cfe/trunk/README.txt Wed Jul 11 11:22:45 2007
@@ -40,12 +40,11 @@
See GCC options: -ftarget-charset and -ftarget-wide-charset.
* Universal character support. Experimental in GCC, enabled with
-fextended-identifiers.
- * Poisoned identifiers.
* -fpreprocessed mode.
Preprocessor:
* #line / #file directives
- * Detection of "atomic" headers (#ifndef/#define), #pragma once support.
+ * Detection of "atomic" headers (#ifndef/#define).
* Function-style #define & macro expansion
* -C & -P output modes.
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38568&r1=38567&r2=38568&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:22:45 2007
@@ -88,6 +88,8 @@
"ISO C99 requires whitespace after the macro name")
DIAG(pp_pragma_once_in_main_file, WARNING,
"#pragma once in main file")
+DIAG(pp_poisoning_existing_macro, WARNING,
+ "poisoning existing macro")
DIAG(ext_pp_import_directive, EXTENSION,
"#import is a language extension")
@@ -148,9 +150,12 @@
"division by zero in preprocessor expression")
DIAG(err_pp_remainder_by_zero, ERROR,
"remainder by zero in preprocessor expression")
-
DIAG(err_pp_expr_bad_token, ERROR,
"token is not valid in preprocessor expressions")
+DIAG(err_pp_invalid_poison, ERROR,
+ "can only poison identifier tokens")
+DIAG(err_pp_used_poisoned_id, ERROR,
+ "attempt to use a poisoned identifier")
// Should be a sorry?
DIAG(err_pp_I_dash_not_supported, ERROR,
Modified: cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h?rev=38568&r1=38567&r2=38568&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h Wed Jul 11 11:22:45 2007
@@ -30,8 +30,9 @@
class IdentifierTokenInfo {
unsigned NameLen; // String that is the identifier.
MacroInfo *Macro; // Set if this identifier is #define'd.
- tok::TokenKind TokenID:8;// Nonzero if this is a front-end token.
- bool IsExtension : 1; // True if this token is a language extension.
+ tok::TokenKind TokenID:8;// Front-end token ID or tok::identifier.
+ bool IsExtension : 1; // True if this identifier is a language extension.
+ bool IsPoisoned : 1; // True if this identifier is poisoned.
void *FETokenInfo; // Managed by the language front-end.
friend class IdentifierTable;
public:
@@ -67,6 +68,12 @@
bool isExtensionToken() const { return IsExtension; }
void setIsExtensionToken(bool Val) { IsExtension = Val; }
+ /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the
+ /// Preprocessor will emit an error every time this token is used.
+ void setIsPoisoned() { IsPoisoned = true; }
+
+ /// isPoisoned - Return true if this token has been poisoned.
+ bool isPoisoned() const { return IsPoisoned; }
/// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
/// associate arbitrary metadata with this token.
Modified: cfe/cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=38568&r1=38567&r2=38568&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:22:45 2007
@@ -427,6 +427,7 @@
void HandlePragmaDirective(LexerToken &Result);
public:
void HandlePragmaOnce(LexerToken &OnceTok);
+ void HandlePragmaPoison(LexerToken &PoisonTok);
};
} // end namespace clang
More information about the cfe-commits
mailing list