]> granicus.if.org Git - clang/commitdiff
Re-arranged some internal functions for coming __has_include changes.
authorJohn Thompson <John.Thompson.JTSoftware@gmail.com>
Fri, 30 Oct 2009 13:49:06 +0000 (13:49 +0000)
committerJohn Thompson <John.Thompson.JTSoftware@gmail.com>
Fri, 30 Oct 2009 13:49:06 +0000 (13:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85589 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticLexKinds.td
include/clang/Lex/Preprocessor.h
lib/Lex/PPDirectives.cpp
lib/Lex/PPExpressions.cpp

index 3f132c0dabfa2c47faae325a2f3b49da768ce8f6..f8c013427cac5c422fb12e866686ed83d2094227 100644 (file)
@@ -194,7 +194,7 @@ def err_pp_expected_eol : Error<
   "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">;
index 0765ac391be3f3a53c5d8f1267c80eab0cd46e71..d721278cbe78dd2e6efbeb05df50634c1fbc41d2 100644 (file)
@@ -244,7 +244,12 @@ public:
     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 @@ public:
   ///  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 @@ private:
   ///  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 @@ private:
   /// 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) {
index e264efab9d7b86ff6142894d2fbbfded3d2b66eb..dc7d95e701189a1362c9b3d5a6ca9bc897e18661 100644 (file)
@@ -974,11 +974,11 @@ bool Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc,
 /// 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 @@ static bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer,
     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 @@ static bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer,
     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 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
     // 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();
index 908385c5d392171d604f4dec7354f8e148c92c39..a74396c3146ceba36925fb2200193270874c7bb1 100644 (file)
@@ -71,6 +71,61 @@ struct DefinedTracker {
   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 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
   // '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 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
       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()) {