diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/include/Slice/Parser.h | 22 | ||||
-rw-r--r-- | cpp/src/Slice/Grammar.y | 1 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 140 | ||||
-rw-r--r-- | cpp/src/Slice/Scanner.l | 35 | ||||
-rw-r--r-- | cpp/test/Slice/errorDetection/CaseInsensitive.err | 17 | ||||
-rw-r--r-- | cpp/test/Slice/errorDetection/CaseInsensitive.ice | 25 | ||||
-rw-r--r-- | cpp/test/Slice/errorDetection/DerivedRedefinition.err | 2 | ||||
-rw-r--r-- | cpp/test/Slice/errorDetection/IllegalMI.err | 42 |
8 files changed, 159 insertions, 125 deletions
diff --git a/cpp/include/Slice/Parser.h b/cpp/include/Slice/Parser.h index 63f40f00909..98a1b7cf577 100644 --- a/cpp/include/Slice/Parser.h +++ b/cpp/include/Slice/Parser.h @@ -53,6 +53,7 @@ class Dictionary; class Enum; class Enumerator; class Unit; +class CICompare; typedef ::IceUtil::Handle<GrammarBase> GrammarBasePtr; typedef ::IceUtil::Handle<SyntaxTreeBase> SyntaxTreeBasePtr; @@ -114,9 +115,6 @@ typedef std::list<ContainedPtr> ContainedList; typedef std::list<ModulePtr> ModuleList; typedef std::list<ConstructedPtr> ConstructedList; typedef std::list<ClassDefPtr> ClassList; -typedef std::list<ClassList> GraphPartitionList; // TODO: ML: Can't this be a private typedef for Container? -typedef std::set<std::string> StringSet; -typedef std::list<StringSet> StringSetList; typedef std::list<ExceptionPtr> ExceptionList; typedef std::list<StructPtr> StructList; typedef std::list<SequencePtr> SequenceList; @@ -331,12 +329,15 @@ protected: private: + typedef std::list<ClassList> GraphPartitionList; + typedef std::list<StringList> StringPartitionList; + bool isInList(const GraphPartitionList&, const ClassDefPtr) const; void addPartition(GraphPartitionList&, GraphPartitionList::reverse_iterator, const ClassDefPtr) const; - StringSetList toStringSetList(const GraphPartitionList&) const; - StringList unionOfAllPairIntersections(const StringSetList&) const; + StringPartitionList toStringPartitionList(const GraphPartitionList&) const; + void checkPairIntersections(const StringPartitionList&, const std::string&) const; }; // ---------------------------------------------------------------------- @@ -732,6 +733,17 @@ private: extern SLICE_API Unit* unit; // The current parser for bison/flex +// ---------------------------------------------------------------------- +// CICompare -- function object to do case-insensitive string comparison. +// ---------------------------------------------------------------------- + +class CICompare : public std::binary_function<std::string, std::string, bool> +{ +public: + + bool operator()(const std::string&, const std::string&) const; +}; + } #endif diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y index a174999bff9..0a04428c39c 100644 --- a/cpp/src/Slice/Grammar.y +++ b/cpp/src/Slice/Grammar.y @@ -797,6 +797,7 @@ exception // ML: Not sure if these should be treated as builtin by the // parser. They have no meaning in a Slice definition, so why make // them builtin, if they cannot be used anywhere in Slice? +// MH: Agree -- I don't think anything needs doing here. : scoped_name { StringTokPtr scoped = StringTokPtr::dynamicCast($1); diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 838a56c338e..da052a6aa36 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -326,31 +326,14 @@ Slice::Container::createClassDef(const string& name, bool intf, const ClassList& // set containing the names of operations and data members defined in // the classes in each partition. // - StringSetList spl = toStringSetList(gpl); + StringPartitionList spl = toStringPartitionList(gpl); // // Multiple inheritance is legal if no two partitions contain a common // name (that is, if the union of the intersections of all possible pairs - // of partitions is empty. - // - StringList clashes = unionOfAllPairIntersections(spl); - - // - // The strings in the clashes list are those operations or data members - // that prevent the multiple inheritance hierarchies about to the - // current class to be joined. - // - for(StringList::const_iterator q = clashes.begin(); q != clashes.end(); ++q) - { - string msg = "ambiguous multiple inheritance: `"; - msg += *q + "' is defined in two or more base classes"; - _unit->error(msg); - } - // - // We do *not* return 0 here; otherwise, we get lots of spurious - // "Parse error" messsages and end up with lots of follow-up errors - // about this class not being defined. + // of partitions is empty). // + checkPairIntersections(spl, name); } ClassDefPtr def = new ClassDef(this, name, intf, bases, local); @@ -1347,28 +1330,23 @@ Slice::Container::addPartition(GraphPartitionList& gpl, // // Convert the list of partitions of class definitions into a -// list of sets, with each set containing the operation and member -// names defined by the classes in each partition. +// list of lists, with each member list containing the operation +// names defined by the interfaces in each partition. // -StringSetList -Slice::Container::toStringSetList(const GraphPartitionList& gpl) const +Slice::Container::StringPartitionList +Slice::Container::toStringPartitionList(const GraphPartitionList& gpl) const { - StringSetList spl; + StringPartitionList spl; for(GraphPartitionList::const_iterator i = gpl.begin(); i != gpl.end(); ++i) { - StringSet ss; - spl.push_back(ss); + StringList sl; + spl.push_back(sl); for(ClassList::const_iterator j = i->begin(); j != i->end(); ++j) { OperationList operations = (*j)->operations(); - DataMemberList members = (*j)->dataMembers(); for(OperationList::const_iterator l = operations.begin(); l != operations.end(); ++l) { - spl.rbegin()->insert((*l)->name()); - } - for(DataMemberList::const_iterator m = members.begin(); m != members.end(); ++m) - { - spl.rbegin()->insert((*m)->name()); + spl.rbegin()->push_back((*l)->name()); } } } @@ -1376,24 +1354,44 @@ Slice::Container::toStringSetList(const GraphPartitionList& gpl) const } // -// Return the union of the intersections of all possible pairs of sets of strings. +// For all (unique) pairs of string lists, check whether an identifier in one list occurs +// in the other and, if so, complain. // -StringList -Slice::Container::unionOfAllPairIntersections(const StringSetList& l) const +void +Slice::Container::checkPairIntersections(const StringPartitionList& l, const string& name) const { - StringList result; - for(StringSetList::const_iterator i = l.begin(); i != l.end(); ++i) + set<string> reported; + for(StringPartitionList::const_iterator i = l.begin(); i != l.end(); ++i) { - StringSetList::const_iterator cursor = i; + StringPartitionList::const_iterator cursor = i; ++cursor; - for(StringSetList::const_iterator j = cursor; j != l.end(); ++j) + for(StringPartitionList::const_iterator j = cursor; j != l.end(); ++j) { - set_intersection(i->begin(), i->end(), j->begin(), j->end(), back_inserter(result)); + for(StringList::const_iterator s1 = i->begin(); s1 != i->end(); ++s1) + { + for (StringList::const_iterator s2 = j->begin(); s2 != j->end(); ++s2) + { + if((*s1) == (*s2) && reported.find(*s1) == reported.end()) + { + string msg = "ambiguous multiple inheritance: `" + name; + msg += "' inherits operation `" + *s1 + "' from two or more unrelated base interfaces"; + _unit->error(msg); + reported.insert(*s1); + } + else if(!CICompare()(*s1, *s2) && !CICompare()(*s2, *s1) && + reported.find(*s1) == reported.end() && reported.find(*s2) == reported.end()) + { + string msg = "ambiguous multiple inheritance: `" + name; + msg += "' inherits operations `" + *s1 + "' and `" + *s2; + msg += "', which differ only in capitalization, from unrelated base interfaces"; + _unit->error(msg); + reported.insert(*s1); + reported.insert(*s2); + } + } + } } } - result.sort(); - result.unique(); - return result; } // ---------------------------------------------------------------------- @@ -1412,7 +1410,7 @@ Slice::Module::uses(const ContainedPtr&) const return false; } -std::string +string Slice::Module::kindOf() const { return "module"; @@ -1501,7 +1499,7 @@ Slice::ClassDecl::uses(const ContainedPtr&) const return false; } -std::string +string Slice::ClassDecl::kindOf() const { string s = _interface ? "interface" : "class"; @@ -1927,7 +1925,7 @@ Slice::ClassDef::uses(const ContainedPtr&) const return false; } -std::string +string Slice::ClassDef::kindOf() const { string s; @@ -2142,7 +2140,7 @@ Slice::Exception::uses(const ContainedPtr&) const return false; } -std::string +string Slice::Exception::kindOf() const { return "exception"; @@ -2268,7 +2266,7 @@ Slice::Struct::uses(const ContainedPtr&) const return false; } -std::string +string Slice::Struct::kindOf() const { return "struct"; @@ -2332,7 +2330,7 @@ Slice::Sequence::uses(const ContainedPtr& contained) const return false; } -std::string +string Slice::Sequence::kindOf() const { return "sequence"; @@ -2408,7 +2406,7 @@ Slice::Dictionary::uses(const ContainedPtr& contained) const return false; } -std::string +string Slice::Dictionary::kindOf() const { return "dictionary"; @@ -2481,7 +2479,7 @@ Slice::Enum::uses(const ContainedPtr&) const return false; } -std::string +string Slice::Enum::kindOf() const { return "enumeration"; @@ -2523,7 +2521,7 @@ Slice::Enumerator::uses(const ContainedPtr&) const return false; } -std::string +string Slice::Enumerator::kindOf() const { return "enumerator"; @@ -2614,7 +2612,7 @@ Slice::Operation::uses(const ContainedPtr& contained) const return false; } -std::string +string Slice::Operation::kindOf() const { return "operation"; @@ -2666,7 +2664,7 @@ Slice::DataMember::uses(const ContainedPtr& contained) const return false; } -std::string +string Slice::DataMember::kindOf() const { return "data member"; @@ -3151,3 +3149,35 @@ Slice::Unit::Unit(bool ignRedefs, bool all) : { _unit = this; } + +// ---------------------------------------------------------------------- +// CICompare +// ---------------------------------------------------------------------- + +bool +Slice::CICompare::operator()(const string& s1, const string& s2) const +{ + string::const_iterator p1 = s1.begin(); + string::const_iterator p2 = s2.begin(); + while(p1 != s1.end() && p2 != s2.end() && tolower(*p1) == tolower(*p2)) + { + ++p1; + ++p2; + } + if(p1 == s1.end() && p2 == s2.end()) + { + return false; + } + else if(p1 == s1.end()) + { + return true; + } + else if(p2 == s2.end()) + { + return false; + } + else + { + return tolower(*p1) < tolower(*p2); + } +}; diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l index f37fbc5a00b..0e0b878b21a 100644 --- a/cpp/src/Slice/Scanner.l +++ b/cpp/src/Slice/Scanner.l @@ -20,42 +20,9 @@ namespace Slice { // -// Function object to do case-insensitive string comparison. -// -struct CICompare : public std::binary_function<std::string, std::string, bool> -{ - bool operator()(const std::string& s1, const std::string& s2) const - { - std::string::const_iterator p1 = s1.begin(); - std::string::const_iterator p2 = s2.begin(); - while(p1 != s1.end() && p2 != s2.end() && tolower(*p1) == tolower(*p2)) - { - ++p1; - ++p2; - } - if(p1 == s1.end() && p2 == s2.end()) - { - return false; - } - else if(p1 == s1.end()) - { - return true; - } - else if(p2 == s2.end()) - { - return false; - } - else - { - return tolower(*p1) < tolower(*p2); - } - } -}; - -// // Definitions for the case-insensitive keyword-token map. // -typedef std::map<std::string, int, CICompare> StringTokenMap; +typedef std::map<std::string, int, Slice::CICompare> StringTokenMap; static StringTokenMap keywordMap; void Slice::initScanner(); diff --git a/cpp/test/Slice/errorDetection/CaseInsensitive.err b/cpp/test/Slice/errorDetection/CaseInsensitive.err index 3ddfd52ac60..79b565554f1 100644 --- a/cpp/test/Slice/errorDetection/CaseInsensitive.err +++ b/cpp/test/Slice/errorDetection/CaseInsensitive.err @@ -44,10 +44,13 @@ CaseInsensitive.ice:157: redefinition of enumeration `en1' as enumerator CaseInsensitive.ice:158: warning: enumerator `EN1' differs only in capitalization from enumeration `en1' CaseInsensitive.ice:159: redefinition of module `m1' as enumerator CaseInsensitive.ice:160: warning: enumerator `M1' differs only in capitalization from module `m1' -CaseInsensitive.ice:170: warning: type name `base' is capitalized inconsistently with its previous name: `::xxx::xx::Base' -CaseInsensitive.ice:170: redefinition of interface `Derived' -CaseInsensitive.ice:174: warning: exception name `E1' is capitalized inconsistently with its previous name: `::xxx::xx::e1' -CaseInsensitive.ice:178: warning: type name `S1' is capitalized inconsistently with its previous name: `::xxx::xx::s1' -CaseInsensitive.ice:179: `xx::S1' is not defined -CaseInsensitive.ice:180: warning: type name `XX::s1' is capitalized inconsistently with its previous name: `::xxx::xx::s1' -CaseInsensitive.ice:185: warning: type name `derived' is capitalized inconsistently with its previous name: `::xxx::xx::Derived' +CaseInsensitive.ice:172: warning: type name `base' is capitalized inconsistently with its previous name: `::xxx::xx::Base' +CaseInsensitive.ice:172: redefinition of interface `Derived' +CaseInsensitive.ice:176: warning: exception name `E1' is capitalized inconsistently with its previous name: `::xxx::xx::e1' +CaseInsensitive.ice:180: warning: type name `S1' is capitalized inconsistently with its previous name: `::xxx::xx::s1' +CaseInsensitive.ice:181: `xx::S1' is not defined +CaseInsensitive.ice:182: warning: type name `XX::s1' is capitalized inconsistently with its previous name: `::xxx::xx::s1' +CaseInsensitive.ice:187: warning: type name `derived' is capitalized inconsistently with its previous name: `::xxx::xx::Derived' +CaseInsensitive.ice:195: warning: parameter `param' differs only in capitalization from parameter `Param' +CaseInsensitive.ice:197: warning: exception name `E1' is capitalized inconsistently with its previous name: `::e1' +CaseInsensitive.ice:210: ambiguous multiple inheritance: `derived' inherits operations `op' and `OP', which differ only in capitalization, from unrelated base interfaces diff --git a/cpp/test/Slice/errorDetection/CaseInsensitive.ice b/cpp/test/Slice/errorDetection/CaseInsensitive.ice index 7330da156ea..8647c3a6125 100644 --- a/cpp/test/Slice/errorDetection/CaseInsensitive.ice +++ b/cpp/test/Slice/errorDetection/CaseInsensitive.ice @@ -159,9 +159,11 @@ enum en3 { EN1 }; enum en4 { m1 }; enum en5 { M1 }; -module xxx { +module xxx +{ -module xx { +module xx +{ interface Base { void op(); }; @@ -188,3 +190,22 @@ struct s2 { }; }; + +interface Foo { + void op(long param, string Param); + void op2() throws e1; + void op3() throws E1; +}; + +module CI +{ + interface base1 { + void op(); + }; + + interface base2 { + void OP(); + }; + + interface derived extends base1, base2 {}; +}; diff --git a/cpp/test/Slice/errorDetection/DerivedRedefinition.err b/cpp/test/Slice/errorDetection/DerivedRedefinition.err index 7d1ebbb7e61..3d0e0e7d1d4 100644 --- a/cpp/test/Slice/errorDetection/DerivedRedefinition.err +++ b/cpp/test/Slice/errorDetection/DerivedRedefinition.err @@ -1,6 +1,6 @@ DerivedRedefinition.ice:17: operation `op' is already defined as an operation in a base interface or class DerivedRedefinition.ice:18: operation `op' is already defined as an operation in a base interface or class DerivedRedefinition.ice:31: operation `op' is already defined as an operation in a base interface or class -DerivedRedefinition.ice:34: ambiguous multiple inheritance: `op' is defined in two or more base classes +DerivedRedefinition.ice:34: ambiguous multiple inheritance: `D3' inherits operation `op' from two or more unrelated base interfaces DerivedRedefinition.ice:39: data member `l' is already defined as a data member in a base interface or class DerivedRedefinition.ice:41: data member `l' is already defined as a data member in a base interface or class diff --git a/cpp/test/Slice/errorDetection/IllegalMI.err b/cpp/test/Slice/errorDetection/IllegalMI.err index 1dc9b23f572..c88c80811fd 100644 --- a/cpp/test/Slice/errorDetection/IllegalMI.err +++ b/cpp/test/Slice/errorDetection/IllegalMI.err @@ -1,26 +1,26 @@ -IllegalMI.ice:46: ambiguous multiple inheritance: `op' is defined in two or more base classes +IllegalMI.ice:46: ambiguous multiple inheritance: `A3' inherits operation `op' from two or more unrelated base interfaces IllegalMI.ice:69: operation `op' is already defined as an operation in a base interface or class IllegalMI.ice:91: operation `op' is already defined as an operation in a base interface or class IllegalMI.ice:113: operation `op' is already defined as an operation in a base interface or class -IllegalMI.ice:154: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:176: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:198: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:221: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:271: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:297: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:323: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:349: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:375: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:401: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:428: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:455: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:482: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:509: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:537: ambiguous multiple inheritance: `op' is defined in two or more base classes +IllegalMI.ice:154: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:176: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:198: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:221: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:271: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:297: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:323: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:349: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:375: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:401: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:428: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:455: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:482: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:509: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:537: ambiguous multiple inheritance: `A2' inherits operation `op' from two or more unrelated base interfaces IllegalMI.ice:604: operation `op' is already defined as an operation in a base interface or class IllegalMI.ice:638: operation `op' is already defined as an operation in a base interface or class -IllegalMI.ice:759: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:820: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:881: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:940: ambiguous multiple inheritance: `op' is defined in two or more base classes -IllegalMI.ice:999: ambiguous multiple inheritance: `op' is defined in two or more base classes +IllegalMI.ice:759: ambiguous multiple inheritance: `A4' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:820: ambiguous multiple inheritance: `A4' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:881: ambiguous multiple inheritance: `A4' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:940: ambiguous multiple inheritance: `A4' inherits operation `op' from two or more unrelated base interfaces +IllegalMI.ice:999: ambiguous multiple inheritance: `A4' inherits operation `op' from two or more unrelated base interfaces |