From: John Thompson Date: Fri, 30 Oct 2009 13:49:06 +0000 (+0000) Subject: Re-arranged some internal functions for coming __has_include changes. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a28cc090f265d5bdaef9ebb24fb9d579928d3a18;p=clang Re-arranged some internal functions for coming __has_include changes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85589 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 3f132c0dab..f8c013427c 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -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">; diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 0765ac391b..d721278cbe 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -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 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 + /// #include FOO + /// because in this case, "" 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 &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 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) { diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index e264efab9d..dc7d95e701 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -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 &FilenameBuffer, - Preprocessor &PP) { +bool Preprocessor::ConcatenateIncludeName( + llvm::SmallVector &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 &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 &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 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 but no ">"? Diagnostic already emitted. FilenameStart = FilenameBuffer.data(); FilenameEnd = FilenameStart + FilenameBuffer.size(); diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp index 908385c5d3..a74396c314 100644 --- a/lib/Lex/PPExpressions.cpp +++ b/lib/Lex/PPExpressions.cpp @@ -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()) {