Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
3da5a326
Commit
3da5a326
authored
Jun 13, 2013
by
John Kessenich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add semantic checks for nested blocks/structures.
git-svn-id:
https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21960
e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent
fd8e1010
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
56 additions
and
30 deletions
+56
-30
ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.cpp
+28
-14
ParseHelper.h
glslang/MachineIndependent/ParseHelper.h
+6
-1
glslang.y
glslang/MachineIndependent/glslang.y
+22
-15
No files found.
glslang/MachineIndependent/ParseHelper.cpp
View file @
3da5a326
...
@@ -44,7 +44,7 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, int v, E
...
@@ -44,7 +44,7 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, int v, E
bool
fc
,
EShMessages
m
)
:
bool
fc
,
EShMessages
m
)
:
intermediate
(
interm
),
symbolTable
(
symt
),
infoSink
(
is
),
language
(
L
),
treeRoot
(
0
),
intermediate
(
interm
),
symbolTable
(
symt
),
infoSink
(
is
),
language
(
L
),
treeRoot
(
0
),
numErrors
(
0
),
lexAfterType
(
false
),
loopNestingLevel
(
0
),
numErrors
(
0
),
lexAfterType
(
false
),
loopNestingLevel
(
0
),
inTypeParen
(
false
),
structNestingLevel
(
0
),
inTypeParen
(
false
),
version
(
v
),
profile
(
p
),
forwardCompatible
(
fc
),
messages
(
m
),
version
(
v
),
profile
(
p
),
forwardCompatible
(
fc
),
messages
(
m
),
contextPragma
(
true
,
false
)
contextPragma
(
true
,
false
)
{
{
...
@@ -1072,6 +1072,20 @@ void TParseContext::paramCheck(int line, TStorageQualifier qualifier, TType* typ
...
@@ -1072,6 +1072,20 @@ void TParseContext::paramCheck(int line, TStorageQualifier qualifier, TType* typ
}
}
}
}
void
TParseContext
::
nestedBlockCheck
(
int
line
)
{
if
(
structNestingLevel
>
0
)
error
(
line
,
"cannot nest a block definition inside a structure or block"
,
""
,
""
);
++
structNestingLevel
;
}
void
TParseContext
::
nestedStructCheck
(
int
line
)
{
if
(
structNestingLevel
>
0
)
error
(
line
,
"cannot nest a structure definition inside a structure or block"
,
""
,
""
);
++
structNestingLevel
;
}
//
//
// Layout qualifier stuff.
// Layout qualifier stuff.
//
//
...
@@ -1449,26 +1463,26 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ
...
@@ -1449,26 +1463,26 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ
//
//
// Do everything needed to add an interface block.
// Do everything needed to add an interface block.
//
//
void
TParseContext
::
addBlock
(
int
line
,
T
PublicType
&
publicType
,
const
TString
&
blockName
,
T
TypeList
&
typeList
,
const
TString
*
instanceName
,
TArraySizes
arraySizes
)
void
TParseContext
::
addBlock
(
int
line
,
TTypeList
&
typeList
,
const
TString
*
instanceName
,
TArraySizes
arraySizes
)
{
{
// First, error checks
// First, error checks
if
(
reservedErrorCheck
(
line
,
blockName
))
if
(
reservedErrorCheck
(
line
,
*
blockName
))
return
;
return
;
if
(
instanceName
&&
reservedErrorCheck
(
line
,
*
instanceName
))
if
(
instanceName
&&
reservedErrorCheck
(
line
,
*
instanceName
))
return
;
return
;
if
(
public
Type
.
basicType
!=
EbtVoid
)
{
if
(
block
Type
.
basicType
!=
EbtVoid
)
{
error
(
line
,
"interface blocks cannot be declared with a type"
,
blockName
.
c_str
(),
""
);
error
(
line
,
"interface blocks cannot be declared with a type"
,
blockName
->
c_str
(),
""
);
return
;
return
;
}
}
if
(
public
Type
.
qualifier
.
storage
==
EvqUniform
)
{
if
(
block
Type
.
qualifier
.
storage
==
EvqUniform
)
{
requireProfile
(
line
,
(
EProfileMask
)(
~
ENoProfileMask
),
"uniform block"
);
requireProfile
(
line
,
(
EProfileMask
)(
~
ENoProfileMask
),
"uniform block"
);
profileRequires
(
line
,
EEsProfile
,
300
,
0
,
"uniform block"
);
profileRequires
(
line
,
EEsProfile
,
300
,
0
,
"uniform block"
);
}
else
{
}
else
{
error
(
line
,
"only uniform interface blocks are supported"
,
blockName
.
c_str
(),
""
);
error
(
line
,
"only uniform interface blocks are supported"
,
blockName
->
c_str
(),
""
);
return
;
return
;
}
}
...
@@ -1476,9 +1490,9 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
...
@@ -1476,9 +1490,9 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
// check for qualifiers and types that don't belong within a block
// check for qualifiers and types that don't belong within a block
for
(
unsigned
int
member
=
0
;
member
<
typeList
.
size
();
++
member
)
{
for
(
unsigned
int
member
=
0
;
member
<
typeList
.
size
();
++
member
)
{
TQualifier
memberQualifier
=
typeList
[
member
].
type
->
getQualifier
();
TQualifier
memberQualifier
=
typeList
[
member
].
type
->
getQualifier
();
if
(
memberQualifier
.
storage
!=
EvqTemporary
&&
memberQualifier
.
storage
!=
EvqGlobal
&&
memberQualifier
.
storage
!=
public
Type
.
qualifier
.
storage
)
if
(
memberQualifier
.
storage
!=
EvqTemporary
&&
memberQualifier
.
storage
!=
EvqGlobal
&&
memberQualifier
.
storage
!=
block
Type
.
qualifier
.
storage
)
error
(
line
,
"member storage qualifier cannot contradict block storage qualifier"
,
typeList
[
member
].
type
->
getFieldName
().
c_str
(),
""
);
error
(
line
,
"member storage qualifier cannot contradict block storage qualifier"
,
typeList
[
member
].
type
->
getFieldName
().
c_str
(),
""
);
if
(
public
Type
.
qualifier
.
storage
==
EvqUniform
&&
memberQualifier
.
isInterpolation
()
||
memberQualifier
.
isAuxillary
())
if
(
block
Type
.
qualifier
.
storage
==
EvqUniform
&&
memberQualifier
.
isInterpolation
()
||
memberQualifier
.
isAuxillary
())
error
(
line
,
"member of uniform block cannot have an auxillary or interpolation qualifier"
,
typeList
[
member
].
type
->
getFieldName
().
c_str
(),
""
);
error
(
line
,
"member of uniform block cannot have an auxillary or interpolation qualifier"
,
typeList
[
member
].
type
->
getFieldName
().
c_str
(),
""
);
TBasicType
basicType
=
typeList
[
member
].
type
->
getBasicType
();
TBasicType
basicType
=
typeList
[
member
].
type
->
getBasicType
();
...
@@ -1489,7 +1503,7 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
...
@@ -1489,7 +1503,7 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
// Make default block qualification, and adjust the member qualifications
// Make default block qualification, and adjust the member qualifications
TQualifier
defaultQualification
=
defaultGlobalQualification
;
TQualifier
defaultQualification
=
defaultGlobalQualification
;
mergeLayoutQualifiers
(
line
,
defaultQualification
,
public
Type
.
qualifier
);
mergeLayoutQualifiers
(
line
,
defaultQualification
,
block
Type
.
qualifier
);
for
(
unsigned
int
member
=
0
;
member
<
typeList
.
size
();
++
member
)
{
for
(
unsigned
int
member
=
0
;
member
<
typeList
.
size
();
++
member
)
{
TQualifier
memberQualification
=
defaultQualification
;
TQualifier
memberQualification
=
defaultQualification
;
mergeLayoutQualifiers
(
line
,
memberQualification
,
typeList
[
member
].
type
->
getQualifier
());
mergeLayoutQualifiers
(
line
,
memberQualification
,
typeList
[
member
].
type
->
getQualifier
());
...
@@ -1498,13 +1512,13 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
...
@@ -1498,13 +1512,13 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
// Build and add the interface block as a new type named blockName
// Build and add the interface block as a new type named blockName
TType
blockType
(
&
typeList
,
blockName
,
public
Type
.
qualifier
.
storage
);
TType
blockType
(
&
typeList
,
*
blockName
,
block
Type
.
qualifier
.
storage
);
if
(
arraySizes
)
if
(
arraySizes
)
blockType
.
setArraySizes
(
arraySizes
);
blockType
.
setArraySizes
(
arraySizes
);
blockType
.
getQualifier
().
layoutPacking
=
defaultQualification
.
layoutPacking
;
blockType
.
getQualifier
().
layoutPacking
=
defaultQualification
.
layoutPacking
;
TVariable
*
userTypeDef
=
new
TVariable
(
&
blockName
,
blockType
,
true
);
TVariable
*
userTypeDef
=
new
TVariable
(
blockName
,
blockType
,
true
);
if
(
!
symbolTable
.
insert
(
*
userTypeDef
))
{
if
(
!
symbolTable
.
insert
(
*
userTypeDef
))
{
error
(
line
,
"redefinition"
,
blockName
.
c_str
(),
"block name"
);
error
(
line
,
"redefinition"
,
blockName
->
c_str
(),
"block name"
);
return
;
return
;
}
}
...
@@ -1518,7 +1532,7 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
...
@@ -1518,7 +1532,7 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
TVariable
*
variable
=
new
TVariable
(
instanceName
,
blockType
);
TVariable
*
variable
=
new
TVariable
(
instanceName
,
blockType
);
if
(
!
symbolTable
.
insert
(
*
variable
))
{
if
(
!
symbolTable
.
insert
(
*
variable
))
{
if
(
*
instanceName
==
""
)
if
(
*
instanceName
==
""
)
error
(
line
,
"nameless block contains a member that already has a name at global scope"
,
blockName
.
c_str
(),
""
);
error
(
line
,
"nameless block contains a member that already has a name at global scope"
,
blockName
->
c_str
(),
""
);
else
else
error
(
line
,
"block instance name redefinition"
,
variable
->
getName
().
c_str
(),
""
);
error
(
line
,
"block instance name redefinition"
,
variable
->
getName
().
c_str
(),
""
);
...
...
glslang/MachineIndependent/ParseHelper.h
View file @
3da5a326
...
@@ -77,6 +77,7 @@ struct TParseContext {
...
@@ -77,6 +77,7 @@ struct TParseContext {
int
numErrors
;
// number of compile-time errors encountered
int
numErrors
;
// number of compile-time errors encountered
bool
lexAfterType
;
// true if we've recognized a type, so can only be looking for an identifier
bool
lexAfterType
;
// true if we've recognized a type, so can only be looking for an identifier
int
loopNestingLevel
;
// 0 if outside all loops
int
loopNestingLevel
;
// 0 if outside all loops
int
structNestingLevel
;
// 0 if outside blocks and structures
TList
<
TIntermSequence
*>
switchSequenceStack
;
// case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
TList
<
TIntermSequence
*>
switchSequenceStack
;
// case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
bool
inTypeParen
;
// true if in parentheses, looking only for an identifier
bool
inTypeParen
;
// true if in parentheses, looking only for an identifier
const
TType
*
currentFunctionType
;
// the return type of the function that's currently being parsed
const
TType
*
currentFunctionType
;
// the return type of the function that's currently being parsed
...
@@ -93,6 +94,8 @@ struct TParseContext {
...
@@ -93,6 +94,8 @@ struct TParseContext {
TQualifier
defaultGlobalQualification
;
TQualifier
defaultGlobalQualification
;
TString
HashErrMsg
;
TString
HashErrMsg
;
bool
AfterEOF
;
bool
AfterEOF
;
const
TString
*
blockName
;
TPublicType
blockType
;
void
initializeExtensionBehavior
();
void
initializeExtensionBehavior
();
const
char
*
getPreamble
();
const
char
*
getPreamble
();
...
@@ -130,6 +133,8 @@ struct TParseContext {
...
@@ -130,6 +133,8 @@ struct TParseContext {
void
nonInitConstCheck
(
int
line
,
TString
&
identifier
,
TPublicType
&
type
);
void
nonInitConstCheck
(
int
line
,
TString
&
identifier
,
TPublicType
&
type
);
void
nonInitCheck
(
int
line
,
TString
&
identifier
,
TPublicType
&
type
);
void
nonInitCheck
(
int
line
,
TString
&
identifier
,
TPublicType
&
type
);
void
paramCheck
(
int
line
,
TStorageQualifier
qualifier
,
TType
*
type
);
void
paramCheck
(
int
line
,
TStorageQualifier
qualifier
,
TType
*
type
);
void
nestedBlockCheck
(
int
line
);
void
nestedStructCheck
(
int
line
);
void
setLayoutQualifier
(
int
line
,
TPublicType
&
,
TString
&
);
void
setLayoutQualifier
(
int
line
,
TPublicType
&
,
TString
&
);
void
setLayoutQualifier
(
int
line
,
TPublicType
&
,
TString
&
,
int
);
void
setLayoutQualifier
(
int
line
,
TPublicType
&
,
TString
&
,
int
);
...
@@ -141,7 +146,7 @@ struct TParseContext {
...
@@ -141,7 +146,7 @@ struct TParseContext {
TIntermTyped
*
addConstructor
(
TIntermNode
*
,
const
TType
&
,
TOperator
,
TFunction
*
,
TSourceLoc
);
TIntermTyped
*
addConstructor
(
TIntermNode
*
,
const
TType
&
,
TOperator
,
TFunction
*
,
TSourceLoc
);
TIntermTyped
*
constructStruct
(
TIntermNode
*
,
const
TType
&
,
int
,
TSourceLoc
);
TIntermTyped
*
constructStruct
(
TIntermNode
*
,
const
TType
&
,
int
,
TSourceLoc
);
TIntermTyped
*
constructBuiltIn
(
const
TType
&
,
TOperator
,
TIntermNode
*
,
TSourceLoc
,
bool
subset
);
TIntermTyped
*
constructBuiltIn
(
const
TType
&
,
TOperator
,
TIntermNode
*
,
TSourceLoc
,
bool
subset
);
void
addBlock
(
int
line
,
T
PublicType
&
qualifier
,
const
TString
&
blockName
,
T
TypeList
&
typeList
,
const
TString
*
instanceName
=
0
,
TArraySizes
arraySizes
=
0
);
void
addBlock
(
int
line
,
TTypeList
&
typeList
,
const
TString
*
instanceName
=
0
,
TArraySizes
arraySizes
=
0
);
void
wrapupSwitchSubsequence
(
TIntermAggregate
*
statements
,
TIntermNode
*
branchNode
);
void
wrapupSwitchSubsequence
(
TIntermAggregate
*
statements
,
TIntermNode
*
branchNode
);
TIntermNode
*
addSwitch
(
int
line
,
TIntermTyped
*
expression
,
TIntermAggregate
*
body
);
TIntermNode
*
addSwitch
(
int
line
,
TIntermTyped
*
expression
,
TIntermAggregate
*
body
);
void
updateDefaults
(
int
line
,
const
TPublicType
&
,
const
TString
*
id
);
void
updateDefaults
(
int
line
,
const
TPublicType
&
,
const
TString
*
id
);
...
...
glslang/MachineIndependent/glslang.y
View file @
3da5a326
...
@@ -208,6 +208,7 @@ extern void yyerror(const char*);
...
@@ -208,6 +208,7 @@ extern void yyerror(const char*);
%type <interm.type> struct_specifier
%type <interm.type> struct_specifier
%type <interm.typeLine> struct_declarator
%type <interm.typeLine> struct_declarator
%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list type_name_list
%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list type_name_list
%type <interm> block_structure
%type <interm.function> function_header function_declarator
%type <interm.function> function_header function_declarator
%type <interm.function> function_header_with_parameters
%type <interm.function> function_header_with_parameters
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
...
@@ -1102,16 +1103,16 @@ declaration
...
@@ -1102,16 +1103,16 @@ declaration
parseContext.setDefaultPrecision($1.line, $3, $2.qualifier.precision);
parseContext.setDefaultPrecision($1.line, $3, $2.qualifier.precision);
$$ = 0;
$$ = 0;
}
}
|
type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE
SEMICOLON {
|
block_structure
SEMICOLON {
parseContext.addBlock($
2.line, $1, *$2.string, *$4
);
parseContext.addBlock($
1.line, *$1.typeList
);
$$ = 0;
$$ = 0;
}
}
|
type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE
IDENTIFIER SEMICOLON {
|
block_structure
IDENTIFIER SEMICOLON {
parseContext.addBlock($
2.line, $1, *$2.string, *$4, $6
.string);
parseContext.addBlock($
1.line, *$1.typeList, $2
.string);
$$ = 0;
$$ = 0;
}
}
|
type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE
IDENTIFIER array_specifier SEMICOLON {
|
block_structure
IDENTIFIER array_specifier SEMICOLON {
parseContext.addBlock($
2.line, $1, *$2.string, *$4, $6.string, $7
.arraySizes);
parseContext.addBlock($
1.line, *$1.typeList, $2.string, $3
.arraySizes);
$$ = 0;
$$ = 0;
}
}
| type_qualifier SEMICOLON {
| type_qualifier SEMICOLON {
...
@@ -1130,6 +1131,15 @@ declaration
...
@@ -1130,6 +1131,15 @@ declaration
}
}
;
;
block_structure
: type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.line); } struct_declaration_list RIGHT_BRACE {
--parseContext.structNestingLevel;
parseContext.blockName = $2.string;
parseContext.blockType = $1;
$$.line = $1.line;
$$.typeList = $5;
}
identifier_list
identifier_list
: COMMA IDENTIFIER {
: COMMA IDENTIFIER {
}
}
...
@@ -2397,25 +2407,22 @@ precision_qualifier
...
@@ -2397,25 +2407,22 @@ precision_qualifier
;
;
struct_specifier
struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
: STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.line); } struct_declaration_list RIGHT_BRACE {
// TODO: semantics: check for qualifiers that don't belong in a struct
TType* structure = new TType($5, *$2.string);
// TODO: semantics: check that this is not nested inside a block or structure
// parseContext.error($1.line, "cannot nest a block or structure definitions", $1.userDef->getTypeName().c_str(), "");
TType* structure = new TType($4, *$2.string);
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! parseContext.symbolTable.insert(*userTypeDef))
if (! parseContext.symbolTable.insert(*userTypeDef))
parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct");
parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct");
$$.init($1.line);
$$.init($1.line);
$$.basicType = EbtStruct;
$$.basicType = EbtStruct;
$$.userDef = structure;
$$.userDef = structure;
--parseContext.structNestingLevel;
}
}
| STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE {
| STRUCT LEFT_BRACE
{ parseContext.nestedStructCheck($1.line); }
struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($
3
, TString(""));
TType* structure = new TType($
4
, TString(""));
$$.init($1.line);
$$.init($1.line);
$$.basicType = EbtStruct;
$$.basicType = EbtStruct;
$$.userDef = structure;
$$.userDef = structure;
--parseContext.structNestingLevel;
}
}
;
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment