From a5a436c4783fb75a0d089a6483219c06db91f593 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 9 Aug 2017 12:57:37 -0700 Subject: Make source location lightweight Fixes #24 So far the code has used a representation for source locations that is heavy-weight, but typical of research or hobby compilers: a `struct` type containing a line number and a (heap-allocated) string. This is actually very convenient for debugging, but it means that any data structure that might contain a source location needs careful memory management (because of those strings) and has a tendency to bloat. The new represnetation is that a source location is just a pointer-sized integer. In the simplest mental model, you can think of this as just counting every byte of source text that is passed in, and using those to name locations. Finding the path and line number that corresponds to a location involves a lookup step, but we can arrange to store all the files in an array sorted by their start locations, and do a binary search. Finding line numbers inside a file is similarly fast (one you pay a one-time cost to build an array of starting offsets for lines). More advanced compilers like clang actually go further and create a unique range of source locations to represent a file each time it gets included, so that they can track the include stack and reproduce it in diagnostic messages. I'm not doing anything that clever here. --- source/slang/parser.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'source/slang/parser.cpp') diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index 41a4411d2..cc6a0dd6f 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -41,7 +41,6 @@ namespace Slang TokenReader tokenReader; DiagnosticSink * sink; - String fileName; int genericDepth = 0; // Have we seen any `import` declarations? If so, we need @@ -73,11 +72,9 @@ namespace Slang Parser( TokenSpan const& _tokens, DiagnosticSink * sink, - String _fileName, RefPtr const& outerScope) : tokenReader(_tokens) , sink(sink) - , fileName(_fileName) , outerScope(outerScope) {} @@ -614,7 +611,7 @@ namespace Slang RefPtr* modifierLink = &modifiers.first; for (;;) { - CodePosition loc = parser->tokenReader.PeekLoc(); + SourceLoc loc = parser->tokenReader.PeekLoc(); if (0) {} @@ -1003,7 +1000,7 @@ namespace Slang struct PointerDeclarator : Declarator { // location of the `*` token - CodePosition starLoc; + SourceLoc starLoc; RefPtr inner; }; @@ -1014,7 +1011,7 @@ namespace Slang RefPtr inner; // location of the `[` token - CodePosition openBracketLoc; + SourceLoc openBracketLoc; // The expression that yields the element count, or NULL RefPtr elementCountExpr; @@ -1377,7 +1374,7 @@ namespace Slang // Either a single declaration, or a group of them struct DeclGroupBuilder { - CodePosition startPosition; + SourceLoc startPosition; RefPtr decl; RefPtr group; @@ -1546,7 +1543,7 @@ namespace Slang Parser* parser, ContainerDecl* containerDecl) { - CodePosition startPosition = parser->tokenReader.PeekLoc(); + SourceLoc startPosition = parser->tokenReader.PeekLoc(); auto typeSpec = parseTypeSpec(parser); @@ -1780,7 +1777,7 @@ namespace Slang // We first look at the declaration keywrod to determine // the type of buffer to declare: String bufferWrapperTypeName; - CodePosition bufferWrapperTypeNamePos = parser->tokenReader.PeekLoc(); + SourceLoc bufferWrapperTypeNamePos = parser->tokenReader.PeekLoc(); if (AdvanceIf(parser, "cbuffer")) { bufferWrapperTypeName = "ConstantBuffer"; @@ -1914,7 +1911,7 @@ namespace Slang // will see through it to the members inside. - CodePosition pos = parser->tokenReader.PeekLoc(); + SourceLoc pos = parser->tokenReader.PeekLoc(); // The initial name before the `{` is only supposed // to be made visible to reflection @@ -2446,7 +2443,7 @@ namespace Slang } PushScope(program); - program->Position = CodePosition(0, 0, 0, fileName); + program->Position = tokenReader.PeekLoc(); ParseDeclBody(this, program, TokenType::EndOfFile); PopScope(); @@ -3853,10 +3850,9 @@ namespace Slang TranslationUnitRequest* translationUnit, TokenSpan const& tokens, DiagnosticSink* sink, - String const& fileName, RefPtr const& outerScope) { - Parser parser(tokens, sink, fileName, outerScope); + Parser parser(tokens, sink, outerScope); parser.translationUnit = translationUnit; -- cgit v1.2.3