summaryrefslogtreecommitdiffstats
path: root/source/slang/preprocessor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/preprocessor.cpp')
-rw-r--r--source/slang/preprocessor.cpp166
1 files changed, 49 insertions, 117 deletions
diff --git a/source/slang/preprocessor.cpp b/source/slang/preprocessor.cpp
index c6c438ef6..103db7dcb 100644
--- a/source/slang/preprocessor.cpp
+++ b/source/slang/preprocessor.cpp
@@ -194,27 +194,18 @@ struct Preprocessor
// represent end-of-input situations.
Token endOfFileToken;
- // The translation unit that is being parsed
- TranslationUnitRequest* translationUnit;
+ /// The linkage the provides the context for preprocessing
+ Linkage* linkage = nullptr;
+
+ /// The module, if any, that the preprocessed result will belong to
+ Module* parentModule = nullptr;
// The unique identities of any paths that have issued `#pragma once` directives to
// stop them from being included again.
HashSet<String> pragmaOnceUniqueIdentities;
- TranslationUnitRequest* getTranslationUnit()
- {
- return translationUnit;
- }
-
- ModuleDecl* getSyntax()
- {
- return getTranslationUnit()->SyntaxNode.Ptr();
- }
-
- CompileRequest* getCompileRequest()
- {
- return getTranslationUnit()->compileRequest;
- }
+ NamePool* getNamePool() { return linkage->getNamePool(); }
+ SourceManager* getSourceManager() { return linkage->getSourceManager(); }
};
// Convenience routine to access the diagnostic sink
@@ -255,11 +246,6 @@ static void destroyInputStream(Preprocessor* /*preprocessor*/, PreprocessorInput
delete inputStream;
}
-static NamePool* getNamePool(Preprocessor* preprocessor)
-{
- return preprocessor->translationUnit->compileRequest->getNamePool();
-}
-
// Create an input stream to represent a pre-tokenized input file.
// TODO(tfoley): pre-tokenizing files isn't going to work in the long run.
static PreprocessorInputStream* CreateInputStreamForSource(
@@ -272,7 +258,7 @@ static PreprocessorInputStream* CreateInputStreamForSource(
initializePrimaryInputStream(preprocessor, inputStream);
// initialize the embedded lexer so that it can generate a token stream
- inputStream->lexer.initialize(sourceView, GetSink(preprocessor), getNamePool(preprocessor), memoryArena);
+ inputStream->lexer.initialize(sourceView, GetSink(preprocessor), preprocessor->getNamePool(), memoryArena);
inputStream->token = inputStream->lexer.lexToken();
return inputStream;
@@ -836,7 +822,7 @@ top:
// Now re-lex the input
- SourceManager* sourceManager = preprocessor->getCompileRequest()->getSourceManager();
+ SourceManager* sourceManager = preprocessor->getSourceManager();
// We create a dummy file to represent the token-paste operation
PathInfo pathInfo = PathInfo::makeTokenPaste();
@@ -845,7 +831,7 @@ top:
SourceView* sourceView = sourceManager->createSourceView(sourceFile, nullptr);
Lexer lexer;
- lexer.initialize(sourceView, GetSink(preprocessor), getNamePool(preprocessor), sourceManager->getMemoryArena());
+ lexer.initialize(sourceView, GetSink(preprocessor), preprocessor->getNamePool(), sourceManager->getMemoryArena());
SimpleTokenInputStream* inputStream = new SimpleTokenInputStream();
initializeInputStream(preprocessor, inputStream);
@@ -1564,7 +1550,7 @@ static void HandleEndIfDirective(PreprocessorDirectiveContext* context)
// we expect it.
//
// Most directives do not need to call this directly, since we have
-// a catch-all case in the main `HandleDirective()` funciton.
+// a catch-all case in the main `HandleDirective()` function.
// The `#include` case will call it directly to avoid complications
// when it switches the input stream.
static void expectEndOfDirective(PreprocessorDirectiveContext* context)
@@ -1589,6 +1575,31 @@ static void expectEndOfDirective(PreprocessorDirectiveContext* context)
AdvanceRawToken(context->preprocessor);
}
+ /// Read a file in the context of handling a preprocessor directive
+static SlangResult readFile(
+ PreprocessorDirectiveContext* context,
+ String const& path,
+ ISlangBlob** outBlob)
+{
+ // The actual file loading will be handled by the file system
+ // associated with the parent linkage.
+ //
+ auto linkage = context->preprocessor->linkage;
+ auto fileSystemExt = linkage->getFileSystemExt();
+ SLANG_RETURN_ON_FAIL(fileSystemExt->loadFile(path.Buffer(), outBlob));
+
+ // If we are running the preprocessor as part of compiling a
+ // specific module, then we must keep track of the file we've
+ // read as yet another file that the module will depend on.
+ //
+ if(auto module = context->preprocessor->parentModule)
+ {
+ module->addFilePathDependency(path);
+ }
+
+ return SLANG_OK;
+}
+
// Handle a `#include` directive
static void HandleIncludeDirective(PreprocessorDirectiveContext* context)
{
@@ -1603,7 +1614,7 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context)
auto directiveLoc = GetDirectiveLoc(context);
- PathInfo includedFromPathInfo = context->preprocessor->translationUnit->compileRequest->getSourceManager()->getPathInfo(directiveLoc, SourceLocType::Actual);
+ PathInfo includedFromPathInfo = context->preprocessor->getSourceManager()->getPathInfo(directiveLoc, SourceLocType::Actual);
IncludeHandler* includeHandler = context->preprocessor->includeHandler;
if (!includeHandler)
@@ -1644,7 +1655,7 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context)
// Push the new file onto our stack of input streams
// TODO(tfoley): check if we have made our include stack too deep
- auto sourceManager = context->preprocessor->getCompileRequest()->getSourceManager();
+ auto sourceManager = context->preprocessor->getSourceManager();
// See if this an already loaded source file
SourceFile* sourceFile = sourceManager->findSourceFileRecursively(filePathInfo.uniqueIdentity);
@@ -1652,7 +1663,7 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context)
if (!sourceFile)
{
ComPtr<ISlangBlob> foundSourceBlob;
- if (SLANG_FAILED(includeHandler->readFile(filePathInfo.foundPath, foundSourceBlob.writeRef())))
+ if (SLANG_FAILED(readFile(context, filePathInfo.foundPath, foundSourceBlob.writeRef())))
{
GetSink(context)->diagnose(pathToken.loc, Diagnostics::includeFailed, path);
return;
@@ -1843,7 +1854,7 @@ static void HandleLineDirective(PreprocessorDirectiveContext* context)
return;
}
- auto sourceManager = context->preprocessor->translationUnit->compileRequest->getSourceManager();
+ auto sourceManager = context->preprocessor->getSourceManager();
String file;
if (PeekTokenType(context) == TokenType::EndOfDirective)
@@ -1891,7 +1902,7 @@ SLANG_PRAGMA_DIRECTIVE_CALLBACK(handlePragmaOnceDirective)
// We are using the 'uniqueIdentity' as determined by the ISlangFileSystemEx interface to determine file identities.
auto directiveLoc = GetDirectiveLoc(context);
- auto issuedFromPathInfo = context->preprocessor->translationUnit->compileRequest->getSourceManager()->getPathInfo(directiveLoc, SourceLocType::Actual);
+ auto issuedFromPathInfo = context->preprocessor->getSourceManager()->getPathInfo(directiveLoc, SourceLocType::Actual);
// Must have uniqueIdentity for a #pragma once to work
if (!issuedFromPathInfo.hasUniqueIdentity())
@@ -1962,82 +1973,6 @@ static void HandlePragmaDirective(PreprocessorDirectiveContext* context)
(subDirective->callback)(context, subDirectiveToken);
}
-// Handle a `#version` directive
-static void handleGLSLVersionDirective(PreprocessorDirectiveContext* context)
-{
- Token versionNumberToken;
- if(!ExpectRaw(
- context,
- TokenType::IntegerLiteral,
- Diagnostics::expectedTokenInPreprocessorDirective,
- &versionNumberToken))
- {
- return;
- }
-
- Token glslProfileToken;
- if(PeekTokenType(context) == TokenType::Identifier)
- {
- glslProfileToken = AdvanceToken(context);
- }
-
- // Need to construct a representation taht we can hook into our compilation result
-
- auto modifier = new GLSLVersionDirective();
- modifier->versionNumberToken = versionNumberToken;
- modifier->glslProfileToken = glslProfileToken;
-
- // Attach the modifier to the program we are parsing!
-
- addModifier(
- context->preprocessor->getSyntax(),
- modifier);
-}
-
-// Handle a `#extension` directive, e.g.,
-//
-// #extension some_extension_name : enable
-//
-static void handleGLSLExtensionDirective(PreprocessorDirectiveContext* context)
-{
- Token extensionNameToken;
- if(!ExpectRaw(
- context,
- TokenType::Identifier,
- Diagnostics::expectedTokenInPreprocessorDirective,
- &extensionNameToken))
- {
- return;
- }
-
- if( !ExpectRaw(context, TokenType::Colon, Diagnostics::expectedTokenInPreprocessorDirective) )
- {
- return;
- }
-
- Token dispositionToken;
- if(!ExpectRaw(
- context,
- TokenType::Identifier,
- Diagnostics::expectedTokenInPreprocessorDirective,
- &dispositionToken))
- {
- return;
- }
-
- // Need to construct a representation taht we can hook into our compilation result
-
- auto modifier = new GLSLExtensionDirective();
- modifier->extensionNameToken = extensionNameToken;
- modifier->dispositionToken = dispositionToken;
-
- // Attach the modifier to the program we are parsing!
-
- addModifier(
- context->preprocessor->getSyntax(),
- modifier);
-}
-
// Handle an invalid directive
static void HandleInvalidDirective(PreprocessorDirectiveContext* context)
{
@@ -2092,11 +2027,6 @@ static const PreprocessorDirective kDirectives[] =
{ "line", &HandleLineDirective, 0 },
{ "pragma", &HandlePragmaDirective, 0 },
- // TODO(tfoley): These are specific to GLSL, and probably
- // shouldn't be enabled for HLSL or Slang
- { "version", &handleGLSLVersionDirective, 0 },
- { "extension", &handleGLSLExtensionDirective, 0 },
-
{ nullptr, nullptr, 0 },
};
@@ -2270,7 +2200,7 @@ static void DefineMacro(
PreprocessorMacro* macro = CreateMacro(preprocessor);
- auto sourceManager = preprocessor->translationUnit->compileRequest->getSourceManager();
+ auto sourceManager = preprocessor->getSourceManager();
SourceFile* keyFile = sourceManager->createSourceFileWithString(pathInfo, key);
SourceFile* valueFile = sourceManager->createSourceFileWithString(pathInfo, value);
@@ -2280,10 +2210,10 @@ static void DefineMacro(
// Use existing `Lexer` to generate a token stream.
Lexer lexer;
- lexer.initialize(valueView, GetSink(preprocessor), getNamePool(preprocessor), sourceManager->getMemoryArena());
+ lexer.initialize(valueView, GetSink(preprocessor), preprocessor->getNamePool(), sourceManager->getMemoryArena());
macro->tokens = lexer.lexAllTokens();
- Name* keyName = preprocessor->translationUnit->compileRequest->getNamePool()->getName(key);
+ Name* keyName = preprocessor->getNamePool()->getName(key);
macro->nameAndLoc.name = keyName;
macro->nameAndLoc.loc = keyView->getRange().begin;
@@ -2321,11 +2251,13 @@ TokenList preprocessSource(
DiagnosticSink* sink,
IncludeHandler* includeHandler,
Dictionary<String, String> defines,
- TranslationUnitRequest* translationUnit)
+ Linkage* linkage,
+ Module* parentModule)
{
Preprocessor preprocessor;
InitializePreprocessor(&preprocessor, sink);
- preprocessor.translationUnit = translationUnit;
+ preprocessor.linkage = linkage;
+ preprocessor.parentModule = parentModule;
preprocessor.includeHandler = includeHandler;
for (auto p : defines)
@@ -2333,7 +2265,7 @@ TokenList preprocessSource(
DefineMacro(&preprocessor, p.Key, p.Value);
}
- SourceManager* sourceManager = translationUnit->compileRequest->getSourceManager();
+ SourceManager* sourceManager = linkage->getSourceManager();
SourceView* sourceView = sourceManager->createSourceView(file, nullptr);