Skip to content

Commit d5acf06

Browse files
committed
Added c++ enum classes
Signed-off-by: Cervenka Dusan <cervenka@acrios.com>
1 parent fed7be6 commit d5acf06

27 files changed

+385
-90
lines changed

erpcgen/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ SOURCES += $(OBJS_ROOT)/erpcgen_parser.tab.cpp \
7171
.SECONDARY: $(OBJS_ROOT)/erpcgen_parser.tab.cpp \
7272
$(OBJS_ROOT)/erpcgen_lexer.cpp \
7373
$(OBJS_ROOT)/erpcgen/src/templates/c_common_header.c \
74+
$(OBJS_ROOT)/erpcgen/src/templates/cpp_common_header.c \
7475
$(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_header.c \
7576
$(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_source.c \
7677
$(OBJS_ROOT)/erpcgen/src/templates/cpp_client_header.c \
@@ -93,6 +94,7 @@ SOURCES += $(OBJS_ROOT)/erpcgen_parser.tab.cpp \
9394
$(OBJS_ROOT)/erpcgen/src/templates/py_global_init.c
9495

9596
SOURCES += $(OBJS_ROOT)/erpcgen/src/templates/c_common_header.c \
97+
$(OBJS_ROOT)/erpcgen/src/templates/cpp_common_header.c \
9698
$(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_header.c \
9799
$(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_source.c \
98100
$(OBJS_ROOT)/erpcgen/src/templates/cpp_client_header.c \

erpcgen/VisualStudio_v14/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ erpcgen_parser.tab.cpp
44
erpcgen_parser.tab.hpp
55

66
# templates
7+
cpp_common_header.cpp
78
cpp_client_source.cpp
89
cpp_client_header.cpp
910
cpp_server_header.cpp

erpcgen/VisualStudio_v14/erpcgen.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
<PreBuildEvent>
100100
<Command>python.exe ..\bin\txt_to_c.py --output .\cpp_coders.cpp ..\src\templates\cpp_coders.template
101101
python.exe ..\bin\txt_to_c.py --output .\c_common_header.cpp ..\src\templates\c_common_header.template
102+
python.exe ..\bin\txt_to_c.py --output .\cpp_common_header.cpp ..\src\templates\cpp_common_header.template
102103
python.exe ..\bin\txt_to_c.py --output .\cpp_interface_header.cpp ..\src\templates\cpp_interface_header.template
103104
python.exe ..\bin\txt_to_c.py --output .\cpp_interface_source.cpp ..\src\templates\cpp_interface_source.template
104105
python.exe ..\bin\txt_to_c.py --output .\cpp_client_header.cpp ..\src\templates\cpp_client_header.template
@@ -146,6 +147,7 @@ python.exe ..\bin\txt_to_c.py --output .\py_global_init.cpp ..\src\templates\py_
146147
<PreBuildEvent>
147148
<Command>python.exe ..\bin\txt_to_c.py --output .\cpp_coders.cpp ..\src\templates\cpp_coders.template
148149
python.exe ..\bin\txt_to_c.py --output .\c_common_header.cpp ..\src\templates\c_common_header.template
150+
python.exe ..\bin\txt_to_c.py --output .\cpp_common_header.cpp ..\src\templates\cpp_common_header.template
149151
python.exe ..\bin\txt_to_c.py --output .\cpp_interface_header.cpp ..\src\templates\cpp_interface_header.template
150152
python.exe ..\bin\txt_to_c.py --output .\cpp_interface_source.cpp ..\src\templates\cpp_interface_source.template
151153
python.exe ..\bin\txt_to_c.py --output .\cpp_client_header.cpp ..\src\templates\cpp_client_header.template
@@ -245,6 +247,7 @@ python.exe ..\bin\txt_to_c.py --output .\py_global_init.cpp ..\src\templates\py_
245247
<ClCompile Include="..\src\Utils.cpp" />
246248
<ClCompile Include="cpp_coders.cpp" />
247249
<ClCompile Include="c_common_header.cpp" />
250+
<ClCompile Include="cpp_common_header.cpp" />
248251
<ClCompile Include="c_crc.cpp" />
249252
<ClCompile Include="cpp_interface_header.cpp" />
250253
<ClCompile Include="cpp_interface_source.cpp" />

erpcgen/VisualStudio_v14/erpcgen.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@
170170
<ClCompile Include="c_common_header.cpp">
171171
<Filter>Source Files</Filter>
172172
</ClCompile>
173+
<ClCompile Include="cpp_common_header.cpp">
174+
<Filter>Source Files</Filter>
175+
</ClCompile>
173176
<ClCompile Include="cpp_interface_header.cpp">
174177
<Filter>Source Files</Filter>
175178
</ClCompile>

erpcgen/src/CGenerator.cpp

Lines changed: 132 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -98,22 +98,13 @@ void CGenerator::generateOutputFiles(const string &fileName)
9898
generateServerCSourceFile(fileName);
9999
}
100100

101-
void CGenerator::generateCommonCHeaderFiles(string fileName)
102-
{
103-
fileName += "_common.h";
104-
m_templateData["commonGuardMacro"] = generateIncludeGuardName(fileName);
105-
m_templateData["commonCHeaderName"] = fileName;
106-
m_templateData["cCommonHeaderFile"] = true;
107-
generateOutputFile(fileName, "c_common_header", m_templateData, kCCommonHeader);
108-
}
109-
110101
void CGenerator::generateCommonCppHeaderFiles(string fileName)
111102
{
112103
fileName += "_common.hpp";
113104
m_templateData["commonGuardMacro"] = generateIncludeGuardName(fileName);
114105
m_templateData["commonCppHeaderName"] = fileName;
115106
m_templateData["cCommonHeaderFile"] = false;
116-
generateOutputFile(fileName, "c_common_header", m_templateData, kCCommonHeader);
107+
generateOutputFile(fileName, "cpp_common_header", m_templateData, kCppCommonHeader);
117108
}
118109

119110
void CGenerator::generateInterfaceCppHeaderFile(string fileName)
@@ -163,6 +154,15 @@ void CGenerator::generateServerCppSourceFile(string fileName)
163154
generateOutputFile(fileName, "cpp_server_source", m_templateData, kCppServerSource);
164155
}
165156

157+
void CGenerator::generateCommonCHeaderFiles(string fileName)
158+
{
159+
fileName = "c_" + fileName + "_common.h";
160+
m_templateData["commonGuardMacro"] = generateIncludeGuardName(fileName);
161+
m_templateData["commonCHeaderName"] = fileName;
162+
m_templateData["cCommonHeaderFile"] = true;
163+
generateOutputFile(fileName, "c_common_header", m_templateData, kCCommonHeader);
164+
}
165+
166166
void CGenerator::generateClientCHeaderFile(string fileName)
167167
{
168168
fileName = "c_" + fileName + "_client.h";
@@ -760,38 +760,52 @@ void CGenerator::makeAliasesTemplateData()
760760

761761
if (elementDataType->getName() != "")
762762
{
763-
string realType;
763+
string realTypeC;
764+
string realTypeCpp;
764765
if (elementDataType->isFunction())
765766
{
766-
realType = getOutputName(aliasType);
767+
realTypeC = getOutputName(aliasType);
767768
aliasInfo["name"] = elementDataType->getName();
768769
}
769770
else
770771
{
771-
realType = getTypenameName(elementDataType, getOutputName(aliasType));
772+
realTypeC = getTypenameName(elementDataType, getOutputName(aliasType));
772773
aliasInfo["name"] = getOutputName(aliasType);
773774
}
774775

775-
Log::info("%s\n", realType.c_str());
776+
Log::info("%s\n", realTypeC.c_str());
776777

777778
/* For case typedef struct/union */
778779
if (elementDataType->getName() == aliasType->getName() ||
779780
getOutputName(elementDataType, false) == aliasType->getName())
780781
{
781782
if (elementDataType->isStruct())
782783
{
783-
realType = "struct " + realType;
784+
realTypeC = "struct " + realTypeC;
785+
realTypeCpp = "struct " + aliasType->getName();
784786
}
785787
else
786788
{
787-
realType = "union " + realType;
789+
realTypeC = "union " + realTypeC;
790+
realTypeCpp = "union " + aliasType->getName();
788791
}
789792
}
790793

791-
aliasInfo["typenameName"] = realType;
794+
if (elementDataType->getName() == aliasType->getName())
795+
{
796+
aliasInfo["forwardDecl"] = realTypeC;
797+
aliasInfo["forwardDeclCpp"] = realTypeCpp;
798+
aliasInfo["typenameName"] = "";
799+
}
800+
else
801+
{
802+
aliasInfo["typenameName"] = realTypeC;
803+
aliasInfo["forwardDecl"] = "";
804+
}
792805
}
793806
else
794807
{
808+
aliasInfo["forwardDecl"] = "";
795809
aliasInfo["typenameName"] = "";
796810
aliasInfo["unnamedName"] = getOutputName(aliasType);
797811
switch (elementDataType->getDataType())
@@ -1351,11 +1365,18 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn)
13511365
info["isNonExternalFunction"] = !findAnnotation(fnSymbol, EXTERNAL_ANNOTATION);
13521366

13531367
// Get return value info
1354-
data_map returnInfo;
1355-
returnInfo["type"] = getTypeInfo(fn->getReturnType(), true);
1356-
StructMember *structMember = fn->getReturnStructMemberType();
13571368
DataType *dataType = fn->getReturnType();
13581369
DataType *trueDataType = dataType->getTrueDataType();
1370+
data_map returnInfo;
1371+
returnInfo["type"] = getTypeInfo(dataType, true);
1372+
StructMember *structMember = fn->getReturnStructMemberType();
1373+
// TODO: in case we want distinguish cpp and c type macro
1374+
// std::string retypeName = "";
1375+
// if (dataType->isArray())
1376+
// {
1377+
// retypeName = "*";
1378+
// }
1379+
// returnInfo["typename"] = getTypenameName(dataType, retypeName);
13591380
if (!trueDataType->isVoid())
13601381
{
13611382
string result = "result";
@@ -1568,6 +1589,29 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn)
15681589
paramInfo["shared"] = isShared;
15691590
paramInfo["pureName"] = name;
15701591
paramInfo["pureNameC"] = pureCName;
1592+
// TODO: in case we want distinguish cpp and c type macro
1593+
// std::string retypeParamName = "";
1594+
// bool isDoubleArray = false;
1595+
// if (paramType->isArray())
1596+
// {
1597+
// ArrayType *paramArrayType = dynamic_cast<ArrayType *>(paramType);
1598+
// retypeParamName = getTypenameName(paramArrayType->getElementType(), "*");
1599+
// isDoubleArray = paramArrayType->getElementType()->isArray();
1600+
// }
1601+
// else
1602+
// {
1603+
// retypeParamName = getTypenameName(paramType, "");
1604+
// }
1605+
// if (!paramType->getTrueContainerDataType()->isBuiltin() || paramType->isAlias())
1606+
// {
1607+
// retypeParamName = m_templateData["namespace"].get().get()->getvalue() + "::" + retypeParamName;
1608+
// }
1609+
// if ((param->getDirection() == kInDirection) && (isDoubleArray == false) &&
1610+
// (!paramType->getTrueContainerDataType()->isString()))
1611+
// {
1612+
// retypeParamName = "const " + retypeParamName;
1613+
// }
1614+
// paramInfo["typename"] = retypeParamName;
15711615
string encodeDecodeName;
15721616
if (isShared)
15731617
{
@@ -1886,6 +1930,10 @@ string CGenerator::getErrorReturnValue(FunctionBase *fn)
18861930
return (integerValue->getValue()) ? "true" : "false";
18871931
}
18881932
}
1933+
else if (dataType->isEnum())
1934+
{
1935+
return fn->getReturnType()->getName() + "::" + returnVal->toString();
1936+
}
18891937
return returnVal->toString();
18901938
}
18911939
else
@@ -2747,7 +2795,39 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT
27472795
for (auto unionCase : unionType->getCases())
27482796
{
27492797
data_map caseData;
2750-
caseData["name"] = unionCase->getCaseName();
2798+
DataType *caseDataType = unionCase->getCaseDataType();
2799+
std::string caseName;
2800+
caseData["caseCast"] = "";
2801+
if (caseDataType == nullptr)
2802+
{
2803+
caseName = "";
2804+
}
2805+
else
2806+
{
2807+
if (unionType->isNonEncapsulatedUnion())
2808+
{
2809+
caseData["caseCast"] = "int32_t";
2810+
}
2811+
else
2812+
{
2813+
DataType *disType = getDiscriminatorType(unionType, structType, structMember);
2814+
if (disType != nullptr)
2815+
{
2816+
std::string disName;
2817+
if (disType->isBuiltin())
2818+
{
2819+
disName = getBuiltinTypename(dynamic_cast<BuiltinType *>(disType));
2820+
}
2821+
else
2822+
{
2823+
disName = disType->getName();
2824+
}
2825+
caseData["caseCast"] = (disName == caseDataType->getName()) ? "" : disName;
2826+
}
2827+
}
2828+
caseName = caseDataType->getName() + "::";
2829+
}
2830+
caseData["name"] = caseName + unionCase->getCaseName();
27512831
caseData["value"] = unionCase->getCaseValue();
27522832
// if current case need call free function, default false
27532833
caseData["needCaseFreeingCall"] = false;
@@ -3337,6 +3417,37 @@ bool CGenerator::setDiscriminatorTemp(UnionType *unionType, StructType *structTy
33373417
return needTempVariableI32;
33383418
}
33393419

3420+
DataType *CGenerator::getDiscriminatorType(UnionType *unionType, StructType *structType, StructMember *structMember)
3421+
{
3422+
DataType *retVal = nullptr;
3423+
3424+
if (structType)
3425+
{
3426+
string discriminatorName;
3427+
Symbol *disSymbol;
3428+
3429+
if (unionType->isNonEncapsulatedUnion())
3430+
{
3431+
discriminatorName = getAnnStringValue(structMember, DISCRIMINATOR_ANNOTATION);
3432+
disSymbol = m_globals->getSymbol(discriminatorName, false);
3433+
ConstType *constType = dynamic_cast<ConstType *>(disSymbol);
3434+
assert(constType);
3435+
retVal = constType->getDataType();
3436+
}
3437+
else
3438+
{
3439+
discriminatorName = unionType->getDiscriminatorName();
3440+
disSymbol = structType->getScope().getSymbol(discriminatorName);
3441+
assert(disSymbol);
3442+
StructMember *disMember = dynamic_cast<StructMember *>(disSymbol);
3443+
assert(disMember);
3444+
retVal = disMember->getDataType();
3445+
}
3446+
}
3447+
3448+
return retVal;
3449+
}
3450+
33403451
string CGenerator::getScalarTypename(DataType *dataType)
33413452
{
33423453
if (dataType->getTrueDataType()->isScalar())

erpcgen/src/CGenerator.hpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ class CGenerator : public Generator
6262
cpptempl::data_list m_symbolsTemplate; /*!< List of all symbol templates */
6363

6464
std::vector<ListType *>
65-
m_listBinaryTypes; /*!<
66-
* Contains binary types transformed to list<uint8>.
67-
* More ListType are present when @length annotation is used for binary type.
68-
* If binary without @length is used then it is placed on first place in this vector.
69-
*/
65+
m_listBinaryTypes; /*!<
66+
* Contains binary types transformed to list<uint8>.
67+
* More ListType are present when @length annotation is used for binary type.
68+
* If binary without @length is used then it is placed on first place in this vector.
69+
*/
7070

7171
std::vector<StructType *> m_structListTypes; /*!<
7272
* Contains list types transformed to struct{list<>}.
@@ -757,9 +757,31 @@ class CGenerator : public Generator
757757
*/
758758
void setNoSharedAnn(Symbol *parentSymbol, Symbol *childSymbol);
759759

760+
/*!
761+
* @brief Set template data related to discriminator
762+
*
763+
* @param unionType Union for which discriminator are data related
764+
* @param structType Structure for which discriminator are data related
765+
* @param structMember Structure member for which discriminator are data related
766+
* @param isFunctionParam Is discriminator function parameter?
767+
* @param templateData Object where data are stored.
768+
*
769+
* @return bool Return true if temporary variable need be generated.
770+
*/
760771
bool setDiscriminatorTemp(UnionType *unionType, StructType *structType, StructMember *structMember,
761772
bool isFunctionParam, cpptempl::data_map &templateData);
762773

774+
/*!
775+
* @brief Get the Discriminator type.
776+
*
777+
* @param unionType Union for which discriminator are data related
778+
* @param structType Structure for which discriminator are data related
779+
* @param structMember Structure member for which discriminator are data related
780+
*
781+
* @return DataType* Nullptr or discriminator data type.
782+
*/
783+
DataType *getDiscriminatorType(UnionType *unionType, StructType *structType, StructMember *structMember);
784+
763785
/*!
764786
* @brief This function returns data type name for scalar data type.
765787
*

erpcgen/src/SymbolScanner.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,24 @@ AstNode *SymbolScanner::handleUnionCase(AstNode *node, bottom_up)
920920
caseIdIntValue = (uint32_t) dynamic_cast<IntegerValue *>(caseIdValue)->getValue();
921921
const string caseIdName = caseIdTok.getStringValue();
922922
Log::debug("union case id name: %s\n", caseIdName.c_str());
923-
newCase = new UnionCase(caseIdName, caseIdIntValue);
923+
DataType *caseDataType = nullptr;
924+
for (Symbol *enumSymbol : m_globals->getSymbolsOfType(Symbol::kTypenameSymbol))
925+
{
926+
if (enumSymbol->isDatatypeSymbol())
927+
{
928+
DataType *datatype = dynamic_cast<DataType *>(enumSymbol);
929+
if (datatype->isEnum())
930+
{
931+
EnumType *enumType = dynamic_cast<EnumType *>(enumSymbol);
932+
EnumMember *enumMember = enumType->getMember(caseIdName);
933+
if (enumMember != nullptr)
934+
{
935+
caseDataType = enumType;
936+
}
937+
}
938+
}
939+
}
940+
newCase = new UnionCase(caseDataType, caseIdName, caseIdIntValue);
924941
delete caseIdValue;
925942
}
926943
/* If there is no identifier, simply record the case value */

erpcgen/src/templates/c_common_header.template

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ extern "C"
6060
// Aliases data types declarations
6161
{% for alias in aliases %}
6262
{$> alias.mlComment}
63-
{% if alias.typenameName == "" %}
63+
{% if alias.forwardDecl != "" %}
64+
typedef {$alias.forwardDecl};{$alias.ilComment}
65+
{% elif alias.typenameName == "" %}
6466
typedef {$alias.unnamedType}
6567
{
6668
{% for mem in alias.unnamed.members %}

0 commit comments

Comments
 (0)