diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/include/Slice/Parser.h | 9 | ||||
-rw-r--r-- | cpp/src/Slice/Grammar.y | 44 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 134 | ||||
-rw-r--r-- | cpp/test/Slice/errorDetection/IllegalLocal.err | 20 | ||||
-rw-r--r-- | cpp/test/Slice/errorDetection/IllegalLocal.ice | 65 |
5 files changed, 245 insertions, 27 deletions
diff --git a/cpp/include/Slice/Parser.h b/cpp/include/Slice/Parser.h index a4ef6fbce6e..aec3c2e934b 100644 --- a/cpp/include/Slice/Parser.h +++ b/cpp/include/Slice/Parser.h @@ -213,6 +213,8 @@ class SLICE_API Type : virtual public SyntaxTreeBase { public: + virtual bool isLocal() const = 0; + protected: Type(const UnitPtr&); @@ -240,6 +242,9 @@ public: KindObjectProxy, KindLocalObject }; + + virtual bool isLocal() const; + Kind kind() const; std::string kindAsString() const; @@ -420,7 +425,7 @@ public: virtual std::string kindOf() const; virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly. - static void checkBasesAreLegal(const std::string&, const ClassList&, const UnitPtr&); + static void checkBasesAreLegal(const std::string&, bool, const ClassList&, const UnitPtr&); protected: @@ -496,6 +501,8 @@ class SLICE_API Proxy : virtual public Type { public: + virtual bool isLocal() const; + ClassDeclPtr _class() const; Proxy(const ClassDeclPtr&); diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y index bc0d12b742c..43d98d82d9b 100644 --- a/cpp/src/Slice/Grammar.y +++ b/cpp/src/Slice/Grammar.y @@ -208,7 +208,7 @@ exception_id // ---------------------------------------------------------------------- exception_decl // ---------------------------------------------------------------------- -: local exception_id +: local_qualifier exception_id { unit->error("exceptions cannot be forward declared"); $$ = $2; @@ -218,7 +218,7 @@ exception_decl // ---------------------------------------------------------------------- exception_def // ---------------------------------------------------------------------- -: local exception_id exception_extends +: local_qualifier exception_id exception_extends { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); @@ -330,7 +330,7 @@ struct_id // ---------------------------------------------------------------------- struct_decl // ---------------------------------------------------------------------- -: local struct_id +: local_qualifier struct_id { unit->error("structs cannot be forward declared"); $$ = $2; @@ -340,7 +340,7 @@ struct_decl // ---------------------------------------------------------------------- struct_def // ---------------------------------------------------------------------- -: local struct_id +: local_qualifier struct_id { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); @@ -446,7 +446,7 @@ class_id // ---------------------------------------------------------------------- class_decl // ---------------------------------------------------------------------- -: local class_id +: local_qualifier class_id { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); @@ -459,7 +459,7 @@ class_decl // ---------------------------------------------------------------------- class_def // ---------------------------------------------------------------------- -: local class_id class_extends implements +: local_qualifier class_id class_extends implements { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); @@ -620,7 +620,7 @@ interface_id // ---------------------------------------------------------------------- interface_decl // ---------------------------------------------------------------------- -: local interface_id +: local_qualifier interface_id { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); @@ -634,7 +634,7 @@ interface_decl // ---------------------------------------------------------------------- interface_def // ---------------------------------------------------------------------- -: local interface_id interface_extends +: local_qualifier interface_id interface_extends { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); @@ -821,7 +821,7 @@ exception // ---------------------------------------------------------------------- sequence_def // ---------------------------------------------------------------------- -: local ICE_SEQUENCE '<' type '>' ICE_IDENTIFIER +: local_qualifier ICE_SEQUENCE '<' type '>' ICE_IDENTIFIER { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($6); @@ -829,7 +829,7 @@ sequence_def ContainerPtr cont = unit->currentContainer(); $$ = cont->createSequence(ident->v, type, local->v); } -| local ICE_SEQUENCE '<' type '>' keyword +| local_qualifier ICE_SEQUENCE '<' type '>' keyword { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($6); @@ -843,7 +843,7 @@ sequence_def // ---------------------------------------------------------------------- dictionary_def // ---------------------------------------------------------------------- -: local ICE_DICTIONARY '<' type ',' type '>' ICE_IDENTIFIER +: local_qualifier ICE_DICTIONARY '<' type ',' type '>' ICE_IDENTIFIER { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($8); @@ -852,7 +852,7 @@ dictionary_def ContainerPtr cont = unit->currentContainer(); $$ = cont->createDictionary(ident->v, keyType, valueType, local->v); } -| local ICE_DICTIONARY '<' type ',' type '>' keyword +| local_qualifier ICE_DICTIONARY '<' type ',' type '>' keyword { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($8); @@ -882,7 +882,7 @@ enum_id // ---------------------------------------------------------------------- enum_def // ---------------------------------------------------------------------- -: local enum_id +: local_qualifier enum_id { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); @@ -1042,15 +1042,15 @@ out_qualifier // ---------------------------------------------------------------------- : ICE_OUT { - BoolTokPtr local = new BoolTok; - local->v = true; - $$ = local; + BoolTokPtr out = new BoolTok; + out->v = true; + $$ = out; } | { - BoolTokPtr local = new BoolTok; - local->v = false; - $$ = local; + BoolTokPtr out = new BoolTok; + out->v = false; + $$ = out; } ; @@ -1237,6 +1237,10 @@ type YYERROR; // Can't continue, jump to next yyerrok } cont->checkIntroduced(scoped->v); + if(cl->isLocal()) + { + unit->error("cannot create proxy for " + cl->kindOf() + " `" + cl->name() + "'"); + } *p = new Proxy(cl); } $$ = types.front(); @@ -1277,7 +1281,7 @@ string_list ; // ---------------------------------------------------------------------- -local +local_qualifier // ---------------------------------------------------------------------- : ICE_LOCAL { diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 7858d7ab93b..8dd38a14f25 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -73,6 +73,12 @@ Slice::Type::Type(const UnitPtr& unit) : // Builtin // ---------------------------------------------------------------------- +bool +Slice::Builtin::isLocal() const +{ + return _kind == KindLocalObject; +} + Builtin::Kind Slice::Builtin::kind() const { @@ -328,7 +334,7 @@ Slice::Container::createClassDef(const string& name, bool intf, const ClassList& return 0; } - ClassDecl::checkBasesAreLegal(name, bases, _unit); + ClassDecl::checkBasesAreLegal(name, local, bases, _unit); ClassDefPtr def = new ClassDef(this, name, intf, bases, local); _contents.push_back(def); @@ -459,6 +465,14 @@ Slice::Container::createException(const string& name, const ExceptionPtr& base, _unit->warning(msg); // TODO: Change to error in stable_39 } + // + // If this definition is non-local, base cannot be local + // + if(!local && base && base->isLocal()) + { + _unit->error("non-local exception `" + name + "' cannot have local base exception `" + base->name() + "'"); + } + ExceptionPtr p = new Exception(this, name, base, local); _contents.push_back(p); return p; @@ -523,6 +537,15 @@ Slice::Container::createSequence(const string& name, const TypePtr& type, bool l msg += matches.front()->kindOf() + " `" + matches.front()->name() + "'"; _unit->warning(msg); // TODO: change to error in stable_39 } + + // + // If sequence is non-local, element type cannot be local + // + if(!local && type->isLocal()) + { + string msg = "non-local sequence `" + name + "' cannot have local element type"; + _unit->error(msg); + } SequencePtr p = new Sequence(this, name, type, local); _contents.push_back(p); @@ -562,6 +585,20 @@ Slice::Container::createDictionary(const string& name, const TypePtr& keyType, c return 0; } + if(!local) + { + if(keyType->isLocal()) + { + string msg = "non-local dictionary `" + name + "' cannot have local key type"; + _unit->error(msg); + } + if(valueType->isLocal()) + { + string msg = "non-local dictionary `" + name + "' cannot have local value type"; + _unit->error(msg); + } + } + DictionaryPtr p = new Dictionary(this, name, keyType, valueType, local); _contents.push_back(p); return p; @@ -1497,9 +1534,25 @@ Slice::ClassDecl::recDependencies(set<ConstructedPtr>& dependencies) } void -Slice::ClassDecl::checkBasesAreLegal(const string& name, const ClassList& bases, const UnitPtr& unit) +Slice::ClassDecl::checkBasesAreLegal(const string& name, bool local, const ClassList& bases, const UnitPtr& unit) { // + // If this definition is non-local, no base can be local + // + if(!local) + { + for(ClassList::const_iterator p = bases.begin(); p != bases.end(); ++p) + { + if((*p)->isLocal()) + { + string msg = "non-local `" + name + "' cannot have base "; + msg += (*p)->kindOf() + " `" + (*p)->name() + "'"; + unit->error(msg); + } + } + } + + // // Check whether, for multiple inheritance, any of the bases define // the same operations. // @@ -1684,9 +1737,6 @@ Slice::ClassDef::destroy() OperationPtr Slice::ClassDef::createOperation(const string& name, const TypePtr& returnType) - //const TypeStringList& inParams, - //const TypeStringList& outParams, - //const ExceptionList& throws) { ContainedList matches = _unit->findContents(thisScope() + name); if(!matches.empty()) @@ -1774,8 +1824,17 @@ Slice::ClassDef::createOperation(const string& name, } } } + + // + // Non-local class/interface cannot have operation with local return type + // + if(!isLocal() && returnType && returnType->isLocal()) + { + string msg = "non-local " + this->kindOf() + " `" + this->name() + "' cannot have operation `"; + msg += name + "' with local return type"; + _unit->error(msg); + } - //OperationPtr op = new Operation(this, name, returnType, inParams, outParams, uniqueExceptions); OperationPtr op = new Operation(this, name, returnType); _contents.push_back(op); return op; @@ -1873,6 +1932,15 @@ Slice::ClassDef::createDataMember(const string& name, const TypePtr& type) } } + // + // If data member is local, enclosing class/interface must be local + // + if(!isLocal() && type->isLocal()) + { + string msg = "non-local " + kindOf() + "`" + this->name() + "' cannot contain local member `" + name + "'"; + _unit->error(msg); + } + _hasDataMembers = true; DataMemberPtr member = new DataMember(this, name, type); _contents.push_back(member); @@ -2075,6 +2143,12 @@ Slice::ClassDef::ClassDef(const ContainerPtr& container, const string& name, boo // Proxy // ---------------------------------------------------------------------- +bool +Slice::Proxy::isLocal() const +{ + return __class->isLocal(); +} + ClassDeclPtr Slice::Proxy::_class() const { @@ -2180,6 +2254,15 @@ Slice::Exception::createDataMember(const string& name, const TypePtr& type) } } + // + // If data member is local, enclosing class/interface must be local + // + if(!isLocal() && type->isLocal()) + { + string msg = "non-local " + kindOf() + "`" + this->name() + "' cannot contain local member `" + name + "'"; + _unit->error(msg); + } + DataMemberPtr p = new DataMember(this, name, type); _contents.push_back(p); return p; @@ -2331,6 +2414,15 @@ Slice::Struct::createDataMember(const string& name, const TypePtr& type) return 0; } + // + // If data member is local, enclosing class/interface must be local + // + if(!isLocal() && type->isLocal()) + { + string msg = "non-local " + kindOf() + "`" + this->name() + "' cannot contain local member `" + name + "'"; + _unit->error(msg); + } + DataMemberPtr p = new DataMember(this, name, type); _contents.push_back(p); return p; @@ -2990,6 +3082,18 @@ Slice::Operation::createParamDecl(const string& name, const TypePtr& type, bool } } + // + // Non-local class/interface cannot have operation with local parameters + // + ClassDefPtr cl = ClassDefPtr::dynamicCast(this->container()); + assert(cl); + if(type->isLocal() && !cl->isLocal()) + { + string msg = "non-local " + cl->kindOf() + " `" + cl->name() + "' cannot have local parameter `"; + msg += name + "' in operation `" + this->name() + "'"; + _unit->error(msg); + } + ParamDeclPtr p = new ParamDecl(this, name, type, isOutParam); _contents.push_back(p); return p; @@ -3056,6 +3160,24 @@ Slice::Operation::setExceptionList(const ExceptionList& el) } _unit->error(msg); } + + // + // If the interface is non-local, no local exception can be thrown + // + ClassDefPtr cl = ClassDefPtr::dynamicCast(container()); + assert(cl); + if(!cl->isLocal()) + { + for(ExceptionList::const_iterator ep = el.begin(); ep != el.end(); ++ep) + { + if((*ep)->isLocal()) + { + string msg = "non-local " + cl->kindOf() + " `" + cl->name() + "' cannot have operation `"; + msg += name() + "' throwing local exception `" + (*ep)->name() + "'"; + _unit->error(msg); + } + } + } } Contained::ContainedType diff --git a/cpp/test/Slice/errorDetection/IllegalLocal.err b/cpp/test/Slice/errorDetection/IllegalLocal.err new file mode 100644 index 00000000000..5eefb3eec02 --- /dev/null +++ b/cpp/test/Slice/errorDetection/IllegalLocal.err @@ -0,0 +1,20 @@ +IllegalLocal.ice:5: non-local `i3' cannot have base local interface `i2' +IllegalLocal.ice:11: non-local `c2' cannot have base local interface `i2' +IllegalLocal.ice:17: non-local interface `i' cannot have operation `op' throwing local exception `le' +IllegalLocal.ice:20: non-local exception `le2' cannot have local base exception `le' +IllegalLocal.ice:26: non-local class`c3' cannot contain local member `lo1' +IllegalLocal.ice:27: cannot create proxy for local interface `i2' +IllegalLocal.ice:27: non-local class`c3' cannot contain local member `lo2' +IllegalLocal.ice:28: non-local class`c3' cannot contain local member `lo3' +IllegalLocal.ice:29: non-local class`c3' cannot contain local member `ls' +IllegalLocal.ice:34: non-local struct`s1' cannot contain local member `ls' +IllegalLocal.ice:39: non-local exception`e3' cannot contain local member `ls' +IllegalLocal.ice:42: non-local sequence `los' cannot have local element type +IllegalLocal.ice:45: non-local dictionary `d1' cannot have local key type +IllegalLocal.ice:46: non-local dictionary `d2' cannot have local value type +IllegalLocal.ice:47: non-local dictionary `d3' cannot have local key type +IllegalLocal.ice:47: non-local dictionary `d3' cannot have local value type +IllegalLocal.ice:52: non-local struct`s2' cannot contain local member `m' +IllegalLocal.ice:58: non-local struct`s3' cannot contain local member `e' +IllegalLocal.ice:63: non-local interface `i5' cannot have local parameter `p' in operation `op' +IllegalLocal.ice:64: non-local interface `i5' cannot have operation `op2' with local return type diff --git a/cpp/test/Slice/errorDetection/IllegalLocal.ice b/cpp/test/Slice/errorDetection/IllegalLocal.ice new file mode 100644 index 00000000000..92cf9e0d9aa --- /dev/null +++ b/cpp/test/Slice/errorDetection/IllegalLocal.ice @@ -0,0 +1,65 @@ +interface i1 {}; + +local interface i2 extends i1 {}; // OK + +interface i3 extends i2 {}; // error + +local interface i4 extends i2 {}; // OK + +class c1 implements i1 {}; // OK + +class c2 implements i2 {}; // error + +local exception le {}; + +interface i +{ + void op() throws le; // error +}; + +exception le2 extends le {}; // error + +local sequence<long> lls; + +class c3 +{ + LocalObject lo1; // error + i2* lo2; // error + i2 lo3; // error + lls ls; // error +}; + +struct s1 +{ + lls ls; // error +}; + +exception e3 +{ + lls ls; // error +}; + +sequence<LocalObject> los; // error + +local sequence<byte> bs; +dictionary<bs, long> d1; // error +dictionary<long, bs> d2; // error +dictionary<bs, bs> d3; // error + +local interface i4; +struct s2 +{ + i4 m; +}; + +local enum en { a }; +struct s3 +{ + en e; +}; + +interface i5 +{ + void op(en p); + LocalObject op2(); +}; |