summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Slice/Grammer.y32
-rw-r--r--cpp/src/Slice/Parser.cpp67
-rw-r--r--cpp/src/Slice/Parser.h16
-rw-r--r--cpp/src/slice2cpp/Gen.cpp225
-rw-r--r--cpp/src/slice2cpp/GenUtil.cpp2
5 files changed, 219 insertions, 123 deletions
diff --git a/cpp/src/Slice/Grammer.y b/cpp/src/Slice/Grammer.y
index f798bec9899..43a38281e1d 100644
--- a/cpp/src/Slice/Grammer.y
+++ b/cpp/src/Slice/Grammer.y
@@ -203,7 +203,9 @@ class_decl
BoolTok_ptr local = BoolTok_ptr::dynamicCast($1);
StringTok_ptr ident = StringTok_ptr::dynamicCast($3);
Container_ptr cont = unit -> currentContainer();
- ClassDecl_ptr cl = cont -> createClassDecl(ident -> v, local -> v, false);
+ ClassDecl_ptr cl = cont -> createClassDecl(ident -> v,
+ local -> v,
+ false);
}
;
@@ -216,11 +218,14 @@ class_def
StringTok_ptr ident = StringTok_ptr::dynamicCast($3);
Container_ptr cont = unit -> currentContainer();
ClassDef_ptr base = ClassDef_ptr::dynamicCast($4);
- ClassListTok_ptr intfs = ClassListTok_ptr::dynamicCast($5);
- ClassDef_ptr derived = cont -> createClassDef(ident -> v, base,
- intfs -> v, local -> v,
- false);
- unit -> pushContainer(derived);
+ ClassListTok_ptr bases = ClassListTok_ptr::dynamicCast($5);
+ if(base)
+ bases -> v.push_front(base);
+ ClassDef_ptr cl = cont -> createClassDef(ident -> v,
+ local -> v,
+ false,
+ bases -> v);
+ unit -> pushContainer(cl);
}
'{' class_exports '}'
{
@@ -290,7 +295,9 @@ interface_decl
BoolTok_ptr local = BoolTok_ptr::dynamicCast($1);
StringTok_ptr ident = StringTok_ptr::dynamicCast($3);
Container_ptr cont = unit -> currentContainer();
- ClassDecl_ptr cl = cont -> createClassDecl(ident -> v, local -> v, true);
+ ClassDecl_ptr cl = cont -> createClassDecl(ident -> v,
+ local -> v,
+ true);
}
;
@@ -302,11 +309,12 @@ interface_def
BoolTok_ptr local = BoolTok_ptr::dynamicCast($1);
StringTok_ptr ident = StringTok_ptr::dynamicCast($3);
Container_ptr cont = unit -> currentContainer();
- ClassListTok_ptr intfs = ClassListTok_ptr::dynamicCast($4);
- ClassDef_ptr derived = cont -> createClassDef(ident -> v, 0,
- intfs -> v, local -> v,
- true);
- unit -> pushContainer(derived);
+ ClassListTok_ptr bases = ClassListTok_ptr::dynamicCast($4);
+ ClassDef_ptr cl = cont -> createClassDef(ident -> v,
+ local -> v,
+ true,
+ bases -> v);
+ unit -> pushContainer(cl);
}
'{' interface_exports '}'
{
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index 20607748105..590ee475113 100644
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -213,11 +213,8 @@ Slice::Container::createModule(const string& name)
}
ClassDef_ptr
-Slice::Container::createClassDef(const string& name,
- const ClassDef_ptr& base,
- const ClassList& interfaces,
- bool local,
- bool intf)
+Slice::Container::createClassDef(const string& name, bool local, bool intf,
+ const ClassList& bases)
{
list<Contained_ptr> matches = unit_ -> findContents(thisScope() + name);
for(list<Contained_ptr>::iterator p = matches.begin();
@@ -226,7 +223,7 @@ Slice::Container::createClassDef(const string& name,
{
ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*p);
if(cl)
- continue; // TODO: Check whether local matches
+ continue; // TODO: Check whether local and interface matches
if(unit_ -> ignRedefs())
{
@@ -238,8 +235,7 @@ Slice::Container::createClassDef(const string& name,
assert(false); // TODO: Already exists and not a class declaration
}
- ClassDef_ptr def = new ClassDef(this, name, base, interfaces,
- local, intf);
+ ClassDef_ptr def = new ClassDef(this, name, local, intf, bases);
contents_.push_back(def);
for(list<Contained_ptr>::iterator q = matches.begin();
@@ -275,12 +271,12 @@ Slice::Container::createClassDecl(const string& name, bool local, bool intf)
{
assert(!def);
def = clDef;
- continue; // TODO: Check whether local matches
+ continue; // TODO: Check whether local and interface matches
}
ClassDecl_ptr clDecl = ClassDecl_ptr::dynamicCast(*p);
if(clDecl)
- continue; // TODO: Check whether local matches
+ continue; // TODO: Check whether local and interface matches
// TODO: Already defined as something other than a class
assert(false);
@@ -305,7 +301,7 @@ Slice::Container::createClassDecl(const string& name, bool local, bool intf)
}
}
- ClassDecl_ptr cl = new ClassDecl(this, name, local, false);
+ ClassDecl_ptr cl = new ClassDecl(this, name, local, intf);
contents_.push_back(cl);
if(def)
@@ -697,7 +693,7 @@ Slice::ClassDecl::ClassDecl(const Container_ptr& container,
void
Slice::ClassDef::destroy()
{
- base_ = 0;
+ bases_.empty();
Container::destroy();
}
@@ -750,16 +746,27 @@ Slice::ClassDef::createDataMember(const string& name, const Type_ptr& type)
return p;
}
-ClassDef_ptr
-Slice::ClassDef::base()
+ClassList
+Slice::ClassDef::bases()
{
- return base_;
+ return bases_;
}
ClassList
-Slice::ClassDef::interfaces()
+Slice::ClassDef::allBases()
{
- return interfaces_;
+ ClassList result = bases_;
+ result.sort();
+ result.unique();
+ for(ClassList::iterator p = bases_.begin();
+ p != bases_.end();
+ ++p)
+ {
+ ClassList li = (*p) -> allBases();
+ result.merge(li);
+ result.unique();
+ }
+ return result;
}
list<Operation_ptr>
@@ -795,7 +802,10 @@ Slice::ClassDef::dataMembers()
bool
Slice::ClassDef::isAbstract()
{
- if(base_ && base_ -> isAbstract())
+ if(isInterface())
+ return true;
+
+ if(!bases_.empty() && bases_.front() -> isAbstract())
return true;
for(list<Contained_ptr>::const_iterator p = contents_.begin();
@@ -840,25 +850,26 @@ Slice::ClassDef::visit(ParserVisitor* visitor)
Slice::ClassDef::ClassDef(const Container_ptr& container,
const string& name,
- const ClassDef_ptr& base,
- const ClassList& interfaces,
bool local,
- bool intf)
+ bool intf,
+ const ClassList& bases)
: Contained(container, name),
Container(container -> unit()),
SyntaxTreeBase(container -> unit()),
- base_(base),
- interfaces_(interfaces),
local_(local),
- interface_(intf)
+ interface_(intf),
+ bases_(bases)
{
- assert(!base_ || !base_ -> isInterface());
+ //
+ // First element of bases may be a class, all others must be
+ // interfaces
+ //
#ifndef NDEBUG
- for(ClassList::iterator p = interfaces_.begin();
- p != interfaces_.end();
+ for(ClassList::iterator p = bases_.begin();
+ p != bases_.end();
++p)
{
- assert((*p) -> isInterface());
+ assert(p == bases_.begin() || (*p) -> isInterface());
}
#endif
}
diff --git a/cpp/src/Slice/Parser.h b/cpp/src/Slice/Parser.h
index 961f2d17abe..22a8db4f475 100644
--- a/cpp/src/Slice/Parser.h
+++ b/cpp/src/Slice/Parser.h
@@ -272,8 +272,8 @@ public:
virtual void destroy();
Module_ptr createModule(const std::string&);
- ClassDef_ptr createClassDef(const std::string&, const ClassDef_ptr&,
- const ClassList&, bool, bool);
+ ClassDef_ptr createClassDef(const std::string&, bool, bool,
+ const ClassList&);
ClassDecl_ptr createClassDecl(const std::string&, bool, bool);
Vector_ptr createVector(const std::string&, const Type_ptr&);
Enum_ptr createEnum(const std::string&, const StringList&);
@@ -371,8 +371,8 @@ public:
const TypeStringList&, const TypeStringList&,
const TypeList&);
DataMember_ptr createDataMember(const std::string&, const Type_ptr&);
- ClassDef_ptr base();
- ClassList interfaces();
+ ClassList bases();
+ ClassList allBases();
std::list<Operation_ptr> operations();
std::list<DataMember_ptr> dataMembers();
bool isAbstract();
@@ -385,16 +385,14 @@ protected:
ClassDef(const Container_ptr&,
const std::string&,
- const ClassDef_ptr&,
- const ClassList&,
bool,
- bool);
+ bool,
+ const ClassList&);
friend class ICE_API Container;
- ClassDef_ptr base_;
- ClassList interfaces_;
bool local_;
bool interface_;
+ ClassList bases_;
};
// ----------------------------------------------------------------------
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index e08329c20b2..b2f302223d4 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -497,17 +497,25 @@ Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDef_ptr& p)
return;
string name = p -> name();
+ ClassList bases = p -> bases();
- ClassDef_ptr base = p -> base();
- string baseS;
- if(base)
- baseS = base -> scoped();
- else
- baseS = "::Ice::Object";
-
H << sp;
- H << nl << "class" << dllExport_ << ' ' << name << " : "
- << "virtual public ::__IceProxy" << baseS;
+ H << nl << "class" << dllExport_ << ' ' << name << " : ";
+ if(bases.empty())
+ H << "virtual public ::__IceProxy::Ice::Object";
+ else
+ {
+ H.useCurrentPosAsIndent();
+ ClassList::iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << "virtual public ::__IceProxy" << (*q) -> scoped();
+ if(++q != bases.end())
+ H << ',' << nl;
+ }
+ H.restoreIndent();
+ }
+
H << sb;
H.dec();
H << nl << "public: ";
@@ -673,16 +681,24 @@ Slice::Gen::DelegateVisitor::visitClassDefStart(const ClassDef_ptr& p)
return;
string name = p -> name();
- ClassDef_ptr base = p -> base();
- string baseS;
- if(base)
- baseS = base -> scoped();
- else
- baseS = "::Ice::Object";
-
+ ClassList bases = p -> bases();
+
H << sp;
- H << nl << "class" << dllExport_ << ' ' << name << " : "
- << "virtual public ::__IceDelegate" << baseS;
+ H << nl << "class" << dllExport_ << ' ' << name << " : ";
+ if(bases.empty())
+ H << "virtual public ::__IceDelegate::Ice::Object";
+ else
+ {
+ H.useCurrentPosAsIndent();
+ ClassList::iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << "virtual public ::__IceDelegate" << (*q) -> scoped();
+ if(++q != bases.end())
+ H << ',' << nl;
+ }
+ H.restoreIndent();
+ }
H << sb;
H.dec();
H << nl << "public: ";
@@ -809,19 +825,24 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDef_ptr& p)
string name = p -> name();
string scoped = p -> scoped();
+ ClassList bases = p -> bases();
- ClassDef_ptr base = p -> base();
- string baseS;
- if(base)
- baseS = base -> scoped();
- else
- baseS = "::Ice::Object";
-
H << sp;
H << nl << "class" << dllExport_ << ' ' << name << " : ";
H.useCurrentPosAsIndent();
H << "virtual public ::__IceDelegate" << scoped << ',';
- H << nl << "virtual public ::__IceDelegateM" << baseS;
+ if(bases.empty())
+ H << nl << "virtual public ::__IceDelegateM::Ice::Object";
+ else
+ {
+ ClassList::iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << nl << "virtual public ::__IceDelegateM" << (*q) -> scoped();
+ if(++q != bases.end())
+ H << ',';
+ }
+ }
H.restoreIndent();
H << sb;
H.dec();
@@ -1022,82 +1043,137 @@ Slice::Gen::ObjectVisitor::visitModuleEnd(const Module_ptr& p)
void
Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDef_ptr& p)
{
- bool isLocal = p -> isLocal();
string name = p -> name();
string scoped = p -> scoped();
-
- vector<ClassDef_ptr> bases;
- vector<ClassDef_ptr>::const_iterator q;
-
- ClassDef_ptr base = p;
- while((base = base -> base()))
- bases.push_back(base);
-
- string baseS;
- if(!bases.empty())
- {
- base = bases[0];
- baseS = base -> scoped();
- }
- else
- {
- if(isLocal)
- baseS = "::Ice::LocalObject";
- else
- baseS = "::Ice::Object";
- }
-
+ ClassList bases = p -> bases();
+
H << sp;
H << nl << "class" << dllExport_ << ' ' << name << " : ";
- if(isLocal)
+ if(p -> isLocal())
{
- // No virtual inheritance for local objects
- H << "public " << baseS;
+ if(bases.empty())
+ H << "virtual public ::Ice::LocalObject";
+ else
+ {
+ H.useCurrentPosAsIndent();
+ ClassList::iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << "virtual public " << (*q) -> scoped();
+ if(++q != bases.end())
+ H << ',' << nl;
+ }
+ H.restoreIndent();
+ }
}
else
{
H.useCurrentPosAsIndent();
H << "virtual public ::__IceDelegate" << scoped << ',';
- H << nl << "virtual public " << baseS;
+ if(bases.empty())
+ H << nl << "virtual public ::Ice::Object";
+ else
+ {
+ ClassList::iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << nl << "virtual public " << (*q) -> scoped();
+ if(++q != bases.end())
+ H << ',';
+ }
+ }
H.restoreIndent();
}
H << sb;
H.dec();
H << nl << "public: ";
H.inc();
- if(!isLocal)
+ if(!p -> isLocal())
{
+ ClassList allBases = p -> allBases();
+ list<string> ids;
+ transform(allBases.begin(), allBases.end(),
+ back_inserter(ids),
+ ::Ice::memFun(&ClassDef::scoped));
+ list<string> other;
+ other.push_back(scoped);
+ other.push_back("::Ice::Object");
+ other.sort();
+ ids.merge(other);
+ ids.unique();
+
+ ClassList allBaseClasses;
+ ClassDef_ptr cl;
+ if(!bases.empty())
+ cl = bases.front();
+ else
+ cl = 0;
+ while(cl && !cl -> isInterface())
+ {
+ allBaseClasses.push_back(cl);
+ ClassList baseBases = cl -> bases();
+ if(!baseBases.empty())
+ cl = baseBases.front();
+ else
+ cl = 0;
+ }
+ list<string> classIds;
+ transform(allBaseClasses.begin(), allBaseClasses.end(),
+ back_inserter(classIds),
+ ::Ice::memFun(&ClassDef::scoped));
+ if(!p -> isInterface())
+ classIds.push_front(scoped);
+ classIds.push_back("::Ice::Object");
+
+ list<string>::iterator q;
+
+ H << sp;
+ H << nl << "static std::string __ids[" << ids.size() << "];";
H << sp;
- H << nl << "static std::string __implements["
- << bases.size() + 2 << "];";
+ H << nl << "static std::string __classIds[" << classIds.size() << "];";
H << sp;
- H << nl << "virtual bool _implements(const std::string&);";
+ H << nl << "virtual bool _isA(const std::string&);";
H << sp;
- H << nl << "virtual const std::string* __ids();";
+ H << nl << "virtual const std::string* _classIds();";
+ C << sp;
+ C << nl << "std::string " << scoped.substr(2)
+ << "::__ids[" << ids.size() << "] =";
+ C << sb;
+ q = ids.begin();
+ while(q != ids.end())
+ {
+ C << nl << '"' << *q << '"';
+ if(++q != ids.end())
+ C << ',';
+ }
+ C << eb << ';';
C << sp;
C << nl << "std::string " << scoped.substr(2)
- << "::__implements[" << bases.size() + 2 << "] =";
+ << "::__classIds[" << classIds.size() << "] =";
C << sb;
- C << nl << '"' << scoped << "\",";
- for(q = bases.begin(); q != bases.end(); ++q)
- C << nl << '"' << (*q) -> scoped() << "\",";
- C << nl << "\"::Ice::Object\"";
+ q = classIds.begin();
+ while(q != classIds.end())
+ {
+ C << nl << '"' << *q << '"';
+ if(++q != classIds.end())
+ C << ',';
+ }
C << eb << ';';
C << sp;
C << nl << "bool" << nl << scoped.substr(2)
- << "::_implements(const std::string& s)";
+ << "::_isA(const std::string& s)";
C << sb;
- C << nl << "std::string* b = __implements;";
- C << nl << "std::string* e = __implements + " << bases.size() + 2
- << ';';
- C << nl << "std::string* r = std::find(b, e, s);";
- C << nl << "return(r != e);";
+ C << nl << "std::string* b = __ids;";
+ C << nl << "std::string* e = __ids + " << ids.size() << ';';
+ C << nl << "std::pair<std::string*, std::string*> r = "
+ << "std::equal_range(b, e, s);";
+ C << nl << "return r.first != r.second;";
C << eb;
C << sp;
C << nl << "const std::string*" << nl << scoped.substr(2)
- << "::__ids()";
+ << "::_classIds()";
C << sb;
- C << nl << "return __implements;";
+ C << nl << "return __classIds;";
C << eb;
}
}
@@ -1109,7 +1185,10 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDef_ptr& p)
string scoped = p -> scoped();
list<Operation_ptr> operations = p -> operations();
- ClassDef_ptr base = p -> base();
+ ClassList bases = p -> bases();
+ ClassDef_ptr base;
+ if(!bases.empty() && !bases.front() -> isInterface())
+ base = bases.front();
if(!p -> isLocal() && !operations.empty())
{
@@ -1431,7 +1510,7 @@ Slice::Gen::IceVisitor::visitClassDefStart(const ClassDef_ptr& p)
C << sb;
C << nl << "d = dynamic_cast< ::__IceProxy" << scoped
<< "*>(b);";
- C << nl << "if(!d && b -> _implements(\"" << scoped << "\"))";
+ C << nl << "if(!d && b -> _isA(\"" << scoped << "\"))";
C << sb;
C << nl << "d = new ::__IceProxy" << scoped << ';';
C << nl << "b -> __copyTo(d);";
diff --git a/cpp/src/slice2cpp/GenUtil.cpp b/cpp/src/slice2cpp/GenUtil.cpp
index 4fb644042aa..d6a48b60bfe 100644
--- a/cpp/src/slice2cpp/GenUtil.cpp
+++ b/cpp/src/slice2cpp/GenUtil.cpp
@@ -174,7 +174,7 @@ Slice::writeMarshalUnmarshalCode(Output& out, const Type_ptr& type,
{
out << nl << "::Ice::Object_ptr __obj;";
out << nl << stream << " -> read(__obj, " << cl -> scoped()
- << "::__implements[0]);";
+ << "::__classIds[0]);";
out << nl << "if(!__obj)";
ClassDef_ptr def = cl -> definition();
if(def && !def -> isAbstract())