From a8654ca2cf9e455feac1157cbee13f4e19022fbd Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 4 Jul 2006 17:42:08 +0000 Subject: [PATCH] Eliminate MultipleIncludeOpt::ReadDirective and all calls to it. Any directives that are lexed are made up of tokens, so the calls are just ugly and redundant. Hook up the MIOpt for the #if case. PPCExpressions doesn't currently implement the hook though, so we still don't handle #if !defined(X) with the MIOpt. llvm-svn: 38649 --- clang/Lex/PPExpressions.cpp | 10 +++--- clang/Lex/Pragma.cpp | 3 -- clang/Lex/Preprocessor.cpp | 35 ++++++++------------ clang/include/clang/Lex/MultipleIncludeOpt.h | 6 ++-- clang/include/clang/Lex/Preprocessor.h | 8 ++--- 5 files changed, 24 insertions(+), 38 deletions(-) diff --git a/clang/Lex/PPExpressions.cpp b/clang/Lex/PPExpressions.cpp index 2b4afa900e5d..979cb171106f 100644 --- a/clang/Lex/PPExpressions.cpp +++ b/clang/Lex/PPExpressions.cpp @@ -26,12 +26,10 @@ using namespace llvm; using namespace clang; /// EvaluateDirectiveExpression - Evaluate an integer constant expression that -/// may occur after a #if or #elif directive. Sets Result to the result of -/// the expression. Returns false normally, true if lexing must be aborted. -/// -/// MinPrec is the minimum precedence that this range of the expression is -/// allowed to include. -bool Preprocessor::EvaluateDirectiveExpression() { +/// may occur after a #if or #elif directive. If the +/// expression is equivalent to "!defined(X)" return X in IfNDefMacro. +bool Preprocessor:: +EvaluateDirectiveExpression(IdentifierTokenInfo *&IfNDefMacro) { // Peek ahead one token. LexerToken Tok; Lex(Tok); diff --git a/clang/Lex/Pragma.cpp b/clang/Lex/Pragma.cpp index 183bed17663b..9b0fe5f495af 100644 --- a/clang/Lex/Pragma.cpp +++ b/clang/Lex/Pragma.cpp @@ -74,9 +74,6 @@ void PragmaNamespace::HandlePragma(Preprocessor &PP, LexerToken &Tok) { void Preprocessor::HandlePragmaDirective() { ++NumPragma; - // Inform MIOpt that we found a side-effect of parsing this file. - CurLexer->MIOpt.ReadDirective(); - // Invoke the first level of pragma handlers which reads the namespace id. LexerToken Tok; PragmaHandlers->HandlePragma(*this, Tok); diff --git a/clang/Lex/Preprocessor.cpp b/clang/Lex/Preprocessor.cpp index 144d5eafa6e3..7c3b7138ec59 100644 --- a/clang/Lex/Preprocessor.cpp +++ b/clang/Lex/Preprocessor.cpp @@ -1020,7 +1020,8 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc, // looked up, etc, inside the #elif expression. assert(SkippingContents && "We have to be skipping here!"); SkippingContents = false; - ShouldEnter = EvaluateDirectiveExpression(); + IdentifierTokenInfo *IfNDefMacro = 0; + ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro); SkippingContents = true; } @@ -1077,14 +1078,13 @@ void Preprocessor::HandleDirective(LexerToken &Result) { #if 0 case tok::numeric_constant: - MIOpt.ReadDirective(); // FIXME: implement # 7 line numbers! break; #endif case tok::kw_else: return HandleElseDirective(Result); case tok::kw_if: - return HandleIfDirective(Result); + return HandleIfDirective(Result, ReadAnyTokensBeforeDirective); case tok::identifier: // Get the identifier name without trigraphs or embedded newlines. const char *Directive = Result.getIdentifierInfo()->getName(); @@ -1092,7 +1092,7 @@ void Preprocessor::HandleDirective(LexerToken &Result) { switch (Result.getIdentifierInfo()->getNameLength()) { case 4: if (Directive[0] == 'l' && !strcmp(Directive, "line")) - CurLexer->MIOpt.ReadDirective(); // FIXME: implement #line + ; // FIXME: implement #line if (Directive[0] == 'e' && !strcmp(Directive, "elif")) return HandleElifDirective(Result); if (Directive[0] == 's' && !strcmp(Directive, "sccs")) @@ -1168,9 +1168,6 @@ void Preprocessor::HandleUserDiagnosticDirective(LexerToken &Tok, /// HandleIdentSCCSDirective - Handle a #ident/#sccs directive. /// void Preprocessor::HandleIdentSCCSDirective(LexerToken &Tok) { - // Inform MIOpt that we found a side-effect of parsing this file. - CurLexer->MIOpt.ReadDirective(); - // Yes, this directive is an extension. Diag(Tok, diag::ext_pp_ident_directive); @@ -1202,9 +1199,6 @@ void Preprocessor::HandleIncludeDirective(LexerToken &IncludeTok, bool isImport) { ++NumIncluded; - // Inform MIOpt that we found a side-effect of parsing this file. - CurLexer->MIOpt.ReadDirective(); - LexerToken FilenameTok; std::string Filename = CurLexer->LexIncludeFilename(FilenameTok); @@ -1310,9 +1304,6 @@ void Preprocessor::HandleImportDirective(LexerToken &ImportTok) { void Preprocessor::HandleDefineDirective(LexerToken &DefineTok) { ++NumDefined; - // Inform MIOpt that we found a side-effect of parsing this file. - CurLexer->MIOpt.ReadDirective(); - LexerToken MacroNameTok; ReadMacroName(MacroNameTok, true); @@ -1383,9 +1374,6 @@ void Preprocessor::HandleDefineDirective(LexerToken &DefineTok) { void Preprocessor::HandleUndefDirective(LexerToken &UndefTok) { ++NumUndefined; - // Inform MIOpt that we found a side-effect of parsing this file. - CurLexer->MIOpt.ReadDirective(); - LexerToken MacroNameTok; ReadMacroName(MacroNameTok, true); @@ -1462,17 +1450,22 @@ void Preprocessor::HandleIfdefDirective(LexerToken &Result, bool isIfndef, /// HandleIfDirective - Implements the #if directive. /// -void Preprocessor::HandleIfDirective(LexerToken &IfToken) { +void Preprocessor::HandleIfDirective(LexerToken &IfToken, + bool ReadAnyTokensBeforeDirective) { ++NumIf; - // FIXME: Detect "#if !defined(X)" for the MIOpt. - CurLexer->MIOpt.ReadDirective(); - // Parse and evaluation the conditional expression. - bool ConditionalTrue = EvaluateDirectiveExpression(); + IdentifierTokenInfo *IfNDefMacro = 0; + bool ConditionalTrue = EvaluateDirectiveExpression(IfNDefMacro); // Should we include the stuff contained by this directive? if (ConditionalTrue) { + // If this condition is equivalent to #ifndef X, and if this is the first + // directive seen, handle it for the multiple-include optimization. + if (!ReadAnyTokensBeforeDirective && + CurLexer->getConditionalStackDepth() == 0 && IfNDefMacro) + CurLexer->MIOpt.EnterTopLevelIFNDEF(IfNDefMacro); + // Yes, remember that we are inside a conditional, then lex the next token. CurLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false, /*foundnonskip*/true, /*foundelse*/false); diff --git a/clang/include/clang/Lex/MultipleIncludeOpt.h b/clang/include/clang/Lex/MultipleIncludeOpt.h index 75aa772064e4..ec00c02ea10c 100644 --- a/clang/include/clang/Lex/MultipleIncludeOpt.h +++ b/clang/include/clang/Lex/MultipleIncludeOpt.h @@ -51,10 +51,8 @@ public: /// the "ifndef x" would count as reading tokens. bool getHasReadAnyTokensVal() const { return ReadAnyTokens; } - // If a token or directive is read, remember that we have seen a side-effect - // in this file. - void ReadToken() { ReadAnyTokens = true; } - void ReadDirective() { ReadAnyTokens = true; } + // If a token is read, remember that we have seen a side-effect in this file. + void ReadToken() { ReadAnyTokens = true; } /// EnterTopLevelIFNDEF - When entering a top-level #ifndef directive (or the /// "#if !defined" equivalent) without any preceding tokens, this method is diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 9370b194c9ff..082fadc90118 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -429,9 +429,9 @@ private: bool FoundNonSkipPortion, bool FoundElse); /// EvaluateDirectiveExpression - Evaluate an integer constant expression that - /// may occur after a #if or #elif directive. Sets Result to the result of - /// the expression. - bool EvaluateDirectiveExpression(); + /// may occur after a #if or #elif directive and return it as a bool. If the + /// expression is equivalent to "!defined(X)" return X in IfNDefMacro. + bool EvaluateDirectiveExpression(IdentifierTokenInfo *&IfNDefMacro); /// EvaluateValue/EvaluateDirectiveSubExpr - Used to implement /// EvaluateDirectiveExpression, see PPExpressions.cpp. bool EvaluateValue(int &Result, LexerToken &PeekTok); @@ -489,7 +489,7 @@ private: // Conditional Inclusion. void HandleIfdefDirective(LexerToken &Tok, bool isIfndef, bool ReadAnyTokensBeforeDirective); - void HandleIfDirective(LexerToken &Tok); + void HandleIfDirective(LexerToken &Tok, bool ReadAnyTokensBeforeDirective); void HandleEndifDirective(LexerToken &Tok); void HandleElseDirective(LexerToken &Tok); void HandleElifDirective(LexerToken &Tok);