104d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org// 20bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com// Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved. 304d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org// Use of this source code is governed by a BSD-style license that can be 404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org// found in the LICENSE file. 504d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org// 604d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org#include "DirectiveParser.h" 804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 904d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org#include <cassert> 1051b96855babe208c6c22693f42925cc6458bd158alokp@chromium.org#include <cstdlib> 1136124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org#include <sstream> 1204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 13b3077d086b365b1d54c3d755df19c6f8f349a562daniel@transgaming.com#include "DiagnosticsBase.h" 14b3077d086b365b1d54c3d755df19c6f8f349a562daniel@transgaming.com#include "DirectiveHandlerBase.h" 1504d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org#include "ExpressionParser.h" 1604d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org#include "MacroExpander.h" 1704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org#include "Token.h" 1804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org#include "Tokenizer.h" 1904d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 2004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.orgnamespace { 21d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.orgenum DirectiveType 22d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org{ 23d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_NONE, 24d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_DEFINE, 25d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_UNDEF, 26d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_IF, 27d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_IFDEF, 28d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_IFNDEF, 29d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_ELSE, 30d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_ELIF, 31d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_ENDIF, 32d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_ERROR, 33d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_PRAGMA, 34d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_EXTENSION, 35d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_VERSION, 36d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DIRECTIVE_LINE 37d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org}; 3804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 39d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao MoDirectiveType getDirective(const pp::Token *token) 40d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org{ 41d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveDefine("define"); 42d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveUndef("undef"); 43d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveIf("if"); 44d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveIfdef("ifdef"); 45d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveIfndef("ifndef"); 46d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveElse("else"); 47d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveElif("elif"); 48d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveEndif("endif"); 49d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveError("error"); 50d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectivePragma("pragma"); 51d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveExtension("extension"); 52d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveVersion("version"); 53d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDirectiveLine("line"); 54d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 55d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (token->type != pp::Token::IDENTIFIER) 56d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_NONE; 57d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 585b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org if (token->text == kDirectiveDefine) 59d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_DEFINE; 60d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveUndef) 61d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_UNDEF; 62d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveIf) 63d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_IF; 64d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveIfdef) 65d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_IFDEF; 66d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveIfndef) 67d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_IFNDEF; 68d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveElse) 69d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_ELSE; 70d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveElif) 71d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_ELIF; 72d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveEndif) 73d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_ENDIF; 74d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveError) 75d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_ERROR; 76d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectivePragma) 77d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_PRAGMA; 78d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveExtension) 79d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_EXTENSION; 80d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveVersion) 81d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_VERSION; 82d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (token->text == kDirectiveLine) 83d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_LINE; 84d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 85d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return DIRECTIVE_NONE; 86d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org} 87d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 88d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mobool isConditionalDirective(DirectiveType directive) 89d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org{ 90d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org switch (directive) 91d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 92d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_IF: 93d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_IFDEF: 94d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_IFNDEF: 95d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_ELSE: 96d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_ELIF: 97d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_ENDIF: 98d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return true; 99d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org default: 100d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return false; 101d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 102d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org} 103d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 104d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org// Returns true if the token represents End Of Directive. 105d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mobool isEOD(const pp::Token *token) 106d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org{ 107d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return (token->type == '\n') || (token->type == pp::Token::LAST); 108d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org} 109d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 110d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid skipUntilEOD(pp::Lexer *lexer, pp::Token *token) 111d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org{ 112d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org while(!isEOD(token)) 113d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 114d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org lexer->lex(token); 115d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 116d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org} 117d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 118d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mobool isMacroNameReserved(const std::string &name) 11998d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org{ 12098d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org // Names prefixed with "GL_" are reserved. 12198d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org if (name.substr(0, 3) == "GL_") 12298d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org return true; 12398d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 12498d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org // Names containing two consecutive underscores are reserved. 12598d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org if (name.find("__") != std::string::npos) 12698d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org return true; 12798d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 12898d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org return false; 12998d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org} 13098d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 131d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mobool isMacroPredefined(const std::string &name, 132d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo const pp::MacroSet ¯oSet) 133f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org{ 134f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org pp::MacroSet::const_iterator iter = macroSet.find(name); 135f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org return iter != macroSet.end() ? iter->second.predefined : false; 136f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org} 137f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org 138d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo} // namespace anonymous 139d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo 14004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.orgnamespace pp 14104d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 14204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 14304d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.orgclass DefinedParser : public Lexer 14404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 14504d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org public: 146d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo DefinedParser(Lexer *lexer, 147d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo const MacroSet *macroSet, 148d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo Diagnostics *diagnostics) 149d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo : mLexer(lexer), 150d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo mMacroSet(macroSet), 151d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo mDiagnostics(diagnostics) 152d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 153d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 15404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 15504d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org protected: 156d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo virtual void lex(Token *token) 15704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org { 158d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org static const std::string kDefined("defined"); 159d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 16004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mLexer->lex(token); 161d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (token->type != Token::IDENTIFIER) 162d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 1635b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org if (token->text != kDefined) 164d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 165d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 166d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org bool paren = false; 167d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org mLexer->lex(token); 168d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (token->type == '(') 169d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 170d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org paren = true; 171d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org mLexer->lex(token); 172d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 173d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 174d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (token->type != Token::IDENTIFIER) 175d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 1767f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 1775b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 178d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mLexer, token); 179d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 180d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 1815b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org MacroSet::const_iterator iter = mMacroSet->find(token->text); 182d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org std::string expression = iter != mMacroSet->end() ? "1" : "0"; 183d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 184d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (paren) 185d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 186d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org mLexer->lex(token); 187d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (token->type != ')') 188d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 1897f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 1905b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 191d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mLexer, token); 192d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 193d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 194d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 195d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 196d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // We have a valid defined operator. 197d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // Convert the current token into a CONST_INT token. 198d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org token->type = Token::CONST_INT; 1995b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->text = expression; 20004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org } 20104d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 20204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org private: 203d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo Lexer *mLexer; 204d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo const MacroSet *mMacroSet; 205d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo Diagnostics *mDiagnostics; 20604d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org}; 20704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 208d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao MoDirectiveParser::DirectiveParser(Tokenizer *tokenizer, 209d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo MacroSet *macroSet, 210d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo Diagnostics *diagnostics, 211d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo DirectiveHandler *directiveHandler) 212d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo : mPastFirstStatement(false), 213d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo mTokenizer(tokenizer), 214d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo mMacroSet(macroSet), 215d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo mDiagnostics(diagnostics), 216d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo mDirectiveHandler(directiveHandler) 2172c958eefb71f1b939dbda4477df3f0c8fa47a7b8alokp@chromium.org{ 2182c958eefb71f1b939dbda4477df3f0c8fa47a7b8alokp@chromium.org} 2192c958eefb71f1b939dbda4477df3f0c8fa47a7b8alokp@chromium.org 220d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::lex(Token *token) 22104d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 22204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org do 22304d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org { 22404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 225d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 226432d6fc4a28f06292801141cc021c60f1b47f5a8alokp@chromium.org if (token->type == Token::PP_HASH) 227d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 228d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseDirective(token); 229d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org mPastFirstStatement = true; 230d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 231d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 232d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (token->type == Token::LAST) 233d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 234d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (!mConditionalStack.empty()) 235d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 236d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo const ConditionalBlock &block = mConditionalStack.back(); 2377f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED, 238d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.location, block.type); 239d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 240d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 241d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 242d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 243d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo } 244d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo while (skipping() || (token->type == '\n')); 245d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org 246d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org mPastFirstStatement = true; 24704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 24804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 249d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseDirective(Token *token) 25004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 251432d6fc4a28f06292801141cc021c60f1b47f5a8alokp@chromium.org assert(token->type == Token::PP_HASH); 25204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 25304d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 254d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org if (isEOD(token)) 255d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org { 256d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org // Empty Directive. 257d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org return; 258d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org } 259d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org 260d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DirectiveType directive = getDirective(token); 261d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 262d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // While in an excluded conditional block/group, 263d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // we only parse conditional directives. 264d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (skipping() && !isConditionalDirective(directive)) 265d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 266d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 267d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 268d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 269d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 270d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org switch(directive) 271d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 272d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_NONE: 2737f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_DIRECTIVE_INVALID_NAME, 2745b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 275d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 276d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 277d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_DEFINE: 278d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseDefine(token); 279d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 280d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_UNDEF: 281d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseUndef(token); 282d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 283d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_IF: 284d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseIf(token); 285d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 286d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_IFDEF: 287d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseIfdef(token); 288d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 289d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_IFNDEF: 290d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseIfndef(token); 291d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 292d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_ELSE: 293d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseElse(token); 294d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 295d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_ELIF: 296d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseElif(token); 297d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 298d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_ENDIF: 299d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseEndif(token); 300d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 301d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_ERROR: 302d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseError(token); 303d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 304d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_PRAGMA: 305d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parsePragma(token); 306d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 307d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_EXTENSION: 308d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseExtension(token); 309d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 310d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_VERSION: 311d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseVersion(token); 312d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 313d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_LINE: 314d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseLine(token); 315d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 316d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org default: 317d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(false); 318d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 319d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 320d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 321d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 322d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (token->type == Token::LAST) 323d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 3247f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE, 3255b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 32604d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org } 32704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 32804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 329d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseDefine(Token *token) 33004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 331d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_DEFINE); 33298d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 33304d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 3347c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (token->type != Token::IDENTIFIER) 33598d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org { 3367f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 3375b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 338f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org return; 339f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org } 3405b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org if (isMacroPredefined(token->text, *mMacroSet)) 341f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org { 3427f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, 3435b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 34498d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org return; 34598d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org } 3465b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org if (isMacroNameReserved(token->text)) 34798d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org { 3487f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, 3495b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 35098d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org return; 35198d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org } 35298d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 35398d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org Macro macro; 35498d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org macro.type = Macro::kTypeObj; 3555b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org macro.name = token->text; 35698d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 35798d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org mTokenizer->lex(token); 35898d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org if (token->type == '(' && !token->hasLeadingSpace()) 35998d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org { 36098d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org // Function-like macro. Collect arguments. 36198d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org macro.type = Macro::kTypeFunc; 362d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo do 363d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo { 36498d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org mTokenizer->lex(token); 3657c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (token->type != Token::IDENTIFIER) 36698d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org break; 3675b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org macro.parameters.push_back(token->text); 36898d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 3697fc38dddd2f5b6349348230475ca359666af583aalokp@chromium.org mTokenizer->lex(token); // Get ','. 370d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo } 371d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo while (token->type == ','); 37298d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 37398d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org if (token->type != ')') 37498d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org { 3757f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 37698d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org token->location, 3775b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->text); 37898d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org return; 37998d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org } 3807fc38dddd2f5b6349348230475ca359666af583aalokp@chromium.org mTokenizer->lex(token); // Get ')'. 38198d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org } 38298d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 3837c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org while ((token->type != '\n') && (token->type != Token::LAST)) 38498d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org { 38598d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org // Reset the token location because it is unnecessary in replacement 38698d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org // list. Resetting it also allows us to reuse Token::equals() to 38798d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org // compare macros. 38898d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org token->location = SourceLocation(); 38998d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org macro.replacements.push_back(*token); 39098d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org mTokenizer->lex(token); 39198d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org } 3927fc38dddd2f5b6349348230475ca359666af583aalokp@chromium.org if (!macro.replacements.empty()) 3937fc38dddd2f5b6349348230475ca359666af583aalokp@chromium.org { 3947fc38dddd2f5b6349348230475ca359666af583aalokp@chromium.org // Whitespace preceding the replacement list is not considered part of 3957fc38dddd2f5b6349348230475ca359666af583aalokp@chromium.org // the replacement list for either form of macro. 3967fc38dddd2f5b6349348230475ca359666af583aalokp@chromium.org macro.replacements.front().setHasLeadingSpace(false); 3977fc38dddd2f5b6349348230475ca359666af583aalokp@chromium.org } 39898d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 39998d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org // Check for macro redefinition. 40098d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org MacroSet::const_iterator iter = mMacroSet->find(macro.name); 40198d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org if (iter != mMacroSet->end() && !macro.equals(iter->second)) 40298d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org { 4037f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, 40498d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org token->location, 40598d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org macro.name); 40698d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org return; 40798d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org } 40898d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org mMacroSet->insert(std::make_pair(macro.name, macro)); 40904d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 41004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 411d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseUndef(Token *token) 41204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 413d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_UNDEF); 41498d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 41598d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org mTokenizer->lex(token); 4167c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (token->type != Token::IDENTIFIER) 41798d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org { 4187f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 4195b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 42098d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org return; 42198d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org } 42298d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 4235b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org MacroSet::iterator iter = mMacroSet->find(token->text); 42498d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org if (iter != mMacroSet->end()) 425f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org { 426f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org if (iter->second.predefined) 427f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org { 4287f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, 4295b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 430f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org } 431f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org else 432f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org { 433f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org mMacroSet->erase(iter); 434f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org } 435f3cdb460d1dde723815eecd006274a3da5d81099alokp@chromium.org } 43698d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org 43704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 43804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 43904d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 440d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseIf(Token *token) 44104d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 442d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_IF); 443d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseConditionalIf(token); 44404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 44504d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 446d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseIfdef(Token *token) 44704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 448d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_IFDEF); 449d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseConditionalIf(token); 45004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 45104d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 452d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseIfndef(Token *token) 45304d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 454d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_IFNDEF); 455d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org parseConditionalIf(token); 45604d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 45704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 458d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseElse(Token *token) 45904d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 460d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_ELSE); 461d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 462d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (mConditionalStack.empty()) 463d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 4647f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF, 4655b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 466d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 467d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 468d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 469d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 470d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo ConditionalBlock &block = mConditionalStack.back(); 471d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (block.skipBlock) 472d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 473d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // No diagnostics. Just skip the whole line. 474d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 475d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 476d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 477d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (block.foundElseGroup) 478d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 4797f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE, 4805b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 481d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 482d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 483d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 484d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 485d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.foundElseGroup = true; 486d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.skipGroup = block.foundValidGroup; 487d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.foundValidGroup = true; 488d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 489d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // Warn if there are extra tokens after #else. 49004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 491d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (!isEOD(token)) 492d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 4937f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, 4945b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 495d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 496d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 49704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 49804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 499d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseElif(Token *token) 50004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 501d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_ELIF); 502d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 503d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (mConditionalStack.empty()) 504d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 5057f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF, 5065b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 507d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 508d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 509d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 510d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 511d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo ConditionalBlock &block = mConditionalStack.back(); 512d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (block.skipBlock) 513d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 514d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // No diagnostics. Just skip the whole line. 515d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 516d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 517d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 518d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (block.foundElseGroup) 519d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 5207f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE, 5215b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 522d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 523d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 524d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 525d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (block.foundValidGroup) 526d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 527d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // Do not parse the expression. 528d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // Also be careful not to emit a diagnostic. 529d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.skipGroup = true; 530d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 531d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 532d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 533d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 534d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org int expression = parseExpressionIf(token); 535d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.skipGroup = expression == 0; 536d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.foundValidGroup = expression != 0; 53704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 53804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 539d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseEndif(Token *token) 54004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 541d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_ENDIF); 542d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 543d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (mConditionalStack.empty()) 544d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 5457f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF, 5465b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 547d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 548d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return; 549d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 550d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 551d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org mConditionalStack.pop_back(); 552d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 553d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // Warn if there are tokens after #endif. 55404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 555d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (!isEOD(token)) 556d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 5577f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, 5585b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 559d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 560d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 56104d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 56204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 563d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseError(Token *token) 56404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 565d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_ERROR); 56636124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org 5672e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org std::ostringstream stream; 56804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 5697c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org while ((token->type != '\n') && (token->type != Token::LAST)) 57036124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org { 57136124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org stream << *token; 57236124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org mTokenizer->lex(token); 57336124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org } 57436124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org mDirectiveHandler->handleError(token->location, stream.str()); 57504d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 57604d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 57736124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org// Parses pragma of form: #pragma name[(value)]. 578d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parsePragma(Token *token) 57904d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 580d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_PRAGMA); 58136124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org 58236124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org enum State 58336124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org { 58436124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org PRAGMA_NAME, 58536124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org LEFT_PAREN, 58636124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org PRAGMA_VALUE, 58736124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org RIGHT_PAREN 58836124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org }; 58936124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org 59036124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org bool valid = true; 59136124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org std::string name, value; 59236124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org int state = PRAGMA_NAME; 59336124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org 59404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 5957c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org while ((token->type != '\n') && (token->type != Token::LAST)) 59636124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org { 59736124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org switch(state++) 59836124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org { 59936124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org case PRAGMA_NAME: 6005b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org name = token->text; 6017c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = valid && (token->type == Token::IDENTIFIER); 60236124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org break; 60336124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org case LEFT_PAREN: 60436124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org valid = valid && (token->type == '('); 60536124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org break; 60636124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org case PRAGMA_VALUE: 6075b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org value = token->text; 6087c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = valid && (token->type == Token::IDENTIFIER); 60936124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org break; 61036124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org case RIGHT_PAREN: 61136124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org valid = valid && (token->type == ')'); 61236124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org break; 61336124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org default: 61436124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org valid = false; 61536124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org break; 61636124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org } 61736124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org mTokenizer->lex(token); 61836124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org } 61936124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org 62036124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org valid = valid && ((state == PRAGMA_NAME) || // Empty pragma. 62136124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org (state == LEFT_PAREN) || // Without value. 62236124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org (state == RIGHT_PAREN + 1)); // With value. 62336124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org if (!valid) 62436124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org { 6257f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, 62636124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org token->location, name); 62736124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org } 62836124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org else if (state > PRAGMA_NAME) // Do not notify for empty pragma. 62936124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org { 63036124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org mDirectiveHandler->handlePragma(token->location, name, value); 63136124de8ce9855c1cfdfb6529b47822e12123274alokp@chromium.org } 63204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 63304d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 634d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseExtension(Token *token) 63504d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 636d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_EXTENSION); 6377c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org 6387c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org enum State 6397c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 6407c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org EXT_NAME, 6417c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org COLON, 6427c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org EXT_BEHAVIOR 6437c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org }; 6447c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org 6457c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org bool valid = true; 6467c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org std::string name, behavior; 6477c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org int state = EXT_NAME; 6487c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org 64904d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 6507c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org while ((token->type != '\n') && (token->type != Token::LAST)) 6517c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 6527c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org switch (state++) 6537c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 6547c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org case EXT_NAME: 6557c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (valid && (token->type != Token::IDENTIFIER)) 6567c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 6577f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_NAME, 6585b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 6597c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = false; 6607c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 6615b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org if (valid) name = token->text; 6627c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org break; 6637c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org case COLON: 6647c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (valid && (token->type != ':')) 6657c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 6667f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 6675b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 6687c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = false; 6697c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 6707c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org break; 6717c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org case EXT_BEHAVIOR: 6727c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (valid && (token->type != Token::IDENTIFIER)) 6737c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 6747f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_BEHAVIOR, 6755b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 6767c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = false; 6777c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 6785b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org if (valid) behavior = token->text; 6797c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org break; 6807c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org default: 6817c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (valid) 6827c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 6837f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 6845b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 6857c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = false; 6867c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 6877c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org break; 6887c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 6897c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org mTokenizer->lex(token); 6907c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 6917c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (valid && (state != EXT_BEHAVIOR + 1)) 6927c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 6937f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, 6945b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 6957c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = false; 6967c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 6977c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (valid) 6987c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org mDirectiveHandler->handleExtension(token->location, name, behavior); 69904d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 70004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 701d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseVersion(Token *token) 70204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 703d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_VERSION); 7047c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org 705d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org if (mPastFirstStatement) 706d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org { 7077f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, 708d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org token->location, token->text); 709d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org skipUntilEOD(mTokenizer, token); 710d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org return; 711d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org } 712d0d9f87ac02955ae496b5cc51d5dffb693b31a87alokp@chromium.org 7137c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org enum State 7147c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 7150bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com VERSION_NUMBER, 7160bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com VERSION_PROFILE, 7170bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com VERSION_ENDLINE 7187c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org }; 7197c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org 7207c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org bool valid = true; 7217c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org int version = 0; 7227c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org int state = VERSION_NUMBER; 7237c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org 72404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org mTokenizer->lex(token); 7250bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com while (valid && (token->type != '\n') && (token->type != Token::LAST)) 7267c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 7270bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com switch (state) 7287c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 7297c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org case VERSION_NUMBER: 7300bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com if (token->type != Token::CONST_INT) 7317c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 7327f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER, 7335b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 7347c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = false; 7357c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 7362e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org if (valid && !token->iValue(&version)) 7372e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org { 7387f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, 7392e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org token->location, token->text); 7402e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org valid = false; 7412e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org } 7427c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (valid) 7437c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 7440bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE; 7450bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com } 7460bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com break; 7470bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com case VERSION_PROFILE: 7480bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com if (token->type != Token::IDENTIFIER || token->text != "es") 7490bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com { 7507f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, 7515b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 7527c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = false; 7537c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 7540bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com state = VERSION_ENDLINE; 7550bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com break; 7560bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com default: 7577f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 7580bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com token->location, token->text); 7590bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com valid = false; 7607c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org break; 7617c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 7620bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com 7637c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org mTokenizer->lex(token); 7647c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 7650bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com 7660bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com if (valid && (state != VERSION_ENDLINE)) 7677c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org { 7687f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, 7695b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 7707c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org valid = false; 7717c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org } 7720bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com 7737c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org if (valid) 7740bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com { 7757c884540ad7607a772b13b2ca7bc8f6b21574946alokp@chromium.org mDirectiveHandler->handleVersion(token->location, version); 7760bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com } 77704d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 77804d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 779d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseLine(Token *token) 78004d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org{ 781d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(getDirective(token) == DIRECTIVE_LINE); 78246aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org 78346aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org enum State 78446aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org { 78546aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org LINE_NUMBER, 78646aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org FILE_NUMBER 78746aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org }; 78846aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org 78946aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org bool valid = true; 79046aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org int line = 0, file = 0; 79146aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org int state = LINE_NUMBER; 79246aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org 79398d04ec8e2db023e04818c4af97b5e613af3f55calokp@chromium.org MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics); 79404d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org macroExpander.lex(token); 79546aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org while ((token->type != '\n') && (token->type != Token::LAST)) 79646aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org { 79746aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org switch (state++) 79846aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org { 79946aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org case LINE_NUMBER: 80046aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org if (valid && (token->type != Token::CONST_INT)) 80146aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org { 8027f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INVALID_LINE_NUMBER, 8035b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 80446aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org valid = false; 80546aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org } 8062e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org if (valid && !token->iValue(&line)) 8072e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org { 8087f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, 8092e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org token->location, token->text); 8102e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org valid = false; 8112e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org } 81246aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org break; 81346aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org case FILE_NUMBER: 81446aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org if (valid && (token->type != Token::CONST_INT)) 81546aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org { 8167f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INVALID_FILE_NUMBER, 8175b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 81846aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org valid = false; 81946aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org } 8202e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org if (valid && !token->iValue(&file)) 8212e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org { 8227f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, 8232e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org token->location, token->text); 8242e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org valid = false; 8252e81891c21bfb199bb53f903bf0967f07efb65d8alokp@chromium.org } 82646aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org break; 82746aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org default: 82846aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org if (valid) 82946aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org { 8307f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 8315b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 83246aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org valid = false; 83346aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org } 83446aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org break; 83546aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org } 83646aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org macroExpander.lex(token); 83746aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org } 83846aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org 83946aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1)) 84046aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org { 8417f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, 8425b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 84346aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org valid = false; 84446aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org } 84546aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org if (valid) 84646aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org { 84746aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org mTokenizer->setLineNumber(line); 848d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (state == FILE_NUMBER + 1) 849d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo mTokenizer->setFileNumber(file); 85046aa13d87fdc2da6d36fd14f678f204f8f98ae41alokp@chromium.org } 85104d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} 85204d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org 853d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.orgbool DirectiveParser::skipping() const 854d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org{ 855d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo if (mConditionalStack.empty()) 856d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo return false; 857d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 858d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org const ConditionalBlock& block = mConditionalStack.back(); 859d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return block.skipBlock || block.skipGroup; 860d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org} 861d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 862d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Movoid DirectiveParser::parseConditionalIf(Token *token) 863d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org{ 864d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org ConditionalBlock block; 8655b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org block.type = token->text; 866d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.location = token->location; 867d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 868d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (skipping()) 869d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 870d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // This conditional block is inside another conditional group 871d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // which is skipped. As a consequence this whole block is skipped. 872d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // Be careful not to parse the conditional expression that might 873d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // emit a diagnostic. 874d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 875d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.skipBlock = true; 876d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 877d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org else 878d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 879d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DirectiveType directive = getDirective(token); 880d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 881d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org int expression = 0; 882d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org switch (directive) 883d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 884d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_IF: 885d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org expression = parseExpressionIf(token); 886d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 887d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_IFDEF: 888d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org expression = parseExpressionIfdef(token); 889d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 890d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org case DIRECTIVE_IFNDEF: 891d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org expression = parseExpressionIfdef(token) == 0 ? 1 : 0; 892d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 893d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org default: 894d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert(false); 895d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org break; 896d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 897d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.skipGroup = expression == 0; 898d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org block.foundValidGroup = expression != 0; 899d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 900d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org mConditionalStack.push_back(block); 901d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org} 902d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 903d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Moint DirectiveParser::parseExpressionIf(Token *token) 904d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org{ 905d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert((getDirective(token) == DIRECTIVE_IF) || 906d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org (getDirective(token) == DIRECTIVE_ELIF)); 907d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 908d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics); 909d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics); 910d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org ExpressionParser expressionParser(¯oExpander, mDiagnostics); 911d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 912d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org int expression = 0; 913d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org macroExpander.lex(token); 914d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org expressionParser.parse(token, &expression); 915d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 916d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // Warn if there are tokens after #if expression. 917d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (!isEOD(token)) 918d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 9197f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, 9205b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 921d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 922d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 923d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 924d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return expression; 925d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org} 926d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 927d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Moint DirectiveParser::parseExpressionIfdef(Token *token) 928d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org{ 929d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org assert((getDirective(token) == DIRECTIVE_IFDEF) || 930d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org (getDirective(token) == DIRECTIVE_IFNDEF)); 931d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 932d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org mTokenizer->lex(token); 933d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (token->type != Token::IDENTIFIER) 934d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 9357f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, 9365b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 937d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 938d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return 0; 939d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 940d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 9415b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org MacroSet::const_iterator iter = mMacroSet->find(token->text); 942d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org int expression = iter != mMacroSet->end() ? 1 : 0; 943d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 944d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org // Warn if there are tokens after #ifdef expression. 945d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org mTokenizer->lex(token); 946d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org if (!isEOD(token)) 947d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org { 9487f2d7945ee702241829727751bd4c7424662b225Shannon Woods mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, 9495b6a68e04a7d27dab71524fa481f42818f84a240alokp@chromium.org token->location, token->text); 950d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org skipUntilEOD(mTokenizer, token); 951d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org } 952d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org return expression; 953d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org} 954d39ec4c15d6e656e027d7ded7ffceaafa0608e89alokp@chromium.org 95504d7d22bb835408a82600244e09b9dcacbc0fa11alokp@chromium.org} // namespace pp 956