From 2b4ebbb1e1882821f0c552776e4110649b0ddc25 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Sun, 5 Jul 2015 16:50:21 -0400 Subject: [PATCH] Update scanner in TParseContext when changing the input stream. After parsing a #include directive, we push a TokenizableString which contains the content of the included file into the input stack. Henceforth, tokens will be read from the newly pushed TokenizableString. However, the scanner in TParseContext still points to the previous input stream. We need to update the scanner to point to the new input stream inside TokenizableString. Thus, the setCurrent{String|Line|..} method in TParseContext updates the status of the correct input stream. After finishing the newly pushed TokenizableString, we need to restore the scanner to the previous input stream. --- glslang/MachineIndependent/ParseHelper.h | 1 + .../MachineIndependent/preprocessor/Pp.cpp | 2 +- .../preprocessor/PpContext.h | 25 +++++++++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index e537ec62..83d0d563 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -218,6 +218,7 @@ public: void setCurrentSourceName(const char* name) { currentScanner->setFile(name); } void setCurrentString(int string) { currentScanner->setString(string); } void setScanner(TInputScanner* scanner) { currentScanner = scanner; } + TInputScanner* getScanner() const { return currentScanner; } bool lineDirectiveShouldSetNextLine() const; diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index c17004b6..8e58a8c2 100644 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -615,7 +615,7 @@ int TPpContext::CPPinclude(TPpToken* ppToken) bool success; std::tie(success, replacement) = includer.include(name); if (success) { - pushInput(new TokenizableString(replacement, this)); + pushInput(new TokenizableString(directiveLoc, replacement, this)); // At EOF, there's no "current" location anymore. if (token != EndOfInput) parseContext.setCurrentColumn(0); // Don't accidentally return EndOfInput, which will end all preprocessing. diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h index 82564ebc..5d06e701 100644 --- a/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/glslang/MachineIndependent/preprocessor/PpContext.h @@ -134,6 +134,10 @@ public: virtual int getch() = 0; virtual void ungetch() = 0; + // Will be called when we start reading tokens from this instance + virtual void notifyActivated() {} + // Will be called when we do not read tokens from this instance anymore + virtual void notifyDeleted() {} protected: bool done; TPpContext* pp; @@ -144,9 +148,11 @@ public: void pushInput(tInput* in) { inputStack.push_back(in); + in->notifyActivated(); } void popInput() { + inputStack.back()->notifyDeleted(); delete inputStack.back(); inputStack.pop_back(); } @@ -426,19 +432,31 @@ protected: class TokenizableString : public tInput { public: // Copies str, which must be non-empty. - TokenizableString(const std::string& str, TPpContext* pp) + TokenizableString(const TSourceLoc& startLoc, const std::string& str, TPpContext* pp) : tInput(pp), str_(str), strings(str_.data()), length(str_.size()), scanner(1, &strings, &length), - stringInput(pp, scanner) {} + prevScanner(nullptr), + stringInput(pp, scanner) { + scanner.setLine(startLoc.line); + scanner.setString(startLoc.string); + scanner.setFile(startLoc.name); + } // tInput methods: int scan(TPpToken* t) override { return stringInput.scan(t); } int getch() override { return stringInput.getch(); } void ungetch() override { stringInput.ungetch(); } + void notifyActivated() override + { + prevScanner = pp->parseContext.getScanner(); + pp->parseContext.setScanner(&scanner); + } + void notifyDeleted() override { pp->parseContext.setScanner(prevScanner); } + private: // Stores the titular string. const std::string str_; @@ -448,6 +466,9 @@ protected: size_t length; // Scans over str_. TInputScanner scanner; + // The previous effective scanner before the scanner in this instance + // has been activated. + TInputScanner* prevScanner; // Delegate object implementing the tInput interface. tStringInput stringInput; };