Fix various parser bugs, improve error reporting

(to show the included file chain -vv is now needed)
This commit is contained in:
rdb 2015-01-04 20:30:24 +01:00
parent 34761a0b9b
commit 5e905d4463
12 changed files with 148 additions and 52 deletions

View File

@ -130,6 +130,29 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
return rep; return rep;
} }
////////////////////////////////////////////////////////////////////
// Function: CPPExtensionType::resolve_type
// Access: Public, Virtual
// Description: If this CPPType object is a forward reference or
// other nonspecified reference to a type that might now
// be known a real type, returns the real type.
// Otherwise returns the type itself.
////////////////////////////////////////////////////////////////////
CPPType *CPPExtensionType::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
if (_ident == NULL) {
// We can't resolve anonymous types. But that's OK, since they
// can't be forward declared anyway.
return this;
}
// Maybe it has been defined by now.
CPPType *type = _ident->find_type(current_scope, global_scope);
if (type != NULL) {
return type;
}
return this;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CPPExtensionType::is_equivalent_type // Function: CPPExtensionType::is_equivalent_type

View File

@ -25,7 +25,9 @@ class CPPIdentifier;
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
// Class : CPPExtensionType // Class : CPPExtensionType
// Description : // Description : Base class of enum, class, struct, and union types.
// An instance of the base class (instead of one of
// the specializations) is used for forward references.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class CPPExtensionType : public CPPType { class CPPExtensionType : public CPPType {
public: public:
@ -50,6 +52,9 @@ public:
CPPScope *current_scope, CPPScope *current_scope,
CPPScope *global_scope); CPPScope *global_scope);
virtual CPPType *resolve_type(CPPScope *current_scope,
CPPScope *global_scope);
virtual bool is_equivalent(const CPPType &other) const; virtual bool is_equivalent(const CPPType &other) const;

View File

@ -432,10 +432,14 @@ warning(const string &message, int line, int col, CPPFile file) {
if (file.empty()) { if (file.empty()) {
file = get_file(); file = get_file();
} }
indent(cerr, _files.size() * 2) int indent_level = 0;
if (_verbose >= 3) {
indent_level = _files.size() * 2;
}
indent(cerr, indent_level)
<< "*** Warning in " << file << "*** Warning in " << file
<< " near line " << line << ", column " << col << ":\n"; << " near line " << line << ", column " << col << ":\n";
indent(cerr, _files.size() * 2) indent(cerr, indent_level)
<< message << "\n"; << message << "\n";
} }
_warning_count++; _warning_count++;
@ -462,10 +466,14 @@ error(const string &message, int line, int col, CPPFile file) {
if (file.empty()) { if (file.empty()) {
file = get_file(); file = get_file();
} }
indent(cerr, _files.size() * 2) int indent_level = 0;
if (_verbose >= 3) {
indent_level = _files.size() * 2;
}
indent(cerr, indent_level)
<< "*** Error in " << file << "*** Error in " << file
<< " near line " << line << ", column " << col << ":\n"; << " near line " << line << ", column " << col << ":\n";
indent(cerr, _files.size() * 2) indent(cerr, indent_level)
<< message << "\n"; << message << "\n";
if (_error_abort) { if (_error_abort) {
@ -608,7 +616,7 @@ init_type(const string &type) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool CPPPreprocessor:: bool CPPPreprocessor::
push_file(const CPPFile &file) { push_file(const CPPFile &file) {
if (_verbose >= 2) { if (_verbose >= 3) {
indent(cerr, _files.size() * 2) indent(cerr, _files.size() * 2)
<< "Reading " << file << "\n"; << "Reading " << file << "\n";
} }
@ -2294,7 +2302,6 @@ unget(int c) {
_unget = c; _unget = c;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CPPPreprocessor::nested_parse_template_instantiation // Function: CPPPreprocessor::nested_parse_template_instantiation
// Access: Private // Access: Private

View File

@ -136,7 +136,7 @@ add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
_declarations.push_back(decl); _declarations.push_back(decl);
handle_declaration(decl, global_scope); handle_declaration(decl, global_scope, preprocessor);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -185,9 +185,12 @@ add_enum_value(CPPInstance *inst, CPPPreprocessor *preprocessor,
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CPPScope:: void CPPScope::
define_extension_type(CPPExtensionType *type) { define_extension_type(CPPExtensionType *type, CPPPreprocessor *error_sink) {
assert(type != NULL); assert(type != NULL);
string name = type->get_simple_name(); string name = type->get_local_name(this);
if (name.empty()) {
return;
}
switch (type->_type) { switch (type->_type) {
case CPPExtensionType::T_class: case CPPExtensionType::T_class:
@ -204,6 +207,7 @@ define_extension_type(CPPExtensionType *type) {
case CPPExtensionType::T_enum: case CPPExtensionType::T_enum:
_enums[name] = type; _enums[name] = type;
break;
} }
// Create an implicit typedef for the extension. // Create an implicit typedef for the extension.
@ -213,21 +217,45 @@ define_extension_type(CPPExtensionType *type) {
if (!result.second) { if (!result.second) {
// There's already a typedef for this extension. This one // There's already a typedef for this extension. This one
// overrides if it has template parameters and the other one // overrides it only if the other is a forward declaration.
// doesn't.
CPPType *other_type = (*result.first).second; CPPType *other_type = (*result.first).second;
if (type->is_template() && !other_type->is_template()) {
if (other_type->get_subtype() == CPPDeclaration::ST_extension) {
CPPExtensionType *other_ext = other_type->as_extension_type();
if (other_ext->_type != type->_type) {
if (error_sink != NULL) {
ostringstream errstr;
errstr << other_ext->_type << " " << type->get_fully_scoped_name()
<< " was previously declared as " << other_ext->_type << "\n";
error_sink->error(errstr.str());
}
}
(*result.first).second = type; (*result.first).second = type;
// Or if the other one is a forward reference. } else {
} else if (other_type->get_subtype() == CPPDeclaration::ST_extension) { CPPTypedefType *other_td = other_type->as_typedef_type();
(*result.first).second = type;
// Error out if the declaration is different than the previous one.
if (other_type != type &&
(other_td == NULL || other_td->_type != type)) {
if (error_sink != NULL) {
ostringstream errstr;
type->output(errstr, 0, NULL, false);
errstr << " has conflicting declaration as ";
other_type->output(errstr, 0, NULL, true);
error_sink->error(errstr.str());
}
}
} }
} }
if (type->is_template()) { if (type->is_template()) {
string simple_name = type->get_simple_name();
pair<Templates::iterator, bool> result = pair<Templates::iterator, bool> result =
_templates.insert(Templates::value_type(name, type)); _templates.insert(Templates::value_type(simple_name, type));
if (!result.second) { if (!result.second) {
// The template was not inserted because we already had a // The template was not inserted because we already had a
@ -277,7 +305,7 @@ add_using(CPPUsing *using_decl, CPPScope *global_scope,
} else { } else {
CPPDeclaration *decl = using_decl->_ident->find_symbol(this, global_scope); CPPDeclaration *decl = using_decl->_ident->find_symbol(this, global_scope);
if (decl != NULL) { if (decl != NULL) {
handle_declaration(decl, global_scope); handle_declaration(decl, global_scope, error_sink);
} else { } else {
if (error_sink != NULL) { if (error_sink != NULL) {
error_sink->warning("Attempt to use unknown symbol: " + using_decl->_ident->get_fully_scoped_name()); error_sink->warning("Attempt to use unknown symbol: " + using_decl->_ident->get_fully_scoped_name());
@ -1047,16 +1075,39 @@ copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst,
// functions, or whatever. // functions, or whatever.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CPPScope:: void CPPScope::
handle_declaration(CPPDeclaration *decl, CPPScope *global_scope) { handle_declaration(CPPDeclaration *decl, CPPScope *global_scope,
CPPPreprocessor *error_sink) {
CPPTypedefType *def = decl->as_typedef_type(); CPPTypedefType *def = decl->as_typedef_type();
if (def != NULL) { if (def != NULL) {
string name = def->get_simple_name(); string name = def->get_simple_name();
pair<Types::iterator, bool> result =
_types.insert(Types::value_type(name, def));
if (!result.second) {
CPPType *other_type = result.first->second;
CPPTypedefType *other_td = other_type->as_typedef_type();
// We don't do redefinitions of typedefs. But we don't complain
// as long as this is actually a typedef to the previous definition.
if (other_type != def->_type &&
(other_td == NULL || other_td->_type != def->_type)) {
if (error_sink != NULL) {
ostringstream errstr;
def->output(errstr, 0, NULL, false);
errstr << " has conflicting declaration as ";
other_type->output(errstr, 0, NULL, true);
error_sink->error(errstr.str());
}
}
} else {
_types[name] = def; _types[name] = def;
}
CPPExtensionType *et = def->_type->as_extension_type(); CPPExtensionType *et = def->_type->as_extension_type();
if (et != NULL) { if (et != NULL) {
define_extension_type(et); define_extension_type(et, error_sink);
} }
return; return;
@ -1066,7 +1117,7 @@ handle_declaration(CPPDeclaration *decl, CPPScope *global_scope) {
if (typedecl != (CPPTypeDeclaration *)NULL) { if (typedecl != (CPPTypeDeclaration *)NULL) {
CPPExtensionType *et = typedecl->_type->as_extension_type(); CPPExtensionType *et = typedecl->_type->as_extension_type();
if (et != NULL) { if (et != NULL) {
define_extension_type(et); define_extension_type(et, error_sink);
} }
return; return;
} }
@ -1121,6 +1172,6 @@ handle_declaration(CPPDeclaration *decl, CPPScope *global_scope) {
CPPExtensionType *et = decl->as_extension_type(); CPPExtensionType *et = decl->as_extension_type();
if (et != NULL) { if (et != NULL) {
define_extension_type(et); define_extension_type(et, error_sink);
} }
} }

View File

@ -66,7 +66,8 @@ public:
virtual void add_enum_value(CPPInstance *inst, virtual void add_enum_value(CPPInstance *inst,
CPPPreprocessor *preprocessor, CPPPreprocessor *preprocessor,
const cppyyltype &pos); const cppyyltype &pos);
virtual void define_extension_type(CPPExtensionType *type); virtual void define_extension_type(CPPExtensionType *type,
CPPPreprocessor *error_sink = NULL);
virtual void define_namespace(CPPNamespace *scope); virtual void define_namespace(CPPNamespace *scope);
virtual void add_using(CPPUsing *using_decl, CPPScope *global_scope, virtual void add_using(CPPUsing *using_decl, CPPScope *global_scope,
CPPPreprocessor *error_sink = NULL); CPPPreprocessor *error_sink = NULL);
@ -113,7 +114,8 @@ private:
copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst, copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst,
CPPScope *global_scope) const; CPPScope *global_scope) const;
void handle_declaration(CPPDeclaration *decl, CPPScope *global_scope); void handle_declaration(CPPDeclaration *decl, CPPScope *global_scope,
CPPPreprocessor *error_sink = NULL);
public: public:
typedef vector<CPPDeclaration *> Declarations; typedef vector<CPPDeclaration *> Declarations;

View File

@ -64,10 +64,10 @@ add_enum_value(CPPInstance *inst, CPPPreprocessor *preprocessor,
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CPPTemplateScope:: void CPPTemplateScope::
define_extension_type(CPPExtensionType *type) { define_extension_type(CPPExtensionType *type, CPPPreprocessor *error_sink) {
type->_template_scope = this; type->_template_scope = this;
assert(_parent_scope != NULL); assert(_parent_scope != NULL);
_parent_scope->define_extension_type(type); _parent_scope->define_extension_type(type, error_sink);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -39,7 +39,8 @@ public:
virtual void add_enum_value(CPPInstance *inst, virtual void add_enum_value(CPPInstance *inst,
CPPPreprocessor *preprocessor, CPPPreprocessor *preprocessor,
const cppyyltype &pos); const cppyyltype &pos);
virtual void define_extension_type(CPPExtensionType *type); virtual void define_extension_type(CPPExtensionType *type,
CPPPreprocessor *error_sink = NULL);
virtual void define_namespace(CPPNamespace *scope); virtual void define_namespace(CPPNamespace *scope);
virtual void add_using(CPPUsing *using_decl, CPPScope *global_scope, virtual void add_using(CPPUsing *using_decl, CPPScope *global_scope,
CPPPreprocessor *error_sink = NULL); CPPPreprocessor *error_sink = NULL);

View File

@ -4774,7 +4774,7 @@ is_cpp_type_legal(CPPType *in_ctype) {
return true; return true;
} else if (TypeManager::is_pointer_to_simple(type)) { } else if (TypeManager::is_pointer_to_simple(type)) {
return true; return true;
} else if (TypeManager::IsExported(type)) { } else if (TypeManager::is_exported(type)) {
return true; return true;
} else if (TypeManager::is_pointer_to_PyObject(in_ctype)) { } else if (TypeManager::is_pointer_to_PyObject(in_ctype)) {
return true; return true;
@ -4797,7 +4797,7 @@ isExportThisRun(CPPType *ctype) {
return true; return true;
} }
if (!TypeManager::IsExported(ctype)) { if (!TypeManager::is_exported(ctype)) {
return false; return false;
} }

View File

@ -53,6 +53,10 @@ resolve_type(CPPType *type, CPPScope *scope) {
return type; return type;
} }
// I think I fixed the bug; no need for the below hack any more.
return type;
/*
CPPType *new_type = parser.parse_type(name); CPPType *new_type = parser.parse_type(name);
if (new_type == (CPPType *)NULL) { if (new_type == (CPPType *)NULL) {
nout << "Type \"" << name << "\" (from " << *orig_type << ") is unknown to parser.\n"; nout << "Type \"" << name << "\" (from " << *orig_type << ") is unknown to parser.\n";
@ -61,6 +65,7 @@ resolve_type(CPPType *type, CPPScope *scope) {
} }
return type; return type;
*/
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -2355,20 +2360,17 @@ has_protected_destructor(CPPType *type) {
return false; return false;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TypeManager::has_protected_destructor // Function: TypeManager::is_exported
// Access: Public, Static // Access: Public, Static
// Description: Returns true if the destructor for the given class or // Description:
// struct is protected or private, or false if the
// destructor is public or absent.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool TypeManager::IsExported(CPPType *in_type) { bool TypeManager::
is_exported(CPPType *in_type) {
string name = in_type->get_local_name(&parser); string name = in_type->get_local_name(&parser);
if (name.empty()) { if (name.empty()) {
return false; return false;
} }
//return true;
// this question is about the base type // this question is about the base type
CPPType *base_type = resolve_type(unwrap(in_type)); CPPType *base_type = resolve_type(unwrap(in_type));
//CPPType *base_type = in_type; //CPPType *base_type = in_type;
@ -2415,7 +2417,7 @@ bool TypeManager::IsExported(CPPType *in_type) {
CPPTypedefType *tdef = base_type->as_typedef_type(); CPPTypedefType *tdef = base_type->as_typedef_type();
if (tdef->_type->get_subtype() == CPPDeclaration::ST_struct) { if (tdef->_type->get_subtype() == CPPDeclaration::ST_struct) {
CPPStructType *struct_type =tdef->_type->resolve_type(&parser, &parser)->as_struct_type(); CPPStructType *struct_type =tdef->_type->resolve_type(&parser, &parser)->as_struct_type();
return IsExported(struct_type); return is_exported(struct_type);
} }
} else if (base_type->get_subtype() == CPPDeclaration::ST_type_declaration) { } else if (base_type->get_subtype() == CPPDeclaration::ST_type_declaration) {
@ -2423,14 +2425,15 @@ bool TypeManager::IsExported(CPPType *in_type) {
if (type->get_subtype() == CPPDeclaration::ST_struct) { if (type->get_subtype() == CPPDeclaration::ST_struct) {
CPPStructType *struct_type =type->as_type()->resolve_type(&parser, &parser)->as_struct_type(); CPPStructType *struct_type =type->as_type()->resolve_type(&parser, &parser)->as_struct_type();
//CPPScope *scope = struct_type->_scope; //CPPScope *scope = struct_type->_scope;
return IsExported(struct_type); return is_exported(struct_type);
} else if (type->get_subtype() == CPPDeclaration::ST_enum) { } else if (type->get_subtype() == CPPDeclaration::ST_enum) {
//CPPEnumType *enum_type = type->as_type()->resolve_type(&parser, &parser)->as_enum_type(); //CPPEnumType *enum_type = type->as_type()->resolve_type(&parser, &parser)->as_enum_type();
if (type->_vis <= min_vis) if (type->_vis <= min_vis) {
return true; return true;
} }
} }
}
/* /*
printf("---------------------> Visibility Failed %s %d Vis=%d, Minvis=%d\n", printf("---------------------> Visibility Failed %s %d Vis=%d, Minvis=%d\n",
@ -2464,10 +2467,13 @@ is_local(CPPType *source_type) {
return false; return false;
default: default:
if (source_type->_file._source == CPPFile::S_local && !source_type->is_incomplete()) { {
CPPType *resolved_type = resolve_type(source_type);
if (resolved_type->_file._source == CPPFile::S_local && !resolved_type->is_incomplete()) {
return true; return true;
} }
} }
}
return false; return false;

View File

@ -143,7 +143,7 @@ public:
static bool has_protected_destructor(CPPType *type); static bool has_protected_destructor(CPPType *type);
static bool IsExported(CPPType *type); static bool is_exported(CPPType *type);
static bool is_local(CPPType *type); static bool is_local(CPPType *type);
}; };

View File

@ -20,11 +20,12 @@
#ifndef CG_H #ifndef CG_H
#define CG_H #define CG_H
typedef int CGcontext; typedef struct _CGcontext *CGcontext;
typedef int CGprogram; typedef struct _CGcontext *CGcontext;
typedef int CGparameter; typedef struct _CGprogram *CGprogram;
typedef int CGprofile; typedef struct _CGparameter *CGparameter;
typedef int CGerror;
typedef enum {} CGprofile;
typedef enum {} CGerror;
#endif #endif

View File

@ -19,7 +19,7 @@
#include "pnotify.h" #include "pnotify.h"
#include "config_express.h" #include "config_express.h"
#if !defined(USE_MEMORY_NOWRAPPERS) #if !defined(USE_MEMORY_NOWRAPPERS) && !defined(CPPPARSER)
// Define functions that hook zlib into panda's memory allocation system. // Define functions that hook zlib into panda's memory allocation system.
static void * static void *
do_zlib_alloc(voidpf opaque, uInt items, uInt size) { do_zlib_alloc(voidpf opaque, uInt items, uInt size) {