diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-08-09 12:57:37 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-08-10 13:05:04 -0700 |
| commit | a5a436c4783fb75a0d089a6483219c06db91f593 (patch) | |
| tree | 224c16ad374c5ed533a497beeb75753e7ce2d771 /source/slang/slang.cpp | |
| parent | 6e4830f4d74adef0a47c6503d84dc114240fafa3 (diff) | |
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.
Diffstat (limited to 'source/slang/slang.cpp')
| -rw-r--r-- | source/slang/slang.cpp | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 0dcbf44ea..e66884923 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -20,6 +20,9 @@ namespace Slang { Session::Session() { + // Make sure our source manager is initialized + builtinSourceManager.initialize(nullptr); + // Initialize representations of some very basic types: initializeTypes(); @@ -82,6 +85,16 @@ struct IncludeHandlerImpl : IncludeHandler } }; +CompileRequest::CompileRequest(Session* session) + : mSession(session) +{ + setSourceManager(&sourceManagerStorage); + + sourceManager->initialize(session->getBuiltinSourceManager()); +} + +CompileRequest::~CompileRequest() +{} void CompileRequest::parseTranslationUnit( TranslationUnitRequest* translationUnit) @@ -117,12 +130,8 @@ void CompileRequest::parseTranslationUnit( for (auto sourceFile : translationUnit->sourceFiles) { - auto sourceFilePath = sourceFile->path; - String source = sourceFile->content; - auto tokens = preprocessSource( - source, - sourceFilePath, + sourceFile, &mSink, &includeHandler, combinedPreprocessorDefinitions, @@ -132,7 +141,6 @@ void CompileRequest::parseTranslationUnit( translationUnit, tokens, &mSink, - sourceFilePath, languageScope); } } @@ -297,16 +305,21 @@ int CompileRequest::addTranslationUnit(SourceLanguage language, String const&) return (int) result; } +void CompileRequest::addTranslationUnitSourceFile( + int translationUnitIndex, + SourceFile* sourceFile) +{ + translationUnits[translationUnitIndex]->sourceFiles.Add(sourceFile); +} + void CompileRequest::addTranslationUnitSourceString( int translationUnitIndex, String const& path, String const& source) { - RefPtr<SourceFile> sourceFile = new SourceFile(); - sourceFile->path = path; - sourceFile->content = source; + RefPtr<SourceFile> sourceFile = getSourceManager()->allocateSourceFile(path, source); - translationUnits[translationUnitIndex]->sourceFiles.Add(sourceFile); + addTranslationUnitSourceFile(translationUnitIndex, sourceFile); } void CompileRequest::addTranslationUnitSourceFile( @@ -322,7 +335,7 @@ void CompileRequest::addTranslationUnitSourceFile( { // Emit a diagnostic! mSink.diagnose( - CodePosition(0, 0, 0, path), + SourceLoc(), Diagnostics::cannotOpenFile, path); return; @@ -359,7 +372,7 @@ RefPtr<ModuleDecl> CompileRequest::loadModule( String const& name, String const& path, String const& source, - CodePosition const&) + SourceLoc const&) { RefPtr<TranslationUnitRequest> translationUnit = new TranslationUnitRequest(); translationUnit->compileRequest = this; @@ -370,9 +383,7 @@ RefPtr<ModuleDecl> CompileRequest::loadModule( // // TODO: decide which options, if any, should be inherited. - RefPtr<SourceFile> sourceFile = new SourceFile(); - sourceFile->path = path; - sourceFile->content = source; + RefPtr<SourceFile> sourceFile = getSourceManager()->allocateSourceFile(path, source); translationUnit->sourceFiles.Add(sourceFile); @@ -413,7 +424,6 @@ void CompileRequest::handlePoundImport( translationUnit.Ptr(), tokens, &mSink, - path, languageScope); // TODO: handle errors @@ -438,7 +448,7 @@ void CompileRequest::handlePoundImport( RefPtr<ModuleDecl> CompileRequest::findOrImportModule( String const& name, - CodePosition const& loc) + SourceLoc const& loc) { // Have we already loaded a module matching this name? // If so, return it. @@ -470,7 +480,9 @@ RefPtr<ModuleDecl> CompileRequest::findOrImportModule( IncludeHandlerImpl includeHandler; includeHandler.request = this; - String pathIncludedFrom = loc.FileName; + auto expandedLoc = getSourceManager()->expandSourceLoc(loc); + + String pathIncludedFrom = expandedLoc.getSpellingPath(); String foundPath; String foundSource; @@ -508,7 +520,7 @@ RefPtr<ModuleDecl> CompileRequest::findOrImportModule( RefPtr<ModuleDecl> findOrImportModule( CompileRequest* request, String const& name, - CodePosition const& loc) + SourceLoc const& loc) { return request->findOrImportModule(name, loc); } @@ -519,9 +531,12 @@ void Session::addBuiltinSource( String const& source) { RefPtr<CompileRequest> compileRequest = new CompileRequest(this); + compileRequest->setSourceManager(getBuiltinSourceManager()); auto translationUnitIndex = compileRequest->addTranslationUnit(SourceLanguage::Slang, path); + RefPtr<SourceFile> sourceFile = builtinSourceManager.allocateSourceFile(path, source); + compileRequest->addTranslationUnitSourceString( translationUnitIndex, path, @@ -818,7 +833,7 @@ SLANG_API int spCompile( } catch (...) { - req->mSink.diagnose(Slang::CodePosition(), Slang::Diagnostics::compilationAborted); + req->mSink.diagnose(Slang::SourceLoc(), Slang::Diagnostics::compilationAborted); return 1; } } |
