diff --git a/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp b/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp
index 8e6dcbd..ec77c21 100644
--- a/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp
+++ b/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp
@@ -1,891 +1,899 @@
-//
-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "DirectiveParser.h"
-
-#include <cassert>
-#include <cstdlib>
-#include <sstream>
-
-#include "Diagnostics.h"
-#include "DirectiveHandler.h"
-#include "ExpressionParser.h"
-#include "MacroExpander.h"
-#include "Token.h"
-#include "Tokenizer.h"
-
-namespace {
-enum DirectiveType
-{
-    DIRECTIVE_NONE,
-    DIRECTIVE_DEFINE,
-    DIRECTIVE_UNDEF,
-    DIRECTIVE_IF,
-    DIRECTIVE_IFDEF,
-    DIRECTIVE_IFNDEF,
-    DIRECTIVE_ELSE,
-    DIRECTIVE_ELIF,
-    DIRECTIVE_ENDIF,
-    DIRECTIVE_ERROR,
-    DIRECTIVE_PRAGMA,
-    DIRECTIVE_EXTENSION,
-    DIRECTIVE_VERSION,
-    DIRECTIVE_LINE
-};
-}  // namespace
-
-static DirectiveType getDirective(const pp::Token* token)
-{
-    static const std::string kDirectiveDefine("define");
-    static const std::string kDirectiveUndef("undef");
-    static const std::string kDirectiveIf("if");
-    static const std::string kDirectiveIfdef("ifdef");
-    static const std::string kDirectiveIfndef("ifndef");
-    static const std::string kDirectiveElse("else");
-    static const std::string kDirectiveElif("elif");
-    static const std::string kDirectiveEndif("endif");
-    static const std::string kDirectiveError("error");
-    static const std::string kDirectivePragma("pragma");
-    static const std::string kDirectiveExtension("extension");
-    static const std::string kDirectiveVersion("version");
-    static const std::string kDirectiveLine("line");
-
-    if (token->type != pp::Token::IDENTIFIER)
-        return DIRECTIVE_NONE;
-
-    if (token->text == kDirectiveDefine)
-        return DIRECTIVE_DEFINE;
-    else if (token->text == kDirectiveUndef)
-        return DIRECTIVE_UNDEF;
-    else if (token->text == kDirectiveIf)
-        return DIRECTIVE_IF;
-    else if (token->text == kDirectiveIfdef)
-        return DIRECTIVE_IFDEF;
-    else if (token->text == kDirectiveIfndef)
-        return DIRECTIVE_IFNDEF;
-    else if (token->text == kDirectiveElse)
-        return DIRECTIVE_ELSE;
-    else if (token->text == kDirectiveElif)
-        return DIRECTIVE_ELIF;
-    else if (token->text == kDirectiveEndif)
-        return DIRECTIVE_ENDIF;
-    else if (token->text == kDirectiveError)
-        return DIRECTIVE_ERROR;
-    else if (token->text == kDirectivePragma)
-        return DIRECTIVE_PRAGMA;
-    else if (token->text == kDirectiveExtension)
-        return DIRECTIVE_EXTENSION;
-    else if (token->text == kDirectiveVersion)
-        return DIRECTIVE_VERSION;
-    else if (token->text == kDirectiveLine)
-        return DIRECTIVE_LINE;
-
-    return DIRECTIVE_NONE;
-}
-
-static bool isConditionalDirective(DirectiveType directive)
-{
-    switch (directive)
-    {
-      case DIRECTIVE_IF:
-      case DIRECTIVE_IFDEF:
-      case DIRECTIVE_IFNDEF:
-      case DIRECTIVE_ELSE:
-      case DIRECTIVE_ELIF:
-      case DIRECTIVE_ENDIF:
-        return true;
-      default:
-        return false;
-    }
-}
-
-// Returns true if the token represents End Of Directive.
-static bool isEOD(const pp::Token* token)
-{
-    return (token->type == '\n') || (token->type == pp::Token::LAST);
-}
-
-static void skipUntilEOD(pp::Lexer* lexer, pp::Token* token)
-{
-    while(!isEOD(token))
-    {
-        lexer->lex(token);
-    }
-}
-
-static bool isMacroNameReserved(const std::string& name)
-{
-    // Names prefixed with "GL_" are reserved.
-    if (name.substr(0, 3) == "GL_")
-        return true;
-
-    // Names containing two consecutive underscores are reserved.
-    if (name.find("__") != std::string::npos)
-        return true;
-
-    return false;
-}
-
-static bool isMacroPredefined(const std::string& name,
-                              const pp::MacroSet& macroSet)
-{
-    pp::MacroSet::const_iterator iter = macroSet.find(name);
-    return iter != macroSet.end() ? iter->second.predefined : false;
-}
-
-namespace pp
-{
-
-DirectiveParser::DirectiveParser(Tokenizer* tokenizer,
-                                 MacroSet* macroSet,
-                                 Diagnostics* diagnostics,
-                                 DirectiveHandler* directiveHandler) :
-    mPastFirstStatement(false),
-    mTokenizer(tokenizer),
-    mMacroSet(macroSet),
-    mDiagnostics(diagnostics),
-    mDirectiveHandler(directiveHandler)
-{
-}
-
-void DirectiveParser::lex(Token* token)
-{
-    do
-    {
-        mTokenizer->lex(token);
-
-        if (token->type == Token::PP_HASH)
-        {
-            parseDirective(token);
-            mPastFirstStatement = true;
-        }
-
-        if (token->type == Token::LAST)
-        {
-            if (!mConditionalStack.empty())
-            {
-                const ConditionalBlock& block = mConditionalStack.back();
-                mDiagnostics->report(Diagnostics::CONDITIONAL_UNTERMINATED,
-                                     block.location, block.type);
-            }
-            break;
-        }
-
-    } while (skipping() || (token->type == '\n'));
-
-    mPastFirstStatement = true;
-}
-
-void DirectiveParser::parseDirective(Token* token)
-{
-    assert(token->type == Token::PP_HASH);
-
-    mTokenizer->lex(token);
-    if (isEOD(token))
-    {
-        // Empty Directive.
-        return;
-    }
-
-    DirectiveType directive = getDirective(token);
-
-    // While in an excluded conditional block/group,
-    // we only parse conditional directives.
-    if (skipping() && !isConditionalDirective(directive))
-    {
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-
-    switch(directive)
-    {
-      case DIRECTIVE_NONE:
-        mDiagnostics->report(Diagnostics::DIRECTIVE_INVALID_NAME,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-        break;
-      case DIRECTIVE_DEFINE:
-        parseDefine(token);
-        break;
-      case DIRECTIVE_UNDEF:
-        parseUndef(token);
-        break;
-      case DIRECTIVE_IF:
-        parseIf(token);
-        break;
-      case DIRECTIVE_IFDEF:
-        parseIfdef(token);
-        break;
-      case DIRECTIVE_IFNDEF:
-        parseIfndef(token);
-        break;
-      case DIRECTIVE_ELSE:
-        parseElse(token);
-        break;
-      case DIRECTIVE_ELIF:
-        parseElif(token);
-        break;
-      case DIRECTIVE_ENDIF:
-        parseEndif(token);
-        break;
-      case DIRECTIVE_ERROR:
-        parseError(token);
-        break;
-      case DIRECTIVE_PRAGMA:
-        parsePragma(token);
-        break;
-      case DIRECTIVE_EXTENSION:
-        parseExtension(token);
-        break;
-      case DIRECTIVE_VERSION:
-        parseVersion(token);
-        break;
-      case DIRECTIVE_LINE:
-        parseLine(token);
-        break;
-      default:
-        assert(false);
-        break;
-    }
-
-    skipUntilEOD(mTokenizer, token);
-    if (token->type == Token::LAST)
-    {
-        mDiagnostics->report(Diagnostics::EOF_IN_DIRECTIVE,
-                             token->location, token->text);
-    }
-}
-
-void DirectiveParser::parseDefine(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_DEFINE);
-
-    mTokenizer->lex(token);
-    if (token->type != Token::IDENTIFIER)
-    {
-        mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
-                             token->location, token->text);
-        return;
-    }
-    if (isMacroPredefined(token->text, *mMacroSet))
-    {
-        mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_REDEFINED,
-                             token->location, token->text);
-        return;
-    }
-    if (isMacroNameReserved(token->text))
-    {
-        mDiagnostics->report(Diagnostics::MACRO_NAME_RESERVED,
-                             token->location, token->text);
-        return;
-    }
-
-    Macro macro;
-    macro.type = Macro::kTypeObj;
-    macro.name = token->text;
-
-    mTokenizer->lex(token);
-    if (token->type == '(' && !token->hasLeadingSpace())
-    {
-        // Function-like macro. Collect arguments.
-        macro.type = Macro::kTypeFunc;
-        do {
-            mTokenizer->lex(token);
-            if (token->type != Token::IDENTIFIER)
-                break;
-
-            if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end())
-            {
-                mDiagnostics->report(Diagnostics::MACRO_DUPLICATE_PARAMETER_NAMES,
-                                     token->location, token->text);
-                return;
-            }
-
-            macro.parameters.push_back(token->text);
-
-            mTokenizer->lex(token);  // Get ','.
-        } while (token->type == ',');
-
-        if (token->type != ')')
-        {
-            mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
-                                 token->location,
-                                 token->text);
-            return;
-        }
-        mTokenizer->lex(token);  // Get ')'.
-    }
-
-    while ((token->type != '\n') && (token->type != Token::LAST))
-    {
-        // Reset the token location because it is unnecessary in replacement
-        // list. Resetting it also allows us to reuse Token::equals() to
-        // compare macros.
-        token->location = SourceLocation();
-        macro.replacements.push_back(*token);
-        mTokenizer->lex(token);
-    }
-    if (!macro.replacements.empty())
-    {
-        // Whitespace preceding the replacement list is not considered part of
-        // the replacement list for either form of macro.
-        macro.replacements.front().setHasLeadingSpace(false);
-    }
-
-    // Check for macro redefinition.
-    MacroSet::const_iterator iter = mMacroSet->find(macro.name);
-    if (iter != mMacroSet->end() && !macro.equals(iter->second))
-    {
-        mDiagnostics->report(Diagnostics::MACRO_REDEFINED,
-                             token->location,
-                             macro.name);
-        return;
-    }
-    mMacroSet->insert(std::make_pair(macro.name, macro));
-}
-
-void DirectiveParser::parseUndef(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_UNDEF);
-
-    mTokenizer->lex(token);
-    if (token->type != Token::IDENTIFIER)
-    {
-        mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
-                             token->location, token->text);
-        return;
-    }
-
-    MacroSet::iterator iter = mMacroSet->find(token->text);
-    if (iter != mMacroSet->end())
-    {
-        if (iter->second.predefined)
-        {
-            mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_UNDEFINED,
-                                 token->location, token->text);
-        }
-        else
-        {
-            mMacroSet->erase(iter);
-        }
-    }
-
-    mTokenizer->lex(token);
-}
-
-void DirectiveParser::parseIf(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_IF);
-    parseConditionalIf(token);
-}
-
-void DirectiveParser::parseIfdef(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_IFDEF);
-    parseConditionalIf(token);
-}
-
-void DirectiveParser::parseIfndef(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_IFNDEF);
-    parseConditionalIf(token);
-}
-
-void DirectiveParser::parseElse(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_ELSE);
-
-    if (mConditionalStack.empty())
-    {
-        mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_WITHOUT_IF,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-
-    ConditionalBlock& block = mConditionalStack.back();
-    if (block.skipBlock)
-    {
-        // No diagnostics. Just skip the whole line.
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-    if (block.foundElseGroup)
-    {
-        mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_AFTER_ELSE,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-
-    block.foundElseGroup = true;
-    block.skipGroup = block.foundValidGroup;
-    block.foundValidGroup = true;
-
-    // Check if there are extra tokens after #else.
-    mTokenizer->lex(token);
-    if (!isEOD(token))
-    {
-        mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-    }
-}
-
-void DirectiveParser::parseElif(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_ELIF);
-
-    if (mConditionalStack.empty())
-    {
-        mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_WITHOUT_IF,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-
-    ConditionalBlock& block = mConditionalStack.back();
-    if (block.skipBlock)
-    {
-        // No diagnostics. Just skip the whole line.
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-    if (block.foundElseGroup)
-    {
-        mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_AFTER_ELSE,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-    if (block.foundValidGroup)
-    {
-        // Do not parse the expression.
-        // Also be careful not to emit a diagnostic.
-        block.skipGroup = true;
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-
-    int expression = parseExpressionIf(token);
-    block.skipGroup = expression == 0;
-    block.foundValidGroup = expression != 0;
-}
-
-void DirectiveParser::parseEndif(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_ENDIF);
-
-    if (mConditionalStack.empty())
-    {
-        mDiagnostics->report(Diagnostics::CONDITIONAL_ENDIF_WITHOUT_IF,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-
-    mConditionalStack.pop_back();
-
-    // Check if there are tokens after #endif.
-    mTokenizer->lex(token);
-    if (!isEOD(token))
-    {
-        mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-    }
-}
-
-void DirectiveParser::parseError(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_ERROR);
-
-    std::ostringstream stream;
-    mTokenizer->lex(token);
-    while ((token->type != '\n') && (token->type != Token::LAST))
-    {
-        stream << *token;
-        mTokenizer->lex(token);
-    }
-    mDirectiveHandler->handleError(token->location, stream.str());
-}
-
-// Parses pragma of form: #pragma name[(value)].
-void DirectiveParser::parsePragma(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_PRAGMA);
-
-    enum State
-    {
-        PRAGMA_NAME,
-        LEFT_PAREN,
-        PRAGMA_VALUE,
-        RIGHT_PAREN
-    };
-
-    bool valid = true;
-    std::string name, value;
-    int state = PRAGMA_NAME;
-
-    mTokenizer->lex(token);
-    while ((token->type != '\n') && (token->type != Token::LAST))
-    {
-        switch(state++)
-        {
-          case PRAGMA_NAME:
-            name = token->text;
-            valid = valid && (token->type == Token::IDENTIFIER);
-            break;
-          case LEFT_PAREN:
-            valid = valid && (token->type == '(');
-            break;
-          case PRAGMA_VALUE:
-            value = token->text;
-            valid = valid && (token->type == Token::IDENTIFIER);
-            break;
-          case RIGHT_PAREN:
-            valid = valid && (token->type == ')');
-            break;
-          default:
-            valid = false;
-            break;
-        }
-        mTokenizer->lex(token);
-    }
-
-    valid = valid && ((state == PRAGMA_NAME) ||     // Empty pragma.
-                      (state == LEFT_PAREN) ||      // Without value.
-                      (state == RIGHT_PAREN + 1));  // With value.
-    if (!valid)
-    {
-        mDiagnostics->report(Diagnostics::UNRECOGNIZED_PRAGMA,
-                             token->location, name);
-    }
-    else if (state > PRAGMA_NAME)  // Do not notify for empty pragma.
-    {
-        mDirectiveHandler->handlePragma(token->location, name, value);
-    }
-}
-
-void DirectiveParser::parseExtension(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_EXTENSION);
-
-    enum State
-    {
-        EXT_NAME,
-        COLON,
-        EXT_BEHAVIOR
-    };
-
-    bool valid = true;
-    std::string name, behavior;
-    int state = EXT_NAME;
-
-    mTokenizer->lex(token);
-    while ((token->type != '\n') && (token->type != Token::LAST))
-    {
-        switch (state++)
-        {
-          case EXT_NAME:
-            if (valid && (token->type != Token::IDENTIFIER))
-            {
-                mDiagnostics->report(Diagnostics::INVALID_EXTENSION_NAME,
-                                     token->location, token->text);
-                valid = false;
-            }
-            if (valid) name = token->text;
-            break;
-          case COLON:
-            if (valid && (token->type != ':'))
-            {
-                mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
-                                     token->location, token->text);
-                valid = false;
-            }
-            break;
-          case EXT_BEHAVIOR:
-            if (valid && (token->type != Token::IDENTIFIER))
-            {
-                mDiagnostics->report(Diagnostics::INVALID_EXTENSION_BEHAVIOR,
-                                     token->location, token->text);
-                valid = false;
-            }
-            if (valid) behavior = token->text;
-            break;
-          default:
-            if (valid)
-            {
-                mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
-                                     token->location, token->text);
-                valid = false;
-            }
-            break;
-        }
-        mTokenizer->lex(token);
-    }
-    if (valid && (state != EXT_BEHAVIOR + 1))
-    {
-        mDiagnostics->report(Diagnostics::INVALID_EXTENSION_DIRECTIVE,
-                             token->location, token->text);
-        valid = false;
-    }
-    if (valid)
-        mDirectiveHandler->handleExtension(token->location, name, behavior);
-}
-
-void DirectiveParser::parseVersion(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_VERSION);
-
-    if (mPastFirstStatement)
-    {
-        mDiagnostics->report(Diagnostics::VERSION_NOT_FIRST_STATEMENT,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-        return;
-    }
-
-    enum State
-    {
-        VERSION_NUMBER,
-        VERSION_PROFILE,
-        VERSION_ENDLINE
-    };
-
-    bool valid = true;
-    int version = 0;
-    int state = VERSION_NUMBER;
-
-    mTokenizer->lex(token);
-    while (valid && (token->type != '\n') && (token->type != Token::LAST))
-    {
-        switch (state)
-        {
-          case VERSION_NUMBER:
-            if (token->type != Token::CONST_INT)
-            {
-                mDiagnostics->report(Diagnostics::INVALID_VERSION_NUMBER,
-                                     token->location, token->text);
-                valid = false;
-            }
-            if (valid && !token->iValue(&version))
-            {
-                mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
-                                     token->location, token->text);
-                valid = false;
-            }
-            if (valid)
-            {
-                state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE;
-            }
-            break;
-          case VERSION_PROFILE:
-            if (token->type != Token::IDENTIFIER || token->text != "es")
-            {
-                mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,
-                                     token->location, token->text);
-                valid = false;
-            }
-            state = VERSION_ENDLINE;
-            break;
-          default:
-            mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
-                                 token->location, token->text);
-            valid = false;
-            break;
-        }
-
-        mTokenizer->lex(token);
-    }
-
-    if (valid && (state != VERSION_ENDLINE))
-    {
-        mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,
-                             token->location, token->text);
-        valid = false;
-    }
-
-    if (valid)
-    {
-        mDirectiveHandler->handleVersion(token->location, version);
-    }
-}
-
-void DirectiveParser::parseLine(Token* token)
-{
-    assert(getDirective(token) == DIRECTIVE_LINE);
-
-    enum State
-    {
-        LINE_NUMBER,
-        FILE_NUMBER
-    };
-
-    bool valid = true;
-    int line = 0, file = 0;
-    int state = LINE_NUMBER;
-
-    MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false);
-    macroExpander.lex(token);
-    while ((token->type != '\n') && (token->type != Token::LAST))
-    {
-        switch (state++)
-        {
-          case LINE_NUMBER:
-            if (valid && (token->type != Token::CONST_INT))
-            {
-                mDiagnostics->report(Diagnostics::INVALID_LINE_NUMBER,
-                                     token->location, token->text);
-                valid = false;
-            }
-            if (valid && !token->iValue(&line))
-            {
-                mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
-                                     token->location, token->text);
-                valid = false;
-            }
-            break;
-          case FILE_NUMBER:
-            if (valid && (token->type != Token::CONST_INT))
-            {
-                mDiagnostics->report(Diagnostics::INVALID_FILE_NUMBER,
-                                     token->location, token->text);
-                valid = false;
-            }
-            if (valid && !token->iValue(&file))
-            {
-                mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
-                                     token->location, token->text);
-                valid = false;
-            }
-            break;
-          default:
-            if (valid)
-            {
-                mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
-                                     token->location, token->text);
-                valid = false;
-            }
-            break;
-        }
-        macroExpander.lex(token);
-    }
-
-    if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1))
-    {
-        mDiagnostics->report(Diagnostics::INVALID_LINE_DIRECTIVE,
-                             token->location, token->text);
-        valid = false;
-    }
-    if (valid)
-    {
-        mTokenizer->setLineNumber(line);
-        if (state == FILE_NUMBER + 1) mTokenizer->setFileNumber(file);
-    }
-}
-
-bool DirectiveParser::skipping() const
-{
-    if (mConditionalStack.empty()) return false;
-
-    const ConditionalBlock& block = mConditionalStack.back();
-    return block.skipBlock || block.skipGroup;
-}
-
-void DirectiveParser::parseConditionalIf(Token* token)
-{
-    ConditionalBlock block;
-    block.type = token->text;
-    block.location = token->location;
-
-    if (skipping())
-    {
-        // This conditional block is inside another conditional group
-        // which is skipped. As a consequence this whole block is skipped.
-        // Be careful not to parse the conditional expression that might
-        // emit a diagnostic.
-        skipUntilEOD(mTokenizer, token);
-        block.skipBlock = true;
-    }
-    else
-    {
-        DirectiveType directive = getDirective(token);
-
-        int expression = 0;
-        switch (directive)
-        {
-          case DIRECTIVE_IF:
-            expression = parseExpressionIf(token);
-            break;
-          case DIRECTIVE_IFDEF:
-            expression = parseExpressionIfdef(token);
-            break;
-          case DIRECTIVE_IFNDEF:
-            expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
-            break;
-          default:
-            assert(false);
-            break;
-        }
-        block.skipGroup = expression == 0;
-        block.foundValidGroup = expression != 0;
-    }
-    mConditionalStack.push_back(block);
-}
-
-int DirectiveParser::parseExpressionIf(Token* token)
-{
-    assert((getDirective(token) == DIRECTIVE_IF) ||
-           (getDirective(token) == DIRECTIVE_ELIF));
-
-    MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true);
-    ExpressionParser expressionParser(&macroExpander, mDiagnostics);
-
-    int expression = 0;
-    macroExpander.lex(token);
-    expressionParser.parse(token, &expression);
-
-    // Check if there are tokens after #if expression.
-    if (!isEOD(token))
-    {
-        mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-    }
-
-    return expression;
-}
-
-int DirectiveParser::parseExpressionIfdef(Token* token)
-{
-    assert((getDirective(token) == DIRECTIVE_IFDEF) ||
-           (getDirective(token) == DIRECTIVE_IFNDEF));
-
-    mTokenizer->lex(token);
-    if (token->type != Token::IDENTIFIER)
-    {
-        mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-        return 0;
-    }
-
-    MacroSet::const_iterator iter = mMacroSet->find(token->text);
-    int expression = iter != mMacroSet->end() ? 1 : 0;
-
-    // Check if there are tokens after #ifdef expression.
-    mTokenizer->lex(token);
-    if (!isEOD(token))
-    {
-        mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
-                             token->location, token->text);
-        skipUntilEOD(mTokenizer, token);
-    }
-    return expression;
-}
-
-}  // namespace pp
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "DirectiveParser.h"
+
+#include <cassert>
+#include <cstdlib>
+#include <sstream>
+
+#include "Diagnostics.h"
+#include "DirectiveHandler.h"
+#include "ExpressionParser.h"
+#include "MacroExpander.h"
+#include "Token.h"
+#include "Tokenizer.h"
+
+namespace {
+enum DirectiveType
+{
+	DIRECTIVE_NONE,
+	DIRECTIVE_DEFINE,
+	DIRECTIVE_UNDEF,
+	DIRECTIVE_IF,
+	DIRECTIVE_IFDEF,
+	DIRECTIVE_IFNDEF,
+	DIRECTIVE_ELSE,
+	DIRECTIVE_ELIF,
+	DIRECTIVE_ENDIF,
+	DIRECTIVE_ERROR,
+	DIRECTIVE_PRAGMA,
+	DIRECTIVE_EXTENSION,
+	DIRECTIVE_VERSION,
+	DIRECTIVE_LINE
+};
+}  // namespace
+
+static DirectiveType getDirective(const pp::Token* token)
+{
+	static const std::string kDirectiveDefine("define");
+	static const std::string kDirectiveUndef("undef");
+	static const std::string kDirectiveIf("if");
+	static const std::string kDirectiveIfdef("ifdef");
+	static const std::string kDirectiveIfndef("ifndef");
+	static const std::string kDirectiveElse("else");
+	static const std::string kDirectiveElif("elif");
+	static const std::string kDirectiveEndif("endif");
+	static const std::string kDirectiveError("error");
+	static const std::string kDirectivePragma("pragma");
+	static const std::string kDirectiveExtension("extension");
+	static const std::string kDirectiveVersion("version");
+	static const std::string kDirectiveLine("line");
+
+	if (token->type != pp::Token::IDENTIFIER)
+		return DIRECTIVE_NONE;
+
+	if (token->text == kDirectiveDefine)
+		return DIRECTIVE_DEFINE;
+	else if (token->text == kDirectiveUndef)
+		return DIRECTIVE_UNDEF;
+	else if (token->text == kDirectiveIf)
+		return DIRECTIVE_IF;
+	else if (token->text == kDirectiveIfdef)
+		return DIRECTIVE_IFDEF;
+	else if (token->text == kDirectiveIfndef)
+		return DIRECTIVE_IFNDEF;
+	else if (token->text == kDirectiveElse)
+		return DIRECTIVE_ELSE;
+	else if (token->text == kDirectiveElif)
+		return DIRECTIVE_ELIF;
+	else if (token->text == kDirectiveEndif)
+		return DIRECTIVE_ENDIF;
+	else if (token->text == kDirectiveError)
+		return DIRECTIVE_ERROR;
+	else if (token->text == kDirectivePragma)
+		return DIRECTIVE_PRAGMA;
+	else if (token->text == kDirectiveExtension)
+		return DIRECTIVE_EXTENSION;
+	else if (token->text == kDirectiveVersion)
+		return DIRECTIVE_VERSION;
+	else if (token->text == kDirectiveLine)
+		return DIRECTIVE_LINE;
+
+	return DIRECTIVE_NONE;
+}
+
+static bool isConditionalDirective(DirectiveType directive)
+{
+	switch (directive)
+	{
+	case DIRECTIVE_IF:
+	case DIRECTIVE_IFDEF:
+	case DIRECTIVE_IFNDEF:
+	case DIRECTIVE_ELSE:
+	case DIRECTIVE_ELIF:
+	case DIRECTIVE_ENDIF:
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true if the token represents End Of Directive.
+static bool isEOD(const pp::Token* token)
+{
+	return (token->type == '\n') || (token->type == pp::Token::LAST);
+}
+
+static void skipUntilEOD(pp::Lexer* lexer, pp::Token* token)
+{
+	while(!isEOD(token))
+	{
+		lexer->lex(token);
+	}
+}
+
+static bool isMacroNameReserved(const std::string& name)
+{
+	// Names prefixed with "GL_" are reserved.
+	if (name.substr(0, 3) == "GL_")
+		return true;
+
+	// Names containing two consecutive underscores are reserved.
+	if (name.find("__") != std::string::npos)
+		return true;
+
+	return false;
+}
+
+static bool isMacroPredefined(const std::string& name,
+                              const pp::MacroSet& macroSet)
+{
+	pp::MacroSet::const_iterator iter = macroSet.find(name);
+	return iter != macroSet.end() ? iter->second.predefined : false;
+}
+
+namespace pp
+{
+
+DirectiveParser::DirectiveParser(Tokenizer* tokenizer,
+                                 MacroSet* macroSet,
+                                 Diagnostics* diagnostics,
+                                 DirectiveHandler* directiveHandler) :
+	mPastFirstStatement(false),
+	mTokenizer(tokenizer),
+	mMacroSet(macroSet),
+	mDiagnostics(diagnostics),
+	mDirectiveHandler(directiveHandler)
+{
+}
+
+void DirectiveParser::lex(Token* token)
+{
+	do
+	{
+		mTokenizer->lex(token);
+
+		if (token->type == Token::PP_HASH)
+		{
+			parseDirective(token);
+			mPastFirstStatement = true;
+		}
+
+		if (token->type == Token::LAST)
+		{
+			if (!mConditionalStack.empty())
+			{
+				const ConditionalBlock& block = mConditionalStack.back();
+				mDiagnostics->report(Diagnostics::CONDITIONAL_UNTERMINATED,
+				                     block.location, block.type);
+			}
+			break;
+		}
+
+	} while (skipping() || (token->type == '\n'));
+
+	mPastFirstStatement = true;
+}
+
+void DirectiveParser::parseDirective(Token* token)
+{
+	assert(token->type == Token::PP_HASH);
+
+	mTokenizer->lex(token);
+	if (isEOD(token))
+	{
+		// Empty Directive.
+		return;
+	}
+
+	DirectiveType directive = getDirective(token);
+
+	// While in an excluded conditional block/group,
+	// we only parse conditional directives.
+	if (skipping() && !isConditionalDirective(directive))
+	{
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	switch(directive)
+	{
+	case DIRECTIVE_NONE:
+		mDiagnostics->report(Diagnostics::DIRECTIVE_INVALID_NAME,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		break;
+	case DIRECTIVE_DEFINE:
+		parseDefine(token);
+		break;
+	case DIRECTIVE_UNDEF:
+		parseUndef(token);
+		break;
+	case DIRECTIVE_IF:
+		parseIf(token);
+		break;
+	case DIRECTIVE_IFDEF:
+		parseIfdef(token);
+		break;
+	case DIRECTIVE_IFNDEF:
+		parseIfndef(token);
+		break;
+	case DIRECTIVE_ELSE:
+		parseElse(token);
+		break;
+	case DIRECTIVE_ELIF:
+		parseElif(token);
+		break;
+	case DIRECTIVE_ENDIF:
+		parseEndif(token);
+		break;
+	case DIRECTIVE_ERROR:
+		parseError(token);
+		break;
+	case DIRECTIVE_PRAGMA:
+		parsePragma(token);
+		break;
+	case DIRECTIVE_EXTENSION:
+		parseExtension(token);
+		break;
+	case DIRECTIVE_VERSION:
+		parseVersion(token);
+		break;
+	case DIRECTIVE_LINE:
+		parseLine(token);
+		break;
+	default:
+		assert(false);
+		break;
+	}
+
+	skipUntilEOD(mTokenizer, token);
+	if (token->type == Token::LAST)
+	{
+		mDiagnostics->report(Diagnostics::EOF_IN_DIRECTIVE,
+		                     token->location, token->text);
+	}
+}
+
+void DirectiveParser::parseDefine(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_DEFINE);
+
+	mTokenizer->lex(token);
+	if (token->type != Token::IDENTIFIER)
+	{
+		mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		return;
+	}
+	if (isMacroPredefined(token->text, *mMacroSet))
+	{
+		mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_REDEFINED,
+		                     token->location, token->text);
+		return;
+	}
+	if (isMacroNameReserved(token->text))
+	{
+		mDiagnostics->report(Diagnostics::MACRO_NAME_RESERVED,
+		                     token->location, token->text);
+		return;
+	}
+
+	Macro macro;
+	macro.type = Macro::kTypeObj;
+	macro.name = token->text;
+
+	mTokenizer->lex(token);
+	if (token->type == '(' && !token->hasLeadingSpace())
+	{
+		// Function-like macro. Collect arguments.
+		macro.type = Macro::kTypeFunc;
+		do {
+			mTokenizer->lex(token);
+			if (token->type != Token::IDENTIFIER)
+				break;
+
+			if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end())
+			{
+				mDiagnostics->report(Diagnostics::MACRO_DUPLICATE_PARAMETER_NAMES,
+				                     token->location, token->text);
+				return;
+			}
+
+			macro.parameters.push_back(token->text);
+
+			mTokenizer->lex(token);  // Get ','.
+		} while (token->type == ',');
+
+		if (token->type != ')')
+		{
+			mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+			                     token->location,
+			                     token->text);
+			return;
+		}
+		mTokenizer->lex(token);  // Get ')'.
+	}
+
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		// Reset the token location because it is unnecessary in replacement
+		// list. Resetting it also allows us to reuse Token::equals() to
+		// compare macros.
+		token->location = SourceLocation();
+		macro.replacements.push_back(*token);
+		mTokenizer->lex(token);
+	}
+	if (!macro.replacements.empty())
+	{
+		// Whitespace preceding the replacement list is not considered part of
+		// the replacement list for either form of macro.
+		macro.replacements.front().setHasLeadingSpace(false);
+	}
+
+	// Check for macro redefinition.
+	MacroSet::const_iterator iter = mMacroSet->find(macro.name);
+	if (iter != mMacroSet->end() && !macro.equals(iter->second))
+	{
+		mDiagnostics->report(Diagnostics::MACRO_REDEFINED,
+		                     token->location,
+		                     macro.name);
+		return;
+	}
+	mMacroSet->insert(std::make_pair(macro.name, macro));
+}
+
+void DirectiveParser::parseUndef(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_UNDEF);
+
+	mTokenizer->lex(token);
+	if (token->type != Token::IDENTIFIER)
+	{
+		mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		return;
+	}
+
+	MacroSet::iterator iter = mMacroSet->find(token->text);
+	if (iter != mMacroSet->end())
+	{
+		if (iter->second.predefined)
+		{
+			mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_UNDEFINED,
+			                     token->location, token->text);
+		}
+		else
+		{
+			mMacroSet->erase(iter);
+		}
+	}
+
+	mTokenizer->lex(token);
+}
+
+void DirectiveParser::parseIf(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_IF);
+	parseConditionalIf(token);
+}
+
+void DirectiveParser::parseIfdef(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_IFDEF);
+	parseConditionalIf(token);
+}
+
+void DirectiveParser::parseIfndef(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_IFNDEF);
+	parseConditionalIf(token);
+}
+
+void DirectiveParser::parseElse(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_ELSE);
+
+	if (mConditionalStack.empty())
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_WITHOUT_IF,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	ConditionalBlock& block = mConditionalStack.back();
+	if (block.skipBlock)
+	{
+		// No diagnostics. Just skip the whole line.
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+	if (block.foundElseGroup)
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_AFTER_ELSE,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	block.foundElseGroup = true;
+	block.skipGroup = block.foundValidGroup;
+	block.foundValidGroup = true;
+
+	// Check if there are extra tokens after #else.
+	mTokenizer->lex(token);
+	if (!isEOD(token))
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+	}
+}
+
+void DirectiveParser::parseElif(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_ELIF);
+
+	if (mConditionalStack.empty())
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_WITHOUT_IF,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	ConditionalBlock& block = mConditionalStack.back();
+	if (block.skipBlock)
+	{
+		// No diagnostics. Just skip the whole line.
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+	if (block.foundElseGroup)
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_AFTER_ELSE,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+	if (block.foundValidGroup)
+	{
+		// Do not parse the expression.
+		// Also be careful not to emit a diagnostic.
+		block.skipGroup = true;
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	int expression = parseExpressionIf(token);
+	block.skipGroup = expression == 0;
+	block.foundValidGroup = expression != 0;
+}
+
+void DirectiveParser::parseEndif(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_ENDIF);
+
+	if (mConditionalStack.empty())
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ENDIF_WITHOUT_IF,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	mConditionalStack.pop_back();
+
+	// Check if there are tokens after #endif.
+	mTokenizer->lex(token);
+	if (!isEOD(token))
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+	}
+}
+
+void DirectiveParser::parseError(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_ERROR);
+
+	std::ostringstream stream;
+	mTokenizer->lex(token);
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		stream << *token;
+		mTokenizer->lex(token);
+	}
+	mDirectiveHandler->handleError(token->location, stream.str());
+}
+
+// Parses pragma of form: #pragma name[(value)].
+void DirectiveParser::parsePragma(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_PRAGMA);
+
+	enum State
+	{
+		PRAGMA_NAME,
+		LEFT_PAREN,
+		PRAGMA_VALUE,
+		RIGHT_PAREN
+	};
+
+	bool valid = true;
+	std::string name, value;
+	int state = PRAGMA_NAME;
+
+	mTokenizer->lex(token);
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		switch(state++)
+		{
+		case PRAGMA_NAME:
+			name = token->text;
+			valid = valid && (token->type == Token::IDENTIFIER);
+			break;
+		case LEFT_PAREN:
+			valid = valid && (token->type == '(');
+			break;
+		case PRAGMA_VALUE:
+			value = token->text;
+			valid = valid && (token->type == Token::IDENTIFIER);
+			break;
+		case RIGHT_PAREN:
+			valid = valid && (token->type == ')');
+			break;
+		default:
+			valid = false;
+			break;
+		}
+		mTokenizer->lex(token);
+	}
+
+	valid = valid && ((state == PRAGMA_NAME) ||     // Empty pragma.
+	                  (state == LEFT_PAREN) ||      // Without value.
+	                  (state == RIGHT_PAREN + 1));  // With value.
+	if (!valid)
+	{
+		mDiagnostics->report(Diagnostics::UNRECOGNIZED_PRAGMA,
+		                     token->location, name);
+	}
+	else if (state > PRAGMA_NAME)  // Do not notify for empty pragma.
+	{
+		mDirectiveHandler->handlePragma(token->location, name, value);
+	}
+}
+
+void DirectiveParser::parseExtension(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_EXTENSION);
+
+	enum State
+	{
+		EXT_NAME,
+		COLON,
+		EXT_BEHAVIOR
+	};
+
+	bool valid = true;
+	std::string name, behavior;
+	int state = EXT_NAME;
+
+	mTokenizer->lex(token);
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		switch (state++)
+		{
+		case EXT_NAME:
+			if (valid && (token->type != Token::IDENTIFIER))
+			{
+				mDiagnostics->report(Diagnostics::INVALID_EXTENSION_NAME,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid) name = token->text;
+			break;
+		case COLON:
+			if (valid && (token->type != ':'))
+			{
+				mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		case EXT_BEHAVIOR:
+			if (valid && (token->type != Token::IDENTIFIER))
+			{
+				mDiagnostics->report(Diagnostics::INVALID_EXTENSION_BEHAVIOR,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid) behavior = token->text;
+			break;
+		default:
+			if (valid)
+			{
+				mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		}
+		mTokenizer->lex(token);
+	}
+	if (valid && (state != EXT_BEHAVIOR + 1))
+	{
+		mDiagnostics->report(Diagnostics::INVALID_EXTENSION_DIRECTIVE,
+		                     token->location, token->text);
+		valid = false;
+	}
+	if (valid)
+		mDirectiveHandler->handleExtension(token->location, name, behavior);
+}
+
+void DirectiveParser::parseVersion(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_VERSION);
+
+	if (mPastFirstStatement)
+	{
+		mDiagnostics->report(Diagnostics::VERSION_NOT_FIRST_STATEMENT,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	enum State
+	{
+		VERSION_NUMBER,
+		VERSION_PROFILE,
+		VERSION_ENDLINE
+	};
+
+	bool valid = true;
+	int version = 0;
+	int state = VERSION_NUMBER;
+
+	mTokenizer->lex(token);
+	while (valid && (token->type != '\n') && (token->type != Token::LAST))
+	{
+		switch (state)
+		{
+		case VERSION_NUMBER:
+			if (token->type != Token::CONST_INT)
+			{
+				mDiagnostics->report(Diagnostics::INVALID_VERSION_NUMBER,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid && !token->iValue(&version))
+			{
+				mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid)
+			{
+				state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE;
+			}
+			break;
+		case VERSION_PROFILE:
+			if (token->type != Token::IDENTIFIER || token->text != "es")
+			{
+				mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,
+				                     token->location, token->text);
+				valid = false;
+			}
+			state = VERSION_ENDLINE;
+			break;
+		default:
+			mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+			                     token->location, token->text);
+			valid = false;
+			break;
+		}
+
+		mTokenizer->lex(token);
+	}
+
+	if (valid && (state != VERSION_ENDLINE))
+	{
+		mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,
+		                     token->location, token->text);
+		valid = false;
+	}
+
+	if (valid)
+	{
+		mDirectiveHandler->handleVersion(token->location, version);
+	}
+}
+
+void DirectiveParser::parseLine(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_LINE);
+
+	enum State
+	{
+		LINE_NUMBER,
+		FILE_NUMBER
+	};
+
+	bool valid = true;
+	int line = 0, file = 0;
+	int state = LINE_NUMBER;
+
+	MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false);
+	macroExpander.lex(token);
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		switch (state++)
+		{
+		case LINE_NUMBER:
+			if (valid && (token->type != Token::CONST_INT))
+			{
+				mDiagnostics->report(Diagnostics::INVALID_LINE_NUMBER,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid && !token->iValue(&line))
+			{
+				mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		case FILE_NUMBER:
+			if (valid && (token->type != Token::CONST_INT))
+			{
+				mDiagnostics->report(Diagnostics::INVALID_FILE_NUMBER,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid && !token->iValue(&file))
+			{
+				mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		default:
+			if (valid)
+			{
+				mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		}
+		macroExpander.lex(token);
+	}
+
+	if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1))
+	{
+		mDiagnostics->report(Diagnostics::INVALID_LINE_DIRECTIVE,
+		                     token->location, token->text);
+		valid = false;
+	}
+	if (valid)
+	{
+		mTokenizer->setLineNumber(line);
+		if (state == FILE_NUMBER + 1) mTokenizer->setFileNumber(file);
+	}
+}
+
+bool DirectiveParser::skipping() const
+{
+	if (mConditionalStack.empty()) return false;
+
+	const ConditionalBlock& block = mConditionalStack.back();
+	return block.skipBlock || block.skipGroup;
+}
+
+void DirectiveParser::parseConditionalIf(Token* token)
+{
+	ConditionalBlock block;
+	block.type = token->text;
+	block.location = token->location;
+
+	if (skipping())
+	{
+		// This conditional block is inside another conditional group
+		// which is skipped. As a consequence this whole block is skipped.
+		// Be careful not to parse the conditional expression that might
+		// emit a diagnostic.
+		skipUntilEOD(mTokenizer, token);
+		block.skipBlock = true;
+	}
+	else
+	{
+		DirectiveType directive = getDirective(token);
+
+		int expression = 0;
+		switch (directive)
+		{
+		case DIRECTIVE_IF:
+			expression = parseExpressionIf(token);
+			break;
+		case DIRECTIVE_IFDEF:
+			expression = parseExpressionIfdef(token);
+			break;
+		case DIRECTIVE_IFNDEF:
+			expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
+			break;
+		default:
+			assert(false);
+			break;
+		}
+		block.skipGroup = expression == 0;
+		block.foundValidGroup = expression != 0;
+	}
+	mConditionalStack.push_back(block);
+}
+
+int DirectiveParser::parseExpressionIf(Token* token)
+{
+	assert((getDirective(token) == DIRECTIVE_IF) ||
+	       (getDirective(token) == DIRECTIVE_ELIF));
+
+	MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true);
+	ExpressionParser expressionParser(&macroExpander, mDiagnostics);
+
+	int expression = 0;
+	macroExpander.lex(token);
+	expressionParser.parse(token, &expression);
+
+	// Check if there are tokens after #if expression.
+	if (!isEOD(token))
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+	}
+
+	return expression;
+}
+
+int DirectiveParser::parseExpressionIfdef(Token* token)
+{
+	assert((getDirective(token) == DIRECTIVE_IFDEF) ||
+		   (getDirective(token) == DIRECTIVE_IFNDEF));
+
+	mTokenizer->lex(token);
+	if (token->type != Token::IDENTIFIER)
+	{
+		mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return 0;
+	}
+
+	MacroSet::const_iterator iter = mMacroSet->find(token->text);
+	int expression = iter != mMacroSet->end() ? 1 : 0;
+
+	// Check if there are tokens after #ifdef expression.
+	mTokenizer->lex(token);
+	if (!isEOD(token))
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+	}
+	return expression;
+}
+
+}  // namespace pp
