[cfe-commits] r38589 - in /cfe/cfe/trunk: Lex/Preprocessor.cpp include/clang/Lex/Preprocessor.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:23:00 PDT 2007


Author: sabre
Date: Wed Jul 11 11:22:59 2007
New Revision: 38589

URL: http://llvm.org/viewvc/llvm-project?rev=38589&view=rev
Log:
Implement the __LINE__ builtin macro.

Modified:
    cfe/cfe/trunk/Lex/Preprocessor.cpp
    cfe/cfe/trunk/include/clang/Lex/Preprocessor.h

Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=38589&r1=38588&r2=38589&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:22:59 2007
@@ -38,6 +38,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/Pragma.h"
+#include "clang/Lex/ScratchBuffer.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
@@ -52,6 +53,8 @@
   : Diags(diags), Features(opts), FileMgr(FM), SourceMgr(SM),
     SystemDirIdx(0), NoCurDirSearch(false),
     CurLexer(0), CurDirLookup(0), CurMacroExpander(0) {
+  ScratchBuf = new ScratchBuffer(SourceMgr);
+      
   // Clear stats.
   NumDirectives = NumIncluded = NumDefined = NumUndefined = NumPragma = 0;
   NumIf = NumElse = NumEndif = 0;
@@ -85,6 +88,9 @@
   
   // Release pragma information.
   delete PragmaHandlers;
+
+  // Delete the scratch buffer info.
+  delete ScratchBuf;
 }
 
 /// getFileInfo - Return the PerFileInfo structure for the specified
@@ -409,18 +415,25 @@
 // Macro Expansion Handling.
 //===----------------------------------------------------------------------===//
 
-/// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
-/// identifier table.
-void Preprocessor::RegisterBuiltinMacros() {
-  // Do this for each thing.
+/// RegisterBuiltinMacro - Register the specified identifier in the identifier
+/// table and mark it as a builtin macro to be expanded.
+IdentifierTokenInfo *Preprocessor::RegisterBuiltinMacro(const char *Name) {
+  // Get the identifier.
+  IdentifierTokenInfo *Id = getIdentifierInfo(Name);
+  
+  // Mark it as being a macro that is builtin.
   MacroInfo *MI = new MacroInfo(SourceLocation());
   MI->setIsBuiltinMacro();
-  getIdentifierInfo("__LINE__")->setMacroInfo(MI);
+  Id->setMacroInfo(MI);
+  return Id;
+}
+
 
-  // FIXME: Warn on #undef / #define of a builtin macro.
-  // FIXME: make HandleMacroExpandedIdentifier handle this case.
+/// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
+/// identifier table.
+void Preprocessor::RegisterBuiltinMacros() {
   // FIXME: implement them all, including _Pragma.
-  //MacroInfo *MI = new MacroInfo(MacroNameTok.getLocation());
+  Ident__LINE__ = RegisterBuiltinMacro("__LINE__");
 }
 
 
@@ -431,6 +444,10 @@
   ++NumMacroExpanded;
   // If we started lexing a macro, enter the macro expansion body.
   // FIXME: Read/Validate the argument list here!
+
+  // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
+  if (MI->isBuiltinMacro())
+    return ExpandBuiltinMacro(Identifier, MI);
   
   // If this macro expands to no tokens, don't bother to push it onto the
   // expansion stack, only to take it right back off.
@@ -499,6 +516,27 @@
   return Lex(Identifier);
 }
 
+/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
+/// as a builtin macro, handle it and return the next token as 'Tok'.
+void Preprocessor::ExpandBuiltinMacro(LexerToken &Tok, MacroInfo *MI) {
+  // Figure out which token this is.
+  IdentifierTokenInfo *ITI = Tok.getIdentifierInfo();
+  assert(ITI && "Can't be a macro without id info!");
+  char TmpBuffer[100];
+  
+  if (ITI == Ident__LINE__) {
+    // __LINE__ expands to a simple numeric value.
+    sprintf(TmpBuffer, "%u", SourceMgr.getLineNumber(Tok.getLocation()));
+    unsigned Length = strlen(TmpBuffer);
+    Tok.SetKind(tok::numeric_constant);
+    Tok.SetLength(Length);
+    Tok.SetLocation(ScratchBuf->getToken(TmpBuffer, Length, Tok.getLocation()));
+    Tok.ClearFlag(LexerToken::NeedsCleaning);
+    return;
+  } else {
+    assert(0 && "Unknown identifier!");
+  }  
+}
 
 //===----------------------------------------------------------------------===//
 // Lexer Event Handling.

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=38589&r1=38588&r2=38589&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:22:59 2007
@@ -30,6 +30,7 @@
 class FileEntry;
 class PragmaNamespace;
 class PragmaHandler;
+class ScratchBuffer;
 
 /// DirectoryLookup - This class is used to specify the search order for
 /// directories in #include directives.
@@ -79,6 +80,7 @@
   const LangOptions &Features;
   FileManager   &FileMgr;
   SourceManager &SourceMgr;
+  ScratchBuffer *ScratchBuf;
   
   // #include search path information.  Requests for #include "x" search the
   /// directory of the #including file first, then each directory in SearchDirs
@@ -89,6 +91,9 @@
   std::vector<DirectoryLookup> SearchDirs;
   unsigned SystemDirIdx;
   bool NoCurDirSearch;
+  
+  /// Identifiers for builtin macros.
+  IdentifierTokenInfo *Ident__LINE__; // __LINE__
 public:
   enum FileChangeReason {
     EnterFile, ExitFile, SystemHeaderPragma, RenameFile
@@ -404,10 +409,15 @@
   /// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
   /// identifier table.
   void RegisterBuiltinMacros();
+  IdentifierTokenInfo *RegisterBuiltinMacro(const char *Name);
   
   /// HandleMacroExpandedIdentifier - If an identifier token is read that is to
   /// be expanded as a macro, handle it and return the next token as 'Tok'.
   void HandleMacroExpandedIdentifier(LexerToken &Tok, MacroInfo *MI);
+
+  /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
+  /// as a builtin macro, handle it and return the next token as 'Tok'.
+  void ExpandBuiltinMacro(LexerToken &Tok, MacroInfo *MI);
   
   //===--------------------------------------------------------------------===//
   /// Handle*Directive - implement the various preprocessor directives.  These





More information about the cfe-commits mailing list