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
58d6905e
Unverified
Commit
58d6905e
authored
Feb 19, 2019
by
John Kessenich
Committed by
GitHub
Feb 19, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1700 from KhronosGroup/fix-pp
PP: Remove sub-tokens in macro recording and record spaces correctly.
parents
bce1f510
6225dd4b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
89 additions
and
172 deletions
+89
-172
Pp.cpp
glslang/MachineIndependent/preprocessor/Pp.cpp
+25
-11
PpContext.h
glslang/MachineIndependent/preprocessor/PpContext.h
+33
-9
PpTokens.cpp
glslang/MachineIndependent/preprocessor/PpTokens.cpp
+31
-152
No files found.
glslang/MachineIndependent/preprocessor/Pp.cpp
View file @
58d6905e
...
...
@@ -166,29 +166,43 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
if
(
existing
!=
nullptr
)
{
if
(
!
existing
->
undef
)
{
// Already defined -- need to make sure they are identical:
// "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
if
(
existing
->
functionLike
!=
mac
.
functionLike
)
parseContext
.
ppError
(
defineLoc
,
"Macro redefined; function-like versus object-like:"
,
"#define"
,
atomStrings
.
getString
(
defAtom
));
else
if
(
existing
->
args
.
size
()
!=
mac
.
args
.
size
())
parseContext
.
ppError
(
defineLoc
,
"Macro redefined; different number of arguments:"
,
"#define"
,
atomStrings
.
getString
(
defAtom
));
else
{
if
(
existing
->
args
!=
mac
.
args
)
parseContext
.
ppError
(
defineLoc
,
"Macro redefined; different argument names:"
,
"#define"
,
atomStrings
.
getString
(
defAtom
));
// "Two replacement lists are identical if and only if the
// preprocessing tokens in both have the same number,
// ordering, spelling, and white-space separation, where all
// white-space separations are considered identical."
if
(
existing
->
functionLike
!=
mac
.
functionLike
)
{
parseContext
.
ppError
(
defineLoc
,
"Macro redefined; function-like versus object-like:"
,
"#define"
,
atomStrings
.
getString
(
defAtom
));
}
else
if
(
existing
->
args
.
size
()
!=
mac
.
args
.
size
())
{
parseContext
.
ppError
(
defineLoc
,
"Macro redefined; different number of arguments:"
,
"#define"
,
atomStrings
.
getString
(
defAtom
));
}
else
{
if
(
existing
->
args
!=
mac
.
args
)
{
parseContext
.
ppError
(
defineLoc
,
"Macro redefined; different argument names:"
,
"#define"
,
atomStrings
.
getString
(
defAtom
));
}
// set up to compare the two
existing
->
body
.
reset
();
mac
.
body
.
reset
();
int
newToken
;
bool
firstToken
=
true
;
do
{
int
oldToken
;
TPpToken
oldPpToken
;
TPpToken
newPpToken
;
oldToken
=
existing
->
body
.
getToken
(
parseContext
,
&
oldPpToken
);
newToken
=
mac
.
body
.
getToken
(
parseContext
,
&
newPpToken
);
// for the first token, preceding spaces don't matter
if
(
firstToken
)
{
newPpToken
.
space
=
oldPpToken
.
space
;
firstToken
=
false
;
}
if
(
oldToken
!=
newToken
||
oldPpToken
!=
newPpToken
)
{
parseContext
.
ppError
(
defineLoc
,
"Macro redefined; different substitutions:"
,
"#define"
,
atomStrings
.
getString
(
defAtom
));
parseContext
.
ppError
(
defineLoc
,
"Macro redefined; different substitutions:"
,
"#define"
,
atomStrings
.
getString
(
defAtom
));
break
;
}
}
while
(
newToken
>
0
);
}
while
(
newToken
!=
EndOfInput
);
}
}
*
existing
=
mac
;
...
...
glslang/MachineIndependent/preprocessor/PpContext.h
View file @
58d6905e
...
...
@@ -243,24 +243,48 @@ public:
// From PpTokens.cpp
//
// Capture the needed parts of a token stream for macro recording/playback.
class
TokenStream
{
public
:
TokenStream
()
:
current
(
0
)
{
}
// Manage a stream of these 'Token', which capture the relevant parts
// of a TPpToken, plus its atom.
class
Token
{
public
:
Token
(
int
atom
,
const
TPpToken
&
ppToken
)
:
atom
(
atom
),
space
(
ppToken
.
space
),
i64val
(
ppToken
.
i64val
),
name
(
ppToken
.
name
)
{
}
int
get
(
TPpToken
&
ppToken
)
{
ppToken
.
clear
();
ppToken
.
space
=
space
;
ppToken
.
i64val
=
i64val
;
snprintf
(
ppToken
.
name
,
sizeof
(
ppToken
.
name
),
"%s"
,
name
.
c_str
());
return
atom
;
}
bool
isAtom
(
int
a
)
{
return
atom
==
a
;
}
protected
:
Token
()
{}
int
atom
;
bool
space
;
// did a space precede the token?
long
long
i64val
;
TString
name
;
};
TokenStream
()
:
currentPos
(
0
)
{
}
void
putToken
(
int
token
,
TPpToken
*
ppToken
);
bool
peekToken
(
int
atom
)
{
return
!
atEnd
()
&&
stream
[
currentPos
].
isAtom
(
atom
);
}
int
getToken
(
TParseContextBase
&
,
TPpToken
*
);
bool
atEnd
()
{
return
current
>=
data
.
size
();
}
bool
atEnd
()
{
return
current
Pos
>=
stream
.
size
();
}
bool
peekTokenizedPasting
(
bool
lastTokenPastes
);
bool
peekUntokenizedPasting
();
void
reset
()
{
current
=
0
;
}
void
reset
()
{
current
Pos
=
0
;
}
protected
:
void
putSubtoken
(
char
);
int
getSubtoken
();
void
ungetSubtoken
();
TVector
<
unsigned
char
>
data
;
size_t
current
;
TVector
<
Token
>
stream
;
size_t
currentPos
;
};
//
...
...
glslang/MachineIndependent/preprocessor/PpTokens.cpp
View file @
58d6905e
...
...
@@ -99,151 +99,33 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace
glslang
{
namespace
{
// When recording (and playing back) should the backing name string
// be saved (restored)?
bool
SaveName
(
int
atom
)
{
switch
(
atom
)
{
case
PpAtomIdentifier
:
case
PpAtomConstString
:
case
PpAtomConstInt
:
case
PpAtomConstUint
:
case
PpAtomConstInt64
:
case
PpAtomConstUint64
:
#ifdef AMD_EXTENSIONS
case
PpAtomConstInt16
:
case
PpAtomConstUint16
:
#endif
case
PpAtomConstFloat
:
case
PpAtomConstDouble
:
case
PpAtomConstFloat16
:
return
true
;
default
:
return
false
;
}
}
// When recording (and playing back) should the numeric value
// be saved (restored)?
bool
SaveValue
(
int
atom
)
{
switch
(
atom
)
{
case
PpAtomConstInt
:
case
PpAtomConstUint
:
case
PpAtomConstInt64
:
case
PpAtomConstUint64
:
#ifdef AMD_EXTENSIONS
case
PpAtomConstInt16
:
case
PpAtomConstUint16
:
#endif
case
PpAtomConstFloat
:
case
PpAtomConstDouble
:
case
PpAtomConstFloat16
:
return
true
;
default
:
return
false
;
}
}
}
// push onto back of stream
void
TPpContext
::
TokenStream
::
putSubtoken
(
char
subtoken
)
{
data
.
push_back
(
static_cast
<
unsigned
char
>
(
subtoken
));
}
// get the next token in stream
int
TPpContext
::
TokenStream
::
getSubtoken
()
{
if
(
current
<
data
.
size
())
return
data
[
current
++
];
else
return
EndOfInput
;
}
// back up one position in the stream
void
TPpContext
::
TokenStream
::
ungetSubtoken
()
{
if
(
current
>
0
)
--
current
;
}
// Add a complete token (including backing string) to the end of a list
// for later playback.
// Add a token (including backing string) to the end of a macro
// token stream, for later playback.
void
TPpContext
::
TokenStream
::
putToken
(
int
atom
,
TPpToken
*
ppToken
)
{
// save the atom
assert
((
atom
&
~
0xff
)
==
0
);
putSubtoken
(
static_cast
<
char
>
(
atom
));
// save the backing name string
if
(
SaveName
(
atom
))
{
const
char
*
s
=
ppToken
->
name
;
while
(
*
s
)
putSubtoken
(
*
s
++
);
putSubtoken
(
0
);
}
// save the numeric value
if
(
SaveValue
(
atom
))
{
const
char
*
n
=
reinterpret_cast
<
const
char
*>
(
&
ppToken
->
i64val
);
for
(
size_t
i
=
0
;
i
<
sizeof
(
ppToken
->
i64val
);
++
i
)
putSubtoken
(
*
n
++
);
}
TokenStream
::
Token
streamToken
(
atom
,
*
ppToken
);
stream
.
push_back
(
streamToken
);
}
// Read the next token from a token stream.
// (Not the source stream, but a stream used to hold a tokenized macro).
// Read the next token from a macro token stream.
int
TPpContext
::
TokenStream
::
getToken
(
TParseContextBase
&
parseContext
,
TPpToken
*
ppToken
)
{
// get the atom
int
atom
=
getSubtoken
();
if
(
atom
==
EndOfInput
)
return
atom
;
if
(
atEnd
())
return
EndOfInput
;
// init the token
ppToken
->
clear
();
int
atom
=
stream
[
currentPos
++
].
get
(
*
ppToken
);
ppToken
->
loc
=
parseContext
.
getCurrentLoc
();
// get the backing name string
if
(
SaveName
(
atom
))
{
int
ch
=
getSubtoken
();
int
len
=
0
;
while
(
ch
!=
0
&&
ch
!=
EndOfInput
)
{
if
(
len
<
MaxTokenLength
)
{
ppToken
->
name
[
len
]
=
(
char
)
ch
;
len
++
;
ch
=
getSubtoken
();
}
else
{
parseContext
.
error
(
ppToken
->
loc
,
"token too long"
,
""
,
""
);
break
;
}
}
ppToken
->
name
[
len
]
=
0
;
}
// Check for ##, unless the current # is the last character
if
(
atom
==
'#'
)
{
if
(
current
<
data
.
size
())
{
if
(
getSubtoken
()
==
'#'
)
{
parseContext
.
requireProfile
(
ppToken
->
loc
,
~
EEsProfile
,
"token pasting (##)"
);
parseContext
.
profileRequires
(
ppToken
->
loc
,
~
EEsProfile
,
130
,
0
,
"token pasting (##)"
);
atom
=
PpAtomPaste
;
}
else
ungetSubtoken
();
if
(
peekToken
(
'#'
))
{
parseContext
.
requireProfile
(
ppToken
->
loc
,
~
EEsProfile
,
"token pasting (##)"
);
parseContext
.
profileRequires
(
ppToken
->
loc
,
~
EEsProfile
,
130
,
0
,
"token pasting (##)"
);
currentPos
++
;
atom
=
PpAtomPaste
;
}
}
// get the numeric value
if
(
SaveValue
(
atom
))
{
char
*
n
=
reinterpret_cast
<
char
*>
(
&
ppToken
->
i64val
);
for
(
size_t
i
=
0
;
i
<
sizeof
(
ppToken
->
i64val
);
++
i
)
*
n
++
=
(
char
)
getSubtoken
();
}
return
atom
;
}
...
...
@@ -256,15 +138,14 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
{
// 1. preceding ##?
size_t
savePos
=
current
;
int
subtoken
;
size_t
savePos
=
currentPos
;
// skip white space
do
{
subtoken
=
getSubtoken
();
}
while
(
subtoken
==
' '
);
current
=
savePos
;
if
(
subtoken
==
PpAtomPaste
)
while
(
peekToken
(
' '
))
++
currentPos
;
if
(
peekToken
(
PpAtomPaste
))
{
currentPos
=
savePos
;
return
true
;
}
// 2. last token and we've been told after this there will be a ##
...
...
@@ -273,18 +154,18 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
// Getting here means the last token will be pasted, after this
// Are we at the last non-whitespace token?
savePos
=
current
;
savePos
=
current
Pos
;
bool
moreTokens
=
false
;
do
{
subtoken
=
getSubtoken
();
if
(
subtoken
==
EndOfInput
)
if
(
atEnd
())
break
;
if
(
subtoken
!=
' '
)
{
if
(
!
peekToken
(
' '
)
)
{
moreTokens
=
true
;
break
;
}
++
currentPos
;
}
while
(
true
);
current
=
savePos
;
current
Pos
=
savePos
;
return
!
moreTokens
;
}
...
...
@@ -293,23 +174,21 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
bool
TPpContext
::
TokenStream
::
peekUntokenizedPasting
()
{
// don't return early, have to restore this
size_t
savePos
=
current
;
size_t
savePos
=
current
Pos
;
// skip white-space
int
subtoken
;
do
{
subtoken
=
getSubtoken
();
}
while
(
subtoken
==
' '
);
while
(
peekToken
(
' '
))
++
currentPos
;
// check for ##
bool
pasting
=
false
;
if
(
subtoken
==
'#'
)
{
subtoken
=
getSubtoken
()
;
if
(
subtoken
==
'#'
)
if
(
peekToken
(
'#'
)
)
{
++
currentPos
;
if
(
peekToken
(
'#'
)
)
pasting
=
true
;
}
current
=
savePos
;
current
Pos
=
savePos
;
return
pasting
;
}
...
...
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