diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/Grammar.y | 263 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 140 | ||||
-rw-r--r-- | cpp/src/Slice/Scanner.l | 16 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 4 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Main.cpp | 2 | ||||
-rw-r--r-- | cpp/src/slice2docbook/Main.cpp | 2 | ||||
-rw-r--r-- | cpp/src/slice2freeze/Main.cpp | 2 | ||||
-rw-r--r-- | cpp/src/slice2freezej/Main.cpp | 2 | ||||
-rw-r--r-- | cpp/src/slice2java/Main.cpp | 2 |
9 files changed, 351 insertions, 82 deletions
diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y index 166f5c45a1e..b182aebc0e5 100644 --- a/cpp/src/Slice/Grammar.y +++ b/cpp/src/Slice/Grammar.y @@ -88,6 +88,10 @@ slice_error(const char* s) %token ICE_FLOATING_POINT_LITERAL %token ICE_IDENT_OP %token ICE_KEYWORD_OP +%token ICE_METADATA_OPEN +%token ICE_METADATA_CLOSE +%token ICE_GLOBAL_METADATA_OPEN +%token ICE_GLOBAL_METADATA_CLOSE %% @@ -103,16 +107,16 @@ start // ---------------------------------------------------------------------- global_meta_data // ---------------------------------------------------------------------- -: '[' '[' string_list ']' ']' +: ICE_GLOBAL_METADATA_OPEN string_list ICE_GLOBAL_METADATA_CLOSE { - $$ = $3; + $$ = $2; } ; // ---------------------------------------------------------------------- meta_data // ---------------------------------------------------------------------- -: '[' string_list ']' +: ICE_METADATA_OPEN string_list ICE_METADATA_CLOSE { $$ = $2; } @@ -145,10 +149,11 @@ definitions unit->setSeenDefinition(); } ';' definitions -| error ';' definitions +| error ';' { yyerrok; } +definitions | meta_data definition { unit->error("`;' missing after definition"); @@ -223,18 +228,28 @@ module_def StringTokPtr ident = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); ModulePtr module = cont->createModule(ident->v); - if(!module) + if(module) + { + cont->checkIntroduced(ident->v, module); + unit->pushContainer(module); + $$ = module; + } + else { - YYERROR; // Can't continue, jump to next yyerrok + $$ = 0; } - cont->checkIntroduced(ident->v, module); - unit->pushContainer(module); - $$ = module; } '{' definitions '}' { - unit->popContainer(); - $$ = $3; + if($3) + { + unit->popContainer(); + $$ = $3; + } + else + { + $$ = 0; + } } ; @@ -273,17 +288,19 @@ exception_def ExceptionPtr base = ExceptionPtr::dynamicCast($3); ContainerPtr cont = unit->currentContainer(); ExceptionPtr ex = cont->createException(ident->v, base, local->v); - if(!ex) + if(ex) { - YYERROR; // Can't continue, jump to next yyerrok + cont->checkIntroduced(ident->v, ex); + unit->pushContainer(ex); } - cont->checkIntroduced(ident->v, ex); - unit->pushContainer(ex); $$ = ex; } '{' exception_exports '}' { - unit->popContainer(); + if($4); + { + unit->popContainer(); + } $$ = $4; } ; @@ -382,17 +399,19 @@ struct_def StringTokPtr ident = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); StructPtr st = cont->createStruct(ident->v, local->v); - if(!st) + if(st) { - YYERROR; // Can't continue, jump to next yyerrok + cont->checkIntroduced(ident->v, st); + unit->pushContainer(st); } - cont->checkIntroduced(ident->v, st); - unit->pushContainer(st); $$ = st; } '{' struct_exports '}' { - unit->popContainer(); + if($3) + { + unit->popContainer(); + } $$ = $3; // @@ -480,18 +499,28 @@ class_def bases->v.push_front(base); } ClassDefPtr cl = cont->createClassDef(ident->v, false, bases->v, local->v); - if(!cl) + if(cl) { - YYERROR; // Can't continue, jump to next yyerrok + cont->checkIntroduced(ident->v, cl); + unit->pushContainer(cl); + $$ = cl; + } + else + { + $$ = 0; } - cont->checkIntroduced(ident->v, cl); - unit->pushContainer(cl); - $$ = cl; } '{' class_exports '}' { - unit->popContainer(); - $$ = $5; + if($5) + { + unit->popContainer(); + $$ = $5; + } + else + { + $$ = 0; + } } ; @@ -664,66 +693,144 @@ operation_preamble TypePtr returnType = TypePtr::dynamicCast($1); string name = StringTokPtr::dynamicCast($2)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - OperationPtr op = cl->createOperation(name, returnType); - cl->checkIntroduced(name, op); - unit->pushContainer(op); - $$ = op; + if(cl) + { + OperationPtr op = cl->createOperation(name, returnType); + if(op) + { + cl->checkIntroduced(name, op); + unit->pushContainer(op); + $$ = op; + } + else + { + $$ = 0; + } + } + else + { + $$ = 0; + } } | ICE_NONMUTATING return_type ICE_IDENT_OP { TypePtr returnType = TypePtr::dynamicCast($2); string name = StringTokPtr::dynamicCast($3)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - OperationPtr op = cl->createOperation(name, returnType, Operation::Nonmutating); - cl->checkIntroduced(name, op); - unit->pushContainer(op); - $$ = op; + if(cl) + { + OperationPtr op = cl->createOperation(name, returnType, Operation::Nonmutating); + if(op) + { + cl->checkIntroduced(name, op); + unit->pushContainer(op); + $$ = op; + } + else + { + $$ = 0; + } + } + else + { + $$ = 0; + } } | ICE_IDEMPOTENT return_type ICE_IDENT_OP { TypePtr returnType = TypePtr::dynamicCast($2); string name = StringTokPtr::dynamicCast($3)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - OperationPtr op = cl->createOperation(name, returnType, Operation::Idempotent); - cl->checkIntroduced(name, op); - unit->pushContainer(op); - $$ = op; + if(cl) + { + OperationPtr op = cl->createOperation(name, returnType, Operation::Idempotent); + if(op) + { + cl->checkIntroduced(name, op); + unit->pushContainer(op); + $$ = op; + } + else + { + $$ = 0; + } + } + else + { + $$ = 0; + } } | return_type ICE_KEYWORD_OP { TypePtr returnType = TypePtr::dynamicCast($1); string name = StringTokPtr::dynamicCast($2)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - OperationPtr op = cl->createOperation(name, returnType); - unit->pushContainer(op); - unit->error("keyword `" + name + "' cannot be used as operation name"); - $$ = op; + if(cl) + { + OperationPtr op = cl->createOperation(name, returnType); + if(op) + { + unit->pushContainer(op); + unit->error("keyword `" + name + "' cannot be used as operation name"); + $$ = op; + } + else + { + $$ = 0; + } + } + else + { + $$ = 0; + } } | ICE_NONMUTATING return_type ICE_KEYWORD_OP { TypePtr returnType = TypePtr::dynamicCast($2); string name = StringTokPtr::dynamicCast($3)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - OperationPtr op = cl->createOperation(name, returnType, Operation::Nonmutating); - unit->pushContainer(op); - unit->error("keyword `" + name + "' cannot be used as operation name"); - $$ = op; + if(cl) + { + OperationPtr op = cl->createOperation(name, returnType, Operation::Nonmutating); + if(op) + { + unit->pushContainer(op); + unit->error("keyword `" + name + "' cannot be used as operation name"); + $$ = op; + } + else + { + $$ = 0; + } + } + else + { + $$ = 0; + } } | ICE_IDEMPOTENT return_type ICE_KEYWORD_OP { TypePtr returnType = TypePtr::dynamicCast($2); string name = StringTokPtr::dynamicCast($3)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - OperationPtr op = cl->createOperation(name, returnType, Operation::Idempotent); - unit->pushContainer(op); - unit->error("keyword `" + name + "' cannot be used as operation name"); - $$ = op; + if(cl) + { + OperationPtr op = cl->createOperation(name, returnType, Operation::Idempotent); + if(op) + { + unit->pushContainer(op); + unit->error("keyword `" + name + "' cannot be used as operation name"); + $$ = op; + } + else + { + return 0; + } + } + else + { + $$ = 0; + } } ; @@ -732,8 +839,15 @@ operation // ---------------------------------------------------------------------- : operation_preamble parameters ')' { - unit->popContainer(); - $$ = $1; + if($1) + { + unit->popContainer(); + $$ = $1; + } + else + { + $$ = 0; + } } throws { @@ -747,7 +861,10 @@ throws } | operation_preamble error ')' { - unit->popContainer(); + if($1) + { + unit->popContainer(); + } yyerrok; } throws @@ -808,18 +925,28 @@ interface_def ContainerPtr cont = unit->currentContainer(); ClassListTokPtr bases = ClassListTokPtr::dynamicCast($3); ClassDefPtr cl = cont->createClassDef(ident->v, true, bases->v, local->v); - if(!cl) + if(cl) { - YYERROR; // Can't continue, jump to next yyerrok + cont->checkIntroduced(ident->v, cl); + unit->pushContainer(cl); + $$ = cl; + } + else + { + $$ = 0; } - cont->checkIntroduced(ident->v, cl); - unit->pushContainer(cl); - $$ = cl; } '{' interface_exports '}' { - unit->popContainer(); - $$ = $4; + if($4) + { + unit->popContainer(); + $$ = $4; + } + else + { + $$ = 0; + } } ; diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 3f1fd5ec1a5..6aeef20ab46 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -424,6 +424,7 @@ Slice::Container::createModule(const string& name) ContainedList matches = _unit->findContents(thisScope() + name); matches.sort(); // Modules can occur many times... matches.unique(); // ... but we only want one instance of each. + for(ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p) { bool differsOnlyInCase = !_unit->caseSensitive() && matches.front()->name() != name; @@ -438,22 +439,27 @@ Slice::Container::createModule(const string& name) return 0; } } - else if(differsOnlyInCase) + else if(!differsOnlyInCase) { - string msg = "module `" + name + "' differs only in capitalization from "; - msg += matches.front()->kindOf() + " name `" + matches.front()->name() + "'"; + string msg = "redefinition of " + matches.front()->kindOf() + " `" + matches.front()->name(); + msg += "' as module"; _unit->error(msg); return 0; } else { - string msg = "redefinition of " + matches.front()->kindOf() + " `" + matches.front()->name(); - msg += "' as module"; + string msg = "module `" + name + "' differs only in capitalization from "; + msg += matches.front()->kindOf() + " name `" + matches.front()->name() + "'"; _unit->error(msg); return 0; } } + if(!nameIsLegal(name, "module")) + { + return 0; + } + ModulePtr q = new Module(this, name); _contents.push_back(q); return q; @@ -517,6 +523,16 @@ Slice::Container::createClassDef(const string& name, bool intf, const ClassList& return 0; } + if(!nameIsLegal(name, intf ? "interface" : "class")) + { + return 0; + } + + if(!checkForGlobalDef(name, intf ? "interface" : "class")) + { + return 0; + } + ClassDecl::checkBasesAreLegal(name, local, bases, _unit); ClassDefPtr def = new ClassDef(this, name, intf, bases, local); @@ -589,6 +605,16 @@ Slice::Container::createClassDecl(const string& name, bool intf, bool local) } } + if(!nameIsLegal(name, intf ? "interface" : "class")) + { + return 0; + } + + if(!checkForGlobalDef(name, intf ? "interface" : "class")) + { + return 0; + } + // // Multiple declarations are permissible. But if we do already // have a declaration for the class in this container, we don't @@ -608,6 +634,7 @@ Slice::Container::createClassDecl(const string& name, bool intf, bool local) } } + _unit->currentContainer(); ClassDeclPtr decl = new ClassDecl(this, name, intf, local); _contents.push_back(decl); @@ -650,6 +677,10 @@ Slice::Container::createException(const string& name, const ExceptionPtr& base, } } + nameIsLegal(name, "exception"); // Don't return here -- we create the exception anyway + + checkForGlobalDef(name, "exception"); // Don't return here -- we create the exception anyway + // // If this definition is non-local, base cannot be local. // @@ -694,6 +725,10 @@ Slice::Container::createStruct(const string& name, bool local) } } + nameIsLegal(name, "structure"); // Don't return here -- we create the struct anyway. + + checkForGlobalDef(name, "structure"); // Don't return here -- we create the struct anyway. + StructPtr p = new Struct(this, name, local); _contents.push_back(p); return p; @@ -730,6 +765,10 @@ Slice::Container::createSequence(const string& name, const TypePtr& type, bool l } } + nameIsLegal(name, "sequence"); // Don't return here -- we create the sequence anyway. + + checkForGlobalDef(name, "sequence"); // Don't return here -- we create the sequence anyway. + // // If sequence is non-local, element type cannot be local. // @@ -775,6 +814,10 @@ Slice::Container::createDictionary(const string& name, const TypePtr& keyType, c } } + nameIsLegal(name, "dictionary"); // Don't return here -- we create the dictionary anyway. + + checkForGlobalDef(name, "dictionary"); // Don't return here -- we create the dictionary anyway. + if(!Dictionary::legalKeyType(keyType)) { _unit->error("dictionary `" + name + "' uses an illegal key type"); @@ -831,6 +874,10 @@ Slice::Container::createEnum(const string& name, bool local) } } + nameIsLegal(name, "enumeration"); // Don't return here -- we create the enumeration anyway. + + checkForGlobalDef(name, "enumeration"); // Don't return here -- we create the enumeration anyway. + EnumPtr p = new Enum(this, name, local); _contents.push_back(p); return p; @@ -867,6 +914,8 @@ Slice::Container::createEnumerator(const string& name) } } + nameIsLegal(name, "enumerator"); // Don't return here -- we create the enumerator anyway. + EnumeratorPtr p = new Enumerator(this, name); _contents.push_back(p); return p; @@ -904,6 +953,10 @@ Slice::Container::createConst(const string name, const TypePtr& constType, } } + nameIsLegal(name, "constant"); // Don't return here -- we create the constant anyway. + + checkForGlobalDef(name, "constant"); // Don't return here -- we create the constant anyway. + // // Check that the constant type is legal. // @@ -1788,6 +1841,68 @@ Slice::Container::checkIntroduced(const string& scoped, ContainedPtr namedThing) return true; } +bool +Slice::Container::nameIsLegal(const string& newName, const char* newConstruct) +{ + // + // Check whether enclosing module has the same name. + // + if(ModulePtr::dynamicCast(this)) + { + ContainedPtr contained = ContainedPtr::dynamicCast(this); + assert(contained); + if(newName == contained->name()) + { + string msg = newConstruct; + msg += " name `" + newName + "' must differ from the name of its immediately enclosing module"; + _unit->error(msg); + return false; + } + if(!_unit->caseSensitive()) + { + string name = newName; + toLower(name); + string thisName = contained->name(); + toLower(thisName); + if(name == thisName) + { + string msg = newConstruct; + msg += " name `" + name + "' cannot differ only in capitalization from its immediately enclosing " + "module name `" + contained->name() + "'"; + _unit->error(msg); + return false; + } + } + } + return true; +} + +bool +Slice::Container::checkForGlobalDef(const string& name, const char* newConstruct) +{ + if(dynamic_cast<Unit*>(this) && strcmp(newConstruct, "module")) + { + if(_unit->hardErrorForGlobals()) + { + static const string vowels = "aeiou"; + string glottalStop; + if(vowels.find_first_of(newConstruct[0]) != string::npos) + { + glottalStop = "n"; + } + _unit->error("`" + name + "': a" + glottalStop + " " + newConstruct + + " can be defined only at module scope"); + return false; + } + else + { + _unit->warning("`" + name + "': " + newConstruct + " definitions at global scope are deprecated"); + } + return true; + } + return true; +} + Slice::Container::Container(const UnitPtr& unit) : SyntaxTreeBase(unit) { @@ -2106,6 +2221,7 @@ Slice::ClassDecl::ClassDecl(const ContainerPtr& container, const string& name, b Constructed(container, name, local), _interface(intf) { + _unit->currentContainer(); } // @@ -2276,7 +2392,6 @@ Slice::ClassDef::createOperation(const string& name, return 0; } - // // Check whether enclosing interface/class has the same name. // @@ -4803,20 +4918,31 @@ Slice::Unit::usesConsts() const return false; } +bool +Slice::Unit::hardErrorForGlobals() const +{ + return _hardErrorForGlobals; +} + StringList Slice::Unit::includeFiles() const { return _includeFiles; } +// +// TODO: remove third parameter once global definitions are outlawed. +// int -Slice::Unit::parse(FILE* file, bool debug) +Slice::Unit::parse(FILE* file, bool debug, bool hardErrorForGlobals) { slice_debug = debug ? 1 : 0; assert(!Slice::unit); Slice::unit = this; + _hardErrorForGlobals = hardErrorForGlobals; // TODO: remove this once global definitions are outlawed. + _currentComment = ""; _currentLine = 1; _currentIncludeLevel = 0; diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l index 76525a689a5..e80e2e0f753 100644 --- a/cpp/src/Slice/Scanner.l +++ b/cpp/src/Slice/Scanner.l @@ -131,6 +131,22 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e return ICE_SCOPE_DELIMITER; } +"[" { + return ICE_METADATA_OPEN; +} + +"]" { + return ICE_METADATA_CLOSE; +} + +"[[" { + return ICE_GLOBAL_METADATA_OPEN; +} + +"]]" { + return ICE_GLOBAL_METADATA_CLOSE; +} + {identifier}[[:space:]]*"(" { StringTokPtr ident = new StringTok; ident->v = *yytext == '\\' ? yytext + 1 : yytext; diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 24f07363326..1ad5b03a644 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -401,7 +401,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) C << sp << nl << "const ::std::string " << scoped.substr(2) << "::_name = \"" << p->scoped().substr(2) << "\";"; C << sp << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_name() const"; C << sb; - C << nl << "return " << scoped.substr(2) << "::_name;"; + C << nl << "return " << scoped << "::_name;"; C << eb; if(p->isLocal()) @@ -426,7 +426,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) H << sp << nl << "static const ::IceInternal::UserExceptionFactoryPtr& ice_factory();"; C << sp << nl << "const ::IceInternal::UserExceptionFactoryPtr&"; - C << nl << scoped.substr(2) << "::ice_factory()"; + C << nl << scoped << "::ice_factory()"; C << sb; C << nl << "return _factory;"; C << eb; diff --git a/cpp/src/slice2cpp/Main.cpp b/cpp/src/slice2cpp/Main.cpp index 1b554a842e5..8caeb79562e 100644 --- a/cpp/src/slice2cpp/Main.cpp +++ b/cpp/src/slice2cpp/Main.cpp @@ -270,7 +270,7 @@ main(int argc, char* argv[]) } UnitPtr u = Unit::createUnit(false, false, ice, caseSensitive); - int parseStatus = u->parse(cppHandle, debug); + int parseStatus = u->parse(cppHandle, debug, false); if(!icecpp.close()) { diff --git a/cpp/src/slice2docbook/Main.cpp b/cpp/src/slice2docbook/Main.cpp index a48fb324789..11bb946ee98 100644 --- a/cpp/src/slice2docbook/Main.cpp +++ b/cpp/src/slice2docbook/Main.cpp @@ -202,7 +202,7 @@ main(int argc, char* argv[]) return EXIT_FAILURE; } - status = p->parse(cppHandle, debug); + status = p->parse(cppHandle, debug, false); if(!icecpp.close()) { diff --git a/cpp/src/slice2freeze/Main.cpp b/cpp/src/slice2freeze/Main.cpp index 96907c2e5b7..59baaff2c16 100644 --- a/cpp/src/slice2freeze/Main.cpp +++ b/cpp/src/slice2freeze/Main.cpp @@ -825,7 +825,7 @@ main(int argc, char* argv[]) return EXIT_FAILURE; } - status = u->parse(cppHandle, debug); + status = u->parse(cppHandle, debug, false); if(!icecpp.close()) { diff --git a/cpp/src/slice2freezej/Main.cpp b/cpp/src/slice2freezej/Main.cpp index 129e52f0162..4079ba2ed0a 100644 --- a/cpp/src/slice2freezej/Main.cpp +++ b/cpp/src/slice2freezej/Main.cpp @@ -883,7 +883,7 @@ main(int argc, char* argv[]) return EXIT_FAILURE; } - status = u->parse(cppHandle, debug); + status = u->parse(cppHandle, debug, false); if(!icecpp.close()) { diff --git a/cpp/src/slice2java/Main.cpp b/cpp/src/slice2java/Main.cpp index 8676ec64a96..d352dda0e22 100644 --- a/cpp/src/slice2java/Main.cpp +++ b/cpp/src/slice2java/Main.cpp @@ -236,7 +236,7 @@ main(int argc, char* argv[]) } UnitPtr p = Unit::createUnit(false, false, ice, caseSensitive); - int parseStatus = p->parse(cppHandle, debug); + int parseStatus = p->parse(cppHandle, debug, false); if(!icecpp.close()) { |