18 #include "cableClass.h"
19 #include "cableClassType.h"
20 #include "cableConstructor.h"
21 #include "cableFunctionType.h"
22 #include "cableMethod.h"
23 #include "cablePointerType.h"
24 #include "cableReferenceType.h"
25 #include "cxxCvQualifiedType.h"
26 #include "cxxFunctionType.h"
27 #include "cxxPointerType.h"
30 #include "gxsys/stl/set"
31 #include "gxsys/SystemTools.hxx"
121 gxsys_stl::string s(t->GetCxxType().GetName());
125 s = t->GetCxxType().GetType()->GenerateName(
"",
false,
false);
143 if (cable::Type::ClassTypeId == t->GetTypeId())
145 c = cable::ClassType::SafeDownCast(t)->GetClass();
147 else if (cable::Type::ReferenceTypeId == t->GetTypeId())
149 c = cable::ClassType::SafeDownCast(
150 cable::ReferenceType::SafeDownCast(t)->GetTarget())->GetClass();
173 s =
"ERROR_unknown_mapped_to_type_or_null_class_type_in_the_export_layer";
191 if ((argType->GetTypeId() == cable::Type::PointerTypeId) &&
192 (cable::PointerType::SafeDownCast(argType)->GetTarget()->GetTypeId() == cable::Type::FunctionTypeId)
201 s =
"ERROR - cannot generate argTypeAndName string for function pointer - add a typedef for the function pointer...";
225 cable::FunctionType *ft = m->GetFunctionType();
226 unsigned int cArgs = ft->GetNumberOfArguments();
227 unsigned int cArgsEmitted = 0;
229 cable::Type *retType = ft->GetReturns();
230 cable::Type *argType = 0;
231 cable::Class* cByRefClass = 0;
234 Emit(os,
"extern \"C\" ");
237 Emit(os,
"MUMMY_DLL_EXPORT\n");
245 Emit(os, cname.c_str());
251 Emit(os,
"(unsigned int* mteStatus, unsigned int* mteIndex, unsigned int* rawRefCount");
254 if (emitExceptionParams)
256 Emit(os,
", unsigned int* mteExceptionIndex, void** clonedException");
262 else if (mname ==
"delete")
272 Emit(os, cname.c_str());
276 if (emitExceptionParams)
278 Emit(os,
", unsigned int* mteExceptionIndex, void** clonedException");
299 Emit(os, cname.c_str());
310 for (i= 0; i<cArgs; ++i)
312 argType = ft->GetArgument(i);
320 if (cable::Type::ReferenceTypeId == argType->GetTypeId())
322 cable::ClassType* classType = cable::ClassType::SafeDownCast(
323 cable::ReferenceType::SafeDownCast(argType)->GetTarget());
326 cByRefClass = classType->GetClass();
358 Emit(os,
"unsigned int* mteStatus, unsigned int* mteIndex, unsigned int* rawRefCount");
362 if (emitExceptionParams)
369 Emit(os,
"unsigned int* mteExceptionIndex, void** clonedException");
383 if (!this->
GetSettings()->FindClassWrappingSettings(cname.c_str(), &cws))
386 <<
"error: no ClassWrappingSettings for class " << cname.c_str());
390 Emit(os,
"if (0 != rv)\n");
400 if (!registerMethod.empty())
403 Emit(os, registerBaseClass.c_str());
404 Emit(os,
"* ro = (");
405 Emit(os, registerBaseClass.c_str());
406 Emit(os,
"*) (void*) rv;\n");
410 if (!registerMethod.empty() && !getMummyTypeEntryMethod.empty())
415 Emit(os,
"Kitware::mummy::TypeEntry* entry = ro->");
416 Emit(os, getMummyTypeEntryMethod.c_str());
419 Emit(os,
"if (!entry)\n");
423 Emit(os,
"entry = Kitware::mummy::Runtime::GetTypeEntry((void*) rv, typeid(*ro).name());\n");
426 Emit(os, setMummyTypeEntryMethod.c_str());
427 Emit(os,
"(entry);\n");
429 Emit(os,
"*mteStatus = 1;\n");
437 Emit(os,
"*mteStatus = 2;\n");
446 Emit(os,
"Kitware::mummy::TypeEntry* entry = Kitware::mummy::Runtime::GetTypeEntry(\n");
449 Emit(os,
"(void*) rv, typeid(*");
450 if (!registerMethod.empty())
461 Emit(os,
").name());\n");
464 Emit(os,
"*mteStatus = 0;\n");
470 Emit(os,
"*mteIndex = entry->GetIndex();\n");
472 if (!registerMethod.empty() && !getRefCountMethod.empty())
475 Emit(os,
"*rawRefCount = (unsigned int) ro->");
476 Emit(os, getRefCountMethod.c_str());
482 Emit(os,
"*rawRefCount = (unsigned int) -86;\n");
494 cable::FunctionType *ft = m->GetFunctionType();
495 unsigned int cArgs = ft->GetNumberOfArguments();
497 unsigned int indent = 1;
498 cable::Type *retType = ft->GetReturns();
499 cable::PointerType::Pointer fakeRetType;
500 bool voidReturn =
false;
501 bool mappedReturnType =
false;
502 bool emitExceptionBlock =
false;
503 gxsys_stl::string rvTypeStr;
504 bool needsInit =
false;
505 gxsys_stl::string initExpression;
520 fakeRetType = cable::PointerType::New();
521 fakeRetType->SetTarget(c->GetClassType());
522 fakeRetType->CreateCxxType(this->GetSourceRepresentation()->GetTypeSystem());
523 retType = fakeRetType;
534 mappedReturnType =
true;
546 if (cable::Type::ReferenceTypeId == retType->GetTypeId())
549 cable::ReferenceType::SafeDownCast(retType)->GetTarget(), 0,
false) +
">";
552 else if (mappedReturnType)
557 initExpression =
"cast";
571 Emit(os, rvTypeStr.c_str());
576 if (initExpression ==
"memset")
580 Emit(os,
"memset(&rv, 0, sizeof(rv))");
582 else if (initExpression ==
"cast")
585 Emit(os, rvTypeStr.c_str());
591 Emit(os, initExpression.c_str());
601 if (emitExceptionBlock)
616 if (mappedReturnType)
619 Emit(os,
" rvmi = ");
633 Emit(os, cname.c_str());
637 else if (mname ==
"delete")
639 Emit(os,
"delete pThis;");
650 Emit(os, cname.c_str());
654 Emit(os, mname.c_str());
656 for (i= 0; i<cArgs; ++i)
672 if (mappedReturnType)
681 Emit(os,
" rvm = rvmi.");
682 Emit(os, mapping_method.c_str());
685 if (map_to_type ==
"string")
688 Emit(os,
"size_t n = 0;\n");
691 Emit(os,
"if (rvm)\n");
695 Emit(os,
"n = strlen(rvm);\n");
700 Emit(os,
"rv = (char*) MUMMY_STRING_ALLOC(n+1);\n");
702 Emit(os,
"if (rv)\n");
706 Emit(os,
"strncpy(rv, rvm, n);\n");
708 Emit(os,
"rv[n] = 0;\n");
716 <<
"Unknown iwhMapToType for return type of method '" << m->GetName() <<
"'");
721 const cable::Class* cRetType = cable::ClassType::SafeDownCast(
722 cable::PointerType::SafeDownCast(retType)->GetTarget()
729 if (emitExceptionBlock)
736 Emit(os,
"& mel_exc)\n");
742 Emit(os,
"* mel_exc_clone = mel_exc.");
747 Emit(os,
"Kitware::mummy::TypeEntry* entry = Kitware::mummy::Runtime::GetTypeEntry(\n");
750 Emit(os,
"(void*) mel_exc_clone, typeid(*mel_exc_clone).name());\n");
753 Emit(os,
"*clonedException = mel_exc_clone;\n");
756 Emit(os,
"*mteExceptionIndex = entry->GetIndex();\n");
767 Emit(os,
"return rv;\n");
778 gxsys_stl::string header(c->GetFile());
797 Emit(os,
"//----------------------------------------------------------------------------\n");
798 Emit(os,
"// Unmanaged class '");
800 Emit(os,
"' maps directly to type '");
801 Emit(os, mapToType.c_str());
803 Emit(os,
"// No code generated for '");
807 LogVerboseInfo(<<
"Skipping code generation because class maps directly to native type.");
813 Emit(os,
"//----------------------------------------------------------------------------\n");
814 Emit(os,
"// You can use this symbol in your header files if there are bits of your\n");
815 Emit(os,
"// code that should be conditionally compiled in this export layer.\n");
817 Emit(os,
"#define MUMMY_EXPORT_LAYER_CXX\n");
819 Emit(os,
"//----------------------------------------------------------------------------\n");
820 Emit(os,
"// Do not emit the silly C4996 warning for strncpy use:\n");
822 Emit(os,
"#ifndef _CRT_SECURE_NO_DEPRECATE\n");
823 Emit(os,
"#define _CRT_SECURE_NO_DEPRECATE\n");
824 Emit(os,
"#endif\n");
826 Emit(os,
"//----------------------------------------------------------------------------\n");
827 Emit(os,
"// Forward declare functions that generated code might call...\n");
829 Emit(os,
"#ifdef _WIN64\n");
830 Emit(os,
"extern \"C\" __declspec(dllimport) void* __stdcall CoTaskMemAlloc(unsigned __int64 cb);\n");
831 Emit(os,
"#define MUMMY_STRING_ALLOC ::CoTaskMemAlloc\n");
833 Emit(os,
"#ifdef _WIN32\n");
834 Emit(os,
"extern \"C\" __declspec(dllimport) void* __stdcall CoTaskMemAlloc(unsigned long cb);\n");
835 Emit(os,
"#define MUMMY_STRING_ALLOC ::CoTaskMemAlloc\n");
836 Emit(os,
"#endif\n");
837 Emit(os,
"#endif\n");
839 Emit(os,
"#ifndef MUMMY_STRING_ALLOC\n");
840 Emit(os,
"#define MUMMY_STRING_ALLOC malloc\n");
841 Emit(os,
"#endif\n");
843 Emit(os,
"//----------------------------------------------------------------------------\n");
844 Emit(os,
"// Macro for exporting functions implemented in this file...\n");
846 Emit(os,
"#ifdef _WIN32\n");
847 Emit(os,
"#define MUMMY_DLL_EXPORT __declspec(dllexport)\n");
849 Emit(os,
"#define MUMMY_DLL_EXPORT\n");
850 Emit(os,
"#endif\n");
852 Emit(os,
"//----------------------------------------------------------------------------\n");
853 Emit(os,
"#include \"");
854 Emit(os, header.c_str());
867 gxsys_stl::vector<cable::Method*> wrapped_methods;
868 cable::Method *factoryM = 0;
869 cable::Method *disposalM = 0;
870 cable::Method *registerM = 0;
871 cable::Method *unRegisterM = 0;
877 bool hasMethodsThatReturnRefs =
false;
878 for(gxsys_stl::vector<cable::Method*>::iterator mit = wrapped_methods.begin();
879 !hasMethodsThatReturnRefs && mit != wrapped_methods.end(); ++mit)
881 cable::FunctionType *ft = (*mit)->GetFunctionType();
882 cable::Type *retType = ft->GetReturns();
883 if (cable::Type::ReferenceTypeId == retType->GetTypeId())
885 hasMethodsThatReturnRefs =
true;
889 if (hasMethodsThatReturnRefs)
891 Emit(os,
"//----------------------------------------------------------------------------\n");
892 Emit(os,
"// Thanks to Brad King for the magic of the ref converter helper class:\n");
893 Emit(os,
"template <typename T>\n");
894 Emit(os,
"class ref\n");
896 Emit(os,
"public:\n");
898 Emit(os,
"ref() throw(): p_(0) {}\n");
900 Emit(os,
"ref<T>& operator=(T& r) throw() { this->p_ = &r; return *this; }\n");
902 Emit(os,
"operator T&() throw() { return *this->p_; }\n");
904 Emit(os,
"private:\n");
906 Emit(os,
"T* p_;\n");
915 gxsys_stl::set<gxsys_stl::string> includeStatements;
917 gxsys_stl::string registerInclude;
921 if (!registerInclude.empty())
923 includeStatements.insert(registerInclude);
927 for(gxsys_stl::vector<cable::Method*>::iterator mit = wrapped_methods.begin();
928 mit != wrapped_methods.end(); ++mit)
930 cable::FunctionType *ft = (*mit)->GetFunctionType();
931 cable::Type *retType = ft->GetReturns();
934 const cable::Class* cRetType = cable::ClassType::SafeDownCast(
935 cable::PointerType::SafeDownCast(retType)->GetTarget()
938 if (!registerInclude.empty())
940 includeStatements.insert(registerInclude);
945 includeStatements.insert(
"#include \"MummyRuntime.h\"");
946 includeStatements.insert(
"#include \"string.h\" // for possible memset use");
948 if (!cws.exceptionInclude.empty())
950 includeStatements.insert(cws.exceptionInclude);
953 if (!includeStatements.empty())
956 Emit(os,
"//----------------------------------------------------------------------------\n");
958 for(gxsys_stl::set<gxsys_stl::string>::iterator sit = includeStatements.begin();
959 sit != includeStatements.end(); ++sit)
961 Emit(os, sit->c_str());
973 Emit(os,
"//----------------------------------------------------------------------------\n");
981 Emit(os,
"//----------------------------------------------------------------------------\n");
989 Emit(os,
"//----------------------------------------------------------------------------\n");
997 Emit(os,
"//----------------------------------------------------------------------------\n");
1008 Emit(os,
"//----------------------------------------------------------------------------\n");
1013 Emit(os,
"//----------------------------------------------------------------------------\n");
1017 for(gxsys_stl::vector<cable::Method*>::iterator mit = wrapped_methods.begin();
1018 mit != wrapped_methods.end(); ++mit)
1022 Emit(os,
"//----------------------------------------------------------------------------\n");
1032 if (extraCode !=
"")
1036 Emit(os,
"//----------------------------------------------------------------------------\n");
1037 Emit(os,
"// Begin extraExportLayerCode\n");
1041 Emit(os,
"// End extraExportLayerCode\n");
virtual void EmitClassMethodDeclarationForExportLayer(gxsys_ios::ostream &os, const cable::Class *c, const cable::Method *m, const gxsys_stl::string &mname, bool emitExceptionParams)
gxsys_stl::string getMummyTypeEntryMethod
void Emit(gxsys_ios::ostream &os, const char *s)
virtual const char * GetArgName(cable::FunctionType *ftype, unsigned int i)
virtual void EmitSpecialHandlingForObjectPointerReturns(gxsys_ios::ostream &os, const gxsys_stl::string &cname, const cable::Method *m, const gxsys_stl::string &mname, const unsigned int indent)
gxsys_stl::string registerMethod
#define LogVerboseInfo(m)
virtual gxsys_stl::string GetExportLayerFunctionName(const cable::Class *c, const cable::Method *m, const gxsys_stl::string &mname)
void EmitIndent(gxsys_ios::ostream &os, const unsigned int n)
gxsys_stl::string GetMapToType(const cable::Type *t)
virtual gxsys_stl::string GetExtraExportLayerCode(const cable::Class *c)
MummyCsharpExportLayerGenerator()
bool EquivalentTypedefNameExists(const cable::Class *c, const cable::FunctionType *target, gxsys_stl::string &s)
bool HasMapToType(const cable::Type *t)
virtual gxsys_stl::string GetExportLayerFunctionName(const cable::Class *c, const cable::Method *m, const gxsys_stl::string &mname)
gxsys_stl::string GetStringMethod(const cable::Type *t)
gxsys_stl::string GetFullyQualifiedNameForCPlusPlus(const cable::Named *n)
gxsys_stl::string GetCPlusPlusZeroInitializerExpression(const cable::Type *t)
gxsys_stl::string setMummyTypeEntryMethod
gxsys_stl::string getRefCountMethod
gxsys_stl::string exceptionCloneMethod
bool IsUtilityClass(const cable::Class *c)
bool IsVoid(const cable::Type *t)
#define LogFileLineErrorMsg(file, line, n, m)
bool IsObjectPointer(const cable::Type *t)
gxsys_stl::string GetExportLayerMappedType(cable::Type *t, bool stripConst)
virtual const char * GetArgName(cable::FunctionType *ftype, unsigned int i)
gxsys_stl::string ExtractMapToType(const cable::SourceObject *o)
virtual gxsys_stl::string GetArgTypeAndNameString(cable::Type *argType, const char *name, bool stripConst)
gxsys_stl::string GetExportLayerActualType(cable::Type *t, bool stripConst)
virtual ~MummyCsharpExportLayerGenerator()
gxsys_stl::string registerBaseClass
virtual void SetCsharpGenerator(MummyCsharpGenerator *generator)
virtual gxsys_stl::string GetRegisterInclude(const cable::Class *c)
virtual const cable::Class * GetTargetClass()
Get the current target class.
virtual void EmitClassForExportLayer(gxsys_ios::ostream &os, const cable::Class *c)
void EmitFile(gxsys_ios::ostream &os, const char *filename)
const cable::Constructor * FindNonAbstractPublicDefaultConstructor(const cable::Class *c)
virtual void EmitClassMethodForExportLayer(gxsys_ios::ostream &os, const cable::Class *c, const cable::Method *m, const gxsys_stl::string &mname)
virtual void GatherWrappedMethods(const cable::Class *c, gxsys_stl::vector< cable::Method * > &wrapped_methods, cable::Method *&factoryM, cable::Method *&disposalM, cable::Method *®isterM, cable::Method *&unRegisterM, bool includeParentMethods)
MummyCsharpGenerator * CsharpGenerator
virtual void EmitMummyVersionComments(gxsys_ios::ostream &os, const char *lineCommentString)
gxsys_stl::string exceptionBaseClass
virtual bool FindClassWrappingSettings(const char *name, ClassWrappingSettings *cws)
virtual MummySettings * GetSettings()
Get the associated settings object.
virtual bool GenerateWrappers()
virtual MummyCsharpGenerator * GetCsharpGenerator()