[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