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
ab89bbe7
Commit
ab89bbe7
authored
Aug 23, 2016
by
John Kessenich
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'overloaded-400' of github.com:KhronosGroup/glslang
parents
32c169db
37023488
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
388 additions
and
10 deletions
+388
-10
400.vert
Test/400.vert
+98
-1
400.vert.out
Test/baseResults/400.vert.out
+0
-0
CMakeLists.txt
glslang/CMakeLists.txt
+1
-0
revision.h
glslang/Include/revision.h
+1
-1
ParseContextBase.cpp
glslang/MachineIndependent/ParseContextBase.cpp
+184
-0
ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.cpp
+94
-4
ParseHelper.h
glslang/MachineIndependent/ParseHelper.h
+6
-0
SymbolTable.h
glslang/MachineIndependent/SymbolTable.h
+2
-2
hlslParseHelper.cpp
hlsl/hlslParseHelper.cpp
+2
-2
No files found.
Test/400.vert
View file @
ab89bbe7
...
@@ -4,6 +4,103 @@ in double d; // ERROR, no doubles
...
@@ -4,6 +4,103 @@ in double d; // ERROR, no doubles
in
dvec3
d3
;
// ERROR, no doubles
in
dvec3
d3
;
// ERROR, no doubles
in
dmat4
dm4
;
// ERROR, no doubles
in
dmat4
dm4
;
// ERROR, no doubles
void
main
()
// function selection under type conversion
void
foo1
(
double
a
,
uint
b
)
{}
void
foo1
(
double
a
,
int
b
)
{}
void
foo1
(
double
a
,
float
b
)
{}
void
foo1
(
double
a
,
double
b
){}
void
foo2
(
double
a
,
float
b
)
{}
void
foo2
(
double
a
,
double
b
){}
void
foo3
(
double
a
,
float
b
)
{}
void
foo3
(
float
a
,
double
b
)
{}
void
ftd
(
int
,
float
,
double
)
{}
void
ftd
(
uint
,
float
,
double
)
{}
void
ftd
(
float
,
double
,
double
)
{}
void
main
()
{
double
d
;
uint
u
;
int
i
;
float
f
;
foo1
(
d
,
d
);
foo1
(
d
,
u
);
foo1
(
d
,
i
);
foo1
(
d
,
f
);
foo1
(
f
,
d
);
foo1
(
f
,
u
);
foo1
(
f
,
i
);
foo1
(
f
,
f
);
foo1
(
u
,
d
);
foo1
(
u
,
u
);
foo1
(
u
,
i
);
foo1
(
u
,
f
);
foo1
(
i
,
d
);
foo1
(
i
,
u
);
foo1
(
i
,
i
);
foo1
(
i
,
f
);
foo2
(
d
,
d
);
foo2
(
d
,
u
);
foo2
(
d
,
i
);
foo2
(
d
,
f
);
foo2
(
f
,
d
);
foo2
(
f
,
u
);
foo2
(
f
,
i
);
foo2
(
f
,
f
);
foo2
(
u
,
d
);
foo2
(
u
,
u
);
foo2
(
u
,
i
);
foo2
(
u
,
f
);
foo2
(
i
,
d
);
foo2
(
i
,
u
);
foo2
(
i
,
i
);
foo2
(
i
,
f
);
foo3
(
d
,
d
);
// ERROR, no match
foo3
(
d
,
u
);
foo3
(
d
,
i
);
foo3
(
d
,
f
);
foo3
(
f
,
d
);
foo3
(
f
,
u
);
// ERROR, ambiguous
foo3
(
f
,
i
);
// ERROR, ambiguous
foo3
(
f
,
f
);
// ERROR, ambiguous
foo3
(
u
,
d
);
foo3
(
u
,
u
);
// ERROR, ambiguous
foo3
(
u
,
i
);
// ERROR, ambiguous
foo3
(
u
,
f
);
// ERROR, ambiguous
foo3
(
i
,
d
);
foo3
(
i
,
u
);
// ERROR, ambiguous
foo3
(
i
,
i
);
// ERROR, ambiguous
foo3
(
i
,
f
);
// ERROR, ambiguous
ftd
(
i
,
f
,
f
);
ftd
(
u
,
f
,
f
);
}
void
itf
(
int
,
float
,
int
);
void
itf
(
int
,
double
,
int
);
void
tf
()
{
{
double
d
;
uint
u
;
int
i
;
float
f
;
itf
(
i
,
i
,
i
);
itf
(
i
,
u
,
i
);
}
}
Test/baseResults/400.vert.out
View file @
ab89bbe7
This diff is collapsed.
Click to expand it.
glslang/CMakeLists.txt
View file @
ab89bbe7
...
@@ -14,6 +14,7 @@ set(SOURCES
...
@@ -14,6 +14,7 @@ set(SOURCES
MachineIndependent/Initialize.cpp
MachineIndependent/Initialize.cpp
MachineIndependent/IntermTraverse.cpp
MachineIndependent/IntermTraverse.cpp
MachineIndependent/Intermediate.cpp
MachineIndependent/Intermediate.cpp
MachineIndependent/ParseContextBase.cpp
MachineIndependent/ParseHelper.cpp
MachineIndependent/ParseHelper.cpp
MachineIndependent/PoolAlloc.cpp
MachineIndependent/PoolAlloc.cpp
MachineIndependent/RemoveTree.cpp
MachineIndependent/RemoveTree.cpp
...
...
glslang/Include/revision.h
View file @
ab89bbe7
...
@@ -2,5 +2,5 @@
...
@@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits.
// For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run).
// For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.143
0
"
#define GLSLANG_REVISION "Overload400-PrecQual.143
3
"
#define GLSLANG_DATE "23-Aug-2016"
#define GLSLANG_DATE "23-Aug-2016"
glslang/MachineIndependent/ParseContextBase.cpp
0 → 100644
View file @
ab89bbe7
//
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
//Copyright (C) 2016 Google, Inc.
//
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
//are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE.
//
// Implement the TParseContextBase class.
#include "ParseHelper.h"
extern
int
yyparse
(
glslang
::
TParseContext
*
);
namespace
glslang
{
// Select the best matching function for 'call' from 'candidateList'.
//
// Assumptions
//
// There is no exact match, so a selection algorithm needs to run. That is, the
// language-specific handler should check for exact match first, to
// decide what to do, before calling this selector.
//
// Input
//
// * list of candidate signatures to select from
// * the call
// * a predicate function convertible(from, to) that says whether or not type
// 'from' can implicitly convert to type 'to' (it includes the case of what
// the calling language would consider a matching type with no conversion
// needed)
// * a predicate function better(from1, from2, to1, to2) that says whether or
// not a conversion from <-> to2 is considered better than a conversion
// from <-> to1 (both in and out directions need testing, as declared by the
// formal parameter)
//
// Output
//
// * best matching candidate (or none, if no viable candidates found)
// * whether there was a tie for the best match (ambiguous overload selection,
// caller's choice for how to report)
//
const
TFunction
*
TParseContextBase
::
selectFunction
(
TVector
<
const
TFunction
*>
candidateList
,
const
TFunction
&
call
,
std
::
function
<
bool
(
const
TType
&
from
,
const
TType
&
to
)
>
convertible
,
std
::
function
<
bool
(
const
TType
&
from
,
const
TType
&
to1
,
const
TType
&
to2
)
>
better
,
/* output */
bool
&
tie
)
{
//
// Operation
//
// 1. Prune the input list of candidates down to a list of viable candidates,
// where each viable candidate has
//
// * at least as many parameters as there are calling arguments, with any
// remaining parameters being optional or having default values
// * each parameter is true under convertible(A, B), where A is the calling
// type for in and B is the formal type, and in addition, for out B is the
// calling type and A is the formal type
//
// 2. If there are no viable candidates, return with no match.
//
// 3. If there is only one viable candidate, it is the best match.
//
// 4. If there are multiple viable candidates, select the first viable candidate
// as the incumbent. Compare the incumbent to the next viable candidate, and if
// that candidate is better (bullets below), make it the incumbent. Repeat, with
// a linear walk through the viable candidate list. The final incumbent will be
// returned as the best match. A viable candidate is better than the incumbent if
//
// * it has a function argument with a better(...) conversion than the incumbent,
// for all directions needed by in and out
// * the incumbent has no argument with a better(...) conversion then the
// candidate, for either in or out (as needed)
//
// 5. Check for ambiguity by comparing the best match against all other viable
// candidates. If any other viable candidate has a function argument with a
// better(...) conversion than the best candidate (for either in or out
// directions), return that there was a tie for best.
//
tie
=
false
;
// 1. prune to viable...
TVector
<
const
TFunction
*>
viableCandidates
;
for
(
auto
it
=
candidateList
.
begin
();
it
!=
candidateList
.
end
();
++
it
)
{
const
TFunction
&
candidate
=
*
(
*
it
);
// to even be a potential match, number of arguments has to match
if
(
call
.
getParamCount
()
!=
candidate
.
getParamCount
())
continue
;
// see if arguments are convertible
bool
viable
=
true
;
for
(
int
param
=
0
;
param
<
candidate
.
getParamCount
();
++
param
)
{
if
(
candidate
[
param
].
type
->
getQualifier
().
isParamInput
())
{
if
(
!
convertible
(
*
call
[
param
].
type
,
*
candidate
[
param
].
type
))
{
viable
=
false
;
break
;
}
}
if
(
candidate
[
param
].
type
->
getQualifier
().
isParamOutput
())
{
if
(
!
convertible
(
*
candidate
[
param
].
type
,
*
call
[
param
].
type
))
{
viable
=
false
;
break
;
}
}
}
if
(
viable
)
viableCandidates
.
push_back
(
&
candidate
);
}
// 2. none viable...
if
(
viableCandidates
.
size
()
==
0
)
return
nullptr
;
// 3. only one viable...
if
(
viableCandidates
.
size
()
==
1
)
return
viableCandidates
.
front
();
// 4. find best...
auto
betterParam
=
[
&
call
,
&
better
](
const
TFunction
&
can1
,
const
TFunction
&
can2
){
// is call -> can2 better than call -> can1 for any parameter
bool
hasBetterParam
=
false
;
for
(
int
param
=
0
;
param
<
call
.
getParamCount
();
++
param
)
{
if
(
better
(
*
call
[
param
].
type
,
*
can1
[
param
].
type
,
*
can2
[
param
].
type
))
{
hasBetterParam
=
true
;
break
;
}
}
return
hasBetterParam
;
};
const
TFunction
*
incumbent
=
viableCandidates
.
front
();
for
(
auto
it
=
viableCandidates
.
begin
()
+
1
;
it
!=
viableCandidates
.
end
();
++
it
)
{
const
TFunction
&
candidate
=
*
(
*
it
);
if
(
betterParam
(
*
incumbent
,
candidate
)
&&
!
betterParam
(
candidate
,
*
incumbent
))
incumbent
=
&
candidate
;
}
// 5. ambiguity...
for
(
auto
it
=
viableCandidates
.
begin
();
it
!=
viableCandidates
.
end
();
++
it
)
{
if
(
incumbent
==
*
it
)
continue
;
const
TFunction
&
candidate
=
*
(
*
it
);
if
(
betterParam
(
*
incumbent
,
candidate
))
tie
=
true
;
}
return
incumbent
;
}
}
// end namespace glslang
glslang/MachineIndependent/ParseHelper.cpp
View file @
ab89bbe7
...
@@ -4886,10 +4886,10 @@ const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFu
...
@@ -4886,10 +4886,10 @@ const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFu
// more than one function."
// more than one function."
const
TFunction
*
candidate
=
nullptr
;
const
TFunction
*
candidate
=
nullptr
;
TVector
<
TFunction
*>
candidateList
;
TVector
<
const
TFunction
*>
candidateList
;
symbolTable
.
findFunctionNameList
(
call
.
getMangledName
(),
candidateList
,
builtIn
);
symbolTable
.
findFunctionNameList
(
call
.
getMangledName
(),
candidateList
,
builtIn
);
for
(
TVector
<
TFunction
*>::
const_iterator
it
=
candidateList
.
begin
();
it
!=
candidateList
.
end
();
++
it
)
{
for
(
auto
it
=
candidateList
.
begin
();
it
!=
candidateList
.
end
();
++
it
)
{
const
TFunction
&
function
=
*
(
*
it
);
const
TFunction
&
function
=
*
(
*
it
);
// to even be a potential match, number of arguments has to match
// to even be a potential match, number of arguments has to match
...
@@ -4937,10 +4937,100 @@ const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFu
...
@@ -4937,10 +4937,100 @@ const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFu
}
}
// Function finding algorithm for desktop version 400 and above.
// Function finding algorithm for desktop version 400 and above.
//
// "When function calls are resolved, an exact type match for all the arguments
// is sought. If an exact match is found, all other functions are ignored, and
// the exact match is used. If no exact match is found, then the implicit
// conversions in section 4.1.10 Implicit Conversions will be applied to find
// a match. Mismatched types on input parameters (in or inout or default) must
// have a conversion from the calling argument type to the formal parameter type.
// Mismatched types on output parameters (out or inout) must have a conversion
// from the formal parameter type to the calling argument type.
//
// "If implicit conversions can be used to find more than one matching function,
// a single best-matching function is sought. To determine a best match, the
// conversions between calling argument and formal parameter types are compared
// for each function argument and pair of matching functions. After these
// comparisons are performed, each pair of matching functions are compared.
// A function declaration A is considered a better match than function
// declaration B if
//
// * for at least one function argument, the conversion for that argument in A
// is better than the corresponding conversion in B; and
// * there is no function argument for which the conversion in B is better than
// the corresponding conversion in A.
//
// "If a single function declaration is considered a better match than every
// other matching function declaration, it will be used. Otherwise, a
// compile-time semantic error for an ambiguous overloaded function call occurs.
//
// "To determine whether the conversion for a single argument in one match is
// better than that for another match, the following rules are applied, in order:
//
// 1. An exact match is better than a match involving any implicit conversion.
// 2. A match involving an implicit conversion from float to double is better
// than a match involving any other implicit conversion.
// 3. A match involving an implicit conversion from either int or uint to float
// is better than a match involving an implicit conversion from either int
// or uint to double.
//
// "If none of the rules above apply to a particular pair of conversions, neither
// conversion is considered better than the other."
//
const
TFunction
*
TParseContext
::
findFunction400
(
const
TSourceLoc
&
loc
,
const
TFunction
&
call
,
bool
&
builtIn
)
const
TFunction
*
TParseContext
::
findFunction400
(
const
TSourceLoc
&
loc
,
const
TFunction
&
call
,
bool
&
builtIn
)
{
{
// TODO: 4.00 functionality: findFunction400()
// first, look for an exact match
return
findFunction120
(
loc
,
call
,
builtIn
);
TSymbol
*
symbol
=
symbolTable
.
find
(
call
.
getMangledName
(),
&
builtIn
);
if
(
symbol
)
return
symbol
->
getAsFunction
();
// no exact match, use the generic selector, parameterized by the GLSL rules
// create list of candidates to send
TVector
<
const
TFunction
*>
candidateList
;
symbolTable
.
findFunctionNameList
(
call
.
getMangledName
(),
candidateList
,
builtIn
);
// can 'from' convert to 'to'?
auto
convertible
=
[
this
](
const
TType
&
from
,
const
TType
&
to
)
{
if
(
from
==
to
)
return
true
;
if
(
from
.
isArray
()
||
to
.
isArray
()
||
!
from
.
sameElementShape
(
to
))
return
false
;
return
intermediate
.
canImplicitlyPromote
(
from
.
getBasicType
(),
to
.
getBasicType
());
};
// Is 'to2' a better conversion than 'to1'?
// Ties should not be considered as better.
// Assumes 'convertible' already said true.
auto
better
=
[](
const
TType
&
from
,
const
TType
&
to1
,
const
TType
&
to2
)
{
// 1. exact match
if
(
from
==
to2
)
return
from
!=
to1
;
if
(
from
==
to1
)
return
false
;
// 2. float -> double is better
if
(
from
.
getBasicType
()
==
EbtFloat
)
{
if
(
to2
.
getBasicType
()
==
EbtDouble
&&
to1
.
getBasicType
()
!=
EbtDouble
)
return
true
;
}
// 3. -> float is better than -> double
return
to2
.
getBasicType
()
==
EbtFloat
&&
to1
.
getBasicType
()
==
EbtDouble
;
};
// for ambiguity reporting
bool
tie
=
false
;
// send to the generic selector
const
TFunction
*
bestMatch
=
selectFunction
(
candidateList
,
call
,
convertible
,
better
,
tie
);
if
(
bestMatch
==
nullptr
)
error
(
loc
,
"no matching overloaded function found"
,
call
.
getName
().
c_str
(),
""
);
else
if
(
tie
)
error
(
loc
,
"ambiguous best function under implicit type conversion"
,
call
.
getName
().
c_str
(),
""
);
return
bestMatch
;
}
}
// When a declaration includes a type, but not a variable name, it can be
// When a declaration includes a type, but not a variable name, it can be
...
...
glslang/MachineIndependent/ParseHelper.h
View file @
ab89bbe7
...
@@ -142,6 +142,12 @@ protected:
...
@@ -142,6 +142,12 @@ protected:
std
::
function
<
void
(
int
,
int
,
const
char
*
)
>
versionCallback
;
std
::
function
<
void
(
int
,
int
,
const
char
*
)
>
versionCallback
;
std
::
function
<
void
(
int
,
const
char
*
,
const
char
*
)
>
extensionCallback
;
std
::
function
<
void
(
int
,
const
char
*
,
const
char
*
)
>
extensionCallback
;
std
::
function
<
void
(
int
,
const
char
*
)
>
errorCallback
;
std
::
function
<
void
(
int
,
const
char
*
)
>
errorCallback
;
// see implementation for detail
const
TFunction
*
selectFunction
(
TVector
<
const
TFunction
*>
,
const
TFunction
&
,
std
::
function
<
bool
(
const
TType
&
,
const
TType
&
)
>
,
std
::
function
<
bool
(
const
TType
&
,
const
TType
&
,
const
TType
&
)
>
,
/* output */
bool
&
tie
);
};
};
//
//
...
...
glslang/MachineIndependent/SymbolTable.h
View file @
ab89bbe7
...
@@ -357,7 +357,7 @@ public:
...
@@ -357,7 +357,7 @@ public:
return
(
*
it
).
second
;
return
(
*
it
).
second
;
}
}
void
findFunctionNameList
(
const
TString
&
name
,
TVector
<
TFunction
*>&
list
)
void
findFunctionNameList
(
const
TString
&
name
,
TVector
<
const
TFunction
*>&
list
)
{
{
size_t
parenAt
=
name
.
find_first_of
(
'('
);
size_t
parenAt
=
name
.
find_first_of
(
'('
);
TString
base
(
name
,
0
,
parenAt
+
1
);
TString
base
(
name
,
0
,
parenAt
+
1
);
...
@@ -624,7 +624,7 @@ public:
...
@@ -624,7 +624,7 @@ public:
return
false
;
return
false
;
}
}
void
findFunctionNameList
(
const
TString
&
name
,
TVector
<
TFunction
*>&
list
,
bool
&
builtIn
)
void
findFunctionNameList
(
const
TString
&
name
,
TVector
<
const
TFunction
*>&
list
,
bool
&
builtIn
)
{
{
// For user levels, return the set found in the first scope with a match
// For user levels, return the set found in the first scope with a match
builtIn
=
false
;
builtIn
=
false
;
...
...
hlsl/hlslParseHelper.cpp
View file @
ab89bbe7
...
@@ -3554,10 +3554,10 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
...
@@ -3554,10 +3554,10 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
// exact match not found, look through a list of overloaded functions of the same name
// exact match not found, look through a list of overloaded functions of the same name
const
TFunction
*
candidate
=
nullptr
;
const
TFunction
*
candidate
=
nullptr
;
TVector
<
TFunction
*>
candidateList
;
TVector
<
const
TFunction
*>
candidateList
;
symbolTable
.
findFunctionNameList
(
call
.
getMangledName
(),
candidateList
,
builtIn
);
symbolTable
.
findFunctionNameList
(
call
.
getMangledName
(),
candidateList
,
builtIn
);
for
(
TVector
<
TFunction
*>::
const_iterator
it
=
candidateList
.
begin
();
it
!=
candidateList
.
end
();
++
it
)
{
for
(
auto
it
=
candidateList
.
begin
();
it
!=
candidateList
.
end
();
++
it
)
{
const
TFunction
&
function
=
*
(
*
it
);
const
TFunction
&
function
=
*
(
*
it
);
// to even be a potential match, number of arguments has to match
// to even be a potential match, number of arguments has to match
...
...
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