[cfe-commits] r85589 - in /cfe/trunk: include/clang/Basic/DiagnosticLexKinds.td include/clang/Lex/Preprocessor.h lib/Lex/PPDirectives.cpp lib/Lex/PPExpressions.cpp

John Thompson John.Thompson.JTSoftware at gmail.com
Fri Oct 30 06:49:07 PDT 2009


Author: jtsoftware
Date: Fri Oct 30 08:49:06 2009
New Revision: 85589

URL: http://llvm.org/viewvc/llvm-project?rev=85589&view=rev
Log:
Re-arranged some internal functions for coming __has_include changes.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/lib/Lex/PPExpressions.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=85589&r1=85588&r2=85589&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Fri Oct 30 08:49:06 2009
@@ -194,7 +194,7 @@
   "expected end of line in preprocessor expression">;
 def err_pp_defined_requires_identifier : Error<
   "operator 'defined' requires an identifier">;
-def err_pp_missing_rparen : Error<"missing ')' after 'defined'">;
+def err_pp_missing_rparen : Error<"missing ')' after '%0'">;
 def err_pp_colon_without_question : Error<"':' without preceding '?'">;
 def err_pp_division_by_zero : Error<
   "division by zero in preprocessor expression">;

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=85589&r1=85588&r2=85589&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Oct 30 08:49:06 2009
@@ -244,7 +244,12 @@
     return CurPPLexer == L;
   }
 
-  /// getCurrentLexer - Return the current file lexer being lexed from.  Note
+  /// getCurrentLexer - Return the current lexer being lexed from.  Note
+  /// that this ignores any potentially active macro expansions and _Pragma
+  /// expansions going on at the time.
+  PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
+
+  /// getCurrentFileLexer - Return the current file lexer being lexed from.  Note
   /// that this ignores any potentially active macro expansions and _Pragma
   /// expansions going on at the time.
   PreprocessorLexer *getCurrentFileLexer() const;
@@ -622,6 +627,43 @@
   ///  SourceLocation.
   MacroInfo* AllocateMacroInfo(SourceLocation L);
 
+  /// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
+  /// checked and spelled filename, e.g. as an operand of #include. This returns
+  /// true if the input filename was in <>'s or false if it were in ""'s.  The
+  /// caller is expected to provide a buffer that is large enough to hold the
+  /// spelling of the filename, but is also expected to handle the case when
+  /// this method decides to use a different buffer.
+  bool GetIncludeFilenameSpelling(SourceLocation Loc,
+                                  const char *&BufStart, const char *&BufEnd);
+
+  /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+  /// return null on failure.  isAngled indicates whether the file reference is
+  /// for system #include's or not (i.e. using <> instead of "").
+  const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd,
+                              bool isAngled, const DirectoryLookup *FromDir,
+                              const DirectoryLookup *&CurDir);
+
+  /// GetCurLookup - The DirectoryLookup structure used to find the current
+  /// FileEntry, if CurLexer is non-null and if applicable.  This allows us to
+  /// implement #include_next and find directory-specific properties.
+  const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; }
+
+  /// isInPrimaryFile - Return true if we're in the top-level file, not in a
+  /// #include.
+  bool isInPrimaryFile() const;
+
+  /// ConcatenateIncludeName - Handle cases where the #include name is expanded
+  /// from a macro as multiple tokens, which need to be glued together.  This
+  /// occurs for code like:
+  ///    #define FOO <a/b.h>
+  ///    #include FOO
+  /// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
+  ///
+  /// This code concatenates and consumes tokens up to the '>' token.  It returns
+  /// false if the > was found, otherwise it returns true if it finds and consumes
+  /// the EOM marker.
+  bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer);
+
 private:
 
   void PushIncludeMacroStack() {
@@ -646,10 +688,6 @@
   ///  be reused for allocating new MacroInfo objects.
   void ReleaseMacroInfo(MacroInfo* MI);
 
-  /// isInPrimaryFile - Return true if we're in the top-level file, not in a
-  /// #include.
-  bool isInPrimaryFile() const;
-
   /// ReadMacroName - Lex and validate a macro name, which occurs after a
   /// #define or #undef.  This emits a diagnostic, sets the token kind to eom,
   /// and discards the rest of the macro line if the macro name is invalid.
@@ -722,24 +760,6 @@
   /// start getting tokens from it using the PTH cache.
   void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
 
-  /// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
-  /// checked and spelled filename, e.g. as an operand of #include. This returns
-  /// true if the input filename was in <>'s or false if it were in ""'s.  The
-  /// caller is expected to provide a buffer that is large enough to hold the
-  /// spelling of the filename, but is also expected to handle the case when
-  /// this method decides to use a different buffer.
-  bool GetIncludeFilenameSpelling(SourceLocation Loc,
-                                  const char *&BufStart, const char *&BufEnd);
-
-  /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
-  /// return null on failure.  isAngled indicates whether the file reference is
-  /// for system #include's or not (i.e. using <> instead of "").
-  const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd,
-                              bool isAngled, const DirectoryLookup *FromDir,
-                              const DirectoryLookup *&CurDir);
-
-
-
   /// IsFileLexer - Returns true if we are lexing from a file and not a
   ///  pragma or a macro.
   static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=85589&r1=85588&r2=85589&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Oct 30 08:49:06 2009
@@ -974,11 +974,11 @@
 /// This code concatenates and consumes tokens up to the '>' token.  It returns
 /// false if the > was found, otherwise it returns true if it finds and consumes
 /// the EOM marker.
-static bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer,
-                                   Preprocessor &PP) {
+bool Preprocessor::ConcatenateIncludeName(
+  llvm::SmallVector<char, 128> &FilenameBuffer) {
   Token CurTok;
 
-  PP.Lex(CurTok);
+  Lex(CurTok);
   while (CurTok.isNot(tok::eom)) {
     // Append the spelling of this token to the buffer. If there was a space
     // before it, add it now.
@@ -990,7 +990,7 @@
     FilenameBuffer.resize(PreAppendSize+CurTok.getLength());
 
     const char *BufPtr = &FilenameBuffer[PreAppendSize];
-    unsigned ActualLen = PP.getSpelling(CurTok, BufPtr);
+    unsigned ActualLen = getSpelling(CurTok, BufPtr);
 
     // If the token was spelled somewhere else, copy it into FilenameBuffer.
     if (BufPtr != &FilenameBuffer[PreAppendSize])
@@ -1004,12 +1004,12 @@
     if (CurTok.is(tok::greater))
       return false;
 
-    PP.Lex(CurTok);
+    Lex(CurTok);
   }
 
   // If we hit the eom marker, emit an error and return true so that the caller
   // knows the EOM has been read.
-  PP.Diag(CurTok.getLocation(), diag::err_pp_expects_filename);
+  Diag(CurTok.getLocation(), diag::err_pp_expects_filename);
   return true;
 }
 
@@ -1047,7 +1047,7 @@
     // This could be a <foo/bar.h> file coming from a macro expansion.  In this
     // case, glue the tokens together into FilenameBuffer and interpret those.
     FilenameBuffer.push_back('<');
-    if (ConcatenateIncludeName(FilenameBuffer, *this))
+    if (ConcatenateIncludeName(FilenameBuffer))
       return;   // Found <eom> but no ">"?  Diagnostic already emitted.
     FilenameStart = FilenameBuffer.data();
     FilenameEnd = FilenameStart + FilenameBuffer.size();

Modified: cfe/trunk/lib/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPExpressions.cpp?rev=85589&r1=85588&r2=85589&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/PPExpressions.cpp (original)
+++ cfe/trunk/lib/Lex/PPExpressions.cpp Fri Oct 30 08:49:06 2009
@@ -71,6 +71,61 @@
   IdentifierInfo *TheMacro;
 };
 
+/// EvaluateDefined - Process a 'defined(sym)' expression.
+static bool EvaluateDefined(PPValue &Result, Token &PeekTok,
+        DefinedTracker &DT, bool ValueLive, Preprocessor &PP) {
+  IdentifierInfo *II;
+  Result.setBegin(PeekTok.getLocation());
+
+  // Get the next token, don't expand it.
+  PP.LexUnexpandedToken(PeekTok);
+
+  // Two options, it can either be a pp-identifier or a (.
+  SourceLocation LParenLoc;
+  if (PeekTok.is(tok::l_paren)) {
+    // Found a paren, remember we saw it and skip it.
+    LParenLoc = PeekTok.getLocation();
+    PP.LexUnexpandedToken(PeekTok);
+  }
+
+  // If we don't have a pp-identifier now, this is an error.
+  if ((II = PeekTok.getIdentifierInfo()) == 0) {
+    PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
+    return true;
+  }
+
+  // Otherwise, we got an identifier, is it defined to something?
+  Result.Val = II->hasMacroDefinition();
+  Result.Val.setIsUnsigned(false);  // Result is signed intmax_t.
+
+  // If there is a macro, mark it used.
+  if (Result.Val != 0 && ValueLive) {
+    MacroInfo *Macro = PP.getMacroInfo(II);
+    Macro->setIsUsed(true);
+  }
+
+  // Consume identifier.
+  Result.setEnd(PeekTok.getLocation());
+  PP.LexNonComment(PeekTok);
+
+  // If we are in parens, ensure we have a trailing ).
+  if (LParenLoc.isValid()) {
+    if (PeekTok.isNot(tok::r_paren)) {
+      PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined";
+      PP.Diag(LParenLoc, diag::note_matching) << "(";
+      return true;
+    }
+    // Consume the ).
+    Result.setEnd(PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);
+  }
+
+  // Success, remember that we saw defined(X).
+  DT.State = DefinedTracker::DefinedMacro;
+  DT.TheMacro = II;
+  return false;
+}
+
 /// EvaluateValue - Evaluate the token PeekTok (and any others needed) and
 /// return the computed value in Result.  Return true if there was an error
 /// parsing.  This function also returns information about the form of the
@@ -87,10 +142,14 @@
   // 'defined' or if it is a macro.  Note that we check here because many
   // keywords are pp-identifiers, so we can't check the kind.
   if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
-    // If this identifier isn't 'defined' and it wasn't macro expanded, it turns
-    // into a simple 0, unless it is the C++ keyword "true", in which case it
-    // turns into "1".
-    if (!II->isStr("defined")) {
+    if (II->isStr("defined")) {
+      // Handle "defined X" and "defined(X)".
+      return(EvaluateDefined(Result, PeekTok, DT, ValueLive, PP));
+    } else {
+      // If this identifier isn't 'defined' or one of the special
+      // preprocessor keywords and it wasn't macro expanded, it turns
+      // into a simple 0, unless it is the C++ keyword "true", in which case it
+      // turns into "1".
       if (ValueLive)
         PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
       Result.Val = II->getTokenID() == tok::kw_true;
@@ -99,57 +158,6 @@
       PP.LexNonComment(PeekTok);
       return false;
     }
-
-    // Handle "defined X" and "defined(X)".
-    Result.setBegin(PeekTok.getLocation());
-
-    // Get the next token, don't expand it.
-    PP.LexUnexpandedToken(PeekTok);
-
-    // Two options, it can either be a pp-identifier or a (.
-    SourceLocation LParenLoc;
-    if (PeekTok.is(tok::l_paren)) {
-      // Found a paren, remember we saw it and skip it.
-      LParenLoc = PeekTok.getLocation();
-      PP.LexUnexpandedToken(PeekTok);
-    }
-
-    // If we don't have a pp-identifier now, this is an error.
-    if ((II = PeekTok.getIdentifierInfo()) == 0) {
-      PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
-      return true;
-    }
-
-    // Otherwise, we got an identifier, is it defined to something?
-    Result.Val = II->hasMacroDefinition();
-    Result.Val.setIsUnsigned(false);  // Result is signed intmax_t.
-
-    // If there is a macro, mark it used.
-    if (Result.Val != 0 && ValueLive) {
-      MacroInfo *Macro = PP.getMacroInfo(II);
-      Macro->setIsUsed(true);
-    }
-
-    // Consume identifier.
-    Result.setEnd(PeekTok.getLocation());
-    PP.LexNonComment(PeekTok);
-
-    // If we are in parens, ensure we have a trailing ).
-    if (LParenLoc.isValid()) {
-      if (PeekTok.isNot(tok::r_paren)) {
-        PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen);
-        PP.Diag(LParenLoc, diag::note_matching) << "(";
-        return true;
-      }
-      // Consume the ).
-      Result.setEnd(PeekTok.getLocation());
-      PP.LexNonComment(PeekTok);
-    }
-
-    // Success, remember that we saw defined(X).
-    DT.State = DefinedTracker::DefinedMacro;
-    DT.TheMacro = II;
-    return false;
   }
 
   switch (PeekTok.getKind()) {





More information about the cfe-commits mailing list