diff options
Diffstat (limited to 'cpp/src/Slice/Parser.cpp')
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 134 |
1 files changed, 128 insertions, 6 deletions
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 |