summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/Slice/Grammer.y134
-rw-r--r--cpp/src/Slice/Parser.cpp267
-rw-r--r--cpp/src/Slice/Parser.h4
-rw-r--r--cpp/src/slice2cpp/Main.cpp24
4 files changed, 325 insertions, 104 deletions
diff --git a/cpp/src/Slice/Grammer.y b/cpp/src/Slice/Grammer.y
index 43a38281e1d..32cc26d8504 100644
--- a/cpp/src/Slice/Grammer.y
+++ b/cpp/src/Slice/Grammer.y
@@ -21,6 +21,12 @@ yyerror(const char* s)
unit -> error(s);
}
+void
+yyerror(const string& s)
+{
+ unit -> error(s.c_str());
+}
+
%}
%token ICE_SCOPE_DELIMITOR
@@ -170,6 +176,8 @@ module_def
StringTok_ptr ident = StringTok_ptr::dynamicCast($2);
Container_ptr cont = unit -> currentContainer();
Module_ptr module = cont -> createModule(ident -> v);
+ if(!module)
+ YYERROR; // Can't continue, jump to next yyerrok
unit -> pushContainer(module);
}
'{' definitions '}'
@@ -225,6 +233,8 @@ class_def
local -> v,
false,
bases -> v);
+ if(!cl)
+ YYERROR; // Can't continue, jump to next yyerrok
unit -> pushContainer(cl);
}
'{' class_exports '}'
@@ -241,30 +251,31 @@ class_extends
StringTok_ptr scoped = StringTok_ptr::dynamicCast($2);
Container_ptr cont = unit -> currentContainer();
list<Type_ptr> types = cont -> lookupType(scoped -> v);
- assert(!types.empty()); // TODO
- ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front());
- if(!cl)
- {
- string msg = "`";
- msg += scoped -> v;
- msg += "' is not a class";
- yyerror(msg.c_str());
- $$ = 0;
- }
- else
+ $$ = 0;
+ if(!types.empty())
{
- ClassDef_ptr def = cl -> definition();
- if(!def)
+ ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front());
+ if(!cl)
{
string msg = "`";
msg += scoped -> v;
- msg += "' has been declared but not defined";
- yyerror(msg.c_str());
- $$ = 0;
+ msg += "' is not a class";
+ yyerror(msg);
}
else
{
- $$ = def;
+ ClassDef_ptr def = cl -> definition();
+ if(!def)
+ {
+ string msg = "`";
+ msg += scoped -> v;
+ msg += "' has been declared but not defined";
+ yyerror(msg);
+ }
+ else
+ {
+ $$ = def;
+ }
}
}
}
@@ -314,6 +325,8 @@ interface_def
local -> v,
true,
bases -> v);
+ if(!cl)
+ YYERROR; // Can't continue, jump to next yyerrok
unit -> pushContainer(cl);
}
'{' interface_exports '}'
@@ -332,28 +345,30 @@ interface_list
StringTok_ptr scoped = StringTok_ptr::dynamicCast($1);
Container_ptr cont = unit -> currentContainer();
list<Type_ptr> types = cont -> lookupType(scoped -> v);
- assert(!types.empty()); // TODO
- ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front());
- if(!cl || !cl -> isInterface())
- {
- string msg = "`";
- msg += scoped -> v;
- msg += "' is not an interface";
- yyerror(msg.c_str());
- }
- else
+ if(!types.empty())
{
- ClassDef_ptr def = cl -> definition();
- if(!def)
+ ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front());
+ if(!cl || !cl -> isInterface())
{
string msg = "`";
msg += scoped -> v;
- msg += "' has been declared but not defined";
- yyerror(msg.c_str());
+ msg += "' is not an interface";
+ yyerror(msg);
}
else
{
- intfs -> v.push_front(def);
+ ClassDef_ptr def = cl -> definition();
+ if(!def)
+ {
+ string msg = "`";
+ msg += scoped -> v;
+ msg += "' has been declared but not defined";
+ yyerror(msg);
+ }
+ else
+ {
+ intfs -> v.push_front(def);
+ }
}
}
}
@@ -364,28 +379,30 @@ interface_list
StringTok_ptr scoped = StringTok_ptr::dynamicCast($1);
Container_ptr cont = unit -> currentContainer();
list<Type_ptr> types = cont -> lookupType(scoped -> v);
- assert(!types.empty()); // TODO
- ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front());
- if(!cl || !cl -> isInterface())
+ if(!types.empty())
{
- string msg = "`";
- msg += scoped -> v;
- msg += "' is not an interface";
- yyerror(msg.c_str());
- }
- else
- {
- ClassDef_ptr def = cl -> definition();
- if(!def)
+ ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front());
+ if(!cl || !cl -> isInterface())
{
string msg = "`";
msg += scoped -> v;
- msg += "' has been declared but not defined";
- yyerror(msg.c_str());
+ msg += "' is not an interface";
+ yyerror(msg);
}
else
{
- intfs -> v.push_front(def);
+ ClassDef_ptr def = cl -> definition();
+ if(!def)
+ {
+ string msg = "`";
+ msg += scoped -> v;
+ msg += "' has been declared but not defined";
+ yyerror(msg);
+ }
+ else
+ {
+ intfs -> v.push_front(def);
+ }
}
}
}
@@ -554,7 +571,14 @@ type
++p)
{
ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*p);
- assert(cl); // TODO: Only classes can be passed as proxy
+ if(!cl)
+ {
+ string msg = "`";
+ msg += scoped -> v;
+ msg += "' must be class or interface";
+ yyerror(msg);
+ YYERROR; // Can't continue, jump to next yyerrok
+ }
*p = new Proxy(cl);
}
$$ = types.front();
@@ -634,20 +658,22 @@ identifier_list
: ICE_IDENTIFIER ',' identifier_list
{
StringTok_ptr ident = StringTok_ptr::dynamicCast($1);
- Container_ptr cont = unit -> currentContainer();
- Enumerator_ptr en = cont -> createEnumerator(ident -> v);
StringListTok_ptr ens = StringListTok_ptr::dynamicCast($3);
- ens -> v.push_front(ident -> v);
$$ = ens;
+ Container_ptr cont = unit -> currentContainer();
+ Enumerator_ptr en = cont -> createEnumerator(ident -> v);
+ if(en)
+ ens -> v.push_front(ident -> v);
}
| ICE_IDENTIFIER
{
StringTok_ptr ident = StringTok_ptr::dynamicCast($1);
- Container_ptr cont = unit -> currentContainer();
- Enumerator_ptr en = cont -> createEnumerator(ident -> v);
StringListTok_ptr ens = new StringListTok;
- ens -> v.push_front(ident -> v);
$$ = ens;
+ Container_ptr cont = unit -> currentContainer();
+ Enumerator_ptr en = cont -> createEnumerator(ident -> v);
+ if(en)
+ ens -> v.push_front(ident -> v);
}
;
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index 04f7b3add7b..7d90baaf121 100644
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -204,7 +204,11 @@ Slice::Container::createModule(const string& name)
if(module)
continue; // Reopening modules is permissible
- assert(false); // TODO: Already exists and not a module
+ string msg = "redefinition of `";
+ msg += name;
+ msg += "' as module";
+ yyerror(msg);
+ return 0;
}
Module_ptr q = new Module(this, name);
@@ -223,16 +227,42 @@ Slice::Container::createClassDef(const string& name, bool local, bool intf,
{
ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*p);
if(cl)
- continue; // TODO: Check whether local and interface matches
+ {
+ if(checkInterfaceAndLocal(name, false,
+ intf, cl -> isInterface(),
+ local, cl -> isLocal()))
+ continue;
+
+ return 0;
+ }
- if(unit_ -> ignRedefs())
+ ClassDef_ptr def = ClassDef_ptr::dynamicCast(*p);
+ if(def)
{
- ClassDef_ptr def = ClassDef_ptr::dynamicCast(*p);
- if(def)
+ if(unit_ -> ignRedefs())
return def;
- }
- assert(false); // TODO: Already exists and not a class declaration
+ string msg = "redefinition of ";
+ if(intf)
+ msg += "interface";
+ else
+ msg += "class";
+ msg += " `";
+ msg += name;
+ msg += "'";
+ yyerror(msg);
+ return 0;
+ }
+
+ string msg = "redefinition of `";
+ msg += name;
+ msg += "' as ";
+ if(intf)
+ msg += "interface";
+ else
+ msg += "class";
+ yyerror(msg);
+ return 0;
}
ClassDef_ptr def = new ClassDef(this, name, local, intf, bases);
@@ -269,17 +299,38 @@ Slice::Container::createClassDecl(const string& name, bool local, bool intf)
ClassDef_ptr clDef = ClassDef_ptr::dynamicCast(*p);
if(clDef)
{
- assert(!def);
- def = clDef;
- continue; // TODO: Check whether local and interface matches
+ if(checkInterfaceAndLocal(name, true,
+ intf, clDef -> isInterface(),
+ local, clDef -> isLocal()))
+ {
+ assert(!def);
+ def = clDef;
+ continue;
+ }
+
+ return 0;
}
ClassDecl_ptr clDecl = ClassDecl_ptr::dynamicCast(*p);
if(clDecl)
- continue; // TODO: Check whether local and interface matches
-
- // TODO: Already defined as something other than a class
- assert(false);
+ {
+ if(checkInterfaceAndLocal(name, false,
+ intf, clDecl -> isInterface(),
+ local, clDecl -> isLocal()))
+ continue;
+
+ return 0;
+ }
+
+ string msg = "declaration of already defined `";
+ msg += name;
+ msg += "' as ";
+ if(intf)
+ msg += "interface";
+ else
+ msg += "class";
+ yyerror(msg);
+ return 0;
}
//
@@ -316,14 +367,24 @@ Slice::Container::createVector(const string& name, const Type_ptr& type)
ContainedList matches = unit_ -> findContents(thisScope() + name);
if(!matches.empty())
{
- if(unit_ -> ignRedefs())
+ Vector_ptr p = Vector_ptr::dynamicCast(matches.front());
+ if(p)
{
- Vector_ptr p = Vector_ptr::dynamicCast(matches.front());
- if(p)
+ if(unit_ -> ignRedefs())
return p;
+
+ string msg = "redefinition of vector `";
+ msg += name;
+ msg += "'";
+ yyerror(msg);
+ return 0;
}
- assert(false); // TODO: Already exits
+ string msg = "redefinition of `";
+ msg += name;
+ msg += "' as vector";
+ yyerror(msg);
+ return 0;
}
Vector_ptr p = new Vector(this, name, type);
@@ -337,14 +398,24 @@ Slice::Container::createEnum(const string& name, const StringList& enumerators)
ContainedList matches = unit_ -> findContents(thisScope() + name);
if(!matches.empty())
{
- if(unit_ -> ignRedefs())
+ Enum_ptr p = Enum_ptr::dynamicCast(matches.front());
+ if(p)
{
- Enum_ptr p = Enum_ptr::dynamicCast(matches.front());
- if(p)
+ if(unit_ -> ignRedefs())
return p;
+
+ string msg = "redefinition of enum `";
+ msg += name;
+ msg += "'";
+ yyerror(msg);
+ return 0;
}
- assert(false); // TODO: Already exits
+ string msg = "redefinition of `";
+ msg += name;
+ msg += "' as enum";
+ yyerror(msg);
+ return 0;
}
Enum_ptr p = new Enum(this, name, enumerators);
@@ -358,14 +429,24 @@ Slice::Container::createEnumerator(const std::string& name)
ContainedList matches = unit_ -> findContents(thisScope() + name);
if(!matches.empty())
{
- if(unit_ -> ignRedefs())
+ Enumerator_ptr p = Enumerator_ptr::dynamicCast(matches.front());
+ if(p)
{
- Enumerator_ptr p = Enumerator_ptr::dynamicCast(matches.front());
- if(p)
+ if(unit_ -> ignRedefs())
return p;
+
+ string msg = "redefinition of enumerator `";
+ msg += name;
+ msg += "'";
+ yyerror(msg);
+ return 0;
}
- assert(false); // TODO: Already exits
+ string msg = "redefinition of `";
+ msg += name;
+ msg += "' as enumerator";
+ yyerror(msg);
+ return 0;
}
Enumerator_ptr p = new Enumerator(this, name);
@@ -379,14 +460,24 @@ Slice::Container::createNative(const string& name)
ContainedList matches = unit_ -> findContents(thisScope() + name);
if(!matches.empty())
{
- if(unit_ -> ignRedefs())
+ Native_ptr p = Native_ptr::dynamicCast(matches.front());
+ if(p)
{
- Native_ptr p = Native_ptr::dynamicCast(matches.front());
- if(p)
+ if(unit_ -> ignRedefs())
return p;
+
+ string msg = "redefinition of native `";
+ msg += name;
+ msg += "'";
+ yyerror(msg);
+ return 0;
}
- assert(false); // TODO: Already exits
+ string msg = "redefinition of `";
+ msg += name;
+ msg += "' as native";
+ yyerror(msg);
+ return 0;
}
Native_ptr p = new Native(this, name);
@@ -407,7 +498,14 @@ Slice::Container::lookupType(const string& scoped)
if(matches.empty())
{
Contained_ptr contained = Contained_ptr::dynamicCast(this);
- assert(contained); // TODO: Not found error
+ if(!contained)
+ {
+ string msg = "`";
+ msg += scoped;
+ msg += "' is not defined";
+ yyerror(msg);
+ return TypeList();
+ }
return contained -> container() -> lookupType(scoped);
}
else
@@ -422,7 +520,14 @@ Slice::Container::lookupType(const string& scoped)
continue; // Ignore class definitions
Type_ptr type = Type_ptr::dynamicCast(*p);
- assert(type); // TODO: Not a type error
+ if(!type)
+ {
+ string msg = "`";
+ msg += scoped;
+ msg += "' is not a type";
+ yyerror(msg);
+ return TypeList();
+ }
results.push_back(type);
}
return results;
@@ -598,6 +703,64 @@ Slice::Container::Container(const Unit_ptr& unit)
includeLevel_ = 0;
}
+bool
+Slice::Container::checkInterfaceAndLocal(const string& name, bool defined,
+ bool intf, bool intfOther,
+ bool local, bool localOther)
+{
+ string definedOrDeclared;
+ if(defined)
+ definedOrDeclared = "defined";
+ else
+ definedOrDeclared = "declared";
+
+ if(!intf && intfOther)
+ {
+ string msg = "class `";
+ msg += name;
+ msg += "' was ";
+ msg += definedOrDeclared;
+ msg += " as interface";
+ yyerror(msg);
+ return false;
+ }
+
+ if(intf && !intfOther)
+ {
+ string msg = "interface `";
+ msg += name;
+ msg += "' was ";
+ msg += definedOrDeclared;
+ msg += " as class";
+ yyerror(msg);
+ return false;
+ }
+
+ if(!local && localOther)
+ {
+ string msg = "non-local `";
+ msg += name;
+ msg += "' was ";
+ msg += definedOrDeclared;
+ msg += " local";
+ yyerror(msg);
+ return false;
+ }
+
+ if(local && !localOther)
+ {
+ string msg = "local `";
+ msg += name;
+ msg += "' was ";
+ msg += definedOrDeclared;
+ msg += " non-local";
+ yyerror(msg);
+ return false;
+ }
+
+ return true;
+}
+
// ----------------------------------------------------------------------
// Module
// ----------------------------------------------------------------------
@@ -707,14 +870,24 @@ Slice::ClassDef::createOperation(const string& name,
ContainedList matches = unit_ -> findContents(thisScope() + name);
if(!matches.empty())
{
- if(unit_ -> ignRedefs())
+ Operation_ptr p = Operation_ptr::dynamicCast(matches.front());
+ if(p)
{
- Operation_ptr p = Operation_ptr::dynamicCast(matches.front());
- if(p)
+ if(unit_ -> ignRedefs())
return p;
+
+ string msg = "redefinition of operation `";
+ msg += name;
+ msg += "'";
+ yyerror(msg);
+ return 0;
}
- assert(false); // TODO: Already exits
+ string msg = "redefinition of `";
+ msg += name;
+ msg += "' as operation";
+ yyerror(msg);
+ return 0;
}
Operation_ptr p = new Operation(this, name, returnType,
@@ -731,14 +904,24 @@ Slice::ClassDef::createDataMember(const string& name, const Type_ptr& type)
ContainedList matches = unit_ -> findContents(thisScope() + name);
if(!matches.empty())
{
- if(unit_ -> ignRedefs())
+ DataMember_ptr p = DataMember_ptr::dynamicCast(matches.front());
+ if(p)
{
- DataMember_ptr p = DataMember_ptr::dynamicCast(matches.front());
- if(p)
+ if(unit_ -> ignRedefs())
return p;
- }
- assert(false); // TODO: Already exits
+ string msg = "redefinition of data member `";
+ msg += name;
+ msg += "'";
+ yyerror(msg);
+ return 0;
+ }
+
+ string msg = "redefinition of `";
+ msg += name;
+ msg += "' as data member";
+ yyerror(msg);
+ return 0;
}
DataMember_ptr p = new DataMember(this, name, type);
@@ -1317,6 +1500,8 @@ Slice::Unit::parse(FILE* file, bool debug)
extern FILE* yyin;
yyin = file;
int status = yyparse();
+ if(yynerrs)
+ status = EXIT_FAILURE;
assert(containerStack_.size() == 1);
popContainer();
diff --git a/cpp/src/Slice/Parser.h b/cpp/src/Slice/Parser.h
index 6dbd1826c0e..fe4bc2df77d 100644
--- a/cpp/src/Slice/Parser.h
+++ b/cpp/src/Slice/Parser.h
@@ -22,6 +22,7 @@ extern int yynerrs;
int yyparse();
int yylex();
void yyerror(const char* s);
+void yyerror(const std::string& s);
namespace Slice
{
@@ -297,6 +298,9 @@ protected:
Container(const Unit_ptr&);
+ bool checkInterfaceAndLocal(const std::string&, bool,
+ bool, bool, bool, bool);
+
int includeLevel_;
ContainedList contents_;
};
diff --git a/cpp/src/slice2cpp/Main.cpp b/cpp/src/slice2cpp/Main.cpp
index 98c21ca0058..5ca04edff48 100644
--- a/cpp/src/slice2cpp/Main.cpp
+++ b/cpp/src/slice2cpp/Main.cpp
@@ -128,6 +128,8 @@ main(int argc, char* argv[])
return EXIT_FAILURE;
}
+ int status = EXIT_SUCCESS;
+
for(idx = 1 ; idx < argc ; ++idx)
{
string base(argv[idx]);
@@ -169,7 +171,7 @@ main(int argc, char* argv[])
}
Unit_ptr unit = Unit::createUnit(false, false);
- int status = unit -> parse(cppHandle, debug);
+ int parseStatus = unit -> parse(cppHandle, debug);
#ifdef WIN32
_pclose(cppHandle);
@@ -177,16 +179,20 @@ main(int argc, char* argv[])
pclose(cppHandle);
#endif
- if(status == EXIT_FAILURE)
- return status;
-
- Gen gen(argv[0], base, include, includePaths, dllExport);
- if(!gen)
- return EXIT_FAILURE;
- gen.generate(unit);
+ if(parseStatus == EXIT_FAILURE)
+ {
+ status = EXIT_FAILURE;
+ }
+ else
+ {
+ Gen gen(argv[0], base, include, includePaths, dllExport);
+ if(!gen)
+ status = EXIT_FAILURE;
+ gen.generate(unit);
+ }
unit -> destroy();
}
- return EXIT_SUCCESS;
+ return status;
}