summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2002-06-24 07:57:54 +0000
committerMichi Henning <michi@zeroc.com>2002-06-24 07:57:54 +0000
commit34a3242a1305c74b6d114c987341ed8eaa9c6840 (patch)
treee553ebd78e1ac6270ea31f9a5a1faf5027a08cf6
parentremoved spaces after keywords (diff)
downloadice-34a3242a1305c74b6d114c987341ed8eaa9c6840.tar.bz2
ice-34a3242a1305c74b6d114c987341ed8eaa9c6840.tar.xz
ice-34a3242a1305c74b6d114c987341ed8eaa9c6840.zip
Added checks to disallow definition of a name in a derived class/interface
if that name is already defined in one of the base classes/interfaces. Added checks to disallow ambiguous multiple inheritance. The following (and many variations thereof) is illegal: interface A { void op(); }; interface B { long op(string s); }; interface C { void op(); }; interface D1 extends A, B { // Ambiguous multiple inheritance // ... }; interface D2 extends A, C { // Ambiguous multiple inheritance // ... }; Someone checked in a DOS-line ending file for Parser.h and Parser.cpp, so the CVS up-to-date check failed and the diff obviously produced a lot of noise. I think I merged everything correctly. There were a few places where the style had changed, from "if(..." to "if (..." (and similar for "while(...", and "for(...". The style guide says to use a space before the parenthesis, so that's how I left things.
-rw-r--r--cpp/include/Slice/Parser.h1435
-rw-r--r--cpp/src/Slice/Grammar.y16
-rw-r--r--cpp/src/Slice/Parser.cpp685
-rw-r--r--cpp/test/Slice/errorDetection/DerivedRedefinition.err6
-rw-r--r--cpp/test/Slice/errorDetection/DerivedRedefinition.ice41
-rw-r--r--cpp/test/Slice/errorDetection/IllegalMI.err26
-rw-r--r--cpp/test/Slice/errorDetection/IllegalMI.ice1002
7 files changed, 2248 insertions, 963 deletions
diff --git a/cpp/include/Slice/Parser.h b/cpp/include/Slice/Parser.h
index 568c05fd288..de7af8f4e6e 100644
--- a/cpp/include/Slice/Parser.h
+++ b/cpp/include/Slice/Parser.h
@@ -1,711 +1,724 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#ifndef SLICE_PARSER_H
-#define SLICE_PARSER_H
-
-#include <IceUtil/Shared.h>
-#include <IceUtil/Handle.h>
-#include <string>
-#include <vector>
-#include <list>
-#include <stack>
-#include <map>
-#include <set>
-
-#ifdef _WIN32
-# ifdef SLICE_API_EXPORTS
-# define SLICE_API __declspec(dllexport)
-# else
-# define SLICE_API __declspec(dllimport)
-# endif
-#else
-# define SLICE_API /**/
-#endif
-
-namespace Slice
-{
-
-class GrammarBase;
-class SyntaxTreeBase;
-class Type;
-class Builtin;
-class Contained;
-class Container;
-class Module;
-class Constructed;
-class ClassDecl;
-class ClassDef;
-class Proxy;
-class Exception;
-class Struct;
-class Operation;
-class DataMember;
-class Sequence;
-class Dictionary;
-class Enum;
-class Enumerator;
-class Unit;
-
-typedef ::IceUtil::Handle<GrammarBase> GrammarBasePtr;
-typedef ::IceUtil::Handle<SyntaxTreeBase> SyntaxTreeBasePtr;
-typedef ::IceUtil::Handle<Type> TypePtr;
-typedef ::IceUtil::Handle<Builtin> BuiltinPtr;
-typedef ::IceUtil::Handle<Contained> ContainedPtr;
-typedef ::IceUtil::Handle<Container> ContainerPtr;
-typedef ::IceUtil::Handle<Module> ModulePtr;
-typedef ::IceUtil::Handle<Constructed> ConstructedPtr;
-typedef ::IceUtil::Handle<ClassDecl> ClassDeclPtr;
-typedef ::IceUtil::Handle<ClassDef> ClassDefPtr;
-typedef ::IceUtil::Handle<Proxy> ProxyPtr;
-typedef ::IceUtil::Handle<Exception> ExceptionPtr;
-typedef ::IceUtil::Handle<Struct> StructPtr;
-typedef ::IceUtil::Handle<Operation> OperationPtr;
-typedef ::IceUtil::Handle<DataMember> DataMemberPtr;
-typedef ::IceUtil::Handle<Sequence> SequencePtr;
-typedef ::IceUtil::Handle<Dictionary> DictionaryPtr;
-typedef ::IceUtil::Handle<Enum> EnumPtr;
-typedef ::IceUtil::Handle<Enumerator> EnumeratorPtr;
-typedef ::IceUtil::Handle<Unit> UnitPtr;
-
-}
-
-//
-// Stuff for flex and bison
-//
-
-#define YYSTYPE Slice::GrammarBasePtr
-#define YY_DECL int yylex(YYSTYPE* yylvalp)
-YY_DECL;
-int yyparse();
-
-//
-// I must set the initial stack depth to the maximum stack depth to
-// disable bison stack resizing. The bison stack resizing routines use
-// simple malloc/alloc/memcpy calls, which do not work for the
-// YYSTYPE, since YYSTYPE is a C++ type, with constructor, destructor,
-// assignment operator, etc.
-//
-#define YYMAXDEPTH 20000 // 20000 should suffice. Bison default is 10000 as maximum.
-#define YYINITDEPTH YYMAXDEPTH // Initial depth is set to max depth, for the reasons described above.
-
-//
-// Newer bison versions allow to disable stack resizing by defining
-// yyoverflow.
-//
-#define yyoverflow(a, b, c, d, e, f) yyerror(a)
-
-namespace Slice
-{
-
-typedef std::list<TypePtr> TypeList;
-typedef std::list<ExceptionPtr> ExceptionList;
-typedef std::list<std::string> StringList;
-typedef std::pair<TypePtr, std::string> TypeString;
-typedef std::list<TypeString> TypeStringList;
-typedef std::list<ContainedPtr> ContainedList;
-typedef std::list<ModulePtr> ModuleList;
-typedef std::list<ConstructedPtr> ConstructedList;
-typedef std::list<ClassDefPtr> ClassList;
-typedef std::list<ExceptionPtr> ExceptionList;
-typedef std::list<StructPtr> StructList;
-typedef std::list<SequencePtr> SequenceList;
-typedef std::list<DictionaryPtr> DictionaryList;
-typedef std::list<EnumPtr> EnumList;
-typedef std::list<OperationPtr> OperationList;
-typedef std::list<DataMemberPtr> DataMemberList;
-typedef std::list<EnumeratorPtr> EnumeratorList;
-
-// ----------------------------------------------------------------------
-// ParserVisitor
-// ----------------------------------------------------------------------
-
-class SLICE_API ParserVisitor
-{
-public:
-
- virtual ~ParserVisitor() { }
- virtual bool visitUnitStart(const UnitPtr&) { return true; }
- virtual void visitUnitEnd(const UnitPtr&) { }
- virtual bool visitModuleStart(const ModulePtr&) { return true; }
- virtual void visitModuleEnd(const ModulePtr&) { }
- virtual void visitClassDecl(const ClassDeclPtr&) { }
- virtual bool visitClassDefStart(const ClassDefPtr&) { return true; }
- virtual void visitClassDefEnd(const ClassDefPtr&) { }
- virtual bool visitExceptionStart(const ExceptionPtr&) { return true; }
- virtual void visitExceptionEnd(const ExceptionPtr&) { }
- virtual bool visitStructStart(const StructPtr&) { return true; }
- virtual void visitStructEnd(const StructPtr&) { }
- virtual void visitOperation(const OperationPtr&) { }
- virtual void visitDataMember(const DataMemberPtr&) { }
- virtual void visitSequence(const SequencePtr&) { }
- virtual void visitDictionary(const DictionaryPtr&) { }
- virtual void visitEnum(const EnumPtr&) { }
-};
-
-// ----------------------------------------------------------------------
-// GrammarBase
-// ----------------------------------------------------------------------
-
-class SLICE_API GrammarBase : public ::IceUtil::SimpleShared
-{
-};
-
-// ----------------------------------------------------------------------
-// SyntaxTreeBase
-// ----------------------------------------------------------------------
-
-class SLICE_API SyntaxTreeBase : public GrammarBase
-{
-public:
-
- virtual void destroy();
- UnitPtr unit();
- virtual void visit(ParserVisitor*);
-
-protected:
-
- SyntaxTreeBase(const UnitPtr&);
-
- UnitPtr _unit;
-};
-
-// ----------------------------------------------------------------------
-// Type
-// ----------------------------------------------------------------------
-
-class SLICE_API Type : virtual public SyntaxTreeBase
-{
-public:
-
-protected:
-
- Type(const UnitPtr&);
-};
-
-// ----------------------------------------------------------------------
-// Builtin
-// ----------------------------------------------------------------------
-
-class SLICE_API Builtin : virtual public Type
-{
-public:
-
- enum Kind
- {
- KindByte,
- KindBool,
- KindShort,
- KindInt,
- KindLong,
- KindFloat,
- KindDouble,
- KindString,
- KindObject,
- KindObjectProxy,
- KindLocalObject
- };
- Kind kind();
-
-protected:
-
- Builtin(const UnitPtr&, Kind);
- friend class SLICE_API Unit;
-
- Kind _kind;
-};
-
-// ----------------------------------------------------------------------
-// Contained
-// ----------------------------------------------------------------------
-
-class SLICE_API Contained : virtual public SyntaxTreeBase
-{
-public:
-
- ContainerPtr container();
- std::string name();
- std::string scoped();
- std::string scope();
- std::string file();
- std::string comment();
-
- int includeLevel();
- void updateIncludeLevel();
-
- std::list<std::string> getMetaData();
- void setMetaData(const std::list<std::string>&);
-
- enum ContainedType
- {
- ContainedTypeSequence,
- ContainedTypeDictionary,
- ContainedTypeEnum,
- ContainedTypeEnumerator,
- ContainedTypeModule,
- ContainedTypeClass,
- ContainedTypeException,
- ContainedTypeStruct,
- ContainedTypeOperation,
- ContainedTypeDataMember
- };
- virtual ContainedType containedType() = 0;
-
- virtual bool uses(const ContainedPtr&) = 0;
-
- bool operator<(const Contained&) const;
- bool operator==(const Contained&) const;
-
-protected:
-
- Contained(const ContainerPtr&, const std::string&);
- friend class SLICE_API Container;
-
- ContainerPtr _container;
- std::string _name;
- std::string _scoped;
- std::string _file;
- std::string _comment;
- int _includeLevel;
- std::list<std::string> _metaData;
-};
-
-// ----------------------------------------------------------------------
-// Container
-// ----------------------------------------------------------------------
-
-class SLICE_API Container : virtual public SyntaxTreeBase
-{
-public:
-
- virtual void destroy();
- ModulePtr createModule(const std::string&);
- ClassDefPtr createClassDef(const std::string&, bool, const ClassList&, bool);
- ClassDeclPtr createClassDecl(const std::string&, bool, bool);
- ExceptionPtr createException(const std::string&, const ExceptionPtr&, bool);
- StructPtr createStruct(const std::string&, bool);
- SequencePtr createSequence(const std::string&, const TypePtr&, bool);
- DictionaryPtr createDictionary(const std::string&, const TypePtr&, const TypePtr&, bool);
- EnumPtr createEnum(const std::string&, bool);
- EnumeratorPtr createEnumerator(const std::string&);
- TypeList lookupType(const std::string&, bool = true);
- TypeList lookupTypeNoBuiltin(const std::string&, bool = true);
- ContainedList lookupContained(const std::string&, bool = true);
- ExceptionPtr lookupException(const std::string&, bool = true);
- ModuleList modules();
- ClassList classes();
- ExceptionList exceptions();
- StructList structs();
- SequenceList sequences();
- DictionaryList dictionaries();
- EnumList enums();
- bool hasNonLocalClassDecls();
- bool hasClassDecls();
- bool hasClassDefs();
- bool hasOtherConstructedOrExceptions(); // Exceptions or constructed types other than classes.
- std::string thisScope();
- void mergeModules();
- void sort();
- void sortContents();
- virtual void visit(ParserVisitor*);
- void containerRecDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
-
-protected:
-
- Container(const UnitPtr&);
-
- bool checkInterfaceAndLocal(const std::string&, bool, bool, bool, bool, bool);
-
- ContainedList _contents;
-};
-
-// ----------------------------------------------------------------------
-// Module
-// ----------------------------------------------------------------------
-
-class SLICE_API Module : virtual public Container, virtual public Contained
-{
-public:
-
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
-
-protected:
-
- Module(const ContainerPtr&, const std::string&);
- friend class SLICE_API Container;
-};
-
-// ----------------------------------------------------------------------
-// Constructed
-// ----------------------------------------------------------------------
-
-class SLICE_API Constructed : virtual public Type, virtual public Contained
-{
-public:
-
- bool isLocal();
- ConstructedList dependencies();
- virtual void recDependencies(std::set<ConstructedPtr>&) = 0; // Internal operation, don't use directly.
-
-protected:
-
- Constructed(const ContainerPtr&, const std::string&, bool);
-
- bool _local;
-};
-
-// ----------------------------------------------------------------------
-// ClassDecl
-// ----------------------------------------------------------------------
-
-class SLICE_API ClassDecl : virtual public Constructed
-{
-public:
-
- virtual void destroy();
- ClassDefPtr definition();
- bool isInterface();
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
- virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
-
-protected:
-
- ClassDecl(const ContainerPtr&, const std::string&, bool, bool);
- friend class SLICE_API Container;
- friend class SLICE_API ClassDef;
-
- ClassDefPtr _definition;
- bool _interface;
-};
-
-// ----------------------------------------------------------------------
-// ClassDef
-// ----------------------------------------------------------------------
-
-//
-// Note: For the purpose of this parser, a class definition is not
-// considered to be a type, but a class declaration is. And each class
-// definition has at least one class declaration (but not vice versa),
-// so if you need the class as a "constructed type", use the
-// declaration() operation to navigate to the class declaration.
-//
-class SLICE_API ClassDef : virtual public Container, virtual public Contained
-{
-public:
-
- virtual void destroy();
- OperationPtr createOperation(const std::string&, const TypePtr&, const TypeStringList&, const TypeStringList&,
- const ExceptionList&);
- DataMemberPtr createDataMember(const std::string&, const TypePtr&);
- ClassDeclPtr declaration();
- ClassList bases();
- ClassList allBases();
- OperationList operations();
- OperationList allOperations();
- DataMemberList dataMembers();
- bool isAbstract();
- bool isInterface();
- bool isLocal();
- bool hasDataMembers();
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
-
-protected:
-
- ClassDef(const ContainerPtr&, const std::string&, bool, const ClassList&, bool);
- friend class SLICE_API Container;
-
- ClassDeclPtr _declaration;
- bool _interface;
- bool _hasDataMembers;
- ClassList _bases;
- bool _local;
-};
-
-// ----------------------------------------------------------------------
-// Proxy
-// ----------------------------------------------------------------------
-
-class SLICE_API Proxy : virtual public Type
-{
-public:
-
- ClassDeclPtr _class();
-
- Proxy(const ClassDeclPtr&);
-
-protected:
-
- ClassDeclPtr __class;
-};
-
-// ----------------------------------------------------------------------
-// Exception
-// ----------------------------------------------------------------------
-
-// No inheritance from Constructed, as this is not a Type
-class SLICE_API Exception : virtual public Container, virtual public Contained
-{
-public:
-
- virtual void destroy();
- DataMemberPtr createDataMember(const std::string&, const TypePtr&);
- DataMemberList dataMembers();
- ExceptionPtr base();
- ExceptionList allBases();
- bool isLocal();
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
-
-protected:
-
- Exception(const ContainerPtr&, const std::string&, const ExceptionPtr&, bool);
- friend class SLICE_API Container;
-
- ExceptionPtr _base;
- bool _local;
-};
-
-// ----------------------------------------------------------------------
-// Struct
-// ----------------------------------------------------------------------
-
-class SLICE_API Struct : virtual public Container, virtual public Constructed
-{
-public:
-
- DataMemberPtr createDataMember(const std::string&, const TypePtr&);
- DataMemberList dataMembers();
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
- virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
-
-protected:
-
- Struct(const ContainerPtr&, const std::string&, bool);
- friend class SLICE_API Container;
-};
-
-// ----------------------------------------------------------------------
-// Sequence
-// ----------------------------------------------------------------------
-
-class SLICE_API Sequence : virtual public Constructed
-{
-public:
-
- TypePtr type();
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
- virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
-
-protected:
-
- Sequence(const ContainerPtr&, const std::string&, const TypePtr&, bool);
- friend class SLICE_API Container;
-
- TypePtr _type;
-};
-
-// ----------------------------------------------------------------------
-// Dictionary
-// ----------------------------------------------------------------------
-
-class SLICE_API Dictionary : virtual public Constructed
-{
-public:
-
- TypePtr keyType();
- TypePtr valueType();
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
- virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
-
-protected:
-
- Dictionary(const ContainerPtr&, const std::string&, const TypePtr&, const TypePtr&, bool);
- friend class SLICE_API Container;
-
- TypePtr _keyType;
- TypePtr _valueType;
-};
-
-// ----------------------------------------------------------------------
-// Enum
-// ----------------------------------------------------------------------
-
-class SLICE_API Enum : virtual public Constructed
-{
-public:
-
- EnumeratorList getEnumerators();
- void setEnumerators(const EnumeratorList&);
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
- virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
-
-protected:
-
- Enum(const ContainerPtr&, const std::string&, bool);
- friend class SLICE_API Container;
-
- EnumeratorList _enumerators;
-};
-
-// ----------------------------------------------------------------------
-// Enumerator
-// ----------------------------------------------------------------------
-
-class SLICE_API Enumerator : virtual public Contained
-{
-public:
-
- virtual bool uses(const ContainedPtr&);
- virtual ContainedType containedType();
-
-protected:
-
- Enumerator(const ContainerPtr&, const std::string&);
- friend class SLICE_API Container;
-};
-
-// ----------------------------------------------------------------------
-// Operation
-// ----------------------------------------------------------------------
-
-class SLICE_API Operation : virtual public Contained
-{
-public:
-
- TypePtr returnType();
- TypeStringList inputParameters();
- TypeStringList outputParameters();
- ExceptionList throws();
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
-
-protected:
-
- Operation(const ContainerPtr&, const std::string&, const TypePtr&, const TypeStringList&, const TypeStringList&,
- const ExceptionList&);
- friend class SLICE_API ClassDef;
-
- TypePtr _returnType;
- TypeStringList _inParams;
- TypeStringList _outParams;
- ExceptionList _throws;
-};
-
-// ----------------------------------------------------------------------
-// DataMember
-// ----------------------------------------------------------------------
-
-class SLICE_API DataMember : virtual public Contained
-{
-public:
-
- TypePtr type();
- virtual ContainedType containedType();
- virtual bool uses(const ContainedPtr&);
- virtual void visit(ParserVisitor*);
-
-protected:
-
- DataMember(const ContainerPtr&, const std::string&, const TypePtr&);
- friend class SLICE_API ClassDef;
- friend class SLICE_API Struct;
- friend class SLICE_API Exception;
-
- TypePtr _type;
-};
-
-// ----------------------------------------------------------------------
-// Unit
-// ----------------------------------------------------------------------
-
-class SLICE_API Unit : virtual public Container
-{
-public:
-
- static UnitPtr createUnit(bool, bool);
-
- bool ignRedefs();
-
- void setComment(const std::string&);
- std::string currentComment();
- std::string currentFile();
-
- void nextLine();
- void scanPosition(const char*);
- int currentIncludeLevel();
-
- void error(const char*);
- void error(const std::string&);
-
- void warning(const char*);
- void warning(const std::string&);
-
- ContainerPtr currentContainer();
- void pushContainer(const ContainerPtr&);
- void popContainer();
-
- void addContent(const ContainedPtr&);
- void removeContent(const ContainedPtr&);
- ContainedList findContents(const std::string&);
- ClassList findDerivedClasses(const ClassDefPtr&);
- ExceptionList findDerivedExceptions(const ExceptionPtr&);
- ContainedList findUsedBy(const ContainedPtr&);
-
- bool usesProxies();
- bool usesNonLocals();
-
- StringList includeFiles();
-
- int parse(FILE*, bool);
-
- virtual void destroy();
- virtual void visit(ParserVisitor*);
-
- BuiltinPtr builtin(Builtin::Kind);
-
-private:
-
- Unit(bool, bool);
-
- bool _ignRedefs;
- bool _all;
- int _errors;
- std::string _currentComment;
- int _currentLine;
- int _currentIncludeLevel;
- std::string _currentFile;
- std::string _topLevelFile;
- StringList _includeFiles;
- std::stack<ContainerPtr> _containerStack;
- std::map<Builtin::Kind, BuiltinPtr> _builtins;
- std::map<std::string, ContainedList > _contentMap;
-};
-
-extern SLICE_API Unit* unit; // The current parser for bison/flex
-
-}
-
-#endif
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef SLICE_PARSER_H
+#define SLICE_PARSER_H
+
+#include <IceUtil/Shared.h>
+#include <IceUtil/Handle.h>
+#include <string>
+#include <vector>
+#include <list>
+#include <stack>
+#include <map>
+#include <set>
+
+#ifdef _WIN32
+# ifdef SLICE_API_EXPORTS
+# define SLICE_API __declspec(dllexport)
+# else
+# define SLICE_API __declspec(dllimport)
+# endif
+#else
+# define SLICE_API /**/
+#endif
+
+namespace Slice
+{
+
+class GrammarBase;
+class SyntaxTreeBase;
+class Type;
+class Builtin;
+class Contained;
+class Container;
+class Module;
+class Constructed;
+class ClassDecl;
+class ClassDef;
+class Proxy;
+class Exception;
+class Struct;
+class Operation;
+class DataMember;
+class Sequence;
+class Dictionary;
+class Enum;
+class Enumerator;
+class Unit;
+
+typedef ::IceUtil::Handle<GrammarBase> GrammarBasePtr;
+typedef ::IceUtil::Handle<SyntaxTreeBase> SyntaxTreeBasePtr;
+typedef ::IceUtil::Handle<Type> TypePtr;
+typedef ::IceUtil::Handle<Builtin> BuiltinPtr;
+typedef ::IceUtil::Handle<Contained> ContainedPtr;
+typedef ::IceUtil::Handle<Container> ContainerPtr;
+typedef ::IceUtil::Handle<Module> ModulePtr;
+typedef ::IceUtil::Handle<Constructed> ConstructedPtr;
+typedef ::IceUtil::Handle<ClassDecl> ClassDeclPtr;
+typedef ::IceUtil::Handle<ClassDef> ClassDefPtr;
+typedef ::IceUtil::Handle<Proxy> ProxyPtr;
+typedef ::IceUtil::Handle<Exception> ExceptionPtr;
+typedef ::IceUtil::Handle<Struct> StructPtr;
+typedef ::IceUtil::Handle<Operation> OperationPtr;
+typedef ::IceUtil::Handle<DataMember> DataMemberPtr;
+typedef ::IceUtil::Handle<Sequence> SequencePtr;
+typedef ::IceUtil::Handle<Dictionary> DictionaryPtr;
+typedef ::IceUtil::Handle<Enum> EnumPtr;
+typedef ::IceUtil::Handle<Enumerator> EnumeratorPtr;
+typedef ::IceUtil::Handle<Unit> UnitPtr;
+
+}
+
+//
+// Stuff for flex and bison
+//
+
+#define YYSTYPE Slice::GrammarBasePtr
+#define YY_DECL int yylex(YYSTYPE* yylvalp)
+YY_DECL;
+int yyparse();
+
+//
+// I must set the initial stack depth to the maximum stack depth to
+// disable bison stack resizing. The bison stack resizing routines use
+// simple malloc/alloc/memcpy calls, which do not work for the
+// YYSTYPE, since YYSTYPE is a C++ type, with constructor, destructor,
+// assignment operator, etc.
+//
+#define YYMAXDEPTH 20000 // 20000 should suffice. Bison default is 10000 as maximum.
+#define YYINITDEPTH YYMAXDEPTH // Initial depth is set to max depth, for the reasons described above.
+
+//
+// Newer bison versions allow to disable stack resizing by defining
+// yyoverflow.
+//
+#define yyoverflow(a, b, c, d, e, f) yyerror(a)
+
+namespace Slice
+{
+
+typedef std::list<TypePtr> TypeList;
+typedef std::list<ExceptionPtr> ExceptionList;
+typedef std::list<std::string> StringList;
+typedef std::pair<TypePtr, std::string> TypeString;
+typedef std::list<TypeString> TypeStringList;
+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;
+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;
+typedef std::list<DictionaryPtr> DictionaryList;
+typedef std::list<EnumPtr> EnumList;
+typedef std::list<OperationPtr> OperationList;
+typedef std::list<DataMemberPtr> DataMemberList;
+typedef std::list<EnumeratorPtr> EnumeratorList;
+
+// ----------------------------------------------------------------------
+// ParserVisitor
+// ----------------------------------------------------------------------
+
+class SLICE_API ParserVisitor
+{
+public:
+
+ virtual ~ParserVisitor() { }
+ virtual bool visitUnitStart(const UnitPtr&) { return true; }
+ virtual void visitUnitEnd(const UnitPtr&) { }
+ virtual bool visitModuleStart(const ModulePtr&) { return true; }
+ virtual void visitModuleEnd(const ModulePtr&) { }
+ virtual void visitClassDecl(const ClassDeclPtr&) { }
+ virtual bool visitClassDefStart(const ClassDefPtr&) { return true; }
+ virtual void visitClassDefEnd(const ClassDefPtr&) { }
+ virtual bool visitExceptionStart(const ExceptionPtr&) { return true; }
+ virtual void visitExceptionEnd(const ExceptionPtr&) { }
+ virtual bool visitStructStart(const StructPtr&) { return true; }
+ virtual void visitStructEnd(const StructPtr&) { }
+ virtual void visitOperation(const OperationPtr&) { }
+ virtual void visitDataMember(const DataMemberPtr&) { }
+ virtual void visitSequence(const SequencePtr&) { }
+ virtual void visitDictionary(const DictionaryPtr&) { }
+ virtual void visitEnum(const EnumPtr&) { }
+};
+
+// ----------------------------------------------------------------------
+// GrammarBase
+// ----------------------------------------------------------------------
+
+class SLICE_API GrammarBase : public ::IceUtil::SimpleShared
+{
+};
+
+// ----------------------------------------------------------------------
+// SyntaxTreeBase
+// ----------------------------------------------------------------------
+
+class SLICE_API SyntaxTreeBase : public GrammarBase
+{
+public:
+
+ virtual void destroy();
+ UnitPtr unit();
+ virtual void visit(ParserVisitor*);
+
+protected:
+
+ SyntaxTreeBase(const UnitPtr&);
+
+ UnitPtr _unit;
+};
+
+// ----------------------------------------------------------------------
+// Type
+// ----------------------------------------------------------------------
+
+class SLICE_API Type : virtual public SyntaxTreeBase
+{
+public:
+
+protected:
+
+ Type(const UnitPtr&);
+};
+
+// ----------------------------------------------------------------------
+// Builtin
+// ----------------------------------------------------------------------
+
+class SLICE_API Builtin : virtual public Type
+{
+public:
+
+ enum Kind
+ {
+ KindByte,
+ KindBool,
+ KindShort,
+ KindInt,
+ KindLong,
+ KindFloat,
+ KindDouble,
+ KindString,
+ KindObject,
+ KindObjectProxy,
+ KindLocalObject
+ };
+ Kind kind();
+
+protected:
+
+ Builtin(const UnitPtr&, Kind);
+ friend class SLICE_API Unit;
+
+ Kind _kind;
+};
+
+// ----------------------------------------------------------------------
+// Contained
+// ----------------------------------------------------------------------
+
+class SLICE_API Contained : virtual public SyntaxTreeBase
+{
+public:
+
+ ContainerPtr container();
+ std::string name();
+ std::string scoped();
+ std::string scope();
+ std::string file();
+ std::string comment();
+
+ int includeLevel();
+ void updateIncludeLevel();
+
+ std::list<std::string> getMetaData();
+ void setMetaData(const std::list<std::string>&);
+
+ enum ContainedType
+ {
+ ContainedTypeSequence,
+ ContainedTypeDictionary,
+ ContainedTypeEnum,
+ ContainedTypeEnumerator,
+ ContainedTypeModule,
+ ContainedTypeClass,
+ ContainedTypeException,
+ ContainedTypeStruct,
+ ContainedTypeOperation,
+ ContainedTypeDataMember
+ };
+ virtual ContainedType containedType() = 0;
+
+ virtual bool uses(const ContainedPtr&) = 0;
+
+ bool operator<(const Contained&) const;
+ bool operator==(const Contained&) const;
+
+protected:
+
+ Contained(const ContainerPtr&, const std::string&);
+ friend class SLICE_API Container;
+
+ ContainerPtr _container;
+ std::string _name;
+ std::string _scoped;
+ std::string _file;
+ std::string _comment;
+ int _includeLevel;
+ std::list<std::string> _metaData;
+};
+
+// ----------------------------------------------------------------------
+// Container
+// ----------------------------------------------------------------------
+
+class SLICE_API Container : virtual public SyntaxTreeBase
+{
+public:
+
+ virtual void destroy();
+ ModulePtr createModule(const std::string&);
+ ClassDefPtr createClassDef(const std::string&, bool, const ClassList&, bool);
+ ClassDeclPtr createClassDecl(const std::string&, bool, bool);
+ ExceptionPtr createException(const std::string&, const ExceptionPtr&, bool);
+ StructPtr createStruct(const std::string&, bool);
+ SequencePtr createSequence(const std::string&, const TypePtr&, bool);
+ DictionaryPtr createDictionary(const std::string&, const TypePtr&, const TypePtr&, bool);
+ EnumPtr createEnum(const std::string&, bool);
+ EnumeratorPtr createEnumerator(const std::string&);
+ TypeList lookupType(const std::string&, bool = true);
+ TypeList lookupTypeNoBuiltin(const std::string&, bool = true);
+ ContainedList lookupContained(const std::string&, bool = true);
+ ExceptionPtr lookupException(const std::string&, bool = true);
+ ModuleList modules();
+ ClassList classes();
+ ExceptionList exceptions();
+ StructList structs();
+ SequenceList sequences();
+ DictionaryList dictionaries();
+ EnumList enums();
+ bool hasNonLocalClassDecls();
+ bool hasClassDecls();
+ bool hasClassDefs();
+ bool hasOtherConstructedOrExceptions(); // Exceptions or constructed types other than classes.
+ std::string thisScope();
+ void mergeModules();
+ void sort();
+ void sortContents();
+ virtual void visit(ParserVisitor*);
+ void containerRecDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
+
+protected:
+
+ Container(const UnitPtr&);
+
+ bool checkInterfaceAndLocal(const std::string&, bool, bool, bool, bool, bool);
+
+ ContainedList _contents;
+
+private:
+
+ 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;
+};
+
+// ----------------------------------------------------------------------
+// Module
+// ----------------------------------------------------------------------
+
+class SLICE_API Module : virtual public Container, virtual public Contained
+{
+public:
+
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+
+protected:
+
+ Module(const ContainerPtr&, const std::string&);
+ friend class SLICE_API Container;
+};
+
+// ----------------------------------------------------------------------
+// Constructed
+// ----------------------------------------------------------------------
+
+class SLICE_API Constructed : virtual public Type, virtual public Contained
+{
+public:
+
+ bool isLocal();
+ ConstructedList dependencies();
+ virtual void recDependencies(std::set<ConstructedPtr>&) = 0; // Internal operation, don't use directly.
+
+protected:
+
+ Constructed(const ContainerPtr&, const std::string&, bool);
+
+ bool _local;
+};
+
+// ----------------------------------------------------------------------
+// ClassDecl
+// ----------------------------------------------------------------------
+
+class SLICE_API ClassDecl : virtual public Constructed
+{
+public:
+
+ virtual void destroy();
+ ClassDefPtr definition();
+ bool isInterface();
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+ virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
+
+protected:
+
+ ClassDecl(const ContainerPtr&, const std::string&, bool, bool);
+ friend class SLICE_API Container;
+ friend class SLICE_API ClassDef;
+
+ ClassDefPtr _definition;
+ bool _interface;
+};
+
+// ----------------------------------------------------------------------
+// ClassDef
+// ----------------------------------------------------------------------
+
+//
+// Note: For the purpose of this parser, a class definition is not
+// considered to be a type, but a class declaration is. And each class
+// definition has at least one class declaration (but not vice versa),
+// so if you need the class as a "constructed type", use the
+// declaration() operation to navigate to the class declaration.
+//
+class SLICE_API ClassDef : virtual public Container, virtual public Contained
+{
+public:
+
+ virtual void destroy();
+ OperationPtr createOperation(const std::string&, const TypePtr&, const TypeStringList&, const TypeStringList&,
+ const ExceptionList&);
+ DataMemberPtr createDataMember(const std::string&, const TypePtr&);
+ ClassDeclPtr declaration();
+ ClassList bases();
+ ClassList allBases();
+ OperationList operations();
+ OperationList allOperations();
+ DataMemberList dataMembers();
+ DataMemberList allDataMembers();
+ bool isAbstract();
+ bool isInterface();
+ bool isLocal();
+ bool hasDataMembers();
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+
+protected:
+
+ ClassDef(const ContainerPtr&, const std::string&, bool, const ClassList&, bool);
+ friend class SLICE_API Container;
+
+ ClassDeclPtr _declaration;
+ bool _interface;
+ bool _hasDataMembers;
+ ClassList _bases;
+ bool _local;
+};
+
+// ----------------------------------------------------------------------
+// Proxy
+// ----------------------------------------------------------------------
+
+class SLICE_API Proxy : virtual public Type
+{
+public:
+
+ ClassDeclPtr _class();
+
+ Proxy(const ClassDeclPtr&);
+
+protected:
+
+ ClassDeclPtr __class;
+};
+
+// ----------------------------------------------------------------------
+// Exception
+// ----------------------------------------------------------------------
+
+// No inheritance from Constructed, as this is not a Type
+class SLICE_API Exception : virtual public Container, virtual public Contained
+{
+public:
+
+ virtual void destroy();
+ DataMemberPtr createDataMember(const std::string&, const TypePtr&);
+ DataMemberList dataMembers();
+ ExceptionPtr base();
+ ExceptionList allBases();
+ bool isLocal();
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+
+protected:
+
+ Exception(const ContainerPtr&, const std::string&, const ExceptionPtr&, bool);
+ friend class SLICE_API Container;
+
+ ExceptionPtr _base;
+ bool _local;
+};
+
+// ----------------------------------------------------------------------
+// Struct
+// ----------------------------------------------------------------------
+
+class SLICE_API Struct : virtual public Container, virtual public Constructed
+{
+public:
+
+ DataMemberPtr createDataMember(const std::string&, const TypePtr&);
+ DataMemberList dataMembers();
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+ virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
+
+protected:
+
+ Struct(const ContainerPtr&, const std::string&, bool);
+ friend class SLICE_API Container;
+};
+
+// ----------------------------------------------------------------------
+// Sequence
+// ----------------------------------------------------------------------
+
+class SLICE_API Sequence : virtual public Constructed
+{
+public:
+
+ TypePtr type();
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+ virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
+
+protected:
+
+ Sequence(const ContainerPtr&, const std::string&, const TypePtr&, bool);
+ friend class SLICE_API Container;
+
+ TypePtr _type;
+};
+
+// ----------------------------------------------------------------------
+// Dictionary
+// ----------------------------------------------------------------------
+
+class SLICE_API Dictionary : virtual public Constructed
+{
+public:
+
+ TypePtr keyType();
+ TypePtr valueType();
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+ virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
+
+protected:
+
+ Dictionary(const ContainerPtr&, const std::string&, const TypePtr&, const TypePtr&, bool);
+ friend class SLICE_API Container;
+
+ TypePtr _keyType;
+ TypePtr _valueType;
+};
+
+// ----------------------------------------------------------------------
+// Enum
+// ----------------------------------------------------------------------
+
+class SLICE_API Enum : virtual public Constructed
+{
+public:
+
+ EnumeratorList getEnumerators();
+ void setEnumerators(const EnumeratorList&);
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+ virtual void recDependencies(std::set<ConstructedPtr>&); // Internal operation, don't use directly.
+
+protected:
+
+ Enum(const ContainerPtr&, const std::string&, bool);
+ friend class SLICE_API Container;
+
+ EnumeratorList _enumerators;
+};
+
+// ----------------------------------------------------------------------
+// Enumerator
+// ----------------------------------------------------------------------
+
+class SLICE_API Enumerator : virtual public Contained
+{
+public:
+
+ virtual bool uses(const ContainedPtr&);
+ virtual ContainedType containedType();
+
+protected:
+
+ Enumerator(const ContainerPtr&, const std::string&);
+ friend class SLICE_API Container;
+};
+
+// ----------------------------------------------------------------------
+// Operation
+// ----------------------------------------------------------------------
+
+class SLICE_API Operation : virtual public Contained
+{
+public:
+
+ TypePtr returnType();
+ TypeStringList inputParameters();
+ TypeStringList outputParameters();
+ ExceptionList throws();
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+
+protected:
+
+ Operation(const ContainerPtr&, const std::string&, const TypePtr&, const TypeStringList&, const TypeStringList&,
+ const ExceptionList&);
+ friend class SLICE_API ClassDef;
+
+ TypePtr _returnType;
+ TypeStringList _inParams;
+ TypeStringList _outParams;
+ ExceptionList _throws;
+};
+
+// ----------------------------------------------------------------------
+// DataMember
+// ----------------------------------------------------------------------
+
+class SLICE_API DataMember : virtual public Contained
+{
+public:
+
+ TypePtr type();
+ virtual ContainedType containedType();
+ virtual bool uses(const ContainedPtr&);
+ virtual void visit(ParserVisitor*);
+
+protected:
+
+ DataMember(const ContainerPtr&, const std::string&, const TypePtr&);
+ friend class SLICE_API ClassDef;
+ friend class SLICE_API Struct;
+ friend class SLICE_API Exception;
+
+ TypePtr _type;
+};
+
+// ----------------------------------------------------------------------
+// Unit
+// ----------------------------------------------------------------------
+
+class SLICE_API Unit : virtual public Container
+{
+public:
+
+ static UnitPtr createUnit(bool, bool);
+
+ bool ignRedefs();
+
+ void setComment(const std::string&);
+ std::string currentComment();
+ std::string currentFile();
+
+ void nextLine();
+ void scanPosition(const char*);
+ int currentIncludeLevel();
+
+ void error(const char*);
+ void error(const std::string&);
+
+ void warning(const char*);
+ void warning(const std::string&);
+
+ ContainerPtr currentContainer();
+ void pushContainer(const ContainerPtr&);
+ void popContainer();
+
+ void addContent(const ContainedPtr&);
+ void removeContent(const ContainedPtr&);
+ ContainedList findContents(const std::string&);
+ ClassList findDerivedClasses(const ClassDefPtr&);
+ ExceptionList findDerivedExceptions(const ExceptionPtr&);
+ ContainedList findUsedBy(const ContainedPtr&);
+
+ bool usesProxies();
+ bool usesNonLocals();
+
+ StringList includeFiles();
+
+ int parse(FILE*, bool);
+
+ virtual void destroy();
+ virtual void visit(ParserVisitor*);
+
+ BuiltinPtr builtin(Builtin::Kind);
+
+private:
+
+ Unit(bool, bool);
+
+ bool _ignRedefs;
+ bool _all;
+ int _errors;
+ std::string _currentComment;
+ int _currentLine;
+ int _currentIncludeLevel;
+ std::string _currentFile;
+ std::string _topLevelFile;
+ StringList _includeFiles;
+ std::stack<ContainerPtr> _containerStack;
+ std::map<Builtin::Kind, BuiltinPtr> _builtins;
+ std::map<std::string, ContainedList > _contentMap;
+};
+
+extern SLICE_API Unit* unit; // The current parser for bison/flex
+
+}
+
+#endif
diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y
index 42d4f6702cd..841fc697dde 100644
--- a/cpp/src/Slice/Grammar.y
+++ b/cpp/src/Slice/Grammar.y
@@ -420,19 +420,6 @@ class_def
{
unit->popContainer();
$$ = $5;
-
- //
- // Check whether at least one data member is present, otherwise the class
- // really is an interface and must be defined as an interface.
- //
- ClassDefPtr cd = ClassDefPtr::dynamicCast($$);
- assert(cd);
-/*
- if (cd->dataMembers().empty())
- {
- unit->error("classes must have at least one data member");
- }
-*/
}
| ICE_CLASS keyword class_extends implements
{
@@ -572,13 +559,14 @@ interface_def
unit->popContainer();
$$ = $4;
+/*
+ // TODO: This may need to be backed out again, depending on what we decide.
//
// Check whether at least one operation is present, otherwise the
// interface is empty, which doesn't make sense.
//
ClassDefPtr cd = ClassDefPtr::dynamicCast($$);
assert(cd);
-/*
if (cd->operations().empty())
{
unit->error("interfaces must have at least one operation");
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index 4bf0998c922..79914e42c14 100644
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -160,11 +160,11 @@ Slice::Contained::Contained(const ContainerPtr& container, const string& name) :
_name(name)
{
ContainedPtr cont = ContainedPtr::dynamicCast(_container);
- if(cont)
+ if (cont)
{
_scoped = cont->scoped();
}
- _scoped += "::" + _name;
+ _scoped += "::" + _name;
assert(_unit);
_unit->addContent(this);
_file = _unit->currentFile();
@@ -188,10 +188,10 @@ ModulePtr
Slice::Container::createModule(const string& name)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- for(ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
+ for (ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
{
ModulePtr module = ModulePtr::dynamicCast(*p);
- if(module)
+ if (module)
{
continue; // Reopening modules is permissible
}
@@ -212,30 +212,30 @@ ClassDefPtr
Slice::Container::createClassDef(const string& name, bool intf, const ClassList& bases, bool local)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- for(ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
+ for (ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
{
ClassDeclPtr decl = ClassDeclPtr::dynamicCast(*p);
- if(decl)
+ if (decl)
{
- if(checkInterfaceAndLocal(name, false, intf, decl->isInterface(), local, decl->isLocal()))
+ if (checkInterfaceAndLocal(name, false, intf, decl->isInterface(), local, decl->isLocal()))
{
continue;
}
-
+
return 0;
}
ClassDefPtr def = ClassDefPtr::dynamicCast(*p);
- if(def)
+ if (def)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
def->updateIncludeLevel();
return def;
}
string msg = "redefinition of ";
- if(intf)
+ if (intf)
{
msg += "interface";
}
@@ -253,7 +253,7 @@ Slice::Container::createClassDef(const string& name, bool intf, const ClassList&
string msg = "redefinition of `";
msg += name;
msg += "' as ";
- if(intf)
+ if (intf)
{
msg += "interface";
}
@@ -264,11 +264,64 @@ Slice::Container::createClassDef(const string& name, bool intf, const ClassList&
_unit->error(msg);
return 0;
}
-
+
+ //
+ // Check whether, for multiple inheritance, any of the bases define
+ // the same operations.
+ //
+ if (bases.size() > 1)
+ {
+ //
+ // We have multiple inheritance. Build a list of paths through the
+ // inheritance graph, such that multiple inheritance is legal if
+ // the union of the names defined in classes on each path are disjoint.
+ //
+ GraphPartitionList gpl;
+ for (ClassList::const_iterator i = bases.begin(); i != bases.end(); ++i)
+ {
+ ClassList cl;
+ gpl.push_back(cl);
+ addPartition(gpl, gpl.rbegin(), *i);
+ }
+
+ //
+ // We now have a list of partitions, with each partition containing
+ // a list of class definitions. Turn the list of partitions of class
+ // definitions into a list of sets of strings, with each
+ // set containing the names of operations and data members defined in
+ // the classes in each partition.
+ //
+ StringSetList spl = toStringSetList(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 i = clashes.begin(); i != clashes.end(); ++i)
+ {
+ string msg = "ambiguous multiple inheritance: `";
+ msg += *i + "' 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.
+ //
+ }
+
ClassDefPtr def = new ClassDef(this, name, intf, bases, local);
_contents.push_back(def);
-
- for(ContainedList::const_iterator q = matches.begin(); q != matches.end(); ++q)
+
+ for (ContainedList::const_iterator q = matches.begin(); q != matches.end(); ++q)
{
ClassDeclPtr decl = ClassDeclPtr::dynamicCast(*q);
decl->_definition = def;
@@ -285,18 +338,124 @@ Slice::Container::createClassDef(const string& name, bool intf, const ClassList&
return def;
}
+//
+// Return true if the class definition cdp is on one of the class lists in gpl, false otherwise.
+//
+bool
+Slice::Container::isInList(const GraphPartitionList& gpl, const ClassDefPtr cdp) const
+{
+ for (GraphPartitionList::const_iterator i = gpl.begin(); i != gpl.end(); ++i)
+ {
+ if (find((*i).begin(), (*i).end(), cdp) != (*i).end())
+{
+ return true;
+}
+ }
+ return false;
+}
+
+void
+Slice::Container::addPartition(GraphPartitionList& gpl, GraphPartitionList::reverse_iterator tail, const ClassDefPtr base) const
+{
+ //
+ // If this base is on one of the partition lists already, do nothing.
+ //
+ if (isInList(gpl, base))
+ {
+ return;
+ }
+ //
+ // Put the current base at the end of the current partition.
+ //
+ (*tail).push_back(base);
+ //
+ // If the base has bases in turn, recurse, adding the first base
+ // of base (the left-most "grandbase") to the current partition.
+ //
+ if (base->_bases.size())
+ {
+ addPartition(gpl, tail, *(base->_bases.begin()));
+ }
+ //
+ // If the base has multiple bases, each of the "grandbases"
+ // except for the left-most (which we just dealt with)
+ // adds a new partition.
+ //
+ if (base->_bases.size() > 1)
+ {
+ ClassList::const_iterator i = base->_bases.begin();
+ while (++i != base->_bases.end())
+ {
+ ClassList cl;
+ gpl.push_back(cl);
+ addPartition(gpl, gpl.rbegin(), *i);
+ }
+ }
+}
+
+//
+// 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.
+//
+StringSetList
+Slice::Container::toStringSetList(const GraphPartitionList& gpl) const
+{
+ StringSetList spl;
+ for (GraphPartitionList::const_iterator i = gpl.begin(); i != gpl.end(); ++i)
+ {
+ StringSet ss;
+ spl.push_back(ss);
+ for (ClassList::const_iterator j = (*i).begin(); j != (*i).end(); ++j)
+ {
+ OperationList operations = (*j)->operations();
+ DataMemberList members = (*j)->dataMembers();
+ for (OperationList::const_iterator k = operations.begin(); k != operations.end(); ++k)
+ {
+ spl.rbegin()->insert((*k)->name());
+ }
+ for (DataMemberList::const_iterator k = members.begin(); k != members.end(); ++k)
+ {
+ spl.rbegin()->insert((*k)->name());
+ }
+ }
+ }
+ return spl;
+}
+
+//
+// Return the union of the intersections of all possible pairs of sets of strings.
+//
+StringList
+Slice::Container::unionOfAllPairIntersections(const StringSetList& l) const
+{
+ StringList result;
+ for (StringSetList::const_iterator i = l.begin(); i != l.end(); ++i)
+ {
+ StringSetList::const_iterator cursor = i;
+ ++cursor;
+ for (StringSetList::const_iterator j = cursor; j != l.end(); ++j)
+ {
+ set_intersection((*i).begin(), (*i).end(), (*j).begin(), (*j).end(), back_inserter(result));
+ }
+ }
+ result.sort();
+ result.unique();
+ return result;
+}
+
ClassDeclPtr
Slice::Container::createClassDecl(const string& name, bool intf, bool local)
{
ClassDefPtr def;
ContainedList matches = _unit->findContents(thisScope() + name);
- for(ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
+ for (ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
{
ClassDefPtr clDef = ClassDefPtr::dynamicCast(*p);
- if(clDef)
+ if (clDef)
{
- if(checkInterfaceAndLocal(name, true, intf, clDef->isInterface(), local, clDef->isLocal()))
+ if (checkInterfaceAndLocal(name, true, intf, clDef->isInterface(), local, clDef->isLocal()))
{
assert(!def);
def = clDef;
@@ -307,20 +466,20 @@ Slice::Container::createClassDecl(const string& name, bool intf, bool local)
}
ClassDeclPtr clDecl = ClassDeclPtr::dynamicCast(*p);
- if(clDecl)
+ if (clDecl)
{
- if(checkInterfaceAndLocal(name, false, intf, clDecl->isInterface(), local, clDecl->isLocal()))
+ if (checkInterfaceAndLocal(name, false, intf, clDecl->isInterface(), local, clDecl->isLocal()))
{
continue;
}
-
+
return 0;
}
string msg = "declaration of already defined `";
msg += name;
msg += "' as ";
- if(intf)
+ if (intf)
{
msg += "interface";
}
@@ -337,12 +496,12 @@ Slice::Container::createClassDecl(const string& name, bool intf, bool local)
// have a declaration for the class in this container, we don't
// create another one.
//
- for(ContainedList::const_iterator q = _contents.begin(); q != _contents.end(); ++q)
+ for (ContainedList::const_iterator q = _contents.begin(); q != _contents.end(); ++q)
{
- if((*q)->name() == name)
+ if ((*q)->name() == name)
{
ClassDeclPtr decl = ClassDeclPtr::dynamicCast(*q);
- if(decl)
+ if (decl)
{
return decl;
}
@@ -354,7 +513,7 @@ Slice::Container::createClassDecl(const string& name, bool intf, bool local)
ClassDeclPtr decl = new ClassDecl(this, name, intf, local);
_contents.push_back(decl);
- if(def)
+ if (def)
{
decl->_definition = def;
}
@@ -366,12 +525,12 @@ ExceptionPtr
Slice::Container::createException(const string& name, const ExceptionPtr& base, bool local)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
ExceptionPtr p = ExceptionPtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
p->updateIncludeLevel();
return p;
@@ -400,12 +559,12 @@ StructPtr
Slice::Container::createStruct(const string& name, bool local)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
StructPtr p = StructPtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
p->updateIncludeLevel();
return p;
@@ -434,12 +593,12 @@ SequencePtr
Slice::Container::createSequence(const string& name, const TypePtr& type, bool local)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
SequencePtr p = SequencePtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
return p;
}
@@ -467,12 +626,12 @@ DictionaryPtr
Slice::Container::createDictionary(const string& name, const TypePtr& keyType, const TypePtr& valueType, bool local)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
DictionaryPtr p = DictionaryPtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
return p;
}
@@ -500,12 +659,12 @@ EnumPtr
Slice::Container::createEnum(const string& name, bool local)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
EnumPtr p = EnumPtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
return p;
}
@@ -533,12 +692,12 @@ EnumeratorPtr
Slice::Container::createEnumerator(const string& name)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
EnumeratorPtr p = EnumeratorPtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
return p;
}
@@ -570,7 +729,7 @@ Slice::Container::lookupType(const string& scoped, bool printError)
//
string sc = scoped;
string::size_type pos;
- while((pos = sc.find_first_of(" \t\r\n")) != string::npos)
+ while ((pos = sc.find_first_of(" \t\r\n")) != string::npos)
{
sc.erase(pos, 1);
}
@@ -593,9 +752,9 @@ Slice::Container::lookupType(const string& scoped, bool printError)
"LocalObject"
};
- for(unsigned int i = 0; i < sizeof(builtinTable) / sizeof(const char*); ++i)
+ for (unsigned int i = 0; i < sizeof(builtinTable) / sizeof(const char*); ++i)
{
- if(sc == builtinTable[i])
+ if (sc == builtinTable[i])
{
TypeList result;
result.push_back(_unit->builtin(static_cast<Builtin::Kind>(i)));
@@ -617,7 +776,7 @@ Slice::Container::lookupTypeNoBuiltin(const string& scoped, bool printError)
//
string sc = scoped;
string::size_type pos;
- while((pos = sc.find_first_of(" \t\r\n")) != string::npos)
+ while ((pos = sc.find_first_of(" \t\r\n")) != string::npos)
{
sc.erase(pos, 1);
}
@@ -625,30 +784,30 @@ Slice::Container::lookupTypeNoBuiltin(const string& scoped, bool printError)
//
// Absolute scoped name?
//
- if(sc.size() >= 2 && sc[0] == ':')
+ if (sc.size() >= 2 && sc[0] == ':')
{
return _unit->lookupTypeNoBuiltin(sc.substr(2), printError);
}
TypeList results;
- if(sc.rfind('*') == sc.length() - 1)
+ if (sc.rfind('*') == sc.length() - 1)
{
//
// Proxies.
//
ContainedList matches = _unit->findContents(thisScope() + sc.substr(0, sc.length() - 1));
- for(ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
+ for (ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
{
ClassDefPtr def = ClassDefPtr::dynamicCast(*p);
- if(def)
+ if (def)
{
continue; // Ignore class definitions
}
ClassDeclPtr cl = ClassDeclPtr::dynamicCast(*p);
- if(!cl)
+ if (!cl)
{
- if(printError)
+ if (printError)
{
string msg = "`";
msg += sc;
@@ -666,18 +825,18 @@ Slice::Container::lookupTypeNoBuiltin(const string& scoped, bool printError)
// Non-Proxies.
//
ContainedList matches = _unit->findContents(thisScope() + sc);
- for(ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
+ for (ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
{
ClassDefPtr def = ClassDefPtr::dynamicCast(*p);
- if(def)
+ if (def)
{
continue; // Ignore class definitions
}
-
+
ExceptionPtr ex = ExceptionPtr::dynamicCast(*p);
- if(ex)
+ if (ex)
{
- if(printError)
+ if (printError)
{
string msg = "`";
msg += sc;
@@ -686,11 +845,11 @@ Slice::Container::lookupTypeNoBuiltin(const string& scoped, bool printError)
}
return TypeList();
}
-
+
TypePtr type = TypePtr::dynamicCast(*p);
- if(!type)
+ if (!type)
{
- if(printError)
+ if (printError)
{
string msg = "`";
msg += sc;
@@ -702,13 +861,13 @@ Slice::Container::lookupTypeNoBuiltin(const string& scoped, bool printError)
results.push_back(type);
}
}
-
- if(results.empty())
+
+ if (results.empty())
{
ContainedPtr contained = ContainedPtr::dynamicCast(this);
- if(!contained)
+ if (!contained)
{
- if(printError)
+ if (printError)
{
string msg = "`";
msg += sc;
@@ -733,7 +892,7 @@ Slice::Container::lookupContained(const string& scoped, bool printError)
//
string sc = scoped;
string::size_type pos;
- while((pos = sc.find_first_of(" \t\r\n")) != string::npos)
+ while ((pos = sc.find_first_of(" \t\r\n")) != string::npos)
{
sc.erase(pos, 1);
}
@@ -741,27 +900,27 @@ Slice::Container::lookupContained(const string& scoped, bool printError)
//
// Absolute scoped name?
//
- if(sc.size() >= 2 && sc[0] == ':')
+ if (sc.size() >= 2 && sc[0] == ':')
{
return _unit->lookupContained(sc.substr(2), printError);
}
-
+
ContainedList matches = _unit->findContents(thisScope() + sc);
ContainedList results;
- for(ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
+ for (ContainedList::const_iterator p = matches.begin(); p != matches.end(); ++p)
{
- if(!ClassDefPtr::dynamicCast(*p)) // Ignore class definitions
+ if (!ClassDefPtr::dynamicCast(*p)) // Ignore class definitions
{
results.push_back(*p);
}
}
- if(results.empty())
+ if (results.empty())
{
ContainedPtr contained = ContainedPtr::dynamicCast(this);
- if(!contained)
+ if (!contained)
{
- if(printError)
+ if (printError)
{
string msg = "`";
msg += sc;
@@ -782,18 +941,18 @@ ExceptionPtr
Slice::Container::lookupException(const string& scoped, bool printError)
{
ContainedList contained = lookupContained(scoped, printError);
- if(contained.empty())
+ if (contained.empty())
{
return 0;
}
ExceptionList exceptions;
- for(ContainedList::iterator p = contained.begin(); p != contained.end(); ++p)
+ for (ContainedList::iterator p = contained.begin(); p != contained.end(); ++p)
{
ExceptionPtr ex = ExceptionPtr::dynamicCast(*p);
- if(!ex)
+ if (!ex)
{
- if(printError)
+ if (printError)
{
string msg = "`";
msg += scoped;
@@ -812,10 +971,10 @@ ModuleList
Slice::Container::modules()
{
ModuleList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
ModulePtr q = ModulePtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -827,10 +986,10 @@ ClassList
Slice::Container::classes()
{
ClassList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
ClassDefPtr q = ClassDefPtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -842,10 +1001,10 @@ ExceptionList
Slice::Container::exceptions()
{
ExceptionList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
ExceptionPtr q = ExceptionPtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -857,10 +1016,10 @@ StructList
Slice::Container::structs()
{
StructList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
StructPtr q = StructPtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -872,10 +1031,10 @@ SequenceList
Slice::Container::sequences()
{
SequenceList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
SequencePtr q = SequencePtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -887,10 +1046,10 @@ DictionaryList
Slice::Container::dictionaries()
{
DictionaryList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
DictionaryPtr q = DictionaryPtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -902,10 +1061,10 @@ EnumList
Slice::Container::enums()
{
EnumList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
EnumPtr q = EnumPtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -916,16 +1075,16 @@ Slice::Container::enums()
bool
Slice::Container::hasNonLocalClassDecls()
{
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
ClassDeclPtr cl = ClassDeclPtr::dynamicCast(*p);
- if(cl && !cl->isLocal())
+ if (cl && !cl->isLocal())
{
return true;
}
ContainerPtr container = ContainerPtr::dynamicCast(*p);
- if(container && container->hasNonLocalClassDecls())
+ if (container && container->hasNonLocalClassDecls())
{
return true;
}
@@ -937,15 +1096,15 @@ Slice::Container::hasNonLocalClassDecls()
bool
Slice::Container::hasClassDecls()
{
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
- if(ClassDeclPtr::dynamicCast(*p))
+ if (ClassDeclPtr::dynamicCast(*p))
{
return true;
}
ContainerPtr container = ContainerPtr::dynamicCast(*p);
- if(container && container->hasClassDecls())
+ if (container && container->hasClassDecls())
{
return true;
}
@@ -957,15 +1116,15 @@ Slice::Container::hasClassDecls()
bool
Slice::Container::hasClassDefs()
{
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
- if(ClassDefPtr::dynamicCast(*p))
+ if (ClassDefPtr::dynamicCast(*p))
{
return true;
}
ContainerPtr container = ContainerPtr::dynamicCast(*p);
- if(container && container->hasClassDefs())
+ if (container && container->hasClassDefs())
{
return true;
}
@@ -977,20 +1136,20 @@ Slice::Container::hasClassDefs()
bool
Slice::Container::hasOtherConstructedOrExceptions()
{
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
- if(ConstructedPtr::dynamicCast(*p) && !ClassDeclPtr::dynamicCast(*p) && !ClassDefPtr::dynamicCast(*p))
+ if (ConstructedPtr::dynamicCast(*p) && !ClassDeclPtr::dynamicCast(*p) && !ClassDefPtr::dynamicCast(*p))
{
return true;
}
- if(ExceptionPtr::dynamicCast(*p))
+ if (ExceptionPtr::dynamicCast(*p))
{
return true;
}
ContainerPtr container = ContainerPtr::dynamicCast(*p);
- if(container && container->hasOtherConstructedOrExceptions())
+ if (container && container->hasOtherConstructedOrExceptions())
{
return true;
}
@@ -1004,7 +1163,7 @@ Slice::Container::thisScope()
{
string s;
ContainedPtr contained = ContainedPtr::dynamicCast(this);
- if(contained)
+ if (contained)
{
s = contained->scoped();
}
@@ -1015,34 +1174,34 @@ Slice::Container::thisScope()
void
Slice::Container::mergeModules()
{
- for(ContainedList::iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::iterator p = _contents.begin(); p != _contents.end(); ++p)
{
ModulePtr mod1 = ModulePtr::dynamicCast(*p);
- if(!mod1)
+ if (!mod1)
{
continue;
}
ContainedList::iterator q = p;
++q;
- while(q != _contents.end())
+ while (q != _contents.end())
{
ModulePtr mod2 = ModulePtr::dynamicCast(*q);
- if(!mod2)
+ if (!mod2)
{
++q;
continue;
}
-
- if(mod1->name() != mod2->name())
+
+ if (mod1->name() != mod2->name())
{
++q;
continue;
}
-
+
mod1->_contents.splice(mod1->_contents.end(), mod2->_contents);
- if(mod1->_comment.length() < mod2->_comment.length())
+ if (mod1->_comment.length() < mod2->_comment.length())
{
mod1->_comment.swap(mod2->_comment);
}
@@ -1066,10 +1225,10 @@ Slice::Container::sort()
void
Slice::Container::sortContents()
{
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
ContainerPtr container = ContainerPtr::dynamicCast(*p);
- if(container)
+ if (container)
{
container->sort();
container->sortContents();
@@ -1080,7 +1239,7 @@ Slice::Container::sortContents()
void
Slice::Container::visit(ParserVisitor* visitor)
{
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
(*p)->visit(visitor);
}
@@ -1090,10 +1249,10 @@ void
Slice::Container::containerRecDependencies(set<ConstructedPtr>& dependencies)
{
ContainedList::iterator p;
- for(p = _contents.begin(); p != _contents.end(); ++p)
+ for (p = _contents.begin(); p != _contents.end(); ++p)
{
ConstructedPtr constructed = ConstructedPtr::dynamicCast(*p);
- if(constructed && dependencies.find(constructed) != dependencies.end())
+ if (constructed && dependencies.find(constructed) != dependencies.end())
{
dependencies.insert(constructed);
constructed->recDependencies(dependencies);
@@ -1112,7 +1271,7 @@ Slice::Container::checkInterfaceAndLocal(const string& name, bool defined,
bool local, bool localOther)
{
string definedOrDeclared;
- if(defined)
+ if (defined)
{
definedOrDeclared = "defined";
}
@@ -1121,7 +1280,7 @@ Slice::Container::checkInterfaceAndLocal(const string& name, bool defined,
definedOrDeclared = "declared";
}
- if(!intf && intfOther)
+ if (!intf && intfOther)
{
string msg = "class `";
msg += name;
@@ -1132,7 +1291,7 @@ Slice::Container::checkInterfaceAndLocal(const string& name, bool defined,
return false;
}
- if(intf && !intfOther)
+ if (intf && !intfOther)
{
string msg = "interface `";
msg += name;
@@ -1143,7 +1302,7 @@ Slice::Container::checkInterfaceAndLocal(const string& name, bool defined,
return false;
}
- if(!local && localOther)
+ if (!local && localOther)
{
string msg = "non-local `";
msg += name;
@@ -1154,7 +1313,7 @@ Slice::Container::checkInterfaceAndLocal(const string& name, bool defined,
return false;
}
- if(local && !localOther)
+ if (local && !localOther)
{
string msg = "local `";
msg += name;
@@ -1187,12 +1346,12 @@ Slice::Module::uses(const ContainedPtr&)
void
Slice::Module::visit(ParserVisitor* visitor)
{
- if(_includeLevel > 0)
+ if (_includeLevel > 0)
{
return;
}
- if(visitor->visitModuleStart(this))
+ if (visitor->visitModuleStart(this))
{
Container::visit(visitor);
visitor->visitModuleEnd(this);
@@ -1276,12 +1435,12 @@ Slice::ClassDecl::visit(ParserVisitor* visitor)
void
Slice::ClassDecl::recDependencies(set<ConstructedPtr>& dependencies)
{
- if(_definition)
+ if (_definition)
{
_definition->containerRecDependencies(dependencies);
ClassList bases = _definition->bases();
ClassList::iterator p;
- for(p = bases.begin(); p != bases.end(); ++p)
+ for (p = bases.begin(); p != bases.end(); ++p)
{
(*p)->declaration()->recDependencies(dependencies);
}
@@ -1317,12 +1476,12 @@ Slice::ClassDef::createOperation(const string& name,
const ExceptionList& throws)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
OperationPtr p = OperationPtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
return p;
}
@@ -1346,11 +1505,11 @@ Slice::ClassDef::createOperation(const string& name,
allParams.insert(allParams.end(), outParams.begin(), outParams.end());
TypeStringList::const_iterator p = allParams.begin();
- while(p != allParams.end())
+ while (p != allParams.end())
{
TypeStringList::const_iterator q = p;
++q;
- while(q != allParams.end())
+ while (q != allParams.end())
{
//
// Complain about duplicate parameters only if they are
@@ -1359,7 +1518,7 @@ Slice::ClassDef::createOperation(const string& name,
// signature (but the missing parameters have been reported
// already).
//
- if(p->second == q->second && p->second != "")
+ if (p->second == q->second && p->second != "")
{
string msg = "duplicate parameter `";
msg += p->second;
@@ -1373,10 +1532,10 @@ Slice::ClassDef::createOperation(const string& name,
}
}
- if(name == this->name())
+ if (name == this->name())
{
string msg;
- if(isInterface())
+ if (isInterface())
{
msg = "interface name `";
}
@@ -1390,6 +1549,24 @@ Slice::ClassDef::createOperation(const string& name,
return 0;
}
+ //
+ // Check whether any bases have defined this operation already
+ //
+ for (ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
+ {
+ OperationList ol = (*p)->allOperations();
+ for (OperationList::const_iterator p = ol.begin(); p != ol.end(); ++p)
+ {
+ if ((*p)->name() == name)
+ {
+ string msg = "operation `" + name;
+ msg += "' is already defined in a base interface or class";
+ _unit->error(msg);
+ return 0;
+ }
+ }
+ }
+
OperationPtr p = new Operation(this, name, returnType, inParams, outParams, throws);
_contents.push_back(p);
return p;
@@ -1398,15 +1575,14 @@ Slice::ClassDef::createOperation(const string& name,
DataMemberPtr
Slice::ClassDef::createDataMember(const string& name, const TypePtr& type)
{
- assert(!isInterface());
-
+ assert(!isInterface());
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
DataMemberPtr p = DataMemberPtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
return p;
}
@@ -1425,10 +1601,10 @@ Slice::ClassDef::createDataMember(const string& name, const TypePtr& type)
return 0;
}
- if(name == this->name())
+ if (name == this->name())
{
string msg;
- if(isInterface())
+ if (isInterface())
{
msg = "interface name `";
}
@@ -1442,8 +1618,26 @@ Slice::ClassDef::createDataMember(const string& name, const TypePtr& type)
return 0;
}
- _hasDataMembers = true;
+ //
+ //
+ // Check whether any bases have defined this data member already
+ //
+ for (ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
+ {
+ DataMemberList dml = (*p)->allDataMembers();
+ for (DataMemberList::const_iterator p = dml.begin(); p != dml.end(); ++p)
+ {
+ if ((*p)->name() == name)
+ {
+ string msg = "data member `" + name;
+ msg += "' is already defined in a base interface or class";
+ _unit->error(msg);
+ return 0;
+ }
+ }
+ }
+ _hasDataMembers = true;
DataMemberPtr p = new DataMember(this, name, type);
_contents.push_back(p);
return p;
@@ -1467,7 +1661,7 @@ Slice::ClassDef::allBases()
ClassList result = _bases;
result.sort();
result.unique();
- for(ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
+ for (ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
{
ClassList li = (*p)->allBases();
result.merge(li);
@@ -1480,10 +1674,10 @@ OperationList
Slice::ClassDef::operations()
{
OperationList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
OperationPtr q = OperationPtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -1497,7 +1691,7 @@ Slice::ClassDef::allOperations()
OperationList result = operations();
result.sort();
result.unique();
- for(ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
+ for (ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
{
OperationList li = (*p)->allOperations();
result.merge(li);
@@ -1510,10 +1704,10 @@ DataMemberList
Slice::ClassDef::dataMembers()
{
DataMemberList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
DataMemberPtr q = DataMemberPtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -1521,22 +1715,37 @@ Slice::ClassDef::dataMembers()
return result;
}
+DataMemberList
+Slice::ClassDef::allDataMembers()
+{
+ DataMemberList result = dataMembers();
+ result.sort();
+ result.unique();
+ for (ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
+ {
+ DataMemberList li = (*p)->allDataMembers();
+ result.merge(li);
+ result.unique();
+ }
+ return result;
+}
+
bool
Slice::ClassDef::isAbstract()
{
- if(isInterface() || _bases.size() > 1) // Is this an interface, or does it derive from interfaces?
+ if (isInterface() || _bases.size() > 1) // Is this an interface, or does it derive from interfaces?
{
return true;
}
- if(!_bases.empty() && _bases.front()->isAbstract())
+ if (!_bases.empty() && _bases.front()->isAbstract())
{
return true;
}
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
- if(OperationPtr::dynamicCast(*p))
+ if (OperationPtr::dynamicCast(*p))
{
return true;
}
@@ -1580,12 +1789,12 @@ Slice::ClassDef::uses(const ContainedPtr&)
void
Slice::ClassDef::visit(ParserVisitor* visitor)
{
- if(_includeLevel > 0)
+ if (_includeLevel > 0)
{
return;
}
-
- if(visitor->visitClassDefStart(this))
+
+ if (visitor->visitClassDefStart(this))
{
Container::visit(visitor);
visitor->visitClassDefEnd(this);
@@ -1607,7 +1816,7 @@ Slice::ClassDef::ClassDef(const ContainerPtr& container, const string& name, boo
// interfaces
//
#ifndef NDEBUG
- for(ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
+ for (ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
{
assert(p == _bases.begin() || (*p)->isInterface());
}
@@ -1646,12 +1855,12 @@ DataMemberPtr
Slice::Exception::createDataMember(const string& name, const TypePtr& type)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
DataMemberPtr p = DataMemberPtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
return p;
}
@@ -1670,7 +1879,7 @@ Slice::Exception::createDataMember(const string& name, const TypePtr& type)
return 0;
}
- if(name == this->name())
+ if (name == this->name())
{
string msg = "exception name `";
msg += name;
@@ -1688,10 +1897,10 @@ DataMemberList
Slice::Exception::dataMembers()
{
DataMemberList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
DataMemberPtr q = DataMemberPtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -1709,7 +1918,7 @@ ExceptionList
Slice::Exception::allBases()
{
ExceptionList result;
- if(_base)
+ if (_base)
{
result = _base->allBases();
result.push_front(_base);
@@ -1739,12 +1948,12 @@ Slice::Exception::uses(const ContainedPtr&)
void
Slice::Exception::visit(ParserVisitor* visitor)
{
- if(_includeLevel > 0)
+ if (_includeLevel > 0)
{
return;
}
- if(visitor->visitExceptionStart(this))
+ if (visitor->visitExceptionStart(this))
{
Container::visit(visitor);
visitor->visitExceptionEnd(this);
@@ -1768,12 +1977,12 @@ DataMemberPtr
Slice::Struct::createDataMember(const string& name, const TypePtr& type)
{
ContainedList matches = _unit->findContents(thisScope() + name);
- if(!matches.empty())
+ if (!matches.empty())
{
DataMemberPtr p = DataMemberPtr::dynamicCast(matches.front());
- if(p)
+ if (p)
{
- if(_unit->ignRedefs())
+ if (_unit->ignRedefs())
{
return p;
}
@@ -1792,7 +2001,7 @@ Slice::Struct::createDataMember(const string& name, const TypePtr& type)
return 0;
}
- if(name == this->name())
+ if (name == this->name())
{
string msg = "struct name `";
msg += name;
@@ -1801,7 +2010,7 @@ Slice::Struct::createDataMember(const string& name, const TypePtr& type)
return 0;
}
- if(type.get() == this)
+ if (type.get() == this)
{
string msg = "struct `";
msg += name;
@@ -1819,10 +2028,10 @@ DataMemberList
Slice::Struct::dataMembers()
{
DataMemberList result;
- for(ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
+ for (ContainedList::const_iterator p = _contents.begin(); p != _contents.end(); ++p)
{
DataMemberPtr q = DataMemberPtr::dynamicCast(*p);
- if(q)
+ if (q)
{
result.push_back(q);
}
@@ -1845,12 +2054,12 @@ Slice::Struct::uses(const ContainedPtr&)
void
Slice::Struct::visit(ParserVisitor* visitor)
{
- if(_includeLevel > 0)
+ if (_includeLevel > 0)
{
return;
}
- if(visitor->visitStructStart(this))
+ if (visitor->visitStructStart(this))
{
Container::visit(visitor);
visitor->visitStructEnd(this);
@@ -1892,7 +2101,7 @@ bool
Slice::Sequence::uses(const ContainedPtr& contained)
{
ContainedPtr contained2 = ContainedPtr::dynamicCast(_type);
- if(contained2 && contained2 == contained)
+ if (contained2 && contained2 == contained)
{
return true;
}
@@ -1910,7 +2119,7 @@ void
Slice::Sequence::recDependencies(set<ConstructedPtr>& dependencies)
{
ConstructedPtr constructed = ConstructedPtr::dynamicCast(_type);
- if(constructed && dependencies.find(constructed) != dependencies.end())
+ if (constructed && dependencies.find(constructed) != dependencies.end())
{
dependencies.insert(constructed);
constructed->recDependencies(dependencies);
@@ -1953,7 +2162,7 @@ Slice::Dictionary::uses(const ContainedPtr& contained)
{
{
ContainedPtr contained2 = ContainedPtr::dynamicCast(_keyType);
- if(contained2 && contained2 == contained)
+ if (contained2 && contained2 == contained)
{
return true;
}
@@ -1961,7 +2170,7 @@ Slice::Dictionary::uses(const ContainedPtr& contained)
{
ContainedPtr contained2 = ContainedPtr::dynamicCast(_valueType);
- if(contained2 && contained2 == contained)
+ if (contained2 && contained2 == contained)
{
return true;
}
@@ -1981,7 +2190,7 @@ Slice::Dictionary::recDependencies(set<ConstructedPtr>& dependencies)
{
{
ConstructedPtr constructed = ConstructedPtr::dynamicCast(_keyType);
- if(constructed && dependencies.find(constructed) != dependencies.end())
+ if (constructed && dependencies.find(constructed) != dependencies.end())
{
dependencies.insert(constructed);
constructed->recDependencies(dependencies);
@@ -1990,7 +2199,7 @@ Slice::Dictionary::recDependencies(set<ConstructedPtr>& dependencies)
{
ConstructedPtr constructed = ConstructedPtr::dynamicCast(_valueType);
- if(constructed && dependencies.find(constructed) != dependencies.end())
+ if (constructed && dependencies.find(constructed) != dependencies.end())
{
dependencies.insert(constructed);
constructed->recDependencies(dependencies);
@@ -2118,7 +2327,7 @@ Slice::Operation::uses(const ContainedPtr& contained)
{
{
ContainedPtr contained2 = ContainedPtr::dynamicCast(_returnType);
- if(contained2 && contained2 == contained)
+ if (contained2 && contained2 == contained)
{
return true;
}
@@ -2126,19 +2335,19 @@ Slice::Operation::uses(const ContainedPtr& contained)
TypeStringList::const_iterator p;
- for(p = _inParams.begin(); p != _inParams.end(); ++p)
+ for (p = _inParams.begin(); p != _inParams.end(); ++p)
{
ContainedPtr contained2 = ContainedPtr::dynamicCast(p->first);
- if(contained2 && contained2 == contained)
+ if (contained2 && contained2 == contained)
{
return true;
}
}
- for(p = _outParams.begin(); p != _outParams.end(); ++p)
+ for (p = _outParams.begin(); p != _outParams.end(); ++p)
{
ContainedPtr contained2 = ContainedPtr::dynamicCast(p->first);
- if(contained2 && contained2 == contained)
+ if (contained2 && contained2 == contained)
{
return true;
}
@@ -2146,10 +2355,10 @@ Slice::Operation::uses(const ContainedPtr& contained)
ExceptionList::const_iterator q;
- for(q = _throws.begin(); q != _throws.end(); ++q)
+ for (q = _throws.begin(); q != _throws.end(); ++q)
{
ContainedPtr contained2 = ContainedPtr::dynamicCast(*q);
- if(contained2 && contained2 == contained)
+ if (contained2 && contained2 == contained)
{
return true;
}
@@ -2196,7 +2405,7 @@ bool
Slice::DataMember::uses(const ContainedPtr& contained)
{
ContainedPtr contained2 = ContainedPtr::dynamicCast(_type);
- if(contained2 && contained2 == contained)
+ if (contained2 && contained2 == contained)
{
return true;
}
@@ -2239,18 +2448,18 @@ Slice::Unit::setComment(const string& comment)
_currentComment = "";
string::size_type end = 0;
- while(true)
+ while (true)
{
string::size_type begin = comment.find_first_not_of(" \t\r\n*", end);
- if(begin == string::npos)
+ if (begin == string::npos)
{
break;
}
end = comment.find('\n', begin);
- if(end != string::npos)
+ if (end != string::npos)
{
- if(end + 1 > begin)
+ if (end + 1 > begin)
{
_currentComment += comment.substr(begin, end + 1 - begin);
}
@@ -2258,9 +2467,9 @@ Slice::Unit::setComment(const string& comment)
else
{
end = comment.find_last_not_of(" \t\r\n*");
- if(end != string::npos)
+ if (end != string::npos)
{
- if(end + 1 > begin)
+ if (end + 1 > begin)
{
_currentComment += comment.substr(begin, end + 1 - begin);
}
@@ -2297,13 +2506,13 @@ Slice::Unit::scanPosition(const char* s)
string::size_type idx;
idx = line.find("line");
- if(idx != string::npos)
+ if (idx != string::npos)
{
line.erase(0, idx + 4);
}
idx = line.find_first_not_of(" \t\r#");
- if(idx != string::npos)
+ if (idx != string::npos)
{
line.erase(0, idx);
}
@@ -2311,18 +2520,18 @@ Slice::Unit::scanPosition(const char* s)
_currentLine = atoi(line.c_str()) - 1;
idx = line.find_first_of(" \t\r");
- if(idx != string::npos)
+ if (idx != string::npos)
{
line.erase(0, idx);
}
idx = line.find_first_not_of(" \t\r\"");
- if(idx != string::npos)
+ if (idx != string::npos)
{
line.erase(0, idx);
idx = line.find_first_of(" \t\r\"");
- if(idx != string::npos)
+ if (idx != string::npos)
{
_currentFile = line.substr(0, idx);
line.erase(0, idx + 1);
@@ -2333,21 +2542,21 @@ Slice::Unit::scanPosition(const char* s)
}
idx = line.find_first_not_of(" \t\r");
- if(idx != string::npos)
+ if (idx != string::npos)
{
line.erase(0, idx);
int val = atoi(line.c_str());
- if(val == 1)
+ if (val == 1)
{
- if(++_currentIncludeLevel == 1)
+ if (++_currentIncludeLevel == 1)
{
- if(find(_includeFiles.begin(), _includeFiles.end(), _currentFile) == _includeFiles.end())
+ if (find(_includeFiles.begin(), _includeFiles.end(), _currentFile) == _includeFiles.end())
{
_includeFiles.push_back(_currentFile);
}
}
}
- else if(val == 2)
+ else if (val == 2)
{
--_currentIncludeLevel;
}
@@ -2355,7 +2564,7 @@ Slice::Unit::scanPosition(const char* s)
}
else
{
- if(_currentIncludeLevel == 0)
+ if (_currentIncludeLevel == 0)
{
_topLevelFile = _currentFile;
}
@@ -2366,7 +2575,7 @@ Slice::Unit::scanPosition(const char* s)
int
Slice::Unit::currentIncludeLevel()
{
- if(_all)
+ if (_all)
{
return 0;
}
@@ -2411,7 +2620,7 @@ Slice::Unit::currentContainer()
void
Slice::Unit::pushContainer(const ContainerPtr& cont)
{
- _containerStack.push(cont);
+ _containerStack.push(cont);
}
void
@@ -2434,9 +2643,9 @@ Slice::Unit::removeContent(const ContainedPtr& contained)
map<string, ContainedList>::iterator p = _contentMap.find(scoped);
assert(p != _contentMap.end());
ContainedList::iterator q;
- for(q = p->second.begin(); q != p->second.end(); ++q)
+ for (q = p->second.begin(); q != p->second.end(); ++q)
{
- if(q->get() == contained.get())
+ if (q->get() == contained.get())
{
p->second.erase(q);
return;
@@ -2453,7 +2662,7 @@ Slice::Unit::findContents(const string& scoped)
map<string, ContainedList>::const_iterator p = _contentMap.find(scoped);
- if(p != _contentMap.end())
+ if (p != _contentMap.end())
{
return p->second;
}
@@ -2467,15 +2676,15 @@ ClassList
Slice::Unit::findDerivedClasses(const ClassDefPtr& cl)
{
ClassList derived;
- for(map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
+ for (map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
{
- for(ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ for (ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
{
ClassDefPtr r = ClassDefPtr::dynamicCast(*q);
- if(r)
+ if (r)
{
ClassList bases = r->bases();
- if(find(bases.begin(), bases.end(), cl) != bases.end())
+ if (find(bases.begin(), bases.end(), cl) != bases.end())
{
derived.push_back(r);
}
@@ -2491,15 +2700,15 @@ ExceptionList
Slice::Unit::findDerivedExceptions(const ExceptionPtr& ex)
{
ExceptionList derived;
- for(map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
+ for (map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
{
- for(ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ for (ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
{
ExceptionPtr r = ExceptionPtr::dynamicCast(*q);
- if(r)
+ if (r)
{
ExceptionPtr base = r->base();
- if(base && base == ex)
+ if (base && base == ex)
{
derived.push_back(r);
}
@@ -2515,11 +2724,11 @@ ContainedList
Slice::Unit::findUsedBy(const ContainedPtr& contained)
{
ContainedList usedBy;
- for(map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
+ for (map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
{
- for(ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ for (ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
{
- if((*q)->uses(contained))
+ if ((*q)->uses(contained))
{
usedBy.push_back(*q);
}
@@ -2533,19 +2742,19 @@ Slice::Unit::findUsedBy(const ContainedPtr& contained)
bool
Slice::Unit::usesProxies()
{
- for(map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
+ for (map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
{
- for(ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ for (ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
{
ClassDeclPtr decl = ClassDeclPtr::dynamicCast(*q);
- if(decl && !decl->isLocal())
+ if (decl && !decl->isLocal())
{
return true;
}
}
}
- if(_builtins.find(Builtin::KindObjectProxy) != _builtins.end())
+ if (_builtins.find(Builtin::KindObjectProxy) != _builtins.end())
{
return true;
}
@@ -2556,30 +2765,30 @@ Slice::Unit::usesProxies()
bool
Slice::Unit::usesNonLocals()
{
- for(map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
+ for (map<string, ContainedList>::const_iterator p = _contentMap.begin(); p != _contentMap.end(); ++p)
{
- for(ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ for (ContainedList::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
{
ConstructedPtr constr = ConstructedPtr::dynamicCast(*q);
- if(constr && !constr->isLocal())
+ if (constr && !constr->isLocal())
{
return true;
}
ExceptionPtr exc = ExceptionPtr::dynamicCast(*q);
- if(exc && !exc->isLocal())
+ if (exc && !exc->isLocal())
{
return true;
}
}
}
- if(_builtins.find(Builtin::KindObject) != _builtins.end())
+ if (_builtins.find(Builtin::KindObject) != _builtins.end())
{
return true;
}
- if(_builtins.find(Builtin::KindObjectProxy) != _builtins.end())
+ if (_builtins.find(Builtin::KindObjectProxy) != _builtins.end())
{
return true;
}
@@ -2610,14 +2819,14 @@ Slice::Unit::parse(FILE* file, bool debug)
yyin = file;
int status = yyparse();
- if(_errors)
+ if (_errors)
{
status = EXIT_FAILURE;
}
- if(status == EXIT_FAILURE)
+ if (status == EXIT_FAILURE)
{
- while(!_containerStack.empty())
+ while (!_containerStack.empty())
{
popContainer();
}
@@ -2643,7 +2852,7 @@ Slice::Unit::destroy()
void
Slice::Unit::visit(ParserVisitor* visitor)
{
- if(visitor->visitUnitStart(this))
+ if (visitor->visitUnitStart(this))
{
Container::visit(visitor);
visitor->visitUnitEnd(this);
@@ -2654,7 +2863,7 @@ BuiltinPtr
Slice::Unit::builtin(Builtin::Kind kind)
{
map<Builtin::Kind, BuiltinPtr>::const_iterator p = _builtins.find(kind);
- if(p != _builtins.end())
+ if (p != _builtins.end())
{
return p->second;
}
diff --git a/cpp/test/Slice/errorDetection/DerivedRedefinition.err b/cpp/test/Slice/errorDetection/DerivedRedefinition.err
new file mode 100644
index 00000000000..3e5ac161938
--- /dev/null
+++ b/cpp/test/Slice/errorDetection/DerivedRedefinition.err
@@ -0,0 +1,6 @@
+DerivedRedefinition.ice:17: operation `op' is already defined in a base interface or class
+DerivedRedefinition.ice:18: operation `op' is already defined in a base interface or class
+DerivedRedefinition.ice:31: operation `op' is already defined in a base interface or class
+DerivedRedefinition.ice:34: ambiguous multiple inheritance: `op' is defined in two or more base classes
+DerivedRedefinition.ice:39: data member `l' is already defined in a base interface or class
+DerivedRedefinition.ice:41: data member `l' is already defined in a base interface or class
diff --git a/cpp/test/Slice/errorDetection/DerivedRedefinition.ice b/cpp/test/Slice/errorDetection/DerivedRedefinition.ice
new file mode 100644
index 00000000000..19cee9050e8
--- /dev/null
+++ b/cpp/test/Slice/errorDetection/DerivedRedefinition.ice
@@ -0,0 +1,41 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+interface Base1 {
+ void op();
+ void op2();
+};
+
+interface Derived1 extends Base1 {
+ void op(); // error
+ long op(); // error
+ void foo();
+};
+
+interface Base2 {
+ void op();
+};
+
+interface D1 extends Base1 {
+ void foo(); // OK
+};
+
+interface D2 extends D1 {
+ void op(); // error, op() in Base1
+};
+
+interface D3 extends D1, Base2 {
+ void bar(); // error, op() in Base1 and Base2
+};
+
+class c1 { long l; };
+class c2 extends c1 { double l; }; // error
+class c3 extends c1 { double d; }; // OK
+class c4 extends c3 { short l; }; // error, l in c1
diff --git a/cpp/test/Slice/errorDetection/IllegalMI.err b/cpp/test/Slice/errorDetection/IllegalMI.err
new file mode 100644
index 00000000000..9757ff2c20e
--- /dev/null
+++ b/cpp/test/Slice/errorDetection/IllegalMI.err
@@ -0,0 +1,26 @@
+IllegalMI.ice:46: ambiguous multiple inheritance: `op' is defined in two or more base classes
+IllegalMI.ice:69: operation `op' is already defined in a base interface or class
+IllegalMI.ice:91: operation `op' is already defined in a base interface or class
+IllegalMI.ice:113: operation `op' is already defined 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:604: operation `op' is already defined in a base interface or class
+IllegalMI.ice:638: operation `op' is already defined 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
diff --git a/cpp/test/Slice/errorDetection/IllegalMI.ice b/cpp/test/Slice/errorDetection/IllegalMI.ice
new file mode 100644
index 00000000000..8318949e909
--- /dev/null
+++ b/cpp/test/Slice/errorDetection/IllegalMI.ice
@@ -0,0 +1,1002 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+module M1 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ };
+
+ interface A3 extends A2, B2 { // OK
+ void ia3();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M2 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ void op();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ void op();
+ };
+
+ interface A3 extends A2, B2 { // Error
+ void ia3();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M3 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ void op();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ };
+
+ interface A3 extends A2, B2 {
+ void ia3();
+ void op(); // Error
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M4 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ void op();
+ };
+
+ interface A3 extends A2, B2 {
+ void ia3();
+ void op(); // Error
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M5 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ };
+
+ interface A3 extends A2, B2 {
+ void ia3();
+ void op(); // Error
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M6 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface A2 extends A1, B1, C1 { // OK
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M7 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface A2 extends A1, B1, C1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M8 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M9 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M10 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M11 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface D1 {
+ void id1();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // OK
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M12 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface D1 {
+ void id1();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M13 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface D1 {
+ void id1();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M14 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface D1 {
+ void id1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M15 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface D1 {
+ void id1();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M16 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface D1 {
+ void id1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M17 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface D1 {
+ void id1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M18 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface D1 {
+ void id1();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M19 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface D1 {
+ void id1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1, D1 {
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M20 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface D1 {
+ void id1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M21 {
+ interface A1 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface D1 {
+ void id1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M22 {
+ interface A1 {
+ void ia1();
+ void op();
+ };
+
+ interface B1 {
+ void ib1();
+ void op();
+ };
+
+ interface C1 {
+ void ic1();
+ void op();
+ };
+
+ interface D1 {
+ void id1();
+ void op();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // Error
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M23 {
+ interface A0 {
+ void ia0();
+ };
+
+ interface B0 {
+ void ib0();
+ };
+
+ interface A1 extends A0, B0 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface D1 {
+ void id1();
+ };
+
+ interface A2 extends A1, B1, C1, D1 { // OK
+ void ia2();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M24 {
+ interface A0 {
+ void ia0();
+ void op();
+ };
+
+ interface B0 {
+ void ib0();
+ };
+
+ interface A1 extends A0, B0 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface D1 {
+ void id1();
+ };
+
+ interface A2 extends A1, B1, C1, D1 {
+ void ia2();
+ void op(); // Error
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M25 {
+ interface A0 {
+ void ia0();
+ };
+
+ interface B0 {
+ void ib0();
+ void op();
+ };
+
+ interface A1 extends A0, B0 {
+ void ia1();
+ };
+
+ interface B1 {
+ void ib1();
+ };
+
+ interface C1 {
+ void ic1();
+ };
+
+ interface D1 {
+ void id1();
+ };
+
+ interface A2 extends A1, B1, C1, D1 {
+ void ia2();
+ void op(); // Error
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M26 {
+ // A0 B0 C0 D0 //
+ interface A0 { // \ / \ / \ //
+ void ia0(); // \ / \ / \ //
+ }; // A1 B1 C1 //
+ // / \ / \ / //
+ interface B0 { // / \ / \ / //
+ void ib0(); // A2 B2 C2 D2 //
+ }; // \ / \ / //
+ // \ / \ / //
+ interface C0 { // A3 B3 //
+ void ic0(); // \ / //
+ }; // \ / //
+ // \ / //
+ interface D0 { // \ / //
+ void id0(); // A4 //
+ };
+
+ interface A1 extends A0, B0 {
+ void ia1();
+ };
+
+ interface B1 extends C0, D0 {
+ void ib1();
+ };
+
+ interface C1 extends D0 {
+ void ic1();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ };
+
+ interface C2 extends B1 {
+ void ic2();
+ };
+
+ interface D2 extends B1, C1 {
+ void id2();
+ };
+
+ interface A3 extends A2, B2 {
+ void ia3();
+ };
+
+ interface B3 extends C2, D2 {
+ void ib3();
+ };
+
+ interface A4 extends A3, B3 { // OK
+ void ia4();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M27 {
+ // A0 B0 C0 D0 //
+ interface A0 { // \ / \ / \ //
+ void ia0(); // \ / \ / \ //
+ }; // A1 B1 C1 //
+ // / \ / \ / //
+ interface B0 { // / \ / \ / //
+ void ib0(); // A2 B2 C2 D2 //
+ }; // \ / \ / //
+ // \ / \ / //
+ interface C0 { // A3 B3 //
+ void ic0(); void op(); // \ / //
+ }; // \ / //
+ // \ / //
+ interface D0 { // \ / //
+ void id0(); // A4 //
+ };
+
+ interface A1 extends A0, B0 {
+ void ia1();
+ };
+
+ interface B1 extends C0, D0 {
+ void ib1();
+ };
+
+ interface C1 extends D0 {
+ void ic1();
+ };
+
+ interface A2 extends A1 {
+ void ia2(); void op();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ };
+
+ interface C2 extends B1 {
+ void ic2();
+ };
+
+ interface D2 extends B1, C1 {
+ void id2();
+ };
+
+ interface A3 extends A2, B2 {
+ void ia3();
+ };
+
+ interface B3 extends C2, D2 {
+ void ib3();
+ };
+
+ interface A4 extends A3, B3 { // Error
+ void ia4();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M28 {
+ // A0 B0 C0 D0 //
+ interface A0 { // \ / \ / \ //
+ void ia0(); // \ / \ / \ //
+ }; // A1 B1 C1 //
+ // / \ / \ / //
+ interface B0 { // / \ / \ / //
+ void ib0(); void op(); // A2 B2 C2 D2 //
+ }; // \ / \ / //
+ // \ / \ / //
+ interface C0 { // A3 B3 //
+ void ic0(); void op(); // \ / //
+ }; // \ / //
+ // \ / //
+ interface D0 { // \ / //
+ void id0(); // A4 //
+ };
+
+ interface A1 extends A0, B0 {
+ void ia1();
+ };
+
+ interface B1 extends C0, D0 {
+ void ib1();
+ };
+
+ interface C1 extends D0 {
+ void ic1();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ };
+
+ interface C2 extends B1 {
+ void ic2();
+ };
+
+ interface D2 extends B1, C1 {
+ void id2();
+ };
+
+ interface A3 extends A2, B2 {
+ void ia3();
+ };
+
+ interface B3 extends C2, D2 {
+ void ib3();
+ };
+
+ interface A4 extends A3, B3 { // Error
+ void ia4();
+ };
+};
+
+// ----------------------------------------------------------------------
+
+module M29 {
+ // A0 B0 C0 D0 //
+ interface A0 { // \ / \ / \ //
+ void ia0(); // \ / \ / \ //
+ }; // A1 B1 C1 //
+ // / \ / \ / //
+ interface B0 { // / \ / \ / //
+ void ib0(); void op(); // A2 B2 C2 D2 //
+ }; // \ / \ / //
+ // \ / \ / //
+ interface C0 { // A3 B3 //
+ void ic0(); // \ / //
+ }; // \ / //
+ // \ / //
+ interface D0 { // \ / //
+ void id0(); void op(); // A4 //
+ };
+
+ interface A1 extends A0, B0 {
+ void ia1();
+ };
+
+ interface B1 extends C0, D0 {
+ void ib1();
+ };
+
+ interface C1 extends D0 {
+ void ic1();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ };
+
+ interface C2 extends B1 {
+ void ic2();
+ };
+
+ interface D2 extends B1, C1 {
+ void id2();
+ };
+
+ interface A3 extends A2, B2 {
+ void ia3();
+ };
+
+ interface B3 extends C2, D2 {
+ void ib3();
+ };
+
+ interface A4 extends A3, B3 { // Error
+ void ia4();
+ };
+};
+
+module M30 {
+ // A0 B0 C0 D0 //
+ interface A0 { // \ / \ / \ //
+ void ia0(); // \ / \ / \ //
+ }; // A1 B1 C1 //
+ // / \ / \ / //
+ interface B0 { // / \ / \ / //
+ void ib0(); void op(); // A2 B2 C2 D2 //
+ }; // \ / \ / //
+ // \ / \ / //
+ interface C0 { // A3 B3 //
+ void ic0(); // \ / //
+ }; // \ / //
+ // \ / //
+ interface D0 { // \ / //
+ void id0(); // A4 //
+ };
+
+ interface A1 extends A0, B0 {
+ void ia1();
+ };
+
+ interface B1 extends C0, D0 {
+ void ib1();
+ };
+
+ interface C1 extends D0 {
+ void ic1(); void op();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ };
+
+ interface C2 extends B1 {
+ void ic2();
+ };
+
+ interface D2 extends B1, C1 {
+ void id2();
+ };
+
+ interface A3 extends A2, B2 {
+ void ia3();
+ };
+
+ interface B3 extends C2, D2 {
+ void ib3();
+ };
+
+ interface A4 extends A3, B3 { // Error
+ void ia4();
+ };
+};
+
+module M31 {
+ // A0 B0 C0 D0 //
+ interface A0 { // \ / \ / \ //
+ void ia0(); // \ / \ / \ //
+ }; // A1 B1 C1 //
+ // / \ / \ / //
+ interface B0 { // / \ / \ / //
+ void ib0(); // A2 B2 C2 D2 //
+ }; // \ / \ / //
+ // \ / \ / //
+ interface C0 { // A3 B3 //
+ void ic0(); // \ / //
+ }; // \ / //
+ // \ / //
+ interface D0 { // \ / //
+ void id0(); // A4 //
+ };
+
+ interface A1 extends A0, B0 {
+ void ia1(); void op();
+ };
+
+ interface B1 extends C0, D0 {
+ void ib1();
+ };
+
+ interface C1 extends D0 {
+ void ic1(); void op();
+ };
+
+ interface A2 extends A1 {
+ void ia2();
+ };
+
+ interface B2 extends A1 {
+ void ib2();
+ };
+
+ interface C2 extends B1 {
+ void ic2();
+ };
+
+ interface D2 extends B1, C1 {
+ void id2();
+ };
+
+ interface A3 extends A2, B2 {
+ void ia3();
+ };
+
+ interface B3 extends C2, D2 {
+ void ib3();
+ };
+
+ interface A4 extends A3, B3 { // Error
+ void ia4();
+ };
+};