Eliminate flex as the GLSL lexical analyzer, going from two nested lexical analyzers down to one, leaving just the preprocessor's lexical analysis. A new layer replaces it, to translate from the preprocessor's view of tokenization to glslang's view of tokenization.

Also:
 - change source locations from an int to TSourceLoc (shader number, line number) throughout
 - various improvements to the preprocessor


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22277 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-07-06 19:54:21 +00:00
parent 73ed17a87b
commit 5f1a0b7998
35 changed files with 2535 additions and 2515 deletions

View File

@ -125,5 +125,9 @@ int linenumber = __LINE__;
int filenumber = __FILE__;
int version = __VERSION__;
#define PI (3.14)
#define TWOPI (2.0 * PI)
float twoPi = TWOPI;
#define PASTE(a,b) a ## b
float PASTE(tod, ay) = 17;

View File

@ -1,14 +1,20 @@
#version 300 es
// this file cont\
ains no errors
ains no errors other than the #error which are there to see if line numbering for errors is correct
#error e1
float f\
oo; // same as 'float foo;'
#error e2
#define MAIN void main() \
{ \
gl_Position = vec4(foo); \
}
#error e3
MAIN

View File

@ -14,13 +14,13 @@ int OE = 0777777777777777777777; // ERROR
int HE = 0x1234567890ABCDEF0; // ERROR
// 1023 character fraction
float F = 1.012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012;
float F = 1.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
// 1024 character value
float G = 1.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
float G = 1.01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678890;
// 1027 character fraction
float E3 = 1.01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234;
// 1025 character fraction
float E3 = 1.012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012;
void main()
{

View File

@ -150,7 +150,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="glslang\MachineIndependent\Constant.cpp" />
<ClCompile Include="glslang\MachineIndependent\gen_glslang.cpp" />
<ClCompile Include="glslang\MachineIndependent\glslang_tab.cpp" />
<ClCompile Include="glslang\MachineIndependent\InfoSink.cpp" />
<ClCompile Include="glslang\MachineIndependent\Initialize.cpp" />
@ -192,7 +191,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
<ClInclude Include="glslang\MachineIndependent\RemoveTree.h" />
<ClInclude Include="glslang\MachineIndependent\localintermediate.h" />
<ClInclude Include="glslang\MachineIndependent\preprocessor\atom.h" />
<ClInclude Include="glslang\MachineIndependent\preprocessor\compile.h" />
<ClInclude Include="glslang\MachineIndependent\preprocessor\cpp.h" />
<ClInclude Include="glslang\MachineIndependent\preprocessor\memory.h" />
<ClInclude Include="glslang\MachineIndependent\preprocessor\parser.h" />
@ -206,6 +204,7 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
<ClInclude Include="glslang\Include\ConstantUnion.h" />
<ClInclude Include="glslang\Include\InfoSink.h" />
<ClInclude Include="glslang\MachineIndependent\Scan.h" />
<ClInclude Include="glslang\MachineIndependent\ScanContext.h" />
<ClInclude Include="glslang\MachineIndependent\Versions.h" />
<ClInclude Include="OGLCompilersDLL\InitializeDll.h" />
<ClInclude Include="glslang\Include\InitializeGlobals.h" />
@ -238,23 +237,6 @@ cd %(RootDir)%(Directory)
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RootDir)%(Directory)%(Filename)_tab.cpp;%(Outputs)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="glslang\MachineIndependent\glslang.l">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">cd %(RootDir)%(Directory)
%(RootDir)%(Directory)..\..\tools\flex.exe glslang.l
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Executing flex on glslang.l</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RootDir)%(Directory)gen_glslang.cpp</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RootDir)%(Directory)glslang_tab.cpp.h</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">cd %(RootDir)%(Directory)
%(RootDir)%(Directory)..\..\tools\flex.exe glslang.l
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Executing flex on glslang.l</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RootDir)%(Directory)gen_glslang.cpp</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RootDir)%(Directory)glslang_tab.cpp.h</AdditionalInputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -97,9 +97,6 @@
<ClCompile Include="glslang\OSDependent\Linux\ossource.cpp">
<Filter>OSDependent\Linux</Filter>
</ClCompile>
<ClCompile Include="glslang\MachineIndependent\gen_glslang.cpp">
<Filter>Machine Independent\Generated Source</Filter>
</ClCompile>
<ClCompile Include="glslang\MachineIndependent\glslang_tab.cpp">
<Filter>Machine Independent\Generated Source</Filter>
</ClCompile>
@ -135,9 +132,6 @@
<ClInclude Include="glslang\MachineIndependent\preprocessor\atom.h">
<Filter>Machine Independent\CPP</Filter>
</ClInclude>
<ClInclude Include="glslang\MachineIndependent\preprocessor\compile.h">
<Filter>Machine Independent\CPP</Filter>
</ClInclude>
<ClInclude Include="glslang\MachineIndependent\preprocessor\cpp.h">
<Filter>Machine Independent\CPP</Filter>
</ClInclude>
@ -222,13 +216,13 @@
<ClInclude Include="glslang\MachineIndependent\Scan.h">
<Filter>Machine Independent</Filter>
</ClInclude>
<ClInclude Include="glslang\MachineIndependent\ScanContext.h">
<Filter>Machine Independent</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="glslang\MachineIndependent\glslang.y">
<Filter>Machine Independent</Filter>
</CustomBuild>
<CustomBuild Include="glslang\MachineIndependent\glslang.l">
<Filter>Machine Independent</Filter>
</CustomBuild>
</ItemGroup>
</Project>

View File

@ -66,8 +66,6 @@
#include <stdio.h>
#include <assert.h>
typedef int TSourceLoc;
#include "PoolAlloc.h"
//
@ -162,25 +160,10 @@ inline const TString String(const int i, const int base = 10)
return text;
}
const unsigned int SourceLocLineMask = 0xffff;
const unsigned int SourceLocStringShift = 16;
__inline TPersistString FormatSourceLoc(const TSourceLoc loc)
{
const int maxSize = 64;
char locText[maxSize];
int string = loc >> SourceLocStringShift;
int line = loc & SourceLocLineMask;
if (line)
snprintf(locText, maxSize, "%d:%d", string, line);
else
snprintf(locText, maxSize, "%d:? ", string);
return TPersistString(locText);
}
struct TSourceLoc {
int string;
int line;
};
typedef TMap<TString, TString> TPragmaTable;
typedef TMap<TString, TString>::tAllocator TPragmaTableAllocator;

View File

@ -94,7 +94,10 @@ public:
}
}
void location(TSourceLoc loc) {
append(FormatSourceLoc(loc).c_str());
const int maxSize = 24;
char locText[maxSize];
snprintf(locText, maxSize, "%d:%d", loc.string, loc.line);
append(locText);
append(": ");
}
void message(TPrefixType message, const char* s) {

View File

@ -142,11 +142,11 @@ struct TSampler {
// Need to have association of line numbers to types in a list for building structs.
//
class TType;
struct TTypeLine {
struct TTypeLoc {
TType* type;
int line;
TSourceLoc loc;
};
typedef TVector<TTypeLine> TTypeList;
typedef TVector<TTypeLoc> TTypeList;
inline TTypeList* NewPoolTTypeList()
{
@ -347,9 +347,9 @@ public:
int matrixRows : 4;
TArraySizes arraySizes;
const TType* userDef;
int line;
TSourceLoc loc;
void initType(int ln = 0)
void initType(TSourceLoc l)
{
basicType = EbtVoid;
vectorSize = 1;
@ -357,7 +357,7 @@ public:
matrixCols = 0;
arraySizes = 0;
userDef = 0;
line = ln;
loc = l;
}
void initQualifiers(bool global = false)
@ -367,9 +367,9 @@ public:
qualifier.storage = EvqGlobal;
}
void init(int line = 0, bool global = false)
void init(TSourceLoc loc, bool global = false)
{
initType(line);
initType(loc);
sampler.clear();
initQualifiers(global);
}
@ -479,10 +479,10 @@ public:
// create the new structure here
structure = NewPoolTTypeList();
for (unsigned int i = 0; i < copyOf.structure->size(); ++i) {
TTypeLine typeLine;
typeLine.line = (*copyOf.structure)[i].line;
typeLine.type = (*copyOf.structure)[i].type->clone(remapper);
structure->push_back(typeLine);
TTypeLoc typeLoc;
typeLoc.loc = (*copyOf.structure)[i].loc;
typeLoc.type = (*copyOf.structure)[i].type->clone(remapper);
structure->push_back(typeLoc);
}
} else {
structure = iter->second;

View File

@ -320,9 +320,9 @@ class TIntermNode {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TIntermNode() : line(0) {}
virtual TSourceLoc getLine() const { return line; }
virtual void setLine(TSourceLoc l) { line = l; }
TIntermNode() { loc.line = 0; loc.string = 0; }
virtual TSourceLoc getLoc() const { return loc; }
virtual void setLoc(TSourceLoc l) { loc = l; }
virtual void traverse(TIntermTraverser*) = 0;
virtual TIntermTyped* getAsTyped() { return 0; }
virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
@ -336,7 +336,7 @@ public:
virtual TIntermBranch* getAsBranchNode() { return 0; }
virtual ~TIntermNode() { }
protected:
TSourceLoc line;
TSourceLoc loc;
};
//

View File

@ -195,7 +195,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
break;
default:
infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLoc());
return 0;
}
}
@ -352,13 +352,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
break;
default:
infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine());
infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLoc());
return 0;
}
TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
newNode->setLine(getLine());
newNode->setLoc(getLoc());
return newNode;
}
@ -416,7 +416,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLoc());
return 0;
}
break;
@ -425,7 +425,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
switch (getType().getBasicType()) {
case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLoc());
return 0;
}
break;
@ -570,14 +570,14 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
case EOpAll:
default:
infoSink.info.message(EPrefixInternalError, "missing operator for unary constant folding", getLine());
infoSink.info.message(EPrefixInternalError, "missing operator for unary constant folding", getLoc());
return 0;
}
}
TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
newNode->getTypePointer()->getQualifier().storage = EvqConst;
newNode->setLine(getLine());
newNode->setLoc(getLoc());
return newNode;
}
@ -667,7 +667,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpReflect:
case EOpRefract:
case EOpOuterProduct:
infoSink.info.message(EPrefixInternalError, "constant folding operation not implemented", aggrNode->getLine());
infoSink.info.message(EPrefixInternalError, "constant folding operation not implemented", aggrNode->getLoc());
return aggrNode;
default:
@ -676,7 +676,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, aggrNode->getType());
newNode->getTypePointer()->getQualifier().storage = EvqConst;
newNode->setLine(aggrNode->getLine());
newNode->setLoc(aggrNode->getLoc());
return newNode;
}
@ -705,12 +705,12 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode)
constUnion* unionArray = new constUnion[aggrNode->getType().getObjectSize()];
if (aggrNode->getSequence().size() == 1)
returnVal = parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
returnVal = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
else
returnVal = parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType());
returnVal = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType());
if (returnVal)
return aggrNode;
return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLine());
return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLoc());
}

View File

@ -70,7 +70,5 @@ protected:
void IdentifyBuiltIns(int version, EProfile profile, EShLanguage, TSymbolTable&);
void IdentifyBuiltIns(int version, EProfile profile, EShLanguage, TSymbolTable&, const TBuiltInResource &resources);
extern "C" int InitPreprocessor(void);
extern "C" int FinalizePreprocessor(void);
#endif // _INITIALIZE_INCLUDED_

View File

@ -56,10 +56,10 @@
//
// Returns the added node.
//
TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line)
TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc loc)
{
TIntermSymbol* node = new TIntermSymbol(id, name, type);
node->setLine(line);
node->setLoc(loc);
return node;
}
@ -69,7 +69,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
//
// Returns the added node.
//
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
{
// No operations work on blocks
if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
@ -92,9 +92,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
// one and promote it to the right type.
//
TIntermBinary* node = new TIntermBinary(op);
if (line == 0)
line = right->getLine();
node->setLine(line);
if (loc.line == 0)
loc = right->getLoc();
node->setLoc(loc);
node->setLeft(left);
node->setRight(right);
@ -114,7 +114,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
if (folded)
return folded;
else
infoSink.info.message(EPrefixInternalError, "Constant folding failed", line);
infoSink.info.message(EPrefixInternalError, "Constant folding failed", loc);
}
return node;
@ -125,7 +125,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
//
// Returns the added node.
//
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
{
// No block assignment
if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
@ -136,9 +136,9 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
// from right to left.
//
TIntermBinary* node = new TIntermBinary(op);
if (line == 0)
line = left->getLine();
node->setLine(line);
if (loc.line == 0)
loc = left->getLoc();
node->setLoc(loc);
TIntermTyped* child = addConversion(op, left->getType(), right);
if (child == 0)
@ -161,12 +161,12 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
// Returns the added node.
// The caller should set the type of the returned node.
//
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line)
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc)
{
TIntermBinary* node = new TIntermBinary(op);
if (line == 0)
line = index->getLine();
node->setLine(line);
if (loc.line == 0)
loc = index->getLoc();
node->setLoc(loc);
node->setLeft(base);
node->setRight(index);
@ -180,7 +180,7 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT
//
// Returns the added node.
//
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line)
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc loc)
{
TIntermTyped* child = childNode->getAsTyped();
@ -188,7 +188,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
return 0;
if (child == 0) {
infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", loc);
return 0;
}
@ -248,9 +248,9 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
// Make a new node for the operator.
//
TIntermUnary* node = new TIntermUnary(op);
if (line == 0)
line = child->getLine();
node->setLine(line);
if (loc.line == 0)
loc = child->getLoc();
node->setLoc(loc);
node->setOperand(child);
if (! node->promote(infoSink))
@ -274,7 +274,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI
//
TIntermTyped* child = childNode->getAsTyped();
if (child == 0) {
infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", child->getLine());
infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", child->getLoc());
return 0;
}
@ -284,7 +284,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI
return child->getAsConstantUnion()->fold(op, returnType, infoSink);
TIntermUnary* node = new TIntermUnary(op);
node->setLine(child->getLine());
node->setLoc(child->getLoc());
node->setOperand(child);
node->setType(returnType);
@ -299,7 +299,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI
return node;
} else {
// setAggregateOperater() calls fold() for constant folding
TIntermTyped* node = setAggregateOperator(childNode, op, returnType, childNode->getLine());
TIntermTyped* node = setAggregateOperator(childNode, op, returnType, childNode->getLoc());
TPrecisionQualifier correctPrecision = returnType.getQualifier().precision;
if (correctPrecision == EpqNone && profile == EEsProfile) {
@ -328,7 +328,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI
// Returns an aggregate node, which could be the one passed in if
// it was already an aggregate.
//
TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc line)
TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc)
{
TIntermAggregate* aggNode;
@ -343,8 +343,8 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o
//
aggNode = new TIntermAggregate();
aggNode->getSequence().push_back(node);
if (line == 0)
line = node->getLine();
if (loc.line == 0)
loc = node->getLoc();
}
} else
aggNode = new TIntermAggregate();
@ -353,8 +353,8 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o
// Set the operator.
//
aggNode->setOperator(op);
if (line != 0)
aggNode->setLine(line);
if (loc.line != 0)
aggNode->setLoc(loc);
aggNode->setType(type);
@ -510,7 +510,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
//case EbtBool: newOp = EOpConvBoolToDouble; break;
//case EbtFloat: newOp = EOpConvFloatToDouble; break;
//default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0;
//}
break;
@ -521,7 +521,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtBool: newOp = EOpConvBoolToFloat; break;
case EbtDouble: newOp = EOpConvDoubleToFloat; break;
default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0;
}
break;
@ -532,7 +532,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtFloat: newOp = EOpConvFloatToBool; break;
case EbtDouble: newOp = EOpConvDoubleToBool; break;
default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0;
}
break;
@ -543,7 +543,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtFloat: newOp = EOpConvFloatToInt; break;
case EbtDouble: newOp = EOpConvDoubleToInt; break;
default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0;
}
break;
@ -554,18 +554,18 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtFloat: newOp = EOpConvFloatToUint; break;
case EbtDouble: newOp = EOpConvDoubleToUint; break;
default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0;
}
break;
default:
infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLoc());
return 0;
}
TType type(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
newNode = new TIntermUnary(newOp, type);
newNode->setLine(node->getLine());
newNode->setLoc(node->getLoc());
newNode->setOperand(node);
return newNode;
@ -628,7 +628,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to)
// Returns the resulting aggregate, unless 0 was passed in for
// both existing nodes.
//
TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line)
TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right)
{
if (left == 0 && right == 0)
return 0;
@ -645,8 +645,13 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
if (right)
aggNode->getSequence().push_back(right);
if (line != 0)
aggNode->setLine(line);
return aggNode;
}
TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc loc)
{
TIntermAggregate* aggNode = growAggregate(left, right);
aggNode->setLoc(loc);
return aggNode;
}
@ -656,18 +661,26 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
//
// Returns an aggregate, unless 0 was passed in for the existing node.
//
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line)
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node)
{
if (node == 0)
return 0;
TIntermAggregate* aggNode = new TIntermAggregate;
aggNode->getSequence().push_back(node);
aggNode->setLoc(node->getLoc());
if (line != 0)
aggNode->setLine(line);
else
aggNode->setLine(node->getLine());
return aggNode;
}
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc loc)
{
if (node == 0)
return 0;
TIntermAggregate* aggNode = new TIntermAggregate;
aggNode->getSequence().push_back(node);
aggNode->setLoc(loc);
return aggNode;
}
@ -679,7 +692,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc lin
//
// Returns the selection node created.
//
TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line)
TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc loc)
{
//
// For compile time constant selections, prune the code and
@ -694,20 +707,20 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
}
TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
node->setLine(line);
node->setLoc(loc);
return node;
}
TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
{
if (left->getType().getQualifier().storage == EvqConst &&
right->getType().getQualifier().storage == EvqConst) {
return right;
} else {
TIntermTyped *commaAggregate = growAggregate(left, right, line);
TIntermTyped *commaAggregate = growAggregate(left, right, loc);
commaAggregate->getAsAggregate()->setOperator(EOpComma);
commaAggregate->setType(right->getType());
commaAggregate->getTypePointer()->getQualifier().storage = EvqTemporary;
@ -717,10 +730,10 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
}
}
TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, TSourceLoc line)
TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, TSourceLoc loc)
{
TIntermMethod* method = new TIntermMethod(object, type, *name);
method->setLine(line);
method->setLoc(loc);
return method;
}
@ -732,7 +745,7 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
//
// Returns the selection node created, or 0 if one could not be.
//
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc loc)
{
//
// Get compatible types.
@ -767,7 +780,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// Make a selection node.
//
TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
node->setLine(line);
node->setLoc(loc);
node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);
return node;
@ -779,20 +792,20 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// Returns the constant union node created.
//
TIntermConstantUnion* TIntermediate::addConstantUnion(constUnion* unionArrayPointer, const TType& t, TSourceLoc line)
TIntermConstantUnion* TIntermediate::addConstantUnion(constUnion* unionArrayPointer, const TType& t, TSourceLoc loc)
{
TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
node->setLine(line);
node->setLoc(loc);
return node;
}
TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc loc)
{
TIntermAggregate* node = new TIntermAggregate(EOpSequence);
node->setLine(line);
node->setLoc(loc);
TIntermConstantUnion* constIntNode;
TIntermSequence &sequenceVector = node->getSequence();
constUnion* unionArray;
@ -800,7 +813,7 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
for (int i = 0; i < fields.num; i++) {
unionArray = new constUnion[1];
unionArray->setIConst(fields.offsets[i]);
constIntNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), line);
constIntNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc);
sequenceVector.push_back(constIntNode);
}
@ -810,10 +823,10 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
//
// Create loop nodes.
//
TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc line)
TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc loc)
{
TIntermNode* node = new TIntermLoop(body, test, terminal, testFirst);
node->setLine(line);
node->setLoc(loc);
return node;
}
@ -821,15 +834,15 @@ TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TInte
//
// Add branches.
//
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line)
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc loc)
{
return addBranch(branchOp, 0, line);
return addBranch(branchOp, 0, loc);
}
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line)
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc loc)
{
TIntermBranch* node = new TIntermBranch(branchOp, expression);
node->setLine(line);
node->setLoc(loc);
return node;
}
@ -886,7 +899,7 @@ void TIntermediate::addSymbolLinkageNodes(TIntermNode* root, TIntermAggregate*&
linkage->setOperator(EOpLinkerObjects);
// Add a child to the root node for the linker objects
growAggregate(root, linkage, 0);
growAggregate(root, linkage);
}
}
@ -900,7 +913,7 @@ void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTabl
void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable& variable)
{
TIntermSymbol* node = new TIntermSymbol(variable.getUniqueId(), variable.getName(), variable.getType());
linkage = growAggregate(linkage, node, 0);
linkage = growAggregate(linkage, node);
}
//
@ -1218,7 +1231,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
setType(TType(basicType, EvqTemporary, right->getVectorSize()));
}
} else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
infoSink.info.message(EPrefixInternalError, "Missing elses", getLoc());
return false;
}
break;
@ -1250,7 +1263,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
op = EOpVectorTimesScalarAssign;
}
} else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
infoSink.info.message(EPrefixInternalError, "Missing elses", getLoc());
return false;
}
break;
@ -1381,7 +1394,7 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
{
if (node->getType().isArray())
infoSink.info.message(EPrefixInternalError, "Cannot promote array", node->getLine());
infoSink.info.message(EPrefixInternalError, "Cannot promote array", node->getLoc());
constUnion *rightUnionArray = node->getUnionArrayPointer();
int size = node->getType().getObjectSize();
@ -1408,7 +1421,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
break;
default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
return 0;
}
break;
@ -1428,7 +1441,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i] = rightUnionArray[i];
break;
default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
return 0;
}
break;
@ -1448,7 +1461,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst()));
break;
default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
return 0;
}
break;
@ -1468,7 +1481,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst()));
break;
default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
return 0;
}
break;
@ -1488,12 +1501,12 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0);
break;
default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
return 0;
}
break;
default:
infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLoc());
return 0;
}
}
@ -1501,7 +1514,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
const TType& t = node->getType();
return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()),
node->getLine());
node->getLoc());
}
void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,9 @@ struct TPragma {
TPragmaTable pragmaTable;
};
namespace glslang {
class TScanContext;
};
//
// The following are extra variables needed during parsing, grouped together so
@ -64,6 +66,7 @@ struct TPragma {
struct TParseContext {
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&,
bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
glslang::TScanContext *scanContext;
TIntermediate& intermediate; // to hold and build a parse tree
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
TInfoSink& infoSink;
@ -71,7 +74,6 @@ struct TParseContext {
TIntermNode* treeRoot; // root of parse tree being created
TIntermAggregate *linkage; // aggregate node of objects the linker may need, if not reference by the rest of the AST
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
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
@ -91,7 +93,7 @@ struct TParseContext {
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex()
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
TString HashErrMsg;
bool AfterEOF;
bool afterEOF;
const TString* blockName;
TQualifier globalUniformDefaults;
TQualifier globalInputDefaults;
@ -100,93 +102,91 @@ struct TParseContext {
void initializeExtensionBehavior();
const char* getPreamble();
bool parseShaderStrings(char* strings[], int strLen[], int numStrings);
void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
const char *szExtraInfoFormat, ...);
void C_DECL warn(TSourceLoc, const char *szReason, const char *szToken,
const char *szExtraInfoFormat, ...);
bool reservedErrorCheck(int line, const TString& identifier);
bool reservedErrorCheck(TSourceLoc, const TString& identifier);
TIntermTyped* handleVariable(int line, TSymbol* symbol, TString* string);
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
void assignError(int line, const char* op, TString left, TString right);
void unaryOpError(int line, const char* op, TString operand);
void binaryOpError(int line, const char* op, TString left, TString right);
TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&);
void assignError(TSourceLoc, const char* op, TString left, TString right);
void unaryOpError(TSourceLoc, const char* op, TString operand);
void binaryOpError(TSourceLoc, const char* op, TString left, TString right);
void variableCheck(TIntermTyped*& nodePtr);
bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
bool lValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*);
void constCheck(TIntermTyped* node, const char* token);
void integerCheck(TIntermTyped* node, const char* token);
void globalCheck(int line, bool global, const char* token);
bool constructorError(int line, TIntermNode*, TFunction&, TOperator, TType&);
void arraySizeCheck(int line, TIntermTyped* expr, int& size);
bool arrayQualifierError(int line, const TPublicType&);
void arraySizeRequiredCheck(int line, int& size);
void arrayDimError(int line);
void arrayDimCheck(int line, TArraySizes sizes1, TArraySizes sizes2);
void arrayDimCheck(int line, const TType*, TArraySizes);
void arrayCheck(int line, TString& identifier, const TPublicType&, TVariable*& variable);
void globalCheck(TSourceLoc, bool global, const char* token);
bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&);
void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size);
bool arrayQualifierError(TSourceLoc, const TPublicType&);
void arraySizeRequiredCheck(TSourceLoc, int& size);
void arrayDimError(TSourceLoc);
void arrayDimCheck(TSourceLoc, TArraySizes sizes1, TArraySizes sizes2);
void arrayDimCheck(TSourceLoc, const TType*, TArraySizes);
void arrayCheck(TSourceLoc, TString& identifier, const TPublicType&, TVariable*& variable);
bool insertBuiltInArrayAtGlobalLevel();
bool voidErrorCheck(int, const TString&, const TPublicType&);
void boolCheck(int, const TIntermTyped*);
void boolCheck(int, const TPublicType&);
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
void globalQualifierFix(int line, TQualifier&, const TPublicType&);
bool structQualifierErrorCheck(int line, const TPublicType& pType);
void mergeQualifiers(int line, TQualifier& dst, const TQualifier& src, bool force);
void setDefaultPrecision(int line, TPublicType&, TPrecisionQualifier);
bool voidErrorCheck(TSourceLoc, const TString&, const TPublicType&);
void boolCheck(TSourceLoc, const TIntermTyped*);
void boolCheck(TSourceLoc, const TPublicType&);
bool samplerErrorCheck(TSourceLoc, const TPublicType& pType, const char* reason);
void globalQualifierFix(TSourceLoc, TQualifier&, const TPublicType&);
bool structQualifierErrorCheck(TSourceLoc, const TPublicType& pType);
void mergeQualifiers(TSourceLoc, TQualifier& dst, const TQualifier& src, bool force);
void setDefaultPrecision(TSourceLoc, TPublicType&, TPrecisionQualifier);
int computeSamplerTypeIndex(TSampler&);
TPrecisionQualifier getDefaultPrecision(TPublicType&);
void precisionQualifierCheck(int line, TPublicType&);
void parameterSamplerCheck(int line, TStorageQualifier qualifier, const TType& type);
void precisionQualifierCheck(TSourceLoc, TPublicType&);
void parameterSamplerCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type);
bool containsSampler(const TType& type);
void nonInitConstCheck(int line, TString& identifier, TPublicType& type);
void nonInitCheck(int line, TString& identifier, TPublicType& type);
void paramCheck(int line, TStorageQualifier qualifier, TType* type);
void nestedBlockCheck(int line);
void nestedStructCheck(int line);
void nonInitConstCheck(TSourceLoc, TString& identifier, TPublicType& type);
void nonInitCheck(TSourceLoc, TString& identifier, TPublicType& type);
void paramCheck(TSourceLoc, TStorageQualifier qualifier, TType* type);
void nestedBlockCheck(TSourceLoc);
void nestedStructCheck(TSourceLoc);
void setLayoutQualifier(int line, TPublicType&, TString&);
void setLayoutQualifier(int line, TPublicType&, TString&, int);
void mergeLayoutQualifiers(int line, TQualifier& dest, const TQualifier& src);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
void mergeLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src);
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
bool executeInitializerError(TSourceLoc line, TString& identifier, TPublicType& pType,
const TFunction* findFunction(TSourceLoc, TFunction* pfnCall, bool *builtIn = 0);
bool executeInitializerError(TSourceLoc, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
TIntermTyped* addConstructor(TIntermNode*, const TType&, TOperator, TFunction*, TSourceLoc);
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
void addBlock(int line, TTypeList& typeList, const TString* instanceName = 0, TArraySizes arraySizes = 0);
void addQualifierToExisting(int line, TQualifier, const TString& identifier);
void addQualifierToExisting(int line, TQualifier, TIdentifierList&);
void addBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes arraySizes = 0);
void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier);
void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
void updateQualifierDefaults(TQualifier);
void updateQualifierDefaults(int line, TQualifier);
void updateTypedDefaults(int line, TQualifier, const TString* id);
void updateQualifierDefaults(TSourceLoc, TQualifier);
void updateTypedDefaults(TSourceLoc, TQualifier, const TString* id);
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
TIntermNode* addSwitch(int line, TIntermTyped* expression, TIntermAggregate* body);
TIntermNode* addSwitch(TSourceLoc, TIntermTyped* expression, TIntermAggregate* body);
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc);
TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
void requireProfile(int line, EProfileMask profileMask, const char *featureDesc);
void requireStage(int line, EShLanguageMask languageMask, const char *featureDesc);
void profileRequires(int line, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc);
void profileRequires(int line, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc);
void checkDeprecated(int line, EProfile callingProfile, int depVersion, const char *featureDesc);
void requireNotRemoved(int line, EProfile callingProfile, int removedVersion, const char *featureDesc);
void fullIntegerCheck(int line, const char* op);
void doubleCheck(int line, const char* op);
void requireProfile(TSourceLoc, EProfileMask profileMask, const char *featureDesc);
void requireStage(TSourceLoc, EShLanguageMask languageMask, const char *featureDesc);
void profileRequires(TSourceLoc, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc);
void profileRequires(TSourceLoc, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc);
void checkDeprecated(TSourceLoc, EProfile callingProfile, int depVersion, const char *featureDesc);
void requireNotRemoved(TSourceLoc, EProfile callingProfile, int removedVersion, const char *featureDesc);
void fullIntegerCheck(TSourceLoc, const char* op);
void doubleCheck(TSourceLoc, const char* op);
};
int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&, const char* preamble);
int PaParseComment(int &lineno, TParseContext&);
void ResetFlex();
typedef TParseContext* TParseContextPointer;
TParseContextPointer& ThreadLocalParseContext();
// TODO: threading:
typedef struct TThreadParseContextRec
{
TParseContext *lpGlobalParseContext;

View File

@ -34,9 +34,24 @@
//POSSIBILITY OF SUCH DAMAGE.
//
//
// GLSL scanning, leveraging the scanning done by the preprocessor.
//
#include <string.h>
#include "Scan.h"
#include "Include/Types.h"
#include "SymbolTable.h"
#include "glslang_tab.cpp.h"
#include "ParseHelper.h"
#include "ScanContext.h"
// preprocessor includes
extern "C" {
#include "preprocessor/parser.h"
#include "preprocessor/preprocess.h"
}
namespace glslang {
@ -138,10 +153,14 @@ void ConsumeWhitespaceComment(TInputScanner& input, bool& foundNonSpaceTab)
} while (true);
}
// Returns true if there was non-white space (e.g., a comment, newline) before the #version;
// otherwise, returns true.
// Returns true if there was non-white space (e.g., a comment, newline) before the #version
// or no #version was found; otherwise, returns false. There is no error case, it always
// succeeds, but will leave version == 0 if no #version was found.
//
// N.B. does not attempt to leave input in any particular known state. The assumption
// is that scanning will start anew, following the rules for the chosen version/profile,
// and with a corresponding parsing context.
//
// N.B. does not attempt to leave input in any particular known state
bool ScanVersion(TInputScanner& input, int& version, EProfile& profile)
{
// This function doesn't have to get all the semantics correct,
@ -214,3 +233,793 @@ bool ScanVersion(TInputScanner& input, int& version, EProfile& profile)
}
}; // end glslang namespace
namespace glslang {
// This gets filled in by the preprocessor scanner.
class TPpToken{
public:
yystypepp lexer;
};
// Fill this in when doing glslang-level scanning, to hand back to the parser.
class TParserToken {
public:
explicit TParserToken(YYSTYPE& b) : sType(b) { }
YYSTYPE& sType;
};
}; // end namespace glslang
// This is the function the glslang parser (i.e., bison) calls to get its next token
int yylex(YYSTYPE* glslangTokenDesc, TParseContext& parseContext)
{
glslang::TParserToken token(*glslangTokenDesc);
return parseContext.scanContext->tokenize(token);
}
namespace {
// A single global usable by all threads, by all versions, by all languages.
// After a single process-level initialization, this is read only and thread safe
std::map<std::string, int>* KeywordMap = 0;
std::set<std::string>* ReservedSet = 0;
};
namespace glslang {
void TScanContext::fillInKeywordMap()
{
if (KeywordMap != 0) {
// this is really an error, as this should called only once per process
// but, the only risk is if two threads called simultaneously
return;
}
KeywordMap = new std::map<std::string, int>;
(*KeywordMap)["const"] = CONST;
(*KeywordMap)["uniform"] = UNIFORM;
(*KeywordMap)["in"] = IN;
(*KeywordMap)["out"] = OUT;
(*KeywordMap)["inout"] = INOUT;
(*KeywordMap)["struct"] = STRUCT;
(*KeywordMap)["break"] = BREAK;
(*KeywordMap)["continue"] = CONTINUE;
(*KeywordMap)["do"] = DO;
(*KeywordMap)["for"] = FOR;
(*KeywordMap)["while"] = WHILE;
(*KeywordMap)["switch"] = SWITCH;
(*KeywordMap)["case"] = CASE;
(*KeywordMap)["default"] = DEFAULT;
(*KeywordMap)["if"] = IF;
(*KeywordMap)["else"] = ELSE;
(*KeywordMap)["discard"] = DISCARD;
(*KeywordMap)["return"] = RETURN;
(*KeywordMap)["void"] = VOID;
(*KeywordMap)["bool"] = BOOL;
(*KeywordMap)["float"] = FLOAT;
(*KeywordMap)["int"] = INT;
(*KeywordMap)["bvec2"] = BVEC2;
(*KeywordMap)["bvec3"] = BVEC3;
(*KeywordMap)["bvec4"] = BVEC4;
(*KeywordMap)["vec2"] = VEC2;
(*KeywordMap)["vec3"] = VEC3;
(*KeywordMap)["vec4"] = VEC4;
(*KeywordMap)["ivec2"] = IVEC2;
(*KeywordMap)["ivec3"] = IVEC3;
(*KeywordMap)["ivec4"] = IVEC4;
(*KeywordMap)["mat2"] = MAT2;
(*KeywordMap)["mat3"] = MAT3;
(*KeywordMap)["mat4"] = MAT4;
(*KeywordMap)["sampler2D"] = SAMPLER2D;
(*KeywordMap)["samplerCube"] = SAMPLERCUBE;
(*KeywordMap)["true"] = BOOLCONSTANT;
(*KeywordMap)["false"] = BOOLCONSTANT;
(*KeywordMap)["attribute"] = ATTRIBUTE;
(*KeywordMap)["varying"] = VARYING;
(*KeywordMap)["buffer"] = BUFFER;
(*KeywordMap)["coherent"] = COHERENT;
(*KeywordMap)["restrict"] = RESTRICT;
(*KeywordMap)["readonly"] = READONLY;
(*KeywordMap)["writeonly"] = WRITEONLY;
(*KeywordMap)["atomic_uint"] = ATOMIC_UINT;
(*KeywordMap)["volatile"] = VOLATILE;
(*KeywordMap)["layout"] = LAYOUT;
(*KeywordMap)["shared"] = SHARED;
(*KeywordMap)["patch"] = PATCH;
(*KeywordMap)["sample"] = SAMPLE;
(*KeywordMap)["subroutine"] = SUBROUTINE;
(*KeywordMap)["highp"] = HIGH_PRECISION;
(*KeywordMap)["mediump"] = MEDIUM_PRECISION;
(*KeywordMap)["lowp"] = LOW_PRECISION;
(*KeywordMap)["precision"] = PRECISION;
(*KeywordMap)["mat2x2"] = MAT2X2;
(*KeywordMap)["mat2x3"] = MAT2X3;
(*KeywordMap)["mat2x4"] = MAT2X4;
(*KeywordMap)["mat3x2"] = MAT3X2;
(*KeywordMap)["mat3x3"] = MAT3X3;
(*KeywordMap)["mat3x4"] = MAT3X4;
(*KeywordMap)["mat4x2"] = MAT4X2;
(*KeywordMap)["mat4x3"] = MAT4X3;
(*KeywordMap)["mat4x4"] = MAT4X4;
(*KeywordMap)["dmat2"] = DMAT2;
(*KeywordMap)["dmat3"] = DMAT3;
(*KeywordMap)["dmat4"] = DMAT4;
(*KeywordMap)["dmat2x2"] = DMAT2X2;
(*KeywordMap)["dmat2x3"] = DMAT2X3;
(*KeywordMap)["dmat2x4"] = DMAT2X4;
(*KeywordMap)["dmat3x2"] = DMAT3X2;
(*KeywordMap)["dmat3x3"] = DMAT3X3;
(*KeywordMap)["dmat3x4"] = DMAT3X4;
(*KeywordMap)["dmat4x2"] = DMAT4X2;
(*KeywordMap)["dmat4x3"] = DMAT4X3;
(*KeywordMap)["dmat4x4"] = DMAT4X4;
(*KeywordMap)["image1D"] = IMAGE1D;
(*KeywordMap)["iimage1D"] = IIMAGE1D;
(*KeywordMap)["uimage1D"] = UIMAGE1D;
(*KeywordMap)["image2D"] = IMAGE2D;
(*KeywordMap)["iimage2D"] = IIMAGE2D;
(*KeywordMap)["uimage2D"] = UIMAGE2D;
(*KeywordMap)["image3D"] = IMAGE3D;
(*KeywordMap)["iimage3D"] = IIMAGE3D;
(*KeywordMap)["uimage3D"] = UIMAGE3D;
(*KeywordMap)["image2DRect"] = IMAGE2DRECT;
(*KeywordMap)["iimage2DRect"] = IIMAGE2DRECT;
(*KeywordMap)["uimage2DRect"] = UIMAGE2DRECT;
(*KeywordMap)["imageCube"] = IMAGECUBE;
(*KeywordMap)["iimageCube"] = IIMAGECUBE;
(*KeywordMap)["uimageCube"] = UIMAGECUBE;
(*KeywordMap)["imageBuffer"] = IMAGEBUFFER;
(*KeywordMap)["iimageBuffer"] = IIMAGEBUFFER;
(*KeywordMap)["uimageBuffer"] = UIMAGEBUFFER;
(*KeywordMap)["image1DArray"] = IMAGE1DARRAY;
(*KeywordMap)["iimage1DArray"] = IIMAGE1DARRAY;
(*KeywordMap)["uimage1DArray"] = UIMAGE1DARRAY;
(*KeywordMap)["image2DArray"] = IMAGE2DARRAY;
(*KeywordMap)["iimage2DArray"] = IIMAGE2DARRAY;
(*KeywordMap)["uimage2DArray"] = UIMAGE2DARRAY;
(*KeywordMap)["imageCubeArray"] = IMAGECUBEARRAY;
(*KeywordMap)["iimageCubeArray"] = IIMAGECUBEARRAY;
(*KeywordMap)["uimageCubeArray"] = UIMAGECUBEARRAY;
(*KeywordMap)["image2DMS"] = IMAGE2DMS;
(*KeywordMap)["iimage2DMS"] = IIMAGE2DMS;
(*KeywordMap)["uimage2DMS"] = UIMAGE2DMS;
(*KeywordMap)["image2DMSArray"] = IMAGE2DMSARRAY;
(*KeywordMap)["iimage2DMSArray"] = IIMAGE2DMSARRAY;
(*KeywordMap)["uimage2DMSArray"] = UIMAGE2DMSARRAY;
(*KeywordMap)["double"] = DOUBLE;
(*KeywordMap)["dvec2"] = DVEC2;
(*KeywordMap)["dvec3"] = DVEC3;
(*KeywordMap)["dvec4"] = DVEC4;
(*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY;
(*KeywordMap)["samplerCubeArrayShadow"] = SAMPLERCUBEARRAYSHADOW;
(*KeywordMap)["isamplerCubeArray"] = ISAMPLERCUBEARRAY;
(*KeywordMap)["usamplerCubeArray"] = USAMPLERCUBEARRAY;
(*KeywordMap)["sampler1DArrayShadow"] = SAMPLER1DARRAYSHADOW;
(*KeywordMap)["isampler1DArray"] = ISAMPLER1DARRAY;
(*KeywordMap)["usampler1D"] = USAMPLER1D;
(*KeywordMap)["isampler1D"] = ISAMPLER1D;
(*KeywordMap)["usampler1DArray"] = USAMPLER1DARRAY;
(*KeywordMap)["samplerBuffer"] = SAMPLERBUFFER;
(*KeywordMap)["uint"] = UINT;
(*KeywordMap)["uvec2"] = UVEC2;
(*KeywordMap)["uvec3"] = UVEC3;
(*KeywordMap)["uvec4"] = UVEC4;
(*KeywordMap)["samplerCubeShadow"] = SAMPLERCUBESHADOW;
(*KeywordMap)["sampler2DArray"] = SAMPLER2DARRAY;
(*KeywordMap)["sampler2DArrayShadow"] = SAMPLER2DARRAYSHADOW;
(*KeywordMap)["isampler2D"] = ISAMPLER2D;
(*KeywordMap)["isampler3D"] = ISAMPLER3D;
(*KeywordMap)["isamplerCube"] = ISAMPLERCUBE;
(*KeywordMap)["isampler2DArray"] = ISAMPLER2DARRAY;
(*KeywordMap)["usampler2D"] = USAMPLER2D;
(*KeywordMap)["usampler3D"] = USAMPLER3D;
(*KeywordMap)["usamplerCube"] = USAMPLERCUBE;
(*KeywordMap)["usampler2DArray"] = USAMPLER2DARRAY;
(*KeywordMap)["isampler2DRect"] = ISAMPLER2DRECT;
(*KeywordMap)["usampler2DRect"] = USAMPLER2DRECT;
(*KeywordMap)["isamplerBuffer"] = ISAMPLERBUFFER;
(*KeywordMap)["usamplerBuffer"] = USAMPLERBUFFER;
(*KeywordMap)["sampler2DMS"] = SAMPLER2DMS;
(*KeywordMap)["isampler2DMS"] = ISAMPLER2DMS;
(*KeywordMap)["usampler2DMS"] = USAMPLER2DMS;
(*KeywordMap)["sampler2DMSArray"] = SAMPLER2DMSARRAY;
(*KeywordMap)["isampler2DMSArray"] = ISAMPLER2DMSARRAY;
(*KeywordMap)["usampler2DMSArray"] = USAMPLER2DMSARRAY;
(*KeywordMap)["sampler1D"] = SAMPLER1D;
(*KeywordMap)["sampler1DShadow"] = SAMPLER1DSHADOW;
(*KeywordMap)["sampler3D"] = SAMPLER3D;
(*KeywordMap)["sampler2DShadow"] = SAMPLER2DSHADOW;
(*KeywordMap)["sampler2DRect"] = SAMPLER2DRECT;
(*KeywordMap)["sampler2DRectShadow"] = SAMPLER2DRECTSHADOW;
(*KeywordMap)["sampler1DArray"] = SAMPLER1DARRAY;
(*KeywordMap)["noperspective"] = NOPERSPECTIVE;
(*KeywordMap)["smooth"] = SMOOTH;
(*KeywordMap)["flat"] = FLAT;
(*KeywordMap)["centroid"] = CENTROID;
(*KeywordMap)["precise"] = PRECISE;
(*KeywordMap)["invariant"] = INVARIANT;
(*KeywordMap)["packed"] = PACKED;
(*KeywordMap)["resource"] = RESOURCE;
(*KeywordMap)["superp"] = SUPERP;
ReservedSet = new std::set<std::string>;
ReservedSet->insert("common");
ReservedSet->insert("partition");
ReservedSet->insert("active");
ReservedSet->insert("asm");
ReservedSet->insert("class");
ReservedSet->insert("union");
ReservedSet->insert("enum");
ReservedSet->insert("typedef");
ReservedSet->insert("template");
ReservedSet->insert("this");
ReservedSet->insert("goto");
ReservedSet->insert("inline");
ReservedSet->insert("noinline");
ReservedSet->insert("public");
ReservedSet->insert("static");
ReservedSet->insert("extern");
ReservedSet->insert("external");
ReservedSet->insert("interface");
ReservedSet->insert("long");
ReservedSet->insert("short");
ReservedSet->insert("half");
ReservedSet->insert("fixed");
ReservedSet->insert("unsigned");
ReservedSet->insert("input");
ReservedSet->insert("output");
ReservedSet->insert("hvec2");
ReservedSet->insert("hvec3");
ReservedSet->insert("hvec4");
ReservedSet->insert("fvec2");
ReservedSet->insert("fvec3");
ReservedSet->insert("fvec4");
ReservedSet->insert("sampler3DRect");
ReservedSet->insert("filter");
ReservedSet->insert("sizeof");
ReservedSet->insert("cast");
ReservedSet->insert("namespace");
ReservedSet->insert("using");
}
int TScanContext::tokenize(TParserToken& token)
{
parserToken = &token;
TPpToken ppTokenStorage;
ppToken = &ppTokenStorage;
tokenText = PpTokenize(&ppToken->lexer);
loc.string = cpp->tokenLoc->file;
loc.line = cpp->tokenLoc->line;
parserToken->sType.lex.loc = loc;
switch (ppToken->lexer.ppToken) {
case ';': afterType = false; return SEMICOLON;
case ',': afterType = false; return COMMA;
case ':': return COLON;
case '=': afterType = false; return EQUAL;
case '(': afterType = false; return LEFT_PAREN;
case ')': afterType = false; return RIGHT_PAREN;
case '.': field = true; return DOT;
case '!': return BANG;
case '-': return DASH;
case '~': return TILDE;
case '+': return PLUS;
case '*': return STAR;
case '/': return SLASH;
case '%': return PERCENT;
case '<': return LEFT_ANGLE;
case '>': return RIGHT_ANGLE;
case '|': return VERTICAL_BAR;
case '^': return CARET;
case '&': return AMPERSAND;
case '?': return QUESTION;
case '[': return LEFT_BRACKET;
case ']': return RIGHT_BRACKET;
case '{': return LEFT_BRACE;
case '}': return RIGHT_BRACE;
case CPP_AND_OP: return AND_OP;
case CPP_SUB_ASSIGN: return SUB_ASSIGN;
case CPP_MOD_ASSIGN: return MOD_ASSIGN;
case CPP_ADD_ASSIGN: return ADD_ASSIGN;
case CPP_DIV_ASSIGN: return DIV_ASSIGN;
case CPP_MUL_ASSIGN: return MUL_ASSIGN;
case CPP_EQ_OP: return EQ_OP;
case CPP_XOR_OP: return XOR_OP;
case CPP_GE_OP: return GE_OP;
case CPP_RIGHT_OP: return RIGHT_OP;
case CPP_LE_OP: return LE_OP;
case CPP_LEFT_OP: return LEFT_OP;
case CPP_DEC_OP: return DEC_OP;
case CPP_NE_OP: return NE_OP;
case CPP_OR_OP: return OR_OP;
case CPP_INC_OP: return INC_OP;
case CPP_RIGHT_ASSIGN: return RIGHT_ASSIGN;
case CPP_LEFT_ASSIGN: return LEFT_ASSIGN;
case CPP_AND_ASSIGN: return AND_ASSIGN;
case CPP_OR_ASSIGN: return OR_ASSIGN;
case CPP_XOR_ASSIGN: return XOR_ASSIGN;
case CPP_INTCONSTANT: parserToken->sType.lex.i = ppToken->lexer.sc_int; return INTCONSTANT;
case CPP_UINTCONSTANT: parserToken->sType.lex.i = ppToken->lexer.sc_int; return UINTCONSTANT;
case CPP_FLOATCONSTANT: parserToken->sType.lex.d = ppToken->lexer.sc_dval; return FLOATCONSTANT;
case CPP_DOUBLECONSTANT: parserToken->sType.lex.d = ppToken->lexer.sc_dval; return DOUBLECONSTANT;
case CPP_IDENTIFIER: return tokenizeIdentifier();
case EOF: return 0;
default:
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown PP token", loc);
return 0;
}
}
int TScanContext::tokenizeIdentifier()
{
if (ReservedSet->find(tokenText) != ReservedSet->end())
return reservedWord();
keyword = (*KeywordMap)[tokenText];
if (keyword == 0) {
// Should have an identifier of some sort
return identifierOrType();
}
field = false;
switch (keyword) {
case CONST:
case UNIFORM:
case IN:
case OUT:
case INOUT:
case STRUCT:
case BREAK:
case CONTINUE:
case DO:
case FOR:
case WHILE:
case IF:
case ELSE:
case DISCARD:
case RETURN:
case CASE:
return keyword;
case SWITCH:
case DEFAULT:
if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
parseContext.profile != EEsProfile && parseContext.version < 130)
reservedWord();
return keyword;
case VOID:
case BOOL:
case FLOAT:
case INT:
case BVEC2:
case BVEC3:
case BVEC4:
case VEC2:
case VEC3:
case VEC4:
case IVEC2:
case IVEC3:
case IVEC4:
case MAT2:
case MAT3:
case MAT4:
case SAMPLER2D:
case SAMPLERCUBE:
afterType = true;
return keyword;
case BOOLCONSTANT:
if (strcmp("true", tokenText) == 0)
parserToken->sType.lex.b = true;
else
parserToken->sType.lex.b = false;
return keyword;
case ATTRIBUTE:
case VARYING:
if (parseContext.profile == EEsProfile && parseContext.version >= 300)
reservedWord();
return keyword;
case BUFFER:
if (parseContext.version < 430)
return identifierOrType();
return keyword;
case COHERENT:
case RESTRICT:
case READONLY:
case WRITEONLY:
case ATOMIC_UINT:
return es30ReservedFromGLSL(420);
case VOLATILE:
if (parseContext.profile == EEsProfile || parseContext.version < 420)
reservedWord();
return keyword;
case LAYOUT:
case SHARED:
if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
parseContext.profile != EEsProfile && parseContext.version < 140)
return identifierOrType();
return keyword;
case PATCH:
case SAMPLE:
case SUBROUTINE:
return es30ReservedFromGLSL(400);
case HIGH_PRECISION:
case MEDIUM_PRECISION:
case LOW_PRECISION:
case PRECISION:
return precisionKeyword();
case MAT2X2:
case MAT2X3:
case MAT2X4:
case MAT3X2:
case MAT3X3:
case MAT3X4:
case MAT4X2:
case MAT4X3:
case MAT4X4:
return matNxM();
case DMAT2:
case DMAT3:
case DMAT4:
case DMAT2X2:
case DMAT2X3:
case DMAT2X4:
case DMAT3X2:
case DMAT3X3:
case DMAT3X4:
case DMAT4X2:
case DMAT4X3:
case DMAT4X4:
return dMat();
case IMAGE1D:
case IIMAGE1D:
case UIMAGE1D:
case IMAGE2D:
case IIMAGE2D:
case UIMAGE2D:
case IMAGE3D:
case IIMAGE3D:
case UIMAGE3D:
case IMAGE2DRECT:
case IIMAGE2DRECT:
case UIMAGE2DRECT:
case IMAGECUBE:
case IIMAGECUBE:
case UIMAGECUBE:
case IMAGEBUFFER:
case IIMAGEBUFFER:
case UIMAGEBUFFER:
case IMAGE1DARRAY:
case IIMAGE1DARRAY:
case UIMAGE1DARRAY:
case IMAGE2DARRAY:
case IIMAGE2DARRAY:
case UIMAGE2DARRAY:
return firstGenerationImage();
case IMAGECUBEARRAY:
case IIMAGECUBEARRAY:
case UIMAGECUBEARRAY:
case IMAGE2DMS:
case IIMAGE2DMS:
case UIMAGE2DMS:
case IMAGE2DMSARRAY:
case IIMAGE2DMSARRAY:
case UIMAGE2DMSARRAY:
return secondGenerationImage();
case DOUBLE:
case DVEC2:
case DVEC3:
case DVEC4:
case SAMPLERCUBEARRAY:
case SAMPLERCUBEARRAYSHADOW:
case ISAMPLERCUBEARRAY:
case USAMPLERCUBEARRAY:
afterType = true;
if (parseContext.profile == EEsProfile || parseContext.version < 400)
reservedWord();
return keyword;
case ISAMPLER1D:
case ISAMPLER1DARRAY:
case SAMPLER1DARRAYSHADOW:
case USAMPLER1D:
case USAMPLER1DARRAY:
case SAMPLERBUFFER:
afterType = true;
return es30ReservedFromGLSL(130);
case UINT:
case UVEC2:
case UVEC3:
case UVEC4:
case SAMPLERCUBESHADOW:
case SAMPLER2DARRAY:
case SAMPLER2DARRAYSHADOW:
case ISAMPLER2D:
case ISAMPLER3D:
case ISAMPLERCUBE:
case ISAMPLER2DARRAY:
case USAMPLER2D:
case USAMPLER3D:
case USAMPLERCUBE:
case USAMPLER2DARRAY:
afterType = true;
return nonreservedKeyword(300, 130);
case ISAMPLER2DRECT:
case USAMPLER2DRECT:
case ISAMPLERBUFFER:
case USAMPLERBUFFER:
afterType = true;
return es30ReservedFromGLSL(140);
case SAMPLER2DMS:
case ISAMPLER2DMS:
case USAMPLER2DMS:
case SAMPLER2DMSARRAY:
case ISAMPLER2DMSARRAY:
case USAMPLER2DMSARRAY:
afterType = true;
return es30ReservedFromGLSL(150);
case SAMPLER1D:
case SAMPLER1DSHADOW:
afterType = true;
if (parseContext.profile == EEsProfile)
reservedWord();
return keyword;
case SAMPLER3D:
case SAMPLER2DSHADOW:
afterType = true;
if (parseContext.profile == EEsProfile && parseContext.version < 300)
reservedWord();
return keyword;
case SAMPLER2DRECT:
case SAMPLER2DRECTSHADOW:
afterType = true;
if (parseContext.profile == EEsProfile ||
parseContext.profile != EEsProfile && parseContext.version < 140)
reservedWord();
return keyword;
case SAMPLER1DARRAY:
afterType = true;
if (parseContext.profile == EEsProfile && parseContext.version == 300)
reservedWord();
else if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
parseContext.profile != EEsProfile && parseContext.version < 130)
return identifierOrType();
return keyword;
case NOPERSPECTIVE:
return es30ReservedFromGLSL(130);
case SMOOTH:
if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
parseContext.profile != EEsProfile && parseContext.version < 130)
return identifierOrType();
return keyword;
case FLAT:
if (parseContext.profile == EEsProfile && parseContext.version < 300)
reservedWord();
else if (parseContext.profile != EEsProfile && parseContext.version < 130)
return identifierOrType();
return keyword;
case CENTROID:
if (parseContext.version < 120)
return identifierOrType();
return keyword;
case PRECISE:
if (parseContext.profile == EEsProfile ||
parseContext.profile != EEsProfile && parseContext.version < 400)
return identifierOrType();
return keyword;
case INVARIANT:
if (parseContext.profile != EEsProfile && parseContext.version < 120)
return identifierOrType();
return keyword;
case PACKED:
if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
parseContext.profile != EEsProfile && parseContext.version < 330)
return reservedWord();
return identifierOrType();
case RESOURCE:
{
bool reserved = parseContext.profile == EEsProfile && parseContext.version >= 300 ||
parseContext.profile != EEsProfile && parseContext.version >= 420;
return identifierOrReserved(reserved);
}
case SUPERP:
{
bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130;
return identifierOrReserved(reserved);
}
default:
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
return 0;
}
}
int TScanContext::identifierOrType()
{
parserToken->sType.lex.string = NewPoolTString(tokenText);
if (field) {
field = false;
return FIELD_SELECTION;
}
parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
if (afterType == false && parserToken->sType.lex.symbol) {
if (TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
if (variable->isUserType()) {
afterType = true;
return TYPE_NAME;
}
}
}
return IDENTIFIER;
}
int TScanContext::reservedWord()
{
ThreadLocalParseContext()->error(loc, "Reserved word.", tokenText, "", "");
return 0;
}
int TScanContext::identifierOrReserved(bool reserved)
{
if (reserved) {
reservedWord();
return 0;
}
if (parseContext.forwardCompatible)
parseContext.warn(loc, "using future reserved keyword", tokenText, "");
return identifierOrType();
}
// For keywords that suddenly showed up on non-ES (not previously reserved)
// but then got reserved by ES 3.0.
int TScanContext::es30ReservedFromGLSL(int version)
{
if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
parseContext.profile != EEsProfile && parseContext.version < version) {
if (parseContext.forwardCompatible)
parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, "");
return identifierOrType();
} else if (parseContext.profile == EEsProfile && parseContext.version >= 300)
reservedWord();
return keyword;
}
// For a keyword that was never reserved, until it suddenly
// showed up, both in an es version and a non-ES version.
int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion)
{
if (parseContext.profile == EEsProfile && parseContext.version < esVersion ||
parseContext.profile != EEsProfile && parseContext.version < nonEsVersion) {
if (parseContext.forwardCompatible)
parseContext.warn(loc, "using future keyword", tokenText, "");
return identifierOrType();
}
return keyword;
}
int TScanContext::precisionKeyword()
{
if (parseContext.profile == EEsProfile || parseContext.version >= 130)
return keyword;
if (parseContext.forwardCompatible)
parseContext.warn(loc, "using ES precision qualifier keyword", tokenText, "");
return identifierOrType();
}
int TScanContext::matNxM()
{
afterType = true;
if (parseContext.version > 110)
return keyword;
if (parseContext.forwardCompatible)
parseContext.warn(loc, "using future non-square matrix type keyword", tokenText, "");
return identifierOrType();
}
int TScanContext::dMat()
{
afterType = true;
if (parseContext.profile == EEsProfile && parseContext.version >= 300) {
reservedWord();
return keyword;
}
if (parseContext.profile != EEsProfile && parseContext.version >= 400)
return keyword;
if (parseContext.forwardCompatible)
parseContext.warn(loc, "using future type keyword", tokenText, "");
return identifierOrType();
}
int TScanContext::firstGenerationImage()
{
afterType = true;
if (parseContext.profile != EEsProfile && parseContext.version >= 420)
return keyword;
if (parseContext.profile == EEsProfile && parseContext.version >= 300 ||
parseContext.profile != EEsProfile && parseContext.version >= 130) {
reservedWord();
return keyword;
}
if (parseContext.forwardCompatible)
parseContext.warn(loc, "using future type keyword", tokenText, "");
return identifierOrType();
}
int TScanContext::secondGenerationImage()
{
afterType = true;
if (parseContext.profile != EEsProfile && parseContext.version >= 420)
return keyword;
if (parseContext.forwardCompatible)
parseContext.warn(loc, "using future type keyword", tokenText, "");
return identifierOrType();
}
};

View File

@ -105,7 +105,7 @@ protected:
int currentChar;
};
// The location of these is still pending a grand design for going to a singular
// TODO: The location of these is still pending a grand design for going to a singular
// scanner for version finding, preprocessing, and tokenizing:
void ConsumeWhiteSpace(TInputScanner& input, bool& foundNonSpaceTab);
bool ConsumeComment(TInputScanner& input);

View File

@ -0,0 +1,80 @@
//
//Copyright (C) 2013 LunarG, 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.
//
//
// This holds context specific to the GLSL scanner, which
// sits between the preprocessor scanner and parser.
//
#include "ParseHelper.h"
namespace glslang {
class TParserToken;
class TPpToken;
class TScanContext {
public:
explicit TScanContext(TParseContext& pc) : parseContext(pc), afterType(false), field(false) { }
virtual ~TScanContext() { }
static void fillInKeywordMap();
int tokenize(TParserToken&);
protected:
int tokenizeIdentifier();
int identifierOrType();
int reservedWord();
int identifierOrReserved(bool reserved);
int es30ReservedFromGLSL(int version);
int nonreservedKeyword(int esVersion, int nonEsVersion);
int precisionKeyword();
int matNxM();
int dMat();
int firstGenerationImage();
int secondGenerationImage();
TParseContext& parseContext;
bool afterType; // true if we've recognized a type, so can only be looking for an identifier
bool field; // true if we're on a field, right after a '.'
TSourceLoc loc;
TParserToken* parserToken;
TPpToken* ppToken;
const char* tokenText;
int keyword;
};
};

View File

@ -44,10 +44,15 @@
#include "SymbolTable.h"
#include "ParseHelper.h"
#include "Scan.h"
#include "ScanContext.h"
#include "../Include/ShHandle.h"
#include "InitializeDll.h"
extern "C" {
#include "preprocessor/preprocess.h"
}
#define SH_EXPORTING
#include "../Public/ShaderLang.h"
#include "Initialize.h"
@ -99,8 +104,9 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil
symbolTable = &symbolTables[language];
TParseContext parseContext(*symbolTable, intermediate, true, version, profile, language, infoSink);
ThreadLocalParseContext() = &parseContext;
glslang::TScanContext scanContext(parseContext);
parseContext.scanContext = &scanContext;
assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
@ -123,8 +129,6 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil
return false;
}
ResetFlex();
for (TBuiltInStrings::iterator i = BuiltInStrings[parseContext.language].begin();
i != BuiltInStrings[parseContext.language].end(); ++i) {
const char* builtInShaders[1];
@ -132,7 +136,7 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil
builtInShaders[0] = (*i).c_str();
builtInLengths[0] = (int) (*i).size();
if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext, 0) != 0) {
if (! parseContext.parseShaderStrings(const_cast<char**>(builtInShaders), builtInLengths, 1) != 0) {
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
printf("Unable to parse built-ins\n");
@ -271,6 +275,8 @@ int ShInitialize()
PerProcessGPA = new TPoolAllocator(true);
}
glslang::TScanContext::fillInKeywordMap();
return true;
}
@ -411,19 +417,24 @@ int ShCompile(
AddContextSpecificSymbols(resources, compiler->infoSink, &symbolTable, version, profile, compiler->getLanguage());
TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
glslang::TScanContext scanContext(parseContext);
parseContext.scanContext = &scanContext;
TSourceLoc beginning;
beginning.line = 1;
beginning.string = 0;
if (! goodProfile)
parseContext.error(1, "incorrect", "#version", "");
parseContext.error(beginning, "incorrect", "#version", "");
parseContext.initializeExtensionBehavior();
if (versionStatementMissing)
parseContext.warn(1, "statement missing: use #version on first line of shader", "#version", "");
parseContext.warn(beginning, "statement missing: use #version on first line of shader", "#version", "");
else if (profile == EEsProfile && version >= 300 && versionNotFirst)
parseContext.error(1, "statement must appear first in ESSL shader; before comments or newlines", "#version", "");
parseContext.error(beginning, "statement must appear first in ESSL shader; before comments or newlines", "#version", "");
ThreadLocalParseContext() = &parseContext;
ResetFlex();
InitPreprocessor();
//
@ -440,8 +451,8 @@ int ShCompile(
if (parseContext.insertBuiltInArrayAtGlobalLevel())
success = false;
int ret = PaParseStrings(const_cast<char**>(shaderStrings), lengths, numStrings, parseContext, parseContext.getPreamble());
if (ret)
bool ret = parseContext.parseShaderStrings(const_cast<char**>(shaderStrings), lengths, numStrings);
if (! ret)
success = false;
intermediate.addSymbolLinkageNodes(parseContext.treeRoot, parseContext.linkage, parseContext.language, symbolTable);

View File

@ -64,10 +64,10 @@ const char* ProfileName[EProfileCount] = {
// which subset allows the feature. If the current profile is not present,
// give an error message.
//
void TParseContext::requireProfile(int line, EProfileMask profileMask, const char *featureDesc)
void TParseContext::requireProfile(TSourceLoc loc, EProfileMask profileMask, const char *featureDesc)
{
if (((1 << profile) & profileMask) == 0)
error(line, "not supported with this profile:", featureDesc, ProfileName[profile]);
error(loc, "not supported with this profile:", featureDesc, ProfileName[profile]);
}
//
@ -75,10 +75,10 @@ void TParseContext::requireProfile(int line, EProfileMask profileMask, const cha
// which subset allows the feature. If the current stage is not present,
// give an error message.
//
void TParseContext::requireStage(int line, EShLanguageMask languageMask, const char *featureDesc)
void TParseContext::requireStage(TSourceLoc loc, EShLanguageMask languageMask, const char *featureDesc)
{
if (((1 << language) & languageMask) == 0)
error(line, "not supported in this stage:", featureDesc, StageName[language]);
error(loc, "not supported in this stage:", featureDesc, StageName[language]);
}
//
@ -88,7 +88,7 @@ void TParseContext::requireStage(int line, EShLanguageMask languageMask, const c
//
// one that takes multiple extensions
void TParseContext::profileRequires(int line, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc)
void TParseContext::profileRequires(TSourceLoc loc, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc)
{
if (profile == callingProfile) {
bool okay = false;
@ -98,7 +98,7 @@ void TParseContext::profileRequires(int line, EProfile callingProfile, int minVe
TBehavior behavior = extensionBehavior[extensions[i]];
switch (behavior) {
case EBhWarn:
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), line);
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
// fall through
case EBhRequire:
case EBhEnable:
@ -109,29 +109,29 @@ void TParseContext::profileRequires(int line, EProfile callingProfile, int minVe
}
if (! okay)
error(line, "not supported for this version or the enabled extensions", featureDesc, "");
error(loc, "not supported for this version or the enabled extensions", featureDesc, "");
}
}
// one that takes a single extension
void TParseContext::profileRequires(int line, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc)
void TParseContext::profileRequires(TSourceLoc loc, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc)
{
profileRequires(line, callingProfile, minVersion, extension ? 1 : 0, &extension, featureDesc);
profileRequires(loc, callingProfile, minVersion, extension ? 1 : 0, &extension, featureDesc);
}
//
// Within a profile, see if a feature is deprecated and error or warn based on whether
// a future compatibility context is being use.
//
void TParseContext::checkDeprecated(int line, EProfile callingProfile, int depVersion, const char *featureDesc)
void TParseContext::checkDeprecated(TSourceLoc loc, EProfile callingProfile, int depVersion, const char *featureDesc)
{
if (profile == callingProfile) {
if (version >= depVersion) {
if (forwardCompatible)
error(line, "deprecated, may be removed in future release", featureDesc, "");
error(loc, "deprecated, may be removed in future release", featureDesc, "");
else if (! (messages & EShMsgSuppressWarnings))
infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " +
String(depVersion) + "; may be removed in future release").c_str(), line);
String(depVersion) + "; may be removed in future release").c_str(), loc);
}
}
}
@ -140,27 +140,27 @@ void TParseContext::checkDeprecated(int line, EProfile callingProfile, int depVe
// Within a profile, see if a feature has now been removed and if so, give an error.
// The version argument is the first version no longer having the feature.
//
void TParseContext::requireNotRemoved(int line, EProfile callingProfile, int removedVersion, const char *featureDesc)
void TParseContext::requireNotRemoved(TSourceLoc loc, EProfile callingProfile, int removedVersion, const char *featureDesc)
{
if (profile == callingProfile) {
if (version >= removedVersion) {
const int maxSize = 60;
char buf[maxSize];
snprintf(buf, maxSize, "%s profile; removed in version %d", ProfileName[profile], removedVersion);
error(line, "no longer supported in", featureDesc, buf);
error(loc, "no longer supported in", featureDesc, buf);
}
}
}
void TParseContext::fullIntegerCheck(int line, const char* op)
void TParseContext::fullIntegerCheck(TSourceLoc loc, const char* op)
{
profileRequires(line, ENoProfile, 130, 0, op);
profileRequires(line, EEsProfile, 300, 0, op);
profileRequires(loc, ENoProfile, 130, 0, op);
profileRequires(loc, EEsProfile, 300, 0, op);
}
void TParseContext::doubleCheck(int line, const char* op)
void TParseContext::doubleCheck(TSourceLoc loc, const char* op)
{
requireProfile(line, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), op);
profileRequires(line, ECoreProfile, 400, 0, op);
profileRequires(line, ECompatibilityProfile, 400, 0, op);
requireProfile(loc, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), op);
profileRequires(loc, ECoreProfile, 400, 0, op);
profileRequires(loc, ECompatibilityProfile, 400, 0, op);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -63,7 +63,11 @@ void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
{
int i;
infoSink.debug << FormatSourceLoc(node->getLine());
infoSink.debug << node->getLoc().string << ":";
if (node->getLoc().line)
infoSink.debug << node->getLoc().line;
else
infoSink.debug << "? ";
for (i = 0; i < depth; ++i)
infoSink.debug << " ";
@ -445,7 +449,7 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
}
break;
default:
out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
break;
}
}

View File

@ -62,7 +62,9 @@ public:
TIntermTyped* addUnaryMath(TOperator, TIntermNode* child, TSourceLoc);
TIntermTyped* addBuiltInFunctionCall(TOperator, bool unary, TIntermNode*, const TType& returnType);
bool canImplicitlyPromote(TBasicType from, TBasicType to);
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc);
TIntermAggregate* makeAggregate(TIntermNode* node);
TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc);
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
bool areAllChildConst(TIntermAggregate* aggrNode);

View File

@ -69,7 +69,7 @@ public:
void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLoc());
return;
}
@ -84,13 +84,13 @@ bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
const int maxSize = GlslangMaxTypeLength + 50;
char buf[maxSize];
snprintf(buf, maxSize, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str());
oit->infoSink.info.message(EPrefixError, buf, node->getLine());
oit->infoSink.info.message(EPrefixError, buf, node->getLoc());
oit->error = true;
return false;
}
oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLoc());
return false;
}
@ -102,7 +102,7 @@ bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
const int maxSize = GlslangMaxTypeLength + 50;
char buf[maxSize];
snprintf(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
oit->infoSink.info.message(EPrefixError, buf, node->getLine());
oit->infoSink.info.message(EPrefixError, buf, node->getLoc());
oit->error = true;
return false;
@ -116,7 +116,7 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
const int maxSize = GlslangMaxTypeLength + 50;
char buf[maxSize];
snprintf(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
oit->infoSink.info.message(EPrefixError, buf, node->getLine());
oit->infoSink.info.message(EPrefixError, buf, node->getLoc());
oit->error = true;
return false;
@ -165,7 +165,7 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
bool ParseSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine());
oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLoc());
oit->error = true;
return false;
}
@ -235,7 +235,7 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLoc());
oit->error = true;
return false;
@ -244,7 +244,7 @@ bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLoc());
oit->error = true;
return false;

View File

@ -107,29 +107,20 @@ static const struct {
{ CPP_ADD_ASSIGN, "+=" },
{ CPP_DIV_ASSIGN, "/=" },
{ CPP_MUL_ASSIGN, "*=" },
{ CPP_RIGHT_BRACKET, ":>" },
{ CPP_EQ_OP, "==" },
{ CPP_XOR_OP, "^^" },
{ CPP_XOR_ASSIGN, "^=" },
{ CPP_FLOATCONSTANT, "<float-const>" },
{ CPP_GE_OP, ">=" },
{ CPP_RIGHT_OP, ">>" },
{ CPP_RIGHT_ASSIGN, ">>=" },
{ CPP_IDENTIFIER, "<ident>" },
{ CPP_INTCONSTANT, "<int-const>" },
{ CPP_RIGHT_ASSIGN, ">>="},
{ CPP_LE_OP, "<=" },
{ CPP_LEFT_OP, "<<" },
{ CPP_LEFT_ASSIGN, "<<=" },
{ CPP_LEFT_BRACKET, "<:" },
{ CPP_LEFT_BRACE, "<%" },
{ CPP_LEFT_ASSIGN, "<<="},
{ CPP_DEC_OP, "--" },
{ CPP_RIGHT_BRACE, "%>" },
{ CPP_NE_OP, "!=" },
{ CPP_OR_OP, "||" },
{ CPP_OR_ASSIGN, "|=" },
{ CPP_INC_OP, "++" },
{ CPP_STRCONSTANT, "<string-const>" },
{ CPP_TYPEIDENTIFIER, "<type-ident>" },
};
///////////////////////////////////////////////////////////////////////////////////////////////
@ -672,7 +663,7 @@ int InitAtomTable(AtomTable *atable, int htsize)
// Initialize lower part of atom table to "<undefined>" atom:
AddAtomFixed(atable, "<undefined>", 0);
for (ii = 0; ii < FIRST_USER_TOKEN_SY; ii++)
for (ii = 0; ii < CPP_FIRST_USER_TOKEN_SY; ii++)
atable->amap[ii] = atable->amap[0];
// Add single character tokens to the atom table:
@ -697,7 +688,7 @@ int InitAtomTable(AtomTable *atable, int htsize)
// Add error symbol if running in error mode:
if (cpp->options.ErrorMode)
AddAtomFixed(atable, "error", ERROR_SY);
AddAtomFixed(atable, "error", CPP_ERROR_SY);
AddAtom(atable, "<*** end fixed atoms ***>");

View File

@ -1,132 +0,0 @@
//
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
//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.
//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
NVIDIA Corporation("NVIDIA") supplies this software to you in
consideration of your agreement to the following terms, and your use,
installation, modification or redistribution of this NVIDIA software
constitutes acceptance of these terms. If you do not agree with these
terms, please do not use, install, modify or redistribute this NVIDIA
software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, NVIDIA grants you a personal, non-exclusive
license, under NVIDIA's copyrights in this original NVIDIA software (the
"NVIDIA Software"), to use, reproduce, modify and redistribute the
NVIDIA Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the NVIDIA Software, you must
retain the copyright notice of NVIDIA, this notice and the following
text and disclaimers in all such redistributions of the NVIDIA Software.
Neither the name, trademarks, service marks nor logos of NVIDIA
Corporation may be used to endorse or promote products derived from the
NVIDIA Software without specific prior written permission from NVIDIA.
Except as expressly stated in this notice, no other rights or licenses
express or implied, are granted by NVIDIA herein, including but not
limited to any patent rights that may be infringed by your derivative
works or by other works in which the NVIDIA Software may be
incorporated. No hardware is licensed hereunder.
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
PRODUCTS.
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
//
// compile.h
//
#if !defined(__COMPILE_H)
#define __COMPILE_H 1
int InitCPPStruct(void);
typedef struct Options_Rec{
const char *profileString;
int ErrorMode;
int Quiet;
// Debug The Compiler options:
int DumpAtomTable;
} Options;
struct CPPStruct_Rec {
// Public members
SourceLoc *pLastSourceLoc; // Set at the start of each statement by the tree walkers
Options options; // Compile options and parameters
// Private members
SourceLoc lastSourceLoc;
// Scanner data:
SourceLoc *tokenLoc; // Source location of most recent token seen by the scanner
int mostRecentToken; // Most recent token seen by the scanner
InputSrc *currentInput;
int previous_token;
int notAVersionToken; // used to make sure that #version is the first token seen in the file, if present
void *pC; // storing the parseContext of the compile object in cpp.
// Private members:
SourceLoc ltokenLoc;
int ifdepth; //current #if-#else-#endif nesting in the cpp.c file (pre-processor)
int elsedepth[64]; //Keep a track of #if depth..Max allowed is 64.
int elsetracker; //#if-#else and #endif constructs...Counter.
const char *ErrMsg;
int CompileError; //Indicate compile error when #error, #else,#elif mismatch.
//
// Globals used to communicate between PaParseStrings() and yy_input()and
// also across the files.(gen_glslang.cpp and scanner.c)
//
int PaWhichStr; // which string we're parsing
int* PaStrLen; // array of lengths of the PaArgv strings
int PaArgc; // count of strings in the array
char** PaArgv; // our array of strings to parse
unsigned int tokensBeforeEOF : 1;
};
#endif // !defined(__COMPILE_H)

View File

@ -630,7 +630,8 @@ static int CPPerror(yystypepp * yylvalpp)
const char *message;
while (token != '\n') {
if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT) {
StoreStr(yylvalpp->symbol_name);
}else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){
StoreStr(GetStringOfAtom(atable, yylvalpp->sc_ident));
@ -681,11 +682,9 @@ static int CPPpragma(yystypepp * yylvalpp)
strcpy(allTokens[tokenCount++], SrcStr);
break;
case CPP_INTCONSTANT:
SrcStr = yylvalpp->symbol_name;
allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
strcpy(allTokens[tokenCount++], SrcStr);
break;
case CPP_UINTCONSTANT:
case CPP_FLOATCONSTANT:
case CPP_DOUBLECONSTANT:
SrcStr = yylvalpp->symbol_name;
allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
strcpy(allTokens[tokenCount++], SrcStr);
@ -715,41 +714,35 @@ static int CPPpragma(yystypepp * yylvalpp)
return token;
} // CPPpragma
// This is just for error checking: the version and profile are decided before preprocessing starts
static int CPPversion(yystypepp * yylvalpp)
{
int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (cpp->notAVersionToken == 1)
ShPpErrorToInfoLog("#version must occur before any other statement in the program");
if(token=='\n'){
if (token == '\n'){
DecLineNumber();
ShPpErrorToInfoLog("#version");
IncLineNumber();
return token;
}
if (token != CPP_INTCONSTANT)
ShPpErrorToInfoLog("#version");
yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
SetVersion(yylvalpp->sc_int);
yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token == '\n') {
SetProfile(ENoProfile);
if (token == '\n')
return token;
}
else {
if (yylvalpp->sc_ident == coreAtom)
SetProfile(ECoreProfile);
else if (yylvalpp->sc_ident == compatibilityAtom)
SetProfile(ECompatibilityProfile);
else if (yylvalpp->sc_ident == esAtom)
SetProfile(EEsProfile);
else
if (yylvalpp->sc_ident != coreAtom &&
yylvalpp->sc_ident != compatibilityAtom &&
yylvalpp->sc_ident != esAtom)
ShPpErrorToInfoLog("#version profile name");
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
@ -1025,7 +1018,7 @@ int MacroExpand(int atom, yystypepp* yylvalpp, int expandUndef)
}
if (atom == __VERSION__Atom) {
yylvalpp->sc_int = GetVersion(cpp->pC);
yylvalpp->sc_int = GetShaderVersion(cpp->pC);
sprintf(yylvalpp->symbol_name, "%d", yylvalpp->sc_int);
UngetToken(CPP_INTCONSTANT, yylvalpp);

View File

@ -116,8 +116,7 @@ int GetLineNumber(void); // Get the current String Number.
int GetStringNumber(void); // Get the current String Number.
const char* GetStrfromTStr(void); // Convert TString to String.
void SetVersion(int);
void SetProfile(EProfile);
int GetVersion(void*);
int GetShaderVersion(void*);
void updateExtensionBehavior(const char* extName, const char* behavior);
int FreeCPP(void);

View File

@ -86,10 +86,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
CPPStruct *cpp = NULL;
static int refCount = 0;
int InitPreprocessor(void);
int ResetPreprocessor(void);
int FreeCPPStruct(void);
int FinalizePreprocessor(void);
/*
* InitCPPStruct() - Initilaize the CPP structure.

View File

@ -75,20 +75,9 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
#ifndef BISON_PARSER_H
# define BISON_PARSER_H
#ifndef PARSER_H
# define PARSER_H
#ifndef yystypepp
typedef struct {
int sc_int;
float sc_fval;
double sc_dval;
int sc_ident;
char symbol_name[MAX_SYMBOL_NAME_LEN+1];
} yystypepp;
# define YYSTYPE_IS_TRIVIAL 1
#endif
# define CPP_AND_OP 257
# define CPP_SUB_ASSIGN 259
# define CPP_MOD_ASSIGN 260
@ -97,7 +86,7 @@ typedef struct {
# define CPP_MUL_ASSIGN 263
# define CPP_EQ_OP 264
# define CPP_XOR_OP 265
# define ERROR_SY 266
# define CPP_ERROR_SY 266
# define CPP_FLOATCONSTANT 267
# define CPP_GE_OP 268
# define CPP_RIGHT_OP 269
@ -111,9 +100,6 @@ typedef struct {
# define CPP_INC_OP 277
# define CPP_STRCONSTANT 278
# define CPP_TYPEIDENTIFIER 279
# define FIRST_USER_TOKEN_SY 289
# define CPP_RIGHT_ASSIGN 280
# define CPP_LEFT_ASSIGN 281
# define CPP_AND_ASSIGN 282
@ -123,5 +109,8 @@ typedef struct {
# define CPP_RIGHT_BRACKET 286
# define CPP_LEFT_BRACE 287
# define CPP_RIGHT_BRACE 288
# define CPP_UINTCONSTANT 289
# define CPP_DOUBLECONSTANT 290
# define CPP_FIRST_USER_TOKEN_SY 291
#endif /* not BISON_PARSER_H */
#endif /* not PARSER_H */

View File

@ -75,10 +75,84 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
#include "slglobals.h"
#ifndef PREPROCESS_H
#define PREPROCESS_H
typedef struct SourceLoc_Rec {
int file;
int line;
} SourceLoc;
typedef struct Options_Rec {
const char *profileString;
int ErrorMode;
int Quiet;
// Debug The Compiler options:
int DumpAtomTable;
} Options;
#define MAX_TOKEN_LENGTH 1024
typedef struct {
int ppToken;
int sc_int;
double sc_dval;
int sc_ident;
char symbol_name[MAX_TOKEN_LENGTH+1];
} yystypepp;
typedef struct InputSrc {
struct InputSrc *prev;
int (*scan)(struct InputSrc *, yystypepp *);
int (*getch)(struct InputSrc *, yystypepp *);
void (*ungetch)(struct InputSrc *, int, yystypepp *);
int name; /* atom */
int line;
} InputSrc;
typedef struct CPPStruct {
// Public members
SourceLoc *pLastSourceLoc; // Set at the start of each statement by the tree walkers
Options options; // Compile options and parameters
// Private members
SourceLoc lastSourceLoc;
// Scanner data:
SourceLoc *tokenLoc; // Source location of most recent token seen by the scanner
int mostRecentToken; // Most recent token seen by the scanner
InputSrc *currentInput;
int previous_token;
int notAVersionToken; // used to make sure that #version is the first token seen in the file, if present
void *pC; // storing the parseContext of the compile object in cpp.
// Private members:
SourceLoc ltokenLoc;
int ifdepth; //current #if-#else-#endif nesting in the cpp.c file (pre-processor)
int elsedepth[64]; //Keep a track of #if depth..Max allowed is 64.
int elsetracker; //#if-#else and #endif constructs...Counter.
const char *ErrMsg;
int CompileError; //Indicate compile error when #error, #else,#elif mismatch.
//
// Globals used to communicate between parseStrings() and yy_input()and
// also across the files.(gen_glslang.cpp and scanner.c)
//
int PaWhichStr; // which string we're parsing
int* PaStrLen; // array of lengths of the PaArgv strings
int PaArgc; // count of strings in the array
char** PaArgv; // our array of strings to parse
unsigned int tokensBeforeEOF : 1;
} CPPStruct;
extern CPPStruct *cpp;
int InitCPPStruct(void);
int InitScanner(CPPStruct *cpp);
int InitAtomTable(AtomTable *atable, int htsize);
int InitPreprocessor(void);
int FinalizePreprocessor(void);
int ScanFromString(char *s);
char* GetStringOfAtom(AtomTable *atable, int atom);
const char* PpTokenize(yystypepp*);
#endif

View File

@ -222,7 +222,7 @@ int ScanFromString(char *s)
cpp->currentInput = &in->base;
return 1;
} // ScanFromString;
}
///////////////////////////////////////////////////////////////////////////////////////////////
@ -239,6 +239,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
{
int HasDecimal, declen, exp, ExpSign;
int str_len;
int isDouble = 0;
HasDecimal = 0;
declen = 0;
@ -250,7 +251,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
HasDecimal = 1;
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
while (ch >= '0' && ch <= '9') {
if (len < MAX_SYMBOL_NAME_LEN) {
if (len < MAX_TOKEN_LENGTH) {
declen++;
if (len > 0 || ch != '0') {
str[len] = ch;
@ -267,7 +268,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
// Exponent:
if (ch == 'e' || ch == 'E') {
if (len >= MAX_SYMBOL_NAME_LEN) {
if (len >= MAX_TOKEN_LENGTH) {
ShPpErrorToInfoLog("floating-point literal too long");
len = 1,str_len=1;
} else {
@ -284,7 +285,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
}
if (ch >= '0' && ch <= '9') {
while (ch >= '0' && ch <= '9') {
if (len < MAX_SYMBOL_NAME_LEN) {
if (len < MAX_TOKEN_LENGTH) {
exp = exp*10 + ch - '0';
str[len++]=ch;
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
@ -301,7 +302,6 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
}
if (len == 0) {
yylvalpp->sc_fval = 0.0f;
yylvalpp->sc_dval = 0.0;
strcpy(str, "0.0");
} else {
@ -311,16 +311,17 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
cpp->currentInput->ungetch(cpp->currentInput, ch2, yylvalpp);
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
} else {
if (len < MAX_SYMBOL_NAME_LEN) {
if (len < MAX_TOKEN_LENGTH) {
str[len++] = ch;
str[len++] = ch2;
isDouble = 1;
} else {
ShPpErrorToInfoLog("floating-point literal too long");
len = 1,str_len=1;
}
}
} else if (ch == 'f' || ch == 'F') {
if (len < MAX_SYMBOL_NAME_LEN)
if (len < MAX_TOKEN_LENGTH)
str[len++] = ch;
else {
ShPpErrorToInfoLog("floating-point literal too long");
@ -332,11 +333,13 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
str[len]='\0';
yylvalpp->sc_dval = strtod(str, 0);
yylvalpp->sc_fval = (float)yylvalpp->sc_dval;
}
// Suffix:
strcpy(yylvalpp->symbol_name, str);
if (isDouble)
return CPP_DOUBLECONSTANT;
else
return CPP_FLOATCONSTANT;
} // lFloatConst
@ -346,8 +349,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
{
char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
char string_val[MAX_STRING_LEN + 1];
char tokenText[MAX_TOKEN_LENGTH + 1];
int AlreadyComplained = 0;
int len, ch, ii;
unsigned ival = 0;
@ -368,7 +370,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
default:
return ch; // Single character token
case EOF:
return -1;
return EOF;
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
@ -393,30 +395,32 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
ch = nextch;
} else
ShPpErrorToInfoLog("can only escape newlines");
} else if (len < MAX_SYMBOL_NAME_LEN) {
symbol_name[len] = ch;
len++;
} else if (len < MAX_TOKEN_LENGTH) {
tokenText[len++] = ch;
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
} else {
if (! AlreadyComplained) {
ShPpErrorToInfoLog("name too long");
break;
AlreadyComplained = 1;
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
}
} while ((ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch <= '9') ||
ch == '_' ||
ch == '\\');
if (len > MAX_SYMBOL_NAME_LEN)
len = MAX_SYMBOL_NAME_LEN;
symbol_name[len] = '\0';
tokenText[len] = '\0';
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
return CPP_IDENTIFIER;
break;
case '0':
yylvalpp->symbol_name[len++] = ch;
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
if (ch == 'x' || ch == 'X') {
int uint = 0;
yylvalpp->symbol_name[len++] = ch;
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
if ((ch >= '0' && ch <= '9') ||
@ -425,10 +429,8 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
{
ival = 0;
do {
if (len >= MAX_SYMBOL_NAME_LEN)
break;
yylvalpp->symbol_name[len++] = ch;
if (ival <= 0x0fffffff) {
yylvalpp->symbol_name[len++] = ch;
if (ch >= '0' && ch <= '9') {
ii = ch - '0';
} else if (ch >= 'A' && ch <= 'F') {
@ -440,9 +442,10 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
ival = (ival << 4) | ii;
} else {
if (! AlreadyComplained) {
ShPpErrorToInfoLog("hexidecimal literal too long");
ShPpErrorToInfoLog("hexidecimal literal too big");
AlreadyComplained = 1;
}
ival = 0xffffffff;
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
} while ((ch >= '0' && ch <= '9') ||
@ -451,37 +454,50 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
} else {
ShPpErrorToInfoLog("bad digit in hexidecimal literal");
}
if (ch == 'u' || ch == 'U')
if (ch == 'u' || ch == 'U') {
if (len < MAX_TOKEN_LENGTH)
yylvalpp->symbol_name[len++] = ch;
else
uint = 1;
} else
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
yylvalpp->symbol_name[len] = '\0';
yylvalpp->sc_int = (int)ival;
if (uint)
return CPP_UINTCONSTANT;
else
return CPP_INTCONSTANT;
} else if (ch >= '0' && ch <= '7') { // octal integer constants
int uint = 0;
ival = 0;
do {
if (len >= MAX_SYMBOL_NAME_LEN)
break;
yylvalpp->symbol_name[len++] = ch;
if (ival <= 0x1fffffff) {
yylvalpp->symbol_name[len++] = ch;
ii = ch - '0';
ival = (ival << 3) | ii;
} else {
if (!AlreadyComplained) {
ShPpErrorToInfoLog("octal literal too long");
ShPpErrorToInfoLog("octal literal too big");
AlreadyComplained = 1;
}
ival = 0xffffffff;
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
} while (ch >= '0' && ch <= '7');
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L')
return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
yylvalpp->symbol_name[len] = '\0';
else if (ch == 'u' || ch == 'U') {
if (len < MAX_TOKEN_LENGTH)
yylvalpp->symbol_name[len++] = ch;
uint = 1;
} else
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
yylvalpp->symbol_name[len] = '\0';
yylvalpp->sc_int = (int)ival;
if (uint)
return CPP_UINTCONSTANT;
else
return CPP_INTCONSTANT;
} else {
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
@ -491,25 +507,30 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
do {
if (len < MAX_SYMBOL_NAME_LEN) {
if (len < MAX_TOKEN_LENGTH) {
if (len > 0 || ch != '0') {
yylvalpp->symbol_name[len] = ch;
len++;
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
} else {
ShPpErrorToInfoLog("token too long");
break;
if (! AlreadyComplained) {
ShPpErrorToInfoLog("integer literal too long");
AlreadyComplained = 1;
}
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
} while (ch >= '0' && ch <= '9');
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') {
return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
} else {
// Finish handling signed and unsigned integers
int numericLen = len;
if (ch == 'u' || ch == 'U')
int uint = 0;
if (ch == 'u' || ch == 'U') {
if (len < MAX_TOKEN_LENGTH)
yylvalpp->symbol_name[len++] = ch;
else
uint = 1;
} else
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
yylvalpp->symbol_name[len] = '\0';
@ -517,15 +538,17 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
for (ii = 0; ii < numericLen; ii++) {
ch = yylvalpp->symbol_name[ii] - '0';
if ((ival > 429496729) || (ival == 429496729 && ch >= 6)) {
if (! AlreadyComplained) {
ShPpErrorToInfoLog("integral literal too long");
AlreadyComplained = 1;
}
}
ShPpErrorToInfoLog("integral literal too big");
ival = -1;
break;
} else
ival = ival * 10 + ch;
}
yylvalpp->sc_int = (int)ival;
if (uint)
return CPP_UINTCONSTANT;
else
return CPP_INTCONSTANT;
}
break;
@ -737,39 +760,39 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
break;
}
}
if (len < MAX_STRING_LEN) {
string_val[len] = ch;
if (len < MAX_TOKEN_LENGTH) {
tokenText[len] = ch;
len++;
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
} else
break;
};
string_val[len] = '\0';
tokenText[len] = '\0';
if (ch == '"') {
yylvalpp->sc_ident = LookUpAddString(atable, string_val);
yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
return CPP_STRCONSTANT;
} else {
ShPpErrorToInfoLog("end of line in string");
return ERROR_SY;
return CPP_ERROR_SY;
}
}
}
} // byte_scan
int yylex_CPP(char* buf, int maxSize)
const char* PpTokenize(yystypepp* yylvalpp)
{
yystypepp yylvalpp;
int token = '\n';
for(;;) {
char* tokenString = 0;
token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
if(check_EOF(token))
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
yylvalpp->ppToken = token;
if (check_EOF(token))
return 0;
if (token == '#') {
if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
token = readCPPline(&yylvalpp);
token = readCPPline(yylvalpp);
if(check_EOF(token))
return 0;
continue;
@ -779,42 +802,34 @@ int yylex_CPP(char* buf, int maxSize)
}
}
cpp->previous_token = token;
// expand macros
if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp, 0) == 1) {
cpp->notAVersionToken = 1;
continue;
}
if (token == '\n')
continue;
if (token == CPP_IDENTIFIER) {
cpp->notAVersionToken = 1;
tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
} else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){
cpp->notAVersionToken = 1;
tokenString = yylvalpp.symbol_name;
} else {
cpp->notAVersionToken = 1;
tokenString = GetStringOfAtom(atable,token);
}
// expand macros
if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp, 0) == 1)
continue;
if (token == CPP_IDENTIFIER)
tokenString = GetStringOfAtom(atable, yylvalpp->sc_ident);
else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
tokenString = yylvalpp->symbol_name;
else
tokenString = GetStringOfAtom(atable, token);
if (tokenString) {
if ((signed)strlen(tokenString) >= maxSize) {
if (tokenString[0] != 0)
cpp->tokensBeforeEOF = 1;
return maxSize;
} else if (strlen(tokenString) > 0) {
strcpy(buf, tokenString);
cpp->tokensBeforeEOF = 1;
return (int)strlen(tokenString);
}
return 0;
return tokenString;
}
}
return 0;
} // yylex
} // PpTokenize
//Checks if the token just read is EOF or not.
int check_EOF(int token)

View File

@ -81,9 +81,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(__SCANNER_H)
#define __SCANNER_H 1
#define MAX_SYMBOL_NAME_LEN 1025
#define MAX_STRING_LEN 1025
#include "preprocess.h"
#include "parser.h"
// Not really atom table stuff but needed first...
@ -91,23 +89,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern "C" {
#endif
typedef struct SourceLoc_Rec {
unsigned short file, line;
} SourceLoc;
int yyparse (void);
int yylex_CPP(char* buf, int maxSize);
typedef struct InputSrc {
struct InputSrc *prev;
int (*scan)(struct InputSrc *, yystypepp *);
int (*getch)(struct InputSrc *, yystypepp *);
void (*ungetch)(struct InputSrc *, int, yystypepp *);
int name; /* atom */
int line;
} InputSrc;
int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner.
int ScanFromString(char *); // Start scanning the input from the string mentioned.
int check_EOF(int); // check if we hit a EOF abruptly

View File

@ -81,7 +81,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(__SLGLOBALS_H)
#define __SLGLOBALS_H 1
typedef struct CPPStruct_Rec CPPStruct;
#include "preprocess.h"
// TODO: threading: Multi-threading note: The existence of this global makes
// this preprocessing single-threaded only.
@ -101,7 +101,6 @@ extern CPPStruct *cpp;
#include "cpp.h"
#include "tokens.h"
#include "symbols.h"
#include "compile.h"
#if !defined(NO_PARSER)
#include "parser.h"
#endif

View File

@ -257,8 +257,10 @@ void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
lAddByte(pTok, (unsigned char) *s++);
lAddByte(pTok, 0);
break;
case CPP_FLOATCONSTANT:
case CPP_INTCONSTANT:
case CPP_UINTCONSTANT:
case CPP_FLOATCONSTANT:
case CPP_DOUBLECONSTANT:
str = yylvalpp->symbol_name;
while (*str){
lAddByte(pTok, (unsigned char) *str);
@ -293,8 +295,9 @@ void RewindTokenStream(TokenStream *pTok)
int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
{
char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
char string_val[MAX_STRING_LEN + 1];
//TODO: PP: why is this different than byte_scan
char tokenText[MAX_TOKEN_LENGTH + 1];
int ltoken, len;
char ch;
@ -312,8 +315,8 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
(ch >= '0' && ch <= '9') ||
ch == '_')
{
if (len < MAX_SYMBOL_NAME_LEN) {
symbol_name[len] = ch;
if (len < MAX_TOKEN_LENGTH) {
tokenText[len] = ch;
len++;
ch = lReadByte(pTok);
} else {
@ -321,30 +324,31 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
break;
}
}
symbol_name[len] = '\0';
tokenText[len] = '\0';
assert(ch == '\0');
yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
return CPP_IDENTIFIER;
break;
case CPP_STRCONSTANT:
len = 0;
while ((ch = lReadByte(pTok)) != 0) {
if (len < MAX_STRING_LEN)
string_val[len++] = ch;
if (len < MAX_TOKEN_LENGTH)
tokenText[len++] = ch;
else
break;
}
string_val[len] = 0;
yylvalpp->sc_ident = LookUpAddString(atable, string_val);
tokenText[len] = 0;
yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
break;
case CPP_FLOATCONSTANT:
case CPP_DOUBLECONSTANT:
len = 0;
ch = lReadByte(pTok);
while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
while ((ch >= '0' && ch <= '9') || ch=='e' || ch=='E' || ch=='.' || ch=='+' || ch=='-' || ch=='l' || ch=='L' || ch=='f'|| ch=='F')
{
if (len < MAX_SYMBOL_NAME_LEN) {
symbol_name[len] = ch;
if (len < MAX_TOKEN_LENGTH) {
tokenText[len] = ch;
len++;
ch = lReadByte(pTok);
} else {
@ -352,18 +356,19 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
break;
}
}
symbol_name[len] = '\0';
tokenText[len] = '\0';
assert(ch == '\0');
strcpy(yylvalpp->symbol_name,symbol_name);
yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
strcpy(yylvalpp->symbol_name, tokenText);
yylvalpp->sc_dval = atof(yylvalpp->symbol_name);
break;
case CPP_INTCONSTANT:
case CPP_UINTCONSTANT:
len = 0;
ch = lReadByte(pTok);
while ((ch >= '0' && ch <= '9'))
while ((ch >= '0' && ch <= '9') || ch == 'u' || ch == 'U')
{
if (len < MAX_SYMBOL_NAME_LEN) {
symbol_name[len] = ch;
if (len < MAX_TOKEN_LENGTH) {
tokenText[len] = ch;
len++;
ch = lReadByte(pTok);
} else {
@ -371,10 +376,10 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
break;
}
}
symbol_name[len] = '\0';
tokenText[len] = '\0';
assert(ch == '\0');
strcpy(yylvalpp->symbol_name,symbol_name);
yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
strcpy(yylvalpp->symbol_name,tokenText);
yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
break;
case '(':
yylvalpp->sc_int = lReadByte(pTok);
@ -456,7 +461,7 @@ void UngetToken(int token, yystypepp * yylvalpp) {
void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
int token;
const int maxSize = MAX_SYMBOL_NAME_LEN + 5;
const int maxSize = MAX_TOKEN_LENGTH + 5;
char str[100];
if (fp == 0) fp = stdout;
@ -471,10 +476,12 @@ void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
snprintf(str, maxSize, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
break;
case CPP_FLOATCONSTANT:
//printf("%g9.6 ", yylvalpp->sc_fval);
case CPP_DOUBLECONSTANT:
printf("%g9.6 ", yylvalpp->sc_dval);
break;
case CPP_INTCONSTANT:
//printf("%d ", yylvalpp->sc_int);
case CPP_UINTCONSTANT:
printf("%d ", yylvalpp->sc_int);
break;
default:
if (token >= 127)