mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
Try to stay compatible with Bison 2.5 (for Ubuntu precise), support C++11 and C++17 static_assert, improve error reporting, handle several gcc keyword aliases, fix bug handling preprocessor expression in which the same manifest occurs more than once
This commit is contained in:
parent
1c9ff40236
commit
ba45120eac
File diff suppressed because it is too large
Load Diff
@ -131,25 +131,26 @@ extern int cppyydebug;
|
||||
KW_SIGNED = 340,
|
||||
KW_SIZEOF = 341,
|
||||
KW_STATIC = 342,
|
||||
KW_STATIC_CAST = 343,
|
||||
KW_STRUCT = 344,
|
||||
KW_TEMPLATE = 345,
|
||||
KW_THROW = 346,
|
||||
KW_TRUE = 347,
|
||||
KW_TRY = 348,
|
||||
KW_TYPEDEF = 349,
|
||||
KW_TYPENAME = 350,
|
||||
KW_UNION = 351,
|
||||
KW_UNSIGNED = 352,
|
||||
KW_USING = 353,
|
||||
KW_VIRTUAL = 354,
|
||||
KW_VOID = 355,
|
||||
KW_VOLATILE = 356,
|
||||
KW_WCHAR_T = 357,
|
||||
KW_WHILE = 358,
|
||||
START_CPP = 359,
|
||||
START_CONST_EXPR = 360,
|
||||
START_TYPE = 361
|
||||
KW_STATIC_ASSERT = 343,
|
||||
KW_STATIC_CAST = 344,
|
||||
KW_STRUCT = 345,
|
||||
KW_TEMPLATE = 346,
|
||||
KW_THROW = 347,
|
||||
KW_TRUE = 348,
|
||||
KW_TRY = 349,
|
||||
KW_TYPEDEF = 350,
|
||||
KW_TYPENAME = 351,
|
||||
KW_UNION = 352,
|
||||
KW_UNSIGNED = 353,
|
||||
KW_USING = 354,
|
||||
KW_VIRTUAL = 355,
|
||||
KW_VOID = 356,
|
||||
KW_VOLATILE = 357,
|
||||
KW_WCHAR_T = 358,
|
||||
KW_WHILE = 359,
|
||||
START_CPP = 360,
|
||||
START_CONST_EXPR = 361,
|
||||
START_TYPE = 362
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
@ -238,25 +239,26 @@ extern int cppyydebug;
|
||||
#define KW_SIGNED 340
|
||||
#define KW_SIZEOF 341
|
||||
#define KW_STATIC 342
|
||||
#define KW_STATIC_CAST 343
|
||||
#define KW_STRUCT 344
|
||||
#define KW_TEMPLATE 345
|
||||
#define KW_THROW 346
|
||||
#define KW_TRUE 347
|
||||
#define KW_TRY 348
|
||||
#define KW_TYPEDEF 349
|
||||
#define KW_TYPENAME 350
|
||||
#define KW_UNION 351
|
||||
#define KW_UNSIGNED 352
|
||||
#define KW_USING 353
|
||||
#define KW_VIRTUAL 354
|
||||
#define KW_VOID 355
|
||||
#define KW_VOLATILE 356
|
||||
#define KW_WCHAR_T 357
|
||||
#define KW_WHILE 358
|
||||
#define START_CPP 359
|
||||
#define START_CONST_EXPR 360
|
||||
#define START_TYPE 361
|
||||
#define KW_STATIC_ASSERT 343
|
||||
#define KW_STATIC_CAST 344
|
||||
#define KW_STRUCT 345
|
||||
#define KW_TEMPLATE 346
|
||||
#define KW_THROW 347
|
||||
#define KW_TRUE 348
|
||||
#define KW_TRY 349
|
||||
#define KW_TYPEDEF 350
|
||||
#define KW_TYPENAME 351
|
||||
#define KW_UNION 352
|
||||
#define KW_UNSIGNED 353
|
||||
#define KW_USING 354
|
||||
#define KW_VIRTUAL 355
|
||||
#define KW_VOID 356
|
||||
#define KW_VOLATILE 357
|
||||
#define KW_WCHAR_T 358
|
||||
#define KW_WHILE 359
|
||||
#define START_CPP 360
|
||||
#define START_CONST_EXPR 361
|
||||
#define START_TYPE 362
|
||||
|
||||
|
||||
|
||||
|
@ -57,7 +57,7 @@ int yyparse();
|
||||
|
||||
static void
|
||||
yyerror(const string &msg) {
|
||||
current_lexer->error(msg);
|
||||
current_lexer->error(msg, current_lexer->_last_token_loc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -199,9 +199,11 @@ pop_struct() {
|
||||
|
||||
/* This is a bison-specific declaration to enable recursive calls to
|
||||
yyparse(). It changes the calling sequence to yylex(), passing
|
||||
pointers to the current yylval and yylloc. It also adds a pointer
|
||||
to the current lloc to yyerror, which gives us better diagnostics. */
|
||||
%define api.pure full
|
||||
pointers to the current yylval and yylloc. Bison 2.7 introduces a
|
||||
different syntax that will also pass the current yylloc to yyerror,
|
||||
but we have to support Bison versions as old as 2.5 for now. */
|
||||
/*%define api.pure full*/
|
||||
%pure-parser
|
||||
%locations
|
||||
|
||||
%token <u.real> REAL
|
||||
@ -288,6 +290,7 @@ pop_struct() {
|
||||
%token KW_SIGNED
|
||||
%token KW_SIZEOF
|
||||
%token KW_STATIC
|
||||
%token KW_STATIC_ASSERT
|
||||
%token KW_STATIC_CAST
|
||||
%token KW_STRUCT
|
||||
%token KW_TEMPLATE
|
||||
@ -518,10 +521,29 @@ declaration:
|
||||
current_scope->add_declaration(make_property, global_scope, current_lexer, @1);
|
||||
}
|
||||
}
|
||||
| KW_MAKE_SEQ '(' name ',' name ',' name ')' ';'
|
||||
| KW_MAKE_SEQ '(' name ',' name ',' name ')' ';'
|
||||
{
|
||||
CPPMakeSeq *make_seq = new CPPMakeSeq($3->get_simple_name(), $5->get_simple_name(), $7->get_simple_name(), @1.file);
|
||||
current_scope->add_declaration(make_seq, global_scope, current_lexer, @1);
|
||||
}
|
||||
| KW_STATIC_ASSERT '(' const_expr ',' string ')'
|
||||
{
|
||||
CPPExpression::Result result = $3->evaluate();
|
||||
if (result._type == CPPExpression::RT_error) {
|
||||
yywarning("static_assert requires a constant expression", @3);
|
||||
} else if (!result.as_boolean()) {
|
||||
yywarning("static_assert failed: " + $5, @3);
|
||||
}
|
||||
}
|
||||
| KW_STATIC_ASSERT '(' const_expr ')'
|
||||
{
|
||||
// This alternative version of static_assert was introduced in C++17.
|
||||
CPPExpression::Result result = $3->evaluate();
|
||||
if (result._type == CPPExpression::RT_error) {
|
||||
yywarning("static_assert requires a constant expression", @3);
|
||||
} else if (!result.as_boolean()) {
|
||||
yywarning("static_assert failed", @3);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
@ -856,6 +878,9 @@ function_prototype:
|
||||
{
|
||||
pop_scope();
|
||||
CPPType *type = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert(type != NULL);
|
||||
|
||||
CPPInstanceIdentifier *ii = $4;
|
||||
@ -871,6 +896,9 @@ function_prototype:
|
||||
{
|
||||
pop_scope();
|
||||
CPPType *type = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert(type != NULL);
|
||||
|
||||
CPPInstanceIdentifier *ii = $5;
|
||||
@ -1213,6 +1241,9 @@ template_formal_parameter_type:
|
||||
| TYPENAME_IDENTIFIER
|
||||
{
|
||||
$$ = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if ($$ == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert($$ != NULL);
|
||||
}
|
||||
;
|
||||
@ -1608,6 +1639,9 @@ type:
|
||||
| TYPENAME_IDENTIFIER
|
||||
{
|
||||
$$ = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if ($$ == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert($$ != NULL);
|
||||
}
|
||||
| KW_TYPENAME name
|
||||
@ -1668,6 +1702,9 @@ type_decl:
|
||||
| TYPENAME_IDENTIFIER
|
||||
{
|
||||
$$ = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if ($$ == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert($$ != NULL);
|
||||
}
|
||||
| KW_TYPENAME name
|
||||
@ -1746,6 +1783,9 @@ predefined_type:
|
||||
| TYPENAME_IDENTIFIER
|
||||
{
|
||||
$$ = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if ($$ == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert($$ != NULL);
|
||||
}
|
||||
| KW_TYPENAME name
|
||||
@ -2419,6 +2459,9 @@ const_expr:
|
||||
{
|
||||
// A constructor call.
|
||||
CPPType *type = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert(type != NULL);
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
@ -2888,6 +2931,9 @@ typedefname:
|
||||
TYPENAME_IDENTIFIER
|
||||
{
|
||||
CPPType *type = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert(type != NULL);
|
||||
$$ = type;
|
||||
}
|
||||
|
@ -46,9 +46,9 @@ ExpansionNode(const string &str, bool paste) :
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPManifest::
|
||||
CPPManifest(const string &args, const CPPFile &file) :
|
||||
CPPManifest(const string &args, const cppyyltype &loc) :
|
||||
_variadic_param(-1),
|
||||
_file(file),
|
||||
_loc(loc),
|
||||
_expr((CPPExpression *)NULL)
|
||||
{
|
||||
assert(!args.empty());
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "cppFile.h"
|
||||
#include "cppVisibility.h"
|
||||
#include "cppBisonDefs.h"
|
||||
|
||||
#include "vector_string.h"
|
||||
|
||||
@ -31,7 +32,7 @@ class CPPType;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class CPPManifest {
|
||||
public:
|
||||
CPPManifest(const string &args, const CPPFile &file = CPPFile());
|
||||
CPPManifest(const string &args, const cppyyltype &loc = {0});
|
||||
~CPPManifest();
|
||||
|
||||
static string stringify(const string &source);
|
||||
@ -45,7 +46,7 @@ public:
|
||||
bool _has_parameters;
|
||||
int _num_parameters;
|
||||
int _variadic_param;
|
||||
CPPFile _file;
|
||||
cppyyltype _loc;
|
||||
CPPExpression *_expr;
|
||||
|
||||
// Manifests don't have a visibility in the normal sense. Normally
|
||||
|
@ -407,6 +407,7 @@ get_next_token0() {
|
||||
return token;
|
||||
}
|
||||
_saved_tokens.push_back(token);
|
||||
_last_token_loc = loc;
|
||||
return CPPToken(SCOPING, loc, name, result);
|
||||
}
|
||||
|
||||
@ -444,10 +445,12 @@ get_next_token0() {
|
||||
token_type = TYPENAME_IDENTIFIER;
|
||||
}
|
||||
|
||||
_last_token_loc = loc;
|
||||
return CPPToken(token_type, loc, name, result);
|
||||
}
|
||||
|
||||
// This is the normal case: just pass through whatever token we got.
|
||||
_last_token_loc = loc;
|
||||
return token;
|
||||
}
|
||||
|
||||
@ -843,10 +846,6 @@ expand_manifests(const string &input_expr, bool expand_undefined) {
|
||||
// Repeatedly scan the expr for any manifest names or defined()
|
||||
// function.
|
||||
|
||||
// We'll need to save the set of manifests we've already expanded,
|
||||
// to guard against recursive references.
|
||||
set<const CPPManifest *> already_expanded;
|
||||
|
||||
bool manifest_found;
|
||||
do {
|
||||
manifest_found = false;
|
||||
@ -867,10 +866,9 @@ expand_manifests(const string &input_expr, bool expand_undefined) {
|
||||
Manifests::const_iterator mi = _manifests.find(ident);
|
||||
if (mi != _manifests.end()) {
|
||||
const CPPManifest *manifest = (*mi).second;
|
||||
if (already_expanded.insert(manifest).second) {
|
||||
expand_manifest_inline(expr, q, p, (*mi).second);
|
||||
manifest_found = true;
|
||||
}
|
||||
expand_manifest_inline(expr, q, p, (*mi).second);
|
||||
manifest_found = true;
|
||||
|
||||
} else if (expand_undefined && ident != "true" && ident != "false") {
|
||||
// It is not found. Expand it to 0.
|
||||
expr = expr.substr(0, q) + "0" + expr.substr(p);
|
||||
@ -1470,7 +1468,7 @@ handle_define_directive(const string &args, const YYLTYPE &loc) {
|
||||
if (args.empty()) {
|
||||
warning("Ignoring empty #define directive", loc);
|
||||
} else {
|
||||
CPPManifest *manifest = new CPPManifest(args, loc.file);
|
||||
CPPManifest *manifest = new CPPManifest(args, loc);
|
||||
manifest->_vis = preprocessor_vis;
|
||||
if (!manifest->_has_parameters) {
|
||||
string expr_string = manifest->expand();
|
||||
@ -1479,18 +1477,17 @@ handle_define_directive(const string &args, const YYLTYPE &loc) {
|
||||
}
|
||||
}
|
||||
|
||||
// ok one memory leak here..
|
||||
Manifests::iterator mi = _manifests.find(manifest->_name);
|
||||
if(mi != _manifests.end())
|
||||
{
|
||||
// i do not see a goodway to compare the old and new hmmmm
|
||||
//cerr << "Warning Overwriting Constant " << manifest->_name << "\n";
|
||||
delete mi->second;
|
||||
pair<Manifests::iterator, bool> result =
|
||||
_manifests.insert(Manifests::value_type(manifest->_name, manifest));
|
||||
|
||||
if (!result.second) {
|
||||
// There was already a macro with this name. Delete the old.
|
||||
CPPManifest *other = result.first->second;
|
||||
warning("redefinition of macro '" + manifest->_name + "'", loc);
|
||||
warning("previous definition is here", other->_loc);
|
||||
delete other;
|
||||
result.first->second = manifest;
|
||||
}
|
||||
|
||||
_manifests[manifest->_name] = manifest;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1560,7 +1557,9 @@ handle_if_directive(const string &args, const YYLTYPE &loc) {
|
||||
if (expr != (CPPExpression *)NULL) {
|
||||
CPPExpression::Result result = expr->evaluate();
|
||||
if (result._type == CPPExpression::RT_error) {
|
||||
warning("Ignoring invalid expression " + args, loc);
|
||||
ostringstream strm;
|
||||
strm << *expr;
|
||||
warning("Ignoring invalid expression " + strm.str(), loc);
|
||||
} else {
|
||||
expression_result = result.as_integer();
|
||||
}
|
||||
@ -2302,6 +2301,8 @@ check_keyword(const string &name) {
|
||||
if (name == "char32_t") return KW_CHAR32_T;
|
||||
if (name == "class") return KW_CLASS;
|
||||
if (name == "const") return KW_CONST;
|
||||
if (name == "__const") return KW_CONST;
|
||||
if (name == "__const__") return KW_CONST;
|
||||
if (name == "delete") return KW_DELETE;
|
||||
if (name == "double") return KW_DOUBLE;
|
||||
if (name == "dynamic_cast") return KW_DYNAMIC_CAST;
|
||||
@ -2319,6 +2320,8 @@ check_keyword(const string &name) {
|
||||
if (name == "goto") return KW_GOTO;
|
||||
if (name == "if") return KW_IF;
|
||||
if (name == "inline") return KW_INLINE;
|
||||
if (name == "__inline") return KW_INLINE;
|
||||
if (name == "__inline__") return KW_INLINE;
|
||||
if (name == "int") return KW_INT;
|
||||
if (name == "long") return KW_LONG;
|
||||
if (name == "__make_property") return KW_MAKE_PROPERTY;
|
||||
@ -2337,6 +2340,7 @@ check_keyword(const string &name) {
|
||||
if (name == "signed") return KW_SIGNED;
|
||||
if (name == "sizeof") return KW_SIZEOF;
|
||||
if (name == "static") return KW_STATIC;
|
||||
if (name == "static_assert") return KW_STATIC_ASSERT;
|
||||
if (name == "static_cast") return KW_STATIC_CAST;
|
||||
if (name == "struct") return KW_STRUCT;
|
||||
if (name == "template") return KW_TEMPLATE;
|
||||
|
@ -101,6 +101,9 @@ public:
|
||||
// incremented), or set it higher to get more debugging information.
|
||||
int _verbose;
|
||||
|
||||
// The location of the last token.
|
||||
cppyyltype _last_token_loc;
|
||||
|
||||
protected:
|
||||
bool init_cpp(const CPPFile &file);
|
||||
bool init_const_expr(const string &expr);
|
||||
|
@ -1344,14 +1344,14 @@ scan_manifest(CPPManifest *manifest) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (manifest->_file.is_c_file()) {
|
||||
if (manifest->_loc.file.is_c_file()) {
|
||||
// This #define appears in a .C file. We can only export
|
||||
// manifests defined in a .h file.
|
||||
return;
|
||||
}
|
||||
|
||||
if (manifest->_file._source != CPPFile::S_local ||
|
||||
in_ignorefile(manifest->_file._filename_as_referenced)) {
|
||||
if (manifest->_loc.file._source != CPPFile::S_local ||
|
||||
in_ignorefile(manifest->_loc.file._filename_as_referenced)) {
|
||||
// The manifest is defined in some other package or in an
|
||||
// ignorable file.
|
||||
return;
|
||||
|
@ -1354,13 +1354,13 @@ def CompileIgate(woutd,wsrc,opts):
|
||||
cmd += ' -srcdir %s -I%s' % (srcdir, srcdir)
|
||||
cmd += ' -DCPPPARSER -D__STDC__=1 -D__cplusplus=201103L'
|
||||
if (COMPILER=="MSVC"):
|
||||
cmd += ' -D__inline -D_X86_ -DWIN32_VC -DWIN32 -D_WIN32'
|
||||
cmd += ' -D_X86_ -DWIN32_VC -DWIN32 -D_WIN32'
|
||||
if GetTargetArch() == 'x64':
|
||||
cmd += ' -DWIN64_VC -DWIN64 -D_WIN64'
|
||||
# NOTE: this 1600 value is the version number for VC2010.
|
||||
cmd += ' -D_MSC_VER=1600 -D"__declspec(param)=" -D__cdecl -D_near -D_far -D__near -D__far -D__stdcall'
|
||||
if (COMPILER=="GCC"):
|
||||
cmd += ' -D__inline -D__const=const -D__attribute__\(x\)='
|
||||
cmd += ' -D__attribute__\(x\)='
|
||||
if GetTargetArch() in ("x86_64", "amd64"):
|
||||
cmd += ' -D_LP64'
|
||||
else:
|
||||
|
Loading…
x
Reference in New Issue
Block a user