Use extension framework to enable #include directive.
This patch introduces a new extension, GL_GOOGLE_include_directive, to enable support #include directives. It depends on the extension GL_GOOGLE_cpp_style_line_directive.
This commit is contained in:
parent
7be4b8282d
commit
9c1280b225
11 changed files with 51 additions and 13 deletions
13
Test/baseResults/preprocessor.include.disabled.vert.err
Normal file
13
Test/baseResults/preprocessor.include.disabled.vert.err
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
ERROR: 0:8000: '#include' : required extension not requested: GL_GOOGLE_include_directive
|
||||||
|
ERROR: 0:8000: '#include' : must be followed by a file designation
|
||||||
|
ERROR: 0:8001: '#include' : required extension not requested: GL_GOOGLE_include_directive
|
||||||
|
ERROR: 0:8001: '#include' : must be followed by a file designation
|
||||||
|
ERROR: 0:8002: '#include' : required extension not requested: GL_GOOGLE_include_directive
|
||||||
|
ERROR: 0:8002: '#error' : unexpected include directive
|
||||||
|
ERROR: 0:8003: '#include' : required extension not requested: GL_GOOGLE_include_directive
|
||||||
|
ERROR: 0:8003: '#include' : extra content after file designation
|
||||||
|
ERROR: 0:8004: '#include' : required extension not requested: GL_GOOGLE_include_directive
|
||||||
|
ERROR: 0:8004: '#error' : unexpected include directive
|
||||||
|
ERROR: 10 compilation errors. No code generated.
|
||||||
|
|
||||||
|
|
||||||
0
Test/baseResults/preprocessor.include.enabled.vert.out
Normal file
0
Test/baseResults/preprocessor.include.enabled.vert.out
Normal file
|
|
@ -4,3 +4,4 @@
|
||||||
#include "foo"
|
#include "foo"
|
||||||
#include "foo" garbage
|
#include "foo" garbage
|
||||||
#include "no-eol"
|
#include "no-eol"
|
||||||
|
|
||||||
7
Test/preprocessor.include.enabled.vert
Normal file
7
Test/preprocessor.include.enabled.vert
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#line 8000
|
||||||
|
#include
|
||||||
|
#include 123
|
||||||
|
#include "foo"
|
||||||
|
#include "foo" garbage
|
||||||
|
#include "no-eol"
|
||||||
|
|
@ -4,7 +4,8 @@ preprocessor.edge_cases.vert
|
||||||
preprocessor.errors.vert
|
preprocessor.errors.vert
|
||||||
preprocessor.extensions.vert
|
preprocessor.extensions.vert
|
||||||
preprocessor.function_macro.vert
|
preprocessor.function_macro.vert
|
||||||
preprocessor.include.vert
|
preprocessor.include.enabled.vert
|
||||||
|
preprocessor.include.disabled.vert
|
||||||
preprocessor.line.vert
|
preprocessor.line.vert
|
||||||
preprocessor.line.frag
|
preprocessor.line.frag
|
||||||
preprocessor.pragma.vert
|
preprocessor.pragma.vert
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ public:
|
||||||
void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
|
void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
|
||||||
void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
||||||
void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
|
void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
|
||||||
void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc, bool requiredByPreprocessor = false);
|
||||||
TExtensionBehavior getExtensionBehavior(const char*);
|
TExtensionBehavior getExtensionBehavior(const char*);
|
||||||
bool extensionTurnedOn(const char* const extension);
|
bool extensionTurnedOn(const char* const extension);
|
||||||
bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
|
bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,9 @@ void TParseContext::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable;
|
extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable;
|
||||||
// extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members
|
// extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members
|
||||||
|
|
||||||
|
// #line and #include
|
||||||
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisablePartial;
|
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisablePartial;
|
||||||
|
|
@ -219,7 +221,9 @@ const char* TParseContext::getPreamble()
|
||||||
"#define GL_OES_EGL_image_external 1\n"
|
"#define GL_OES_EGL_image_external 1\n"
|
||||||
"#define GL_EXT_shader_texture_lod 1\n"
|
"#define GL_EXT_shader_texture_lod 1\n"
|
||||||
|
|
||||||
|
// #line and #include
|
||||||
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
|
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
|
||||||
|
"#define GL_GOOGLE_include_directive 1\n"
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
"#define GL_ANDROID_extension_pack_es31a 1\n"
|
"#define GL_ANDROID_extension_pack_es31a 1\n"
|
||||||
|
|
@ -270,6 +274,7 @@ const char* TParseContext::getPreamble()
|
||||||
"#define GL_ARB_viewport_array 1\n"
|
"#define GL_ARB_viewport_array 1\n"
|
||||||
|
|
||||||
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
|
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
|
||||||
|
"#define GL_GOOGLE_include_directive 1\n"
|
||||||
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
|
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
@ -410,7 +415,7 @@ void TParseContext::requireNotRemoved(const TSourceLoc& loc, int profileMask, in
|
||||||
// Use when there are no profile/version to check, it's just an error if one of the
|
// Use when there are no profile/version to check, it's just an error if one of the
|
||||||
// extensions is not present.
|
// extensions is not present.
|
||||||
//
|
//
|
||||||
void TParseContext::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
void TParseContext::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc, bool requiredByPreprocessor)
|
||||||
{
|
{
|
||||||
// First, see if any of the extensions are enabled
|
// First, see if any of the extensions are enabled
|
||||||
for (int i = 0; i < numExtensions; ++i) {
|
for (int i = 0; i < numExtensions; ++i) {
|
||||||
|
|
@ -437,8 +442,14 @@ void TParseContext::requireExtensions(const TSourceLoc& loc, int numExtensions,
|
||||||
|
|
||||||
// If we get this far, give errors explaining what extensions are needed
|
// If we get this far, give errors explaining what extensions are needed
|
||||||
if (numExtensions == 1)
|
if (numExtensions == 1)
|
||||||
|
if (requiredByPreprocessor)
|
||||||
|
ppError(loc, "required extension not requested:", featureDesc, extensions[0]);
|
||||||
|
else
|
||||||
error(loc, "required extension not requested:", featureDesc, extensions[0]);
|
error(loc, "required extension not requested:", featureDesc, extensions[0]);
|
||||||
else {
|
else {
|
||||||
|
if (requiredByPreprocessor)
|
||||||
|
ppError(loc, "required extension not requested:", featureDesc, "Possible extensions include:");
|
||||||
|
else
|
||||||
error(loc, "required extension not requested:", featureDesc, "Possible extensions include:");
|
error(loc, "required extension not requested:", featureDesc, "Possible extensions include:");
|
||||||
for (int i = 0; i < numExtensions; ++i)
|
for (int i = 0; i < numExtensions; ++i)
|
||||||
infoSink.info.message(EPrefixNone, extensions[i]);
|
infoSink.info.message(EPrefixNone, extensions[i]);
|
||||||
|
|
@ -525,6 +536,8 @@ void TParseContext::updateExtensionBehavior(int line, const char* extension, con
|
||||||
updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString);
|
updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString);
|
||||||
else if (strcmp(extension, "GL_OES_tessellation_shader") == 0)
|
else if (strcmp(extension, "GL_OES_tessellation_shader") == 0)
|
||||||
updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString);
|
updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseContext::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
void TParseContext::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,9 @@ const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture
|
||||||
const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array";
|
const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array";
|
||||||
//const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
|
//const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
|
||||||
|
|
||||||
|
// #line and #include
|
||||||
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
||||||
|
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
|
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
|
||||||
|
|
|
||||||
|
|
@ -661,7 +661,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
||||||
|
|
||||||
if (token != '\n') {
|
if (token != '\n') {
|
||||||
if (token == PpAtomConstString) {
|
if (token == PpAtomConstString) {
|
||||||
parseContext.requireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line");
|
parseContext.requireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line", true);
|
||||||
// We need to save a copy of the string instead of pointing
|
// We need to save a copy of the string instead of pointing
|
||||||
// to the name field of the token since the name field
|
// to the name field of the token since the name field
|
||||||
// will likely be overwritten by the next token scan.
|
// will likely be overwritten by the next token scan.
|
||||||
|
|
@ -878,6 +878,7 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
||||||
token = CPPifdef(0, ppToken);
|
token = CPPifdef(0, ppToken);
|
||||||
break;
|
break;
|
||||||
case PpAtomInclude:
|
case PpAtomInclude:
|
||||||
|
parseContext.requireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include", true);
|
||||||
token = CPPinclude(ppToken);
|
token = CPPinclude(ppToken);
|
||||||
break;
|
break;
|
||||||
case PpAtomLine:
|
case PpAtomLine:
|
||||||
|
|
@ -1002,7 +1003,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
|
||||||
|
|
||||||
case PpAtomFileMacro: {
|
case PpAtomFileMacro: {
|
||||||
if (const char* current_file = parseContext.getCurrentLoc().name) {
|
if (const char* current_file = parseContext.getCurrentLoc().name) {
|
||||||
parseContext.requireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__");
|
parseContext.requireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__", true);
|
||||||
sprintf(ppToken->name, "\"%s\"", current_file);
|
sprintf(ppToken->name, "\"%s\"", current_file);
|
||||||
} else {
|
} else {
|
||||||
ppToken->ival = parseContext.getCurrentLoc().string;
|
ppToken->ival = parseContext.getCurrentLoc().string;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue