[cfe-commits] r39002 - in /cfe/cfe/trunk: Lex/IdentifierTable.cpp Lex/Preprocessor.cpp include/clang/Basic/TokenKinds.def include/clang/Basic/TokenKinds.h include/clang/Lex/IdentifierTable.h include/clang/Lex/Preprocessor.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:26:42 PDT 2007
Author: sabre
Date: Wed Jul 11 11:26:42 2007
New Revision: 39002
URL: http://llvm.org/viewvc/llvm-project?rev=39002&view=rev
Log:
Make preprocessor keywords like 'define' first class citizens in the
IdentifierTable, instead of making them resort to strcmp'ing.
Modified:
cfe/cfe/trunk/Lex/IdentifierTable.cpp
cfe/cfe/trunk/Lex/Preprocessor.cpp
cfe/cfe/trunk/include/clang/Basic/TokenKinds.def
cfe/cfe/trunk/include/clang/Basic/TokenKinds.h
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=39002&r1=39001&r2=39002&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/IdentifierTable.cpp (original)
+++ cfe/cfe/trunk/Lex/IdentifierTable.cpp Wed Jul 11 11:26:42 2007
@@ -207,6 +207,7 @@
Identifier->TokInfo.NameLen = Length;
Identifier->TokInfo.Macro = 0;
Identifier->TokInfo.TokenID = tok::identifier;
+ Identifier->TokInfo.PPID = tok::pp_not_keyword;
Identifier->TokInfo.IsExtension = false;
Identifier->TokInfo.IsPoisoned = false;
Identifier->TokInfo.IsOtherTargetMacro = false;
Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=39002&r1=39001&r2=39002&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:26:42 2007
@@ -102,6 +102,12 @@
return FileInfo[FE->getUID()];
}
+/// AddPPKeyword - Register a preprocessor keyword like "define" "undef" or
+/// "elif".
+static void AddPPKeyword(tok::PPKeywordKind PPID,
+ const char *Name, unsigned NameLen, Preprocessor &PP) {
+ PP.getIdentifierInfo(Name, Name+NameLen)->setPPKeywordID(PPID);
+}
/// AddKeywords - Add all keywords to the symbol table.
///
@@ -127,9 +133,34 @@
((FLAGS) >> CPPShift) & Mask);
#define ALIAS(NAME, TOK) \
AddKeyword(NAME, tok::kw_ ## TOK, 0, 0, 0);
+#define PPKEYWORD(NAME) \
+ AddPPKeyword(tok::pp_##NAME, #NAME, strlen(#NAME), *this);
#include "clang/Basic/TokenKinds.def"
}
+/// AddKeyword - This method is used to associate a token ID with specific
+/// identifiers because they are language keywords. This causes the lexer to
+/// automatically map matching identifiers to specialized token codes.
+///
+/// The C90/C99/CPP flags are set to 0 if the token should be enabled in the
+/// specified langauge, set to 1 if it is an extension in the specified
+/// language, and set to 2 if disabled in the specified language.
+void Preprocessor::AddKeyword(const std::string &Keyword,
+ tok::TokenKind TokenCode,
+ int C90, int C99, int CPP) {
+ int Flags = Features.CPlusPlus ? CPP : (Features.C99 ? C99 : C90);
+
+ // Don't add this keyword if disabled in this language or if an extension
+ // and extensions are disabled.
+ if (Flags+Features.NoExtensions >= 2) return;
+
+ const char *Str = &Keyword[0];
+ IdentifierInfo &Info = *getIdentifierInfo(Str, Str+Keyword.size());
+ Info.setTokenID(TokenCode);
+ Info.setIsExtensionToken(Flags == 1);
+}
+
+
/// Diag - Forwarding function for diagnostics. This emits a diagnostic at
/// the specified LexerToken's location, translating the token's start
/// position in the current buffer into a SourcePosition object for rendering.
@@ -1405,7 +1436,6 @@
Diag(Result, diag::ext_embedded_directive);
switch (Result.getKind()) {
- default: break;
case tok::eom:
return; // null directive.
@@ -1413,75 +1443,76 @@
// FIXME: implement # 7 line numbers!
DiscardUntilEndOfDirective();
return;
- case tok::kw_else:
- return HandleElseDirective(Result);
- case tok::kw_if:
- return HandleIfDirective(Result, ReadAnyTokensBeforeDirective);
- case tok::identifier:
- // Get the identifier name without trigraphs or embedded newlines.
- const char *Directive = Result.getIdentifierInfo()->getName();
- bool isExtension = false;
- switch (Result.getIdentifierInfo()->getNameLength()) {
- case 4:
- if (Directive[0] == 'l' && !strcmp(Directive, "line")) {
- // FIXME: implement #line
- DiscardUntilEndOfDirective();
- return;
- }
- if (Directive[0] == 'e' && !strcmp(Directive, "elif"))
- return HandleElifDirective(Result);
- if (Directive[0] == 's' && !strcmp(Directive, "sccs"))
- return HandleIdentSCCSDirective(Result);
- break;
- case 5:
- if (Directive[0] == 'e' && !strcmp(Directive, "endif"))
- return HandleEndifDirective(Result);
- if (Directive[0] == 'i' && !strcmp(Directive, "ifdef"))
- return HandleIfdefDirective(Result, false, true/*not valid for miopt*/);
- if (Directive[0] == 'u' && !strcmp(Directive, "undef"))
- return HandleUndefDirective(Result);
- if (Directive[0] == 'e' && !strcmp(Directive, "error"))
- return HandleUserDiagnosticDirective(Result, false);
- if (Directive[0] == 'i' && !strcmp(Directive, "ident"))
- return HandleIdentSCCSDirective(Result);
- break;
- case 6:
- if (Directive[0] == 'd' && !strcmp(Directive, "define"))
- return HandleDefineDirective(Result, false);
- if (Directive[0] == 'i' && !strcmp(Directive, "ifndef"))
- return HandleIfdefDirective(Result, true, ReadAnyTokensBeforeDirective);
- if (Directive[0] == 'i' && !strcmp(Directive, "import"))
- return HandleImportDirective(Result);
- if (Directive[0] == 'p' && !strcmp(Directive, "pragma"))
- return HandlePragmaDirective();
- if (Directive[0] == 'a' && !strcmp(Directive, "assert"))
- isExtension = true; // FIXME: implement #assert
- break;
- case 7:
- if (Directive[0] == 'i' && !strcmp(Directive, "include"))
- return HandleIncludeDirective(Result); // Handle #include.
- if (Directive[0] == 'w' && !strcmp(Directive, "warning")) {
- Diag(Result, diag::ext_pp_warning_directive);
- return HandleUserDiagnosticDirective(Result, true);
- }
- break;
- case 8:
- if (Directive[0] == 'u' && !strcmp(Directive, "unassert")) {
- isExtension = true; // FIXME: implement #unassert
- }
- break;
- case 12:
- if (Directive[0] == 'i' && !strcmp(Directive, "include_next"))
- return HandleIncludeNextDirective(Result); // Handle #include_next.
- break;
- case 13:
- if (Directive[0] == 'd' && !strcmp(Directive, "define_target"))
- return HandleDefineDirective(Result, true);
+ default:
+ IdentifierInfo *II = Result.getIdentifierInfo();
+ if (II == 0) break; // Not an identifier.
+
+ // Ask what the preprocessor keyword ID is.
+ switch (II->getPPKeywordID()) {
+ default: break;
+ // C99 6.10.1 - Conditional Inclusion.
+ case tok::pp_if:
+ return HandleIfDirective(Result, ReadAnyTokensBeforeDirective);
+ case tok::pp_ifdef:
+ return HandleIfdefDirective(Result, false, true/*not valid for miopt*/);
+ case tok::pp_ifndef:
+ return HandleIfdefDirective(Result, true, ReadAnyTokensBeforeDirective);
+ case tok::pp_elif:
+ return HandleElifDirective(Result);
+ case tok::pp_else:
+ return HandleElseDirective(Result);
+ case tok::pp_endif:
+ return HandleEndifDirective(Result);
+
+ // C99 6.10.2 - Source File Inclusion.
+ case tok::pp_include:
+ return HandleIncludeDirective(Result); // Handle #include.
+
+ // C99 6.10.3 - Macro Replacement.
+ case tok::pp_define:
+ return HandleDefineDirective(Result, false);
+ case tok::pp_undef:
+ return HandleUndefDirective(Result);
+
+ // C99 6.10.4 - Line Control.
+ case tok::pp_line:
+ // FIXME: implement #line
+ DiscardUntilEndOfDirective();
+ return;
+
+ // C99 6.10.5 - Error Directive.
+ case tok::pp_error:
+ return HandleUserDiagnosticDirective(Result, false);
+
+ // C99 6.10.6 - Pragma Directive.
+ case tok::pp_pragma:
+ return HandlePragmaDirective();
+
+ // GNU Extensions.
+ case tok::pp_import:
+ return HandleImportDirective(Result);
+ case tok::pp_include_next:
+ return HandleIncludeNextDirective(Result);
+
+ case tok::pp_warning:
+ Diag(Result, diag::ext_pp_warning_directive);
+ return HandleUserDiagnosticDirective(Result, true);
+ case tok::pp_ident:
+ return HandleIdentSCCSDirective(Result);
+ case tok::pp_sccs:
+ return HandleIdentSCCSDirective(Result);
+ case tok::pp_assert:
+ //isExtension = true; // FIXME: implement #assert
break;
- case 19:
- if (Directive[0] == 'd' && !strcmp(Directive, "define_other_target"))
- return HandleDefineOtherTargetDirective(Result);
+ case tok::pp_unassert:
+ //isExtension = true; // FIXME: implement #unassert
break;
+
+ // clang extensions.
+ case tok::pp_define_target:
+ return HandleDefineDirective(Result, true);
+ case tok::pp_define_other_target:
+ return HandleDefineOtherTargetDirective(Result);
}
break;
}
Modified: cfe/cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=39002&r1=39001&r2=39002&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/TokenKinds.def Wed Jul 11 11:26:42 2007
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the TokenKind database. This includes normal tokens like
-// tok::ampamp (corresponding to the && token) as well as keywords for various
-// languages. Users of this file must optionally #define the TOK/KEYWORD/ALIAS
-// macros to make use of this file.
+// This file defines the TokenKind database. This includes normal tokens like
+// tok::ampamp (corresponding to the && token) as well as keywords for various
+// languages. Users of this file must optionally #define the TOK, KEYWORD,
+// ALIAS, or PPKEYWORD macros to make use of this file.
//
//===----------------------------------------------------------------------===//
@@ -23,6 +23,61 @@
#ifndef ALIAS
#define ALIAS(X,Y)
#endif
+#ifndef PPKEYWORD
+#define PPKEYWORD(X)
+#endif
+
+//===----------------------------------------------------------------------===//
+// Preprocessor keywords.
+//===----------------------------------------------------------------------===//
+
+// These have meaning after a '#' at the start of a line. These define enums in
+// the tok::pp_* namespace.
+PPKEYWORD(not_keyword)
+
+// C99 6.10.1 - Conditional Inclusion.
+PPKEYWORD(if)
+PPKEYWORD(ifdef)
+PPKEYWORD(ifndef)
+PPKEYWORD(elif)
+PPKEYWORD(else)
+PPKEYWORD(endif)
+
+// C99 6.10.2 - Source File Inclusion.
+PPKEYWORD(include)
+
+// C99 6.10.3 - Macro Replacement.
+PPKEYWORD(define)
+PPKEYWORD(undef)
+
+// C99 6.10.4 - Line Control.
+PPKEYWORD(line)
+
+// C99 6.10.5 - Error Directive.
+PPKEYWORD(error)
+
+// C99 6.10.6 - Pragma Directive.
+PPKEYWORD(pragma)
+
+// GNU Extensions.
+PPKEYWORD(import)
+PPKEYWORD(include_next)
+PPKEYWORD(warning)
+PPKEYWORD(ident)
+PPKEYWORD(sccs)
+PPKEYWORD(assert)
+PPKEYWORD(unassert)
+
+// clang extensions.
+PPKEYWORD(define_target)
+PPKEYWORD(define_other_target)
+
+
+//===----------------------------------------------------------------------===//
+// Language keywords.
+//===----------------------------------------------------------------------===//
+
+// These define members of the tok::kw_* namespace.
TOK(unknown) // Not a token.
TOK(eof) // End of file.
@@ -239,6 +294,7 @@
ALIAS("__volatile" , volatile )
ALIAS("__volatile__" , volatile )
+#undef PPKEYWORD
#undef ALIAS
#undef KEYWORD
#undef TOK
Modified: cfe/cfe/trunk/include/clang/Basic/TokenKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/TokenKinds.h?rev=39002&r1=39001&r2=39002&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/TokenKinds.h (original)
+++ cfe/cfe/trunk/include/clang/Basic/TokenKinds.h Wed Jul 11 11:26:42 2007
@@ -27,6 +27,12 @@
NUM_TOKENS
};
+enum PPKeywordKind {
+#define PPKEYWORD(X) pp_##X,
+#include "clang/Basic/TokenKinds.def"
+ NUM_PP_KEYWORDS
+};
+
const char *getTokenName(enum TokenKind Kind);
} // end namespace tok
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=39002&r1=39001&r2=39002&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h Wed Jul 11 11:26:42 2007
@@ -32,6 +32,7 @@
unsigned NameLen; // String that is the identifier.
MacroInfo *Macro; // Set if this identifier is #define'd.
tok::TokenKind TokenID : 8; // Front-end token ID or tok::identifier.
+ tok::PPKeywordKind PPID : 5; // ID for preprocessor command like 'ifdef'.
bool IsExtension : 1; // True if identifier is a lang extension.
bool IsPoisoned : 1; // True if identifier is poisoned.
bool IsOtherTargetMacro : 1; // True if ident is a macro on another target.
@@ -64,6 +65,9 @@
tok::TokenKind getTokenID() const { return TokenID; }
void setTokenID(tok::TokenKind ID) { TokenID = ID; }
+ tok::PPKeywordKind getPPKeywordID() const { return PPID; }
+ void setPPKeywordID(tok::PPKeywordKind ID) { PPID = ID; }
+
/// get/setExtension - Initialize information about whether or not this
/// language token is an extension. This controls extension warnings, and is
/// only valid if a custom token ID is set.
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=39002&r1=39001&r2=39002&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:26:42 2007
@@ -276,18 +276,7 @@
/// specified langauge, set to 1 if it is an extension in the specified
/// language, and set to 2 if disabled in the specified language.
void AddKeyword(const std::string &Keyword, tok::TokenKind TokenCode,
- int C90, int C99, int CPP) {
- int Flags = Features.CPlusPlus ? CPP : (Features.C99 ? C99 : C90);
-
- // Don't add this keyword if disabled in this language or if an extension
- // and extensions are disabled.
- if (Flags+Features.NoExtensions >= 2) return;
-
- const char *Str = &Keyword[0];
- IdentifierInfo &Info = *getIdentifierInfo(Str, Str+Keyword.size());
- Info.setTokenID(TokenCode);
- Info.setIsExtensionToken(Flags == 1);
- }
+ int C90, int C99, int CPP);
/// AddKeywords - Add all keywords to the symbol table.
///
More information about the cfe-commits
mailing list