diff options
author | Marc Laukien <marc@zeroc.com> | 2001-07-10 19:50:49 +0000 |
---|---|---|
committer | Marc Laukien <marc@zeroc.com> | 2001-07-10 19:50:49 +0000 |
commit | aadefbf05157f6e2626e7f25241319b4aa010925 (patch) | |
tree | 37f9f19b574351656c8b799fb2776716a9aaf82d /cpp/src | |
parent | more tests (diff) | |
download | ice-aadefbf05157f6e2626e7f25241319b4aa010925.tar.bz2 ice-aadefbf05157f6e2626e7f25241319b4aa010925.tar.xz ice-aadefbf05157f6e2626e7f25241319b4aa010925.zip |
more interface stuff
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/Grammer.y | 32 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 67 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.h | 16 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 225 | ||||
-rw-r--r-- | cpp/src/slice2cpp/GenUtil.cpp | 2 |
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()) |