Commit 8b851c6d by alokp@chromium.org

Preparation of hooking up the new preprocessor.

- Added custom Diagnostics class. Routed all info-log messages via this new class. - Added custom DirectiveHandler class. Moved directive-handling code to this class and routed the old path. - Deleted lexer_glue because it is not needed anymore. The new preprocessor is almost ready! - Killed a bunch of dead code related to PragmaTable. Review URL: https://codereview.appspot.com/6308074 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1150 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 46aa13d8
...@@ -63,6 +63,11 @@ ...@@ -63,6 +63,11 @@
'compiler/debug.h', 'compiler/debug.h',
'compiler/DetectRecursion.cpp', 'compiler/DetectRecursion.cpp',
'compiler/DetectRecursion.h', 'compiler/DetectRecursion.h',
'compiler/Diagnostics.h',
'compiler/Diagnostics.cpp',
'compiler/DirectiveHandler.h',
'compiler/DirectiveHandler.cpp',
'compiler/ExtensionBehavior.h',
'compiler/ForLoopUnroll.cpp', 'compiler/ForLoopUnroll.cpp',
'compiler/ForLoopUnroll.h', 'compiler/ForLoopUnroll.h',
'compiler/glslang.h', 'compiler/glslang.h',
...@@ -76,6 +81,7 @@ ...@@ -76,6 +81,7 @@
'compiler/InitializeDll.cpp', 'compiler/InitializeDll.cpp',
'compiler/InitializeDll.h', 'compiler/InitializeDll.h',
'compiler/InitializeGlobals.h', 'compiler/InitializeGlobals.h',
'compiler/InitializeParseContext.cpp',
'compiler/InitializeParseContext.h', 'compiler/InitializeParseContext.h',
'compiler/Intermediate.cpp', 'compiler/Intermediate.cpp',
'compiler/intermediate.h', 'compiler/intermediate.h',
...@@ -114,8 +120,6 @@ ...@@ -114,8 +120,6 @@
'compiler/preprocessor/cpp.h', 'compiler/preprocessor/cpp.h',
'compiler/preprocessor/cppstruct.c', 'compiler/preprocessor/cppstruct.c',
'compiler/preprocessor/length_limits.h', 'compiler/preprocessor/length_limits.h',
'compiler/preprocessor/lexer_glue.cpp',
'compiler/preprocessor/lexer_glue.h',
'compiler/preprocessor/memory.c', 'compiler/preprocessor/memory.c',
'compiler/preprocessor/memory.h', 'compiler/preprocessor/memory.h',
'compiler/preprocessor/parser.h', 'compiler/preprocessor/parser.h',
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "compiler/DetectRecursion.h" #include "compiler/DetectRecursion.h"
#include "compiler/ForLoopUnroll.h" #include "compiler/ForLoopUnroll.h"
#include "compiler/Initialize.h" #include "compiler/Initialize.h"
#include "compiler/InitializeParseContext.h"
#include "compiler/MapLongVariableNames.h" #include "compiler/MapLongVariableNames.h"
#include "compiler/ParseHelper.h" #include "compiler/ParseHelper.h"
#include "compiler/RenameFunction.h" #include "compiler/RenameFunction.h"
......
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/Diagnostics.h"
#include "compiler/InfoSink.h"
#include "compiler/preprocessor/new/SourceLocation.h"
TDiagnostics::TDiagnostics(TInfoSink& infoSink) : mInfoSink(infoSink)
{
}
TDiagnostics::~TDiagnostics()
{
}
void TDiagnostics::writeInfo(Severity severity,
const pp::SourceLocation& loc,
const std::string& reason,
const std::string& token,
const std::string& extra)
{
TInfoSinkBase& sink = mInfoSink.info;
TPrefixType prefix = severity == ERROR ? EPrefixError : EPrefixWarning;
/* VC++ format: file(linenum) : error #: 'token' : extrainfo */
sink.prefix(prefix);
sink.location(EncodeSourceLoc(loc.file, loc.line));
sink << "'" << token << "' : " << reason << " " << extra << "\n";
}
void TDiagnostics::writeDebug(const std::string& str)
{
mInfoSink.debug << str;
}
void TDiagnostics::print(ID id,
const pp::SourceLocation& loc,
const std::string& text)
{
}
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_DIAGNOSTICS_H_
#define COMPILER_DIAGNOSTICS_H_
#include "compiler/preprocessor/new/Diagnostics.h"
class TInfoSink;
class TDiagnostics : public pp::Diagnostics
{
public:
TDiagnostics(TInfoSink& infoSink);
virtual ~TDiagnostics();
void writeInfo(Severity severity,
const pp::SourceLocation& loc,
const std::string& reason,
const std::string& token,
const std::string& extra);
void writeDebug(const std::string& str);
protected:
virtual void print(ID id,
const pp::SourceLocation& loc,
const std::string& text);
private:
TInfoSink& mInfoSink;
};
#endif // COMPILER_DIAGNOSTICS_H_
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/DirectiveHandler.h"
#include <sstream>
#include "compiler/Debug.h"
#include "compiler/Diagnostics.h"
static TBehavior getBehavior(const std::string& str)
{
static const std::string kRequire("require");
static const std::string kEnable("enable");
static const std::string kDisable("disable");
static const std::string kWarn("warn");
if (str == kRequire) return EBhRequire;
else if (str == kEnable) return EBhEnable;
else if (str == kDisable) return EBhDisable;
else if (str == kWarn) return EBhWarn;
return EBhUndefined;
}
TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
TDiagnostics& diagnostics)
: mExtBehavior(extBehavior),
mDiagnostics(diagnostics)
{
}
TDirectiveHandler::~TDirectiveHandler()
{
}
void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
const std::string& msg)
{
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, msg, "", "");
}
void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
const std::string& name,
const std::string& value)
{
static const std::string kSTDGL("STDGL");
static const std::string kOptimize("optimize");
static const std::string kDebug("debug");
static const std::string kOn("on");
static const std::string kOff("off");
bool invalidValue = false;
if (name == kSTDGL)
{
// The STDGL pragma is used to reserve pragmas for use by future
// revisions of GLSL. Ignore it.
return;
}
else if (name == kOptimize)
{
if (value == kOn) mPragma.optimize = true;
else if (value == kOff) mPragma.optimize = false;
else invalidValue = true;
}
else if (name == kDebug)
{
if (value == kOn) mPragma.debug = true;
else if (value == kOff) mPragma.debug = false;
else invalidValue = true;
}
else
{
mDiagnostics.report(pp::Diagnostics::UNRECOGNIZED_PRAGMA, loc, name);
return;
}
if (invalidValue)
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
"invalid pragma value", value,
"'on' or 'off' expected");
}
void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
const std::string& name,
const std::string& behavior)
{
static const std::string kExtAll("all");
TBehavior behaviorVal = getBehavior(behavior);
if (behaviorVal == EBhUndefined)
{
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
"behavior", name, "invalid");
return;
}
if (name == kExtAll)
{
if (behaviorVal == EBhRequire)
{
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
"extension", name,
"cannot have 'require' behavior");
}
else if (behaviorVal == EBhEnable)
{
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
"extension", name,
"cannot have 'enable' behavior");
}
else
{
for (TExtensionBehavior::iterator iter = mExtBehavior.begin();
iter != mExtBehavior.end(); ++iter)
iter->second = behaviorVal;
}
return;
}
TExtensionBehavior::iterator iter = mExtBehavior.find(name);
if (iter != mExtBehavior.end())
{
iter->second = behaviorVal;
return;
}
pp::Diagnostics::Severity severity = pp::Diagnostics::ERROR;
switch (behaviorVal) {
case EBhRequire:
severity = pp::Diagnostics::ERROR;
break;
case EBhEnable:
case EBhWarn:
case EBhDisable:
severity = pp::Diagnostics::WARNING;
break;
default:
UNREACHABLE();
break;
}
mDiagnostics.writeInfo(severity, loc,
"extension", name, "is not supported");
}
void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
int version)
{
static const int kVersion = 100;
if (version != kVersion)
{
std::stringstream stream;
stream << version;
std::string str = stream.str();
mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc,
"version number", str, "not supported");
}
}
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_DIRECTIVE_HANDLER_H_
#define COMPILER_DIRECTIVE_HANDLER_H_
#include "compiler/ExtensionBehavior.h"
#include "compiler/Pragma.h"
#include "compiler/preprocessor/new/DirectiveHandler.h"
class TDiagnostics;
class TDirectiveHandler : public pp::DirectiveHandler
{
public:
TDirectiveHandler(TExtensionBehavior& extBehavior,
TDiagnostics& diagnostics);
virtual ~TDirectiveHandler();
const TPragma& pragma() const { return mPragma; }
const TExtensionBehavior& extBehavior() const { return mExtBehavior; }
virtual void handleError(const pp::SourceLocation& loc,
const std::string& msg);
virtual void handlePragma(const pp::SourceLocation& loc,
const std::string& name,
const std::string& value);
virtual void handleExtension(const pp::SourceLocation& loc,
const std::string& name,
const std::string& behavior);
virtual void handleVersion(const pp::SourceLocation& loc,
int version);
private:
TPragma mPragma;
TExtensionBehavior& mExtBehavior;
TDiagnostics& mDiagnostics;
};
#endif // COMPILER_DIRECTIVE_HANDLER_H_
...@@ -7,9 +7,11 @@ ...@@ -7,9 +7,11 @@
#ifndef _EXTENSION_BEHAVIOR_INCLUDED_ #ifndef _EXTENSION_BEHAVIOR_INCLUDED_
#define _EXTENSION_BEHAVIOR_INCLUDED_ #define _EXTENSION_BEHAVIOR_INCLUDED_
#include "compiler/Common.h" #include <map>
#include <string>
typedef enum { typedef enum
{
EBhRequire, EBhRequire,
EBhEnable, EBhEnable,
EBhWarn, EBhWarn,
...@@ -19,20 +21,17 @@ typedef enum { ...@@ -19,20 +21,17 @@ typedef enum {
inline const char* getBehaviorString(TBehavior b) inline const char* getBehaviorString(TBehavior b)
{ {
switch(b) { switch(b)
case EBhRequire: {
return "require"; case EBhRequire: return "require";
case EBhEnable: case EBhEnable: return "enable";
return "enable"; case EBhWarn: return "warn";
case EBhWarn: case EBhDisable: return "disable";
return "warn"; default: return NULL;
case EBhDisable:
return "disable";
default:
return NULL;
} }
} }
typedef TMap<TString, TBehavior> TExtensionBehavior; // Mapping between extension name and behavior.
typedef std::map<std::string, TBehavior> TExtensionBehavior;
#endif // _EXTENSION_TABLE_INCLUDED_ #endif // _EXTENSION_TABLE_INCLUDED_
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/InitializeParseContext.h"
#include "compiler/osinclude.h"
OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
bool InitializeParseContextIndex()
{
if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
return false;
}
//
// Allocate a TLS index.
//
GlobalParseContextIndex = OS_AllocTLSIndex();
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
return false;
}
return true;
}
bool FreeParseContextIndex()
{
OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContextIndex(): Parse Context index not initalized");
return false;
}
GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
return OS_FreeTLSIndex(tlsiIndex);
}
bool InitializeGlobalParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalized");
return false;
}
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext != 0) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
return false;
}
TThreadParseContext *lpThreadData = new TThreadParseContext();
if (lpThreadData == 0) {
assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
return false;
}
lpThreadData->lpGlobalParseContext = 0;
OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
return true;
}
bool FreeParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContext(): Parse Context index not initalized");
return false;
}
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext)
delete lpParseContext;
return true;
}
TParseContextPointer& GetGlobalParseContext()
{
//
// Minimal error checking for speed
//
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
return lpParseContext->lpGlobalParseContext;
}
...@@ -13,4 +13,14 @@ bool FreeParseContextIndex(); ...@@ -13,4 +13,14 @@ bool FreeParseContextIndex();
bool InitializeGlobalParseContext(); bool InitializeGlobalParseContext();
bool FreeParseContext(); bool FreeParseContext();
struct TParseContext;
typedef TParseContext* TParseContextPointer;
extern TParseContextPointer& GetGlobalParseContext();
#define GlobalParseContext GetGlobalParseContext()
typedef struct TThreadParseContextRec
{
TParseContext *lpGlobalParseContext;
} TThreadParseContext;
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_ #endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
...@@ -1445,9 +1445,3 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1445,9 +1445,3 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine()); return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine());
} }
void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
{
assert(!pragmaTable);
pragmaTable = new TPragmaTable();
*pragmaTable = pTable;
}
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
#include <stdio.h> #include <stdio.h>
#include "compiler/glslang.h" #include "compiler/glslang.h"
#include "compiler/osinclude.h" #include "compiler/preprocessor/new/SourceLocation.h"
#include "compiler/InitializeParseContext.h"
extern "C" { extern "C" {
extern int InitPreprocessor(); extern int InitPreprocessor();
...@@ -19,17 +18,6 @@ extern int FinalizePreprocessor(); ...@@ -19,17 +18,6 @@ extern int FinalizePreprocessor();
extern void PredefineIntMacro(const char *name, int value); extern void PredefineIntMacro(const char *name, int value);
} }
static void ReportInfo(TInfoSinkBase& sink,
TPrefixType type, TSourceLoc loc,
const char* reason, const char* token,
const char* extraInfo)
{
/* VC++ format: file(linenum) : error #: 'token' : extrainfo */
sink.prefix(type);
sink.location(loc);
sink << "'" << token << "' : " << reason << " " << extraInfo << "\n";
}
static void DefineExtensionMacros(const TExtensionBehavior& extBehavior) static void DefineExtensionMacros(const TExtensionBehavior& extBehavior)
{ {
for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
...@@ -40,6 +28,26 @@ static void DefineExtensionMacros(const TExtensionBehavior& extBehavior) ...@@ -40,6 +28,26 @@ static void DefineExtensionMacros(const TExtensionBehavior& extBehavior)
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
// Preprocessor
//
////////////////////////////////////////////////////////////////////////
bool TParseContext::initPreprocessor()
{
if (InitPreprocessor())
return false;
DefineExtensionMacros(directiveHandler.extBehavior());
return true;
}
void TParseContext::destroyPreprocessor()
{
FinalizePreprocessor();
}
///////////////////////////////////////////////////////////////////////
//
// Sub- vector and matrix fields // Sub- vector and matrix fields
// //
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -210,7 +218,10 @@ void TParseContext::error(TSourceLoc loc, ...@@ -210,7 +218,10 @@ void TParseContext::error(TSourceLoc loc,
va_start(marker, extraInfoFormat); va_start(marker, extraInfoFormat);
vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker); vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
ReportInfo(infoSink.info, EPrefixError, loc, reason, token, extraInfo); pp::SourceLocation srcLoc;
DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
diagnostics.writeInfo(pp::Diagnostics::ERROR,
srcLoc, reason, token, extraInfo);
va_end(marker); va_end(marker);
++numErrors; ++numErrors;
...@@ -224,11 +235,19 @@ void TParseContext::warning(TSourceLoc loc, ...@@ -224,11 +235,19 @@ void TParseContext::warning(TSourceLoc loc,
va_start(marker, extraInfoFormat); va_start(marker, extraInfoFormat);
vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker); vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
ReportInfo(infoSink.info, EPrefixWarning, loc, reason, token, extraInfo); pp::SourceLocation srcLoc;
DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
diagnostics.writeInfo(pp::Diagnostics::WARNING,
srcLoc, reason, token, extraInfo);
va_end(marker); va_end(marker);
} }
void TParseContext::trace(const char* str)
{
diagnostics.writeDebug(str);
}
// //
// Same error message for all places assignments don't work. // Same error message for all places assignments don't work.
// //
...@@ -830,10 +849,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, ...@@ -830,10 +849,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
// its an error // its an error
if (node->getSymbol() == "gl_FragData") { if (node->getSymbol() == "gl_FragData") {
TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn); TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn);
if (fragData == 0) { ASSERT(fragData);
infoSink.info.message(EPrefixInternalError, "gl_MaxDrawBuffers not defined", line);
return true;
}
int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst(); int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
if (fragDataValue <= size) { if (fragDataValue <= size) {
...@@ -926,8 +942,9 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p ...@@ -926,8 +942,9 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p
bool TParseContext::extensionErrorCheck(int line, const TString& extension) bool TParseContext::extensionErrorCheck(int line, const TString& extension)
{ {
TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension); const TExtensionBehavior& extBehavior = directiveHandler.extBehavior();
if (iter == extensionBehavior.end()) { TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
if (iter == extBehavior.end()) {
error(line, "extension", extension.c_str(), "is not supported"); error(line, "extension", extension.c_str(), "is not supported");
return true; return true;
} }
...@@ -937,8 +954,7 @@ bool TParseContext::extensionErrorCheck(int line, const TString& extension) ...@@ -937,8 +954,7 @@ bool TParseContext::extensionErrorCheck(int line, const TString& extension)
return true; return true;
} }
if (iter->second == EBhWarn) { if (iter->second == EBhWarn) {
TString msg = "extension " + extension + " is being used"; warning(line, "extension", extension.c_str(), "is being used");
infoSink.info.message(EPrefixWarning, msg.c_str(), line);
return false; return false;
} }
...@@ -947,8 +963,23 @@ bool TParseContext::extensionErrorCheck(int line, const TString& extension) ...@@ -947,8 +963,23 @@ bool TParseContext::extensionErrorCheck(int line, const TString& extension)
bool TParseContext::supportsExtension(const char* extension) bool TParseContext::supportsExtension(const char* extension)
{ {
TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension); const TExtensionBehavior& extBehavior = directiveHandler.extBehavior();
return (iter != extensionBehavior.end()); TExtensionBehavior::const_iterator iter = extBehavior.find(extension);
return (iter != extBehavior.end());
}
void TParseContext::handleExtensionDirective(int line, const char* extName, const char* behavior)
{
pp::SourceLocation loc;
DecodeSourceLoc(line, &loc.file, &loc.line);
directiveHandler.handleExtension(loc, extName, behavior);
}
void TParseContext::handlePragmaDirective(int line, const char* name, const char* value)
{
pp::SourceLocation loc;
DecodeSourceLoc(line, &loc.file, &loc.line);
directiveHandler.handlePragma(loc, name, value);
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
...@@ -1295,11 +1326,9 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy ...@@ -1295,11 +1326,9 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
ConstantUnion *unionArray; ConstantUnion *unionArray;
if (tempConstantNode) { if (tempConstantNode) {
unionArray = tempConstantNode->getUnionArrayPointer(); unionArray = tempConstantNode->getUnionArrayPointer();
ASSERT(unionArray);
if (!unionArray) { // this error message should never be raised if (!unionArray) {
infoSink.info.message(EPrefixInternalError, "ConstantUnion not initialized in addConstVectorNode function", line);
recover();
return node; return node;
} }
} else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
...@@ -1484,10 +1513,8 @@ int PaParseStrings(int count, const char* const string[], const int length[], ...@@ -1484,10 +1513,8 @@ int PaParseStrings(int count, const char* const string[], const int length[],
if ((count == 0) || (string == NULL)) if ((count == 0) || (string == NULL))
return 1; return 1;
// setup preprocessor. if (!context->initPreprocessor())
if (InitPreprocessor())
return 1; return 1;
DefineExtensionMacros(context->extensionBehavior);
if (glslang_initialize(context)) if (glslang_initialize(context))
return 1; return 1;
...@@ -1497,93 +1524,10 @@ int PaParseStrings(int count, const char* const string[], const int length[], ...@@ -1497,93 +1524,10 @@ int PaParseStrings(int count, const char* const string[], const int length[],
error = glslang_parse(context); error = glslang_parse(context);
glslang_finalize(context); glslang_finalize(context);
FinalizePreprocessor(); context->destroyPreprocessor();
return (error == 0) && (context->numErrors == 0) ? 0 : 1;
}
OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
bool InitializeParseContextIndex() return (error == 0) && (context->numErrors == 0) ? 0 : 1;
{
if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
return false;
}
//
// Allocate a TLS index.
//
GlobalParseContextIndex = OS_AllocTLSIndex();
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
return false;
}
return true;
}
bool FreeParseContextIndex()
{
OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
return false;
}
GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
return OS_FreeTLSIndex(tlsiIndex);
}
bool InitializeGlobalParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalised");
return false;
}
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext != 0) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
return false;
}
TThreadParseContext *lpThreadData = new TThreadParseContext();
if (lpThreadData == 0) {
assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
return false;
}
lpThreadData->lpGlobalParseContext = 0;
OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
return true;
}
bool FreeParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContext(): Parse Context index not initalised");
return false;
}
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext)
delete lpParseContext;
return true;
} }
TParseContextPointer& GetGlobalParseContext()
{
//
// Minimal error checking for speed
//
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
return lpParseContext->lpGlobalParseContext;
}
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
#ifndef _PARSER_HELPER_INCLUDED_ #ifndef _PARSER_HELPER_INCLUDED_
#define _PARSER_HELPER_INCLUDED_ #define _PARSER_HELPER_INCLUDED_
#include "compiler/ExtensionBehavior.h" #include "compiler/Diagnostics.h"
#include "compiler/DirectiveHandler.h"
#include "compiler/localintermediate.h" #include "compiler/localintermediate.h"
#include "compiler/ShHandle.h" #include "compiler/ShHandle.h"
#include "compiler/SymbolTable.h" #include "compiler/SymbolTable.h"
...@@ -18,13 +19,6 @@ struct TMatrixFields { ...@@ -18,13 +19,6 @@ struct TMatrixFields {
int col; int col;
}; };
struct TPragma {
TPragma(bool o, bool d) : optimize(o), debug(d) { }
bool optimize;
bool debug;
TPragmaTable pragmaTable;
};
// //
// The following are extra variables needed during parsing, grouped together so // The following are extra variables needed during parsing, grouped together so
// they can be passed to the parser without needing a global. // they can be passed to the parser without needing a global.
...@@ -33,8 +27,8 @@ struct TParseContext { ...@@ -33,8 +27,8 @@ struct TParseContext {
TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) : TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
intermediate(interm), intermediate(interm),
symbolTable(symt), symbolTable(symt),
extensionBehavior(ext), diagnostics(is),
infoSink(is), directiveHandler(ext, diagnostics),
shaderType(type), shaderType(type),
shaderSpec(spec), shaderSpec(spec),
compileOptions(options), compileOptions(options),
...@@ -48,12 +42,11 @@ struct TParseContext { ...@@ -48,12 +42,11 @@ struct TParseContext {
currentFunctionType(NULL), currentFunctionType(NULL),
functionReturnsValue(false), functionReturnsValue(false),
checksPrecisionErrors(checksPrecErrors), checksPrecisionErrors(checksPrecErrors),
contextPragma(true, false),
scanner(NULL) { } scanner(NULL) { }
TIntermediate& intermediate; // to hold and build a parse tree TIntermediate& intermediate; // to hold and build a parse tree
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
TExtensionBehavior& extensionBehavior; // mapping between supported extensions and current behavior. TDiagnostics diagnostics;
TInfoSink& infoSink; TDirectiveHandler directiveHandler;
ShShaderType shaderType; // vertex or fragment language (future: pack or unpack) ShShaderType shaderType; // vertex or fragment language (future: pack or unpack)
ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
int compileOptions; int compileOptions;
...@@ -67,15 +60,18 @@ struct TParseContext { ...@@ -67,15 +60,18 @@ struct TParseContext {
const TType* currentFunctionType; // the return type of the function that's currently being parsed const TType* currentFunctionType; // the return type of the function that's currently being parsed
bool functionReturnsValue; // true if a non-void function has a return bool functionReturnsValue; // true if a non-void function has a return
bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit. bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
struct TPragma contextPragma;
TString HashErrMsg; TString HashErrMsg;
bool AfterEOF; bool AfterEOF;
void* scanner; void* scanner;
bool initPreprocessor();
void destroyPreprocessor();
void error(TSourceLoc loc, const char *reason, const char* token, void error(TSourceLoc loc, const char *reason, const char* token,
const char* extraInfoFormat, ...); const char* extraInfoFormat, ...);
void warning(TSourceLoc loc, const char* reason, const char* token, void warning(TSourceLoc loc, const char* reason, const char* token,
const char* extraInfoFormat, ...); const char* extraInfoFormat, ...);
void trace(const char* str);
void recover(); void recover();
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line); bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
...@@ -105,7 +101,12 @@ struct TParseContext { ...@@ -105,7 +101,12 @@ struct TParseContext {
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable); bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable);
bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type); bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
bool extensionErrorCheck(int line, const TString&); bool extensionErrorCheck(int line, const TString&);
bool supportsExtension(const char* extension); bool supportsExtension(const char* extension);
void handleExtensionDirective(int line, const char* extName, const char* behavior);
const TPragma& pragma() const { return directiveHandler.pragma(); }
void handlePragmaDirective(int line, const char* name, const char* value);
bool containsSampler(TType& type); bool containsSampler(TType& type);
bool areAllChildConst(TIntermAggregate* aggrNode); bool areAllChildConst(TIntermAggregate* aggrNode);
...@@ -135,13 +136,4 @@ struct TParseContext { ...@@ -135,13 +136,4 @@ struct TParseContext {
int PaParseStrings(int count, const char* const string[], const int length[], int PaParseStrings(int count, const char* const string[], const int length[],
TParseContext* context); TParseContext* context);
typedef TParseContext* TParseContextPointer;
extern TParseContextPointer& GetGlobalParseContext();
#define GlobalParseContext GetGlobalParseContext()
typedef struct TThreadParseContextRec
{
TParseContext *lpGlobalParseContext;
} TThreadParseContext;
#endif // _PARSER_HELPER_INCLUDED_ #endif // _PARSER_HELPER_INCLUDED_
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_PRAGMA_H_
#define COMPILER_PRAGMA_H_
struct TPragma {
// By default optimization is turned on and debug is turned off.
TPragma() : optimize(true), debug(false) { }
TPragma(bool o, bool d) : optimize(o), debug(d) { }
bool optimize;
bool debug;
};
#endif // COMPILER_PRAGMA_H_
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "compiler/ValidateLimitations.h" #include "compiler/ValidateLimitations.h"
#include "compiler/InfoSink.h" #include "compiler/InfoSink.h"
#include "compiler/InitializeParseContext.h"
#include "compiler/ParseHelper.h" #include "compiler/ParseHelper.h"
namespace { namespace {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include "compiler/InitializeParseContext.h"
#include "compiler/ParseHelper.h" #include "compiler/ParseHelper.h"
static const int kTraceBufferLen = 1024; static const int kTraceBufferLen = 1024;
...@@ -28,7 +29,7 @@ void Trace(const char *format, ...) { ...@@ -28,7 +29,7 @@ void Trace(const char *format, ...) {
vsnprintf(buf, kTraceBufferLen, format, args); vsnprintf(buf, kTraceBufferLen, format, args);
va_end(args); va_end(args);
parseContext->infoSink.debug << buf; parseContext->trace(buf);
} }
} }
} // extern "C" } // extern "C"
......
...@@ -283,7 +283,7 @@ extern "C" { ...@@ -283,7 +283,7 @@ extern "C" {
void CPPDebugLogMsg(const char *msg) void CPPDebugLogMsg(const char *msg)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
context->infoSink.debug.message(EPrefixNone, msg); context->trace(msg);
} }
void CPPWarningToInfoLog(const char *msg) void CPPWarningToInfoLog(const char *msg)
...@@ -299,7 +299,7 @@ void CPPShInfoLogMsg(const char *msg) ...@@ -299,7 +299,7 @@ void CPPShInfoLogMsg(const char *msg)
context->recover(); context->recover();
} }
void CPPErrorToInfoLog(char *msg) void CPPErrorToInfoLog(const char *msg)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
context->error(yylineno, msg, "", ""); context->error(yylineno, msg, "", "");
...@@ -357,85 +357,12 @@ void DecLineNumber() ...@@ -357,85 +357,12 @@ void DecLineNumber()
void HandlePragma(const char **tokens, int numTokens) void HandlePragma(const char **tokens, int numTokens)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
if (!strcmp(tokens[0], "optimize")) {
if (numTokens != 4) {
CPPShInfoLogMsg("optimize pragma syntax is incorrect");
return;
}
if (strcmp(tokens[1], "(")) {
CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword");
return;
}
if (!strcmp(tokens[2], "on"))
context->contextPragma.optimize = true;
else if (!strcmp(tokens[2], "off"))
context->contextPragma.optimize = false;
else {
CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
return;
}
if (strcmp(tokens[3], ")")) {
CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
return;
}
} else if (!strcmp(tokens[0], "debug")) {
if (numTokens != 4) {
CPPShInfoLogMsg("debug pragma syntax is incorrect");
return;
}
if (strcmp(tokens[1], "(")) {
CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
return;
}
if (!strcmp(tokens[2], "on")) if (numTokens != 4) return;
context->contextPragma.debug = true; if (strcmp(tokens[1], "(") != 0) return;
else if (!strcmp(tokens[2], "off")) if (strcmp(tokens[3], ")") != 0) return;
context->contextPragma.debug = false;
else {
CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
return;
}
if (strcmp(tokens[3], ")")) { context->handlePragmaDirective(yylineno, tokens[0], tokens[2]);
CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
return;
}
} else {
#ifdef PRAGMA_TABLE
//
// implementation specific pragma
// use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma
// For now, just ignore the pragma that the implementation cannot recognize
// An Example of one such implementation for a pragma that has a syntax like
// #pragma pragmaname(pragmavalue)
// This implementation stores the current pragmavalue against the pragma name in pragmaTable.
//
if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {
TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
TPragmaTable::iterator iter;
iter = pragmaTable.find(TString(tokens[0]));
if (iter != pragmaTable.end()) {
iter->second = tokens[2];
} else {
pragmaTable[ tokens[0] ] = tokens[2];
}
} else if (numTokens >= 2) {
TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
TPragmaTable::iterator iter;
iter = pragmaTable.find(TString(tokens[0]));
if (iter != pragmaTable.end()) {
iter->second = tokens[1];
} else {
pragmaTable[ tokens[0] ] = tokens[1];
}
}
#endif // PRAGMA_TABLE
}
} }
void StoreStr(char *string) void StoreStr(char *string)
...@@ -460,58 +387,10 @@ void ResetTString(void) ...@@ -460,58 +387,10 @@ void ResetTString(void)
context->HashErrMsg = ""; context->HashErrMsg = "";
} }
TBehavior GetBehavior(const char* behavior)
{
if (!strcmp("require", behavior))
return EBhRequire;
else if (!strcmp("enable", behavior))
return EBhEnable;
else if (!strcmp("disable", behavior))
return EBhDisable;
else if (!strcmp("warn", behavior))
return EBhWarn;
else {
CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
return EBhDisable;
}
}
void updateExtensionBehavior(const char* extName, const char* behavior) void updateExtensionBehavior(const char* extName, const char* behavior)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
TBehavior behaviorVal = GetBehavior(behavior); context->handleExtensionDirective(yylineno, extName, behavior);
TMap<TString, TBehavior>:: iterator iter;
TString msg;
// special cased for all extension
if (!strcmp(extName, "all")) {
if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");
return;
} else {
for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter)
iter->second = behaviorVal;
}
} else {
iter = context->extensionBehavior.find(TString(extName));
if (iter == context->extensionBehavior.end()) {
switch (behaviorVal) {
case EBhRequire:
CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());
break;
case EBhEnable:
case EBhWarn:
case EBhDisable:
msg = TString("extension '") + extName + "' is not supported";
context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno);
break;
default:
break;
}
return;
} else
iter->second = behaviorVal;
}
} }
} // extern "C" } // extern "C"
......
...@@ -2116,9 +2116,8 @@ function_definition ...@@ -2116,9 +2116,8 @@ function_definition
// store the pragma information for debug and optimize and other vendor specific // store the pragma information for debug and optimize and other vendor specific
// information. This information can be queried from the parse tree // information. This information can be queried from the parse tree
$$->getAsAggregate()->setOptimize(context->contextPragma.optimize); $$->getAsAggregate()->setOptimize(context->pragma().optimize);
$$->getAsAggregate()->setDebug(context->contextPragma.debug); $$->getAsAggregate()->setDebug(context->pragma().debug);
$$->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable);
if ($3 && $3->getAsAggregate()) if ($3 && $3->getAsAggregate())
$$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine()); $$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine());
......
#line 17 "./compiler/glslang.l" #line 17 "./glslang.l"
// //
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#line 25 "./compiler/glslang_lex.cpp" #line 25 "./glslang_lex.cpp"
#define YY_INT_ALIGNED short int #define YY_INT_ALIGNED short int
...@@ -2959,7 +2959,7 @@ extern "C" { ...@@ -2959,7 +2959,7 @@ extern "C" {
void CPPDebugLogMsg(const char *msg) void CPPDebugLogMsg(const char *msg)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
context->infoSink.debug.message(EPrefixNone, msg); context->trace(msg);
} }
void CPPWarningToInfoLog(const char *msg) void CPPWarningToInfoLog(const char *msg)
...@@ -3033,85 +3033,12 @@ void DecLineNumber() ...@@ -3033,85 +3033,12 @@ void DecLineNumber()
void HandlePragma(const char **tokens, int numTokens) void HandlePragma(const char **tokens, int numTokens)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
if (!strcmp(tokens[0], "optimize")) {
if (numTokens != 4) {
CPPShInfoLogMsg("optimize pragma syntax is incorrect");
return;
}
if (strcmp(tokens[1], "(")) { if (numTokens != 4) return;
CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword"); if (strcmp(tokens[1], "(") != 0) return;
return; if (strcmp(tokens[3], ")") != 0) return;
}
if (!strcmp(tokens[2], "on")) context->handlePragmaDirective(yylineno, tokens[0], tokens[2]);
context->contextPragma.optimize = true;
else if (!strcmp(tokens[2], "off"))
context->contextPragma.optimize = false;
else {
CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
return;
}
if (strcmp(tokens[3], ")")) {
CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
return;
}
} else if (!strcmp(tokens[0], "debug")) {
if (numTokens != 4) {
CPPShInfoLogMsg("debug pragma syntax is incorrect");
return;
}
if (strcmp(tokens[1], "(")) {
CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
return;
}
if (!strcmp(tokens[2], "on"))
context->contextPragma.debug = true;
else if (!strcmp(tokens[2], "off"))
context->contextPragma.debug = false;
else {
CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
return;
}
if (strcmp(tokens[3], ")")) {
CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
return;
}
} else {
#ifdef PRAGMA_TABLE
//
// implementation specific pragma
// use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma
// For now, just ignore the pragma that the implementation cannot recognize
// An Example of one such implementation for a pragma that has a syntax like
// #pragma pragmaname(pragmavalue)
// This implementation stores the current pragmavalue against the pragma name in pragmaTable.
//
if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {
TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
TPragmaTable::iterator iter;
iter = pragmaTable.find(TString(tokens[0]));
if (iter != pragmaTable.end()) {
iter->second = tokens[2];
} else {
pragmaTable[ tokens[0] ] = tokens[2];
}
} else if (numTokens >= 2) {
TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
TPragmaTable::iterator iter;
iter = pragmaTable.find(TString(tokens[0]));
if (iter != pragmaTable.end()) {
iter->second = tokens[1];
} else {
pragmaTable[ tokens[0] ] = tokens[1];
}
}
#endif // PRAGMA_TABLE
}
} }
void StoreStr(char *string) void StoreStr(char *string)
...@@ -3136,58 +3063,10 @@ void ResetTString(void) ...@@ -3136,58 +3063,10 @@ void ResetTString(void)
context->HashErrMsg = ""; context->HashErrMsg = "";
} }
TBehavior GetBehavior(const char* behavior)
{
if (!strcmp("require", behavior))
return EBhRequire;
else if (!strcmp("enable", behavior))
return EBhEnable;
else if (!strcmp("disable", behavior))
return EBhDisable;
else if (!strcmp("warn", behavior))
return EBhWarn;
else {
CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
return EBhDisable;
}
}
void updateExtensionBehavior(const char* extName, const char* behavior) void updateExtensionBehavior(const char* extName, const char* behavior)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
TBehavior behaviorVal = GetBehavior(behavior); context->handleExtensionDirective(yylineno, extName, behavior);
TMap<TString, TBehavior>:: iterator iter;
TString msg;
// special cased for all extension
if (!strcmp(extName, "all")) {
if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");
return;
} else {
for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter)
iter->second = behaviorVal;
}
} else {
iter = context->extensionBehavior.find(TString(extName));
if (iter == context->extensionBehavior.end()) {
switch (behaviorVal) {
case EBhRequire:
CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());
break;
case EBhEnable:
case EBhWarn:
case EBhDisable:
msg = TString("extension '") + extName + "' is not supported";
context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno);
break;
default:
break;
}
return;
} else
iter->second = behaviorVal;
}
} }
} // extern "C" } // extern "C"
......
...@@ -4514,9 +4514,8 @@ yyreduce: ...@@ -4514,9 +4514,8 @@ yyreduce:
// store the pragma information for debug and optimize and other vendor specific // store the pragma information for debug and optimize and other vendor specific
// information. This information can be queried from the parse tree // information. This information can be queried from the parse tree
(yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->contextPragma.optimize); (yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->pragma().optimize);
(yyval.interm.intermNode)->getAsAggregate()->setDebug(context->contextPragma.debug); (yyval.interm.intermNode)->getAsAggregate()->setDebug(context->pragma().debug);
(yyval.interm.intermNode)->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable);
if ((yyvsp[(3) - (3)].interm.intermNode) && (yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate()) if ((yyvsp[(3) - (3)].interm.intermNode) && (yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate())
(yyval.interm.intermNode)->getAsAggregate()->setEndLine((yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate()->getEndLine()); (yyval.interm.intermNode)->getAsAggregate()->setEndLine((yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate()->getEndLine());
......
...@@ -433,15 +433,15 @@ protected: ...@@ -433,15 +433,15 @@ protected:
typedef TVector<TIntermNode*> TIntermSequence; typedef TVector<TIntermNode*> TIntermSequence;
typedef TVector<int> TQualifierList; typedef TVector<int> TQualifierList;
typedef TMap<TString, TString> TPragmaTable;
// //
// Nodes that operate on an arbitrary sized set of children. // Nodes that operate on an arbitrary sized set of children.
// //
class TIntermAggregate : public TIntermOperator { class TIntermAggregate : public TIntermOperator {
public: public:
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0), endLine(0), useEmulatedFunction(false) { } TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0), useEmulatedFunction(false) { } TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
~TIntermAggregate() { delete pragmaTable; } ~TIntermAggregate() { }
virtual TIntermAggregate* getAsAggregate() { return this; } virtual TIntermAggregate* getAsAggregate() { return this; }
virtual void traverse(TIntermTraverser*); virtual void traverse(TIntermTraverser*);
...@@ -458,8 +458,7 @@ public: ...@@ -458,8 +458,7 @@ public:
bool getOptimize() { return optimize; } bool getOptimize() { return optimize; }
void setDebug(bool d) { debug = d; } void setDebug(bool d) { debug = d; }
bool getDebug() { return debug; } bool getDebug() { return debug; }
void addToPragmaTable(const TPragmaTable& pTable);
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
void setEndLine(TSourceLoc line) { endLine = line; } void setEndLine(TSourceLoc line) { endLine = line; }
TSourceLoc getEndLine() const { return endLine; } TSourceLoc getEndLine() const { return endLine; }
...@@ -475,7 +474,6 @@ protected: ...@@ -475,7 +474,6 @@ protected:
bool optimize; bool optimize;
bool debug; bool debug;
TPragmaTable *pragmaTable;
TSourceLoc endLine; TSourceLoc endLine;
// If set to true, replace the built-in function call with an emulated one // If set to true, replace the built-in function call with an emulated one
......
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include <stdlib.h>
#include <string.h>
extern "C" {
#include "compiler/preprocessor/lexer_glue.h"
#include "compiler/preprocessor/slglobals.h"
#include "compiler/preprocessor/scanner.h"
}
#include "compiler/preprocessor/new/Diagnostics.h"
#include "compiler/preprocessor/new/Token.h"
#include "compiler/preprocessor/new/Tokenizer.h"
class Diagnostics : public pp::Diagnostics
{
protected:
virtual void print(ID id,
const pp::SourceLocation& loc,
const std::string& text)
{
// TODO(alokp): Implement me.
}
};
struct InputSrcLexer
{
InputSrc base;
pp::Diagnostics* diagnostics;
pp::Lexer* lexer;
};
static bool CopySymbolName(const std::string& name, yystypepp* yylvalpp)
{
if (name.length() > MAX_SYMBOL_NAME_LEN)
{
CPPErrorToInfoLog("BUFFER OVERFLOW");
return false;
}
strcpy(yylvalpp->symbol_name, name.c_str());
return true;
}
static int lex(InputSrc* in, yystypepp* yylvalpp)
{
InputSrcLexer* src = ((InputSrcLexer *)in);
int ret = 0;
pp::Token token;
src->lexer->lex(&token);
switch (token.type)
{
case 0: // EOF
delete src->lexer;
delete src->diagnostics;
free(src);
cpp->currentInput = 0;
ret = EOF;
break;
case pp::Token::IDENTIFIER:
if (CopySymbolName(token.value, yylvalpp))
{
yylvalpp->sc_ident = LookUpAddString(atable, token.value.c_str());
}
ret = CPP_IDENTIFIER;
break;
case pp::Token::CONST_INT:
if (CopySymbolName(token.value, yylvalpp))
{
yylvalpp->sc_int = atoi(token.value.c_str());
}
ret = CPP_INTCONSTANT;
break;
case pp::Token::CONST_FLOAT:
CopySymbolName(token.value, yylvalpp);
ret = CPP_FLOATCONSTANT;
break;
case pp::Token::OP_INC:
ret = CPP_INC_OP;
break;
case pp::Token::OP_DEC:
ret = CPP_DEC_OP;
break;
case pp::Token::OP_RIGHT:
ret = CPP_RIGHT_OP;
break;
case pp::Token::OP_LE:
ret = CPP_LE_OP;
break;
case pp::Token::OP_GE:
ret = CPP_GE_OP;
break;
case pp::Token::OP_EQ:
ret = CPP_EQ_OP;
break;
case pp::Token::OP_NE:
ret = CPP_NE_OP;
break;
case pp::Token::OP_AND:
ret = CPP_AND_OP;
break;
case pp::Token::OP_XOR:
ret = CPP_XOR_OP;
break;
case pp::Token::OP_OR:
ret = CPP_OR_OP;
break;
case pp::Token::OP_ADD_ASSIGN:
ret = CPP_ADD_ASSIGN;
break;
case pp::Token::OP_SUB_ASSIGN:
ret = CPP_SUB_ASSIGN;
break;
case pp::Token::OP_MUL_ASSIGN:
ret = CPP_MUL_ASSIGN;
break;
case pp::Token::OP_DIV_ASSIGN:
ret = CPP_DIV_ASSIGN;
break;
case pp::Token::OP_MOD_ASSIGN:
ret = CPP_MOD_ASSIGN;
break;
case pp::Token::OP_LEFT_ASSIGN:
ret = CPP_LEFT_ASSIGN;
break;
case pp::Token::OP_RIGHT_ASSIGN:
ret = CPP_RIGHT_ASSIGN;
break;
case pp::Token::OP_AND_ASSIGN:
ret = CPP_AND_ASSIGN;
break;
case pp::Token::OP_XOR_ASSIGN:
ret = CPP_XOR_ASSIGN;
break;
case pp::Token::OP_OR_ASSIGN:
ret = CPP_OR_ASSIGN;
break;
default:
break;
}
SetLineNumber(token.location.line);
SetStringNumber(token.location.file);
return ret;
}
InputSrc* LexerInputSrc(int count, const char* const string[], const int length[])
{
Diagnostics* diagnostics = new Diagnostics;
pp::Tokenizer* lexer = new pp::Tokenizer(diagnostics);
if (!lexer->init(count, string, length))
{
delete lexer;
delete diagnostics;
return 0;
}
InputSrcLexer* in = (InputSrcLexer *) malloc(sizeof(InputSrcLexer));
memset(in, 0, sizeof(InputSrcLexer));
in->base.line = 1;
in->base.scan = lex;
in->diagnostics = diagnostics;
in->lexer = lexer;
return &in->base;
}
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_PREPROCESSOR_LEXER_GLUE_H_
#define COMPILER_PREPROCESSOR_LEXER_GLUE_H_
struct InputSrc;
InputSrc* LexerInputSrc(int count, const char* const string[], const int length[]);
#endif // COMPILER_PREPROCESSOR_LEXER_GLUE_H_
...@@ -59,7 +59,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -59,7 +59,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#include "compiler/preprocessor/slglobals.h" #include "compiler/preprocessor/slglobals.h"
#include "compiler/preprocessor/lexer_glue.h"
#include "compiler/util.h" #include "compiler/util.h"
typedef struct StringInputSrc { typedef struct StringInputSrc {
...@@ -129,22 +128,13 @@ int FreeScanner(void) ...@@ -129,22 +128,13 @@ int FreeScanner(void)
return (FreeCPP()); return (FreeCPP());
} }
// Define this to 1 to use the new lexer.
#define CPP_USE_NEW_LEXER 0
int InitScannerInput(CPPStruct *cpp, int count, const char* const string[], const int length[]) int InitScannerInput(CPPStruct *cpp, int count, const char* const string[], const int length[])
{ {
#if CPP_USE_NEW_LEXER
InputSrc* in = LexerInputSrc(count, string, length);
if (!in) return 1;
cpp->currentInput = in;
#else
cpp->PaWhichStr = 0; cpp->PaWhichStr = 0;
cpp->PaArgv = string; cpp->PaArgv = string;
cpp->PaArgc = count; cpp->PaArgc = count;
cpp->PaStrLen = length; cpp->PaStrLen = length;
ScanFromString(string[0]); ScanFromString(string[0]);
#endif
return 0; return 0;
} }
......
...@@ -105,7 +105,6 @@ Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind); ...@@ -105,7 +105,6 @@ Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind);
Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind); Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind);
Symbol *LookUpLocalSymbol(Scope *fScope, int atom); Symbol *LookUpLocalSymbol(Scope *fScope, int atom);
Symbol *LookUpSymbol(Scope *fScope, int atom); Symbol *LookUpSymbol(Scope *fScope, int atom);
void CPPErrorToInfoLog(const char *);
#endif // !defined(__SYMBOLS_H) #endif // !defined(__SYMBOLS_H)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment