mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
Fix some edge cases for preprocessor, support auto keyword, MSVC compile fix
This commit is contained in:
parent
94b48d568f
commit
155ae811aa
File diff suppressed because it is too large
Load Diff
@ -1723,6 +1723,10 @@ type:
|
||||
str << *$3;
|
||||
yyerror("could not determine type of " + str.str(), @3);
|
||||
}
|
||||
}
|
||||
| KW_AUTO
|
||||
{
|
||||
$$ = new CPPSimpleType(CPPSimpleType::T_auto);
|
||||
}
|
||||
;
|
||||
|
||||
@ -1813,6 +1817,10 @@ type_decl:
|
||||
str << *$3;
|
||||
yyerror("could not determine type of " + str.str(), @3);
|
||||
}
|
||||
}
|
||||
| KW_AUTO
|
||||
{
|
||||
$$ = new CPPSimpleType(CPPSimpleType::T_auto);
|
||||
}
|
||||
;
|
||||
|
||||
@ -2114,7 +2122,7 @@ namespace_declaration:
|
||||
}
|
||||
|
||||
CPPNamespace *nspace = new CPPNamespace($3, scope, @2.file);
|
||||
nspace->_inline = true;
|
||||
nspace->_is_inline = true;
|
||||
current_scope->add_declaration(nspace, global_scope, current_lexer, @2);
|
||||
current_scope->define_namespace(nspace);
|
||||
push_scope(scope);
|
||||
|
@ -189,7 +189,7 @@ get_local_name(CPPScope *scope) const {
|
||||
|
||||
// Strip off template scopes, since they don't add anything
|
||||
// particularly meaningful to the local name.
|
||||
while (my_scope->as_template_scope() != NULL) {
|
||||
while (my_scope != NULL && my_scope->as_template_scope() != NULL) {
|
||||
my_scope = my_scope->get_parent_scope();
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ CPPNamespace(CPPIdentifier *ident, CPPScope *scope, const CPPFile &file) :
|
||||
CPPDeclaration(file),
|
||||
_ident(ident),
|
||||
_scope(scope),
|
||||
_inline(false)
|
||||
_is_inline(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ get_scope() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CPPNamespace::
|
||||
output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
||||
if (_inline) {
|
||||
if (_is_inline) {
|
||||
out << "inline ";
|
||||
}
|
||||
if (!complete && _ident != NULL) {
|
||||
|
@ -42,7 +42,9 @@ public:
|
||||
|
||||
virtual CPPNamespace *as_namespace();
|
||||
|
||||
bool _inline;
|
||||
// We can't call this _inline since that would clash with an MSVC
|
||||
// built-in keyword declaration.
|
||||
bool _is_inline;
|
||||
|
||||
private:
|
||||
CPPIdentifier *_ident;
|
||||
|
@ -72,7 +72,8 @@ parse_file(const Filename &filename) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPExpression *CPPParser::
|
||||
parse_expr(const string &expr) {
|
||||
return CPPPreprocessor::parse_expr(expr, this, this);
|
||||
YYLTYPE loc = {};
|
||||
return CPPPreprocessor::parse_expr(expr, this, this, loc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -774,6 +774,7 @@ push_file(const CPPFile &file) {
|
||||
indent(cerr, _files.size() * 2)
|
||||
<< "Reading " << file << "\n";
|
||||
}
|
||||
assert(_last_c == 0);
|
||||
|
||||
_files.push_back(InputFile());
|
||||
InputFile &infile = _files.back();
|
||||
@ -841,7 +842,8 @@ push_string(const string &input, bool lock_position) {
|
||||
// string and return the new string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string CPPPreprocessor::
|
||||
expand_manifests(const string &input_expr, bool expand_undefined) {
|
||||
expand_manifests(const string &input_expr, bool expand_undefined,
|
||||
const YYLTYPE &loc) {
|
||||
// Get a copy of the expression string we can modify.
|
||||
string expr = input_expr;
|
||||
|
||||
@ -872,11 +874,28 @@ expand_manifests(const string &input_expr, bool expand_undefined) {
|
||||
manifest_found = true;
|
||||
|
||||
} else if (expand_undefined && ident != "true" && ident != "false") {
|
||||
// It is not found. Expand it to 0.
|
||||
// It is not found. Expand it to 0, but only if we are currently
|
||||
// parsing an #if expression.
|
||||
expr = expr.substr(0, q) + "0" + expr.substr(p);
|
||||
p = q + 1;
|
||||
}
|
||||
}
|
||||
} else if (expr[p] == '\'' || expr[p] == '"') {
|
||||
// Skip the next part until we find a closing quotation mark.
|
||||
char quote = expr[p];
|
||||
p++;
|
||||
while (p < expr.size() && expr[p] != quote) {
|
||||
if (expr[p] == '\\') {
|
||||
// This might be an escaped quote. Skip an extra char.
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (p >= expr.size()) {
|
||||
// Unclosed string.
|
||||
warning("missing terminating " + string(1, quote) + " character", loc);
|
||||
}
|
||||
p++;
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
@ -903,8 +922,8 @@ expand_manifests(const string &input_expr, bool expand_undefined) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPExpression *CPPPreprocessor::
|
||||
parse_expr(const string &input_expr, CPPScope *current_scope,
|
||||
CPPScope *global_scope) {
|
||||
string expr = expand_manifests(input_expr, false);
|
||||
CPPScope *global_scope, const YYLTYPE &loc) {
|
||||
string expr = expand_manifests(input_expr, false, loc);
|
||||
|
||||
CPPExpressionParser ep(current_scope, global_scope);
|
||||
ep._verbose = 0;
|
||||
@ -1475,7 +1494,7 @@ handle_define_directive(const string &args, const YYLTYPE &loc) {
|
||||
if (!manifest->_has_parameters) {
|
||||
string expr_string = manifest->expand();
|
||||
if (!expr_string.empty()) {
|
||||
manifest->_expr = parse_expr(expr_string, global_scope, global_scope);
|
||||
manifest->_expr = parse_expr(expr_string, global_scope, global_scope, loc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1554,7 +1573,7 @@ void CPPPreprocessor::
|
||||
handle_if_directive(const string &args, const YYLTYPE &loc) {
|
||||
// When expanding manifests, we should replace unknown macros
|
||||
// with 0.
|
||||
string expr = expand_manifests(args, true);
|
||||
string expr = expand_manifests(args, true, loc);
|
||||
|
||||
int expression_result = 0;
|
||||
CPPExpressionParser ep(current_scope, global_scope);
|
||||
@ -1602,7 +1621,7 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
|
||||
// might not filter out quotes and angle brackets properly, we'll
|
||||
// only expand manifests if we don't begin with a quote or bracket.
|
||||
if (!expr.empty() && (expr[0] != '"' && expr[0] != '<')) {
|
||||
expr = expand_manifests(expr, false);
|
||||
expr = expand_manifests(expr, false, loc);
|
||||
}
|
||||
|
||||
if (!expr.empty()) {
|
||||
@ -2727,14 +2746,11 @@ get() {
|
||||
indent(cerr, _files.size() * 2)
|
||||
<< "End of input stream, restoring to previous input\n";
|
||||
#endif
|
||||
int last_c = _files.back()._prev_last_c;
|
||||
_files.pop_back();
|
||||
|
||||
if (last_c != '\0') {
|
||||
c = last_c;
|
||||
} else if (!_files.empty()) {
|
||||
c = _files.back().get();
|
||||
}
|
||||
// Synthesize a newline, just in case the file doesn't already
|
||||
// end with one.
|
||||
c = '\n';
|
||||
}
|
||||
|
||||
if (c == '\n') {
|
||||
|
@ -111,9 +111,10 @@ protected:
|
||||
bool push_file(const CPPFile &file);
|
||||
bool push_string(const string &input, bool lock_position);
|
||||
|
||||
string expand_manifests(const string &input_expr, bool expand_undefined);
|
||||
string expand_manifests(const string &input_expr, bool expand_undefined,
|
||||
const YYLTYPE &loc);
|
||||
CPPExpression *parse_expr(const string &expr, CPPScope *current_scope,
|
||||
CPPScope *global_scope);
|
||||
CPPScope *global_scope, const YYLTYPE &loc);
|
||||
|
||||
private:
|
||||
CPPToken internal_get_next_token();
|
||||
|
@ -297,7 +297,7 @@ define_namespace(CPPNamespace *ns) {
|
||||
|
||||
_namespaces[name] = ns;
|
||||
|
||||
if (ns->_inline) {
|
||||
if (ns->_is_inline) {
|
||||
// Add an implicit using declaration for an inline namespace.
|
||||
_using.insert(ns->get_scope());
|
||||
}
|
||||
|
@ -158,6 +158,10 @@ output(ostream &out, int, CPPScope *, bool) const {
|
||||
out << "parameter";
|
||||
break;
|
||||
|
||||
case T_auto:
|
||||
out << "auto";
|
||||
break;
|
||||
|
||||
default:
|
||||
out << "***invalid type***";
|
||||
}
|
||||
|
@ -55,6 +55,13 @@ public:
|
||||
// but it initially looks like a function prototype.
|
||||
//
|
||||
T_parameter,
|
||||
|
||||
// T_auto is also a special type that corresponds to the "auto"
|
||||
// keyword used in a variable assignment. The type of it is
|
||||
// automatically determined at a later stage based on the type
|
||||
// of the expression that is assigned to it.
|
||||
//
|
||||
T_auto,
|
||||
};
|
||||
|
||||
enum Flags {
|
||||
|
Loading…
x
Reference in New Issue
Block a user