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; };