Skip to content

Commit

Permalink
Added c++ enum classes
Browse files Browse the repository at this point in the history
Signed-off-by: Cervenka Dusan <[email protected]>
  • Loading branch information
Hadatko committed Sep 22, 2023
1 parent f1b0bf3 commit 393ea9b
Show file tree
Hide file tree
Showing 27 changed files with 385 additions and 90 deletions.
2 changes: 2 additions & 0 deletions erpcgen/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ SOURCES += $(OBJS_ROOT)/erpcgen_parser.tab.cpp \
.SECONDARY: $(OBJS_ROOT)/erpcgen_parser.tab.cpp \
$(OBJS_ROOT)/erpcgen_lexer.cpp \
$(OBJS_ROOT)/erpcgen/src/templates/c_common_header.c \
$(OBJS_ROOT)/erpcgen/src/templates/cpp_common_header.c \
$(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_header.c \
$(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_source.c \
$(OBJS_ROOT)/erpcgen/src/templates/cpp_client_header.c \
Expand All @@ -93,6 +94,7 @@ SOURCES += $(OBJS_ROOT)/erpcgen_parser.tab.cpp \
$(OBJS_ROOT)/erpcgen/src/templates/py_global_init.c

SOURCES += $(OBJS_ROOT)/erpcgen/src/templates/c_common_header.c \
$(OBJS_ROOT)/erpcgen/src/templates/cpp_common_header.c \
$(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_header.c \
$(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_source.c \
$(OBJS_ROOT)/erpcgen/src/templates/cpp_client_header.c \
Expand Down
1 change: 1 addition & 0 deletions erpcgen/VisualStudio_v14/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ erpcgen_parser.tab.cpp
erpcgen_parser.tab.hpp

# templates
cpp_common_header.cpp
cpp_client_source.cpp
cpp_client_header.cpp
cpp_server_header.cpp
Expand Down
3 changes: 3 additions & 0 deletions erpcgen/VisualStudio_v14/erpcgen.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
<PreBuildEvent>
<Command>python.exe ..\bin\txt_to_c.py --output .\cpp_coders.cpp ..\src\templates\cpp_coders.template
python.exe ..\bin\txt_to_c.py --output .\c_common_header.cpp ..\src\templates\c_common_header.template
python.exe ..\bin\txt_to_c.py --output .\cpp_common_header.cpp ..\src\templates\cpp_common_header.template
python.exe ..\bin\txt_to_c.py --output .\cpp_interface_header.cpp ..\src\templates\cpp_interface_header.template
python.exe ..\bin\txt_to_c.py --output .\cpp_interface_source.cpp ..\src\templates\cpp_interface_source.template
python.exe ..\bin\txt_to_c.py --output .\cpp_client_header.cpp ..\src\templates\cpp_client_header.template
Expand Down Expand Up @@ -146,6 +147,7 @@ python.exe ..\bin\txt_to_c.py --output .\py_global_init.cpp ..\src\templates\py_
<PreBuildEvent>
<Command>python.exe ..\bin\txt_to_c.py --output .\cpp_coders.cpp ..\src\templates\cpp_coders.template
python.exe ..\bin\txt_to_c.py --output .\c_common_header.cpp ..\src\templates\c_common_header.template
python.exe ..\bin\txt_to_c.py --output .\cpp_common_header.cpp ..\src\templates\cpp_common_header.template
python.exe ..\bin\txt_to_c.py --output .\cpp_interface_header.cpp ..\src\templates\cpp_interface_header.template
python.exe ..\bin\txt_to_c.py --output .\cpp_interface_source.cpp ..\src\templates\cpp_interface_source.template
python.exe ..\bin\txt_to_c.py --output .\cpp_client_header.cpp ..\src\templates\cpp_client_header.template
Expand Down Expand Up @@ -245,6 +247,7 @@ python.exe ..\bin\txt_to_c.py --output .\py_global_init.cpp ..\src\templates\py_
<ClCompile Include="..\src\Utils.cpp" />
<ClCompile Include="cpp_coders.cpp" />
<ClCompile Include="c_common_header.cpp" />
<ClCompile Include="cpp_common_header.cpp" />
<ClCompile Include="c_crc.cpp" />
<ClCompile Include="cpp_interface_header.cpp" />
<ClCompile Include="cpp_interface_source.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions erpcgen/VisualStudio_v14/erpcgen.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@
<ClCompile Include="c_common_header.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cpp_common_header.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cpp_interface_header.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
153 changes: 132 additions & 21 deletions erpcgen/src/CGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,22 +98,13 @@ void CGenerator::generateOutputFiles(const string &fileName)
generateServerCSourceFile(fileName);
}

void CGenerator::generateCommonCHeaderFiles(string fileName)
{
fileName += "_common.h";
m_templateData["commonGuardMacro"] = generateIncludeGuardName(fileName);
m_templateData["commonCHeaderName"] = fileName;
m_templateData["cCommonHeaderFile"] = true;
generateOutputFile(fileName, "c_common_header", m_templateData, kCCommonHeader);
}

void CGenerator::generateCommonCppHeaderFiles(string fileName)
{
fileName += "_common.hpp";
m_templateData["commonGuardMacro"] = generateIncludeGuardName(fileName);
m_templateData["commonCppHeaderName"] = fileName;
m_templateData["cCommonHeaderFile"] = false;
generateOutputFile(fileName, "c_common_header", m_templateData, kCCommonHeader);
generateOutputFile(fileName, "cpp_common_header", m_templateData, kCppCommonHeader);
}

void CGenerator::generateInterfaceCppHeaderFile(string fileName)
Expand Down Expand Up @@ -163,6 +154,15 @@ void CGenerator::generateServerCppSourceFile(string fileName)
generateOutputFile(fileName, "cpp_server_source", m_templateData, kCppServerSource);
}

void CGenerator::generateCommonCHeaderFiles(string fileName)
{
fileName = "c_" + fileName + "_common.h";
m_templateData["commonGuardMacro"] = generateIncludeGuardName(fileName);
m_templateData["commonCHeaderName"] = fileName;
m_templateData["cCommonHeaderFile"] = true;
generateOutputFile(fileName, "c_common_header", m_templateData, kCCommonHeader);
}

void CGenerator::generateClientCHeaderFile(string fileName)
{
fileName = "c_" + fileName + "_client.h";
Expand Down Expand Up @@ -760,38 +760,52 @@ void CGenerator::makeAliasesTemplateData()

if (elementDataType->getName() != "")
{
string realType;
string realTypeC;
string realTypeCpp;
if (elementDataType->isFunction())
{
realType = getOutputName(aliasType);
realTypeC = getOutputName(aliasType);
aliasInfo["name"] = elementDataType->getName();
}
else
{
realType = getTypenameName(elementDataType, getOutputName(aliasType));
realTypeC = getTypenameName(elementDataType, getOutputName(aliasType));
aliasInfo["name"] = getOutputName(aliasType);
}

Log::info("%s\n", realType.c_str());
Log::info("%s\n", realTypeC.c_str());

/* For case typedef struct/union */
if (elementDataType->getName() == aliasType->getName() ||
getOutputName(elementDataType, false) == aliasType->getName())
{
if (elementDataType->isStruct())
{
realType = "struct " + realType;
realTypeC = "struct " + realTypeC;
realTypeCpp = "struct " + aliasType->getName();
}
else
{
realType = "union " + realType;
realTypeC = "union " + realTypeC;
realTypeCpp = "union " + aliasType->getName();
}
}

aliasInfo["typenameName"] = realType;
if (elementDataType->getName() == aliasType->getName())
{
aliasInfo["forwardDecl"] = realTypeC;
aliasInfo["forwardDeclCpp"] = realTypeCpp;
aliasInfo["typenameName"] = "";
}
else
{
aliasInfo["typenameName"] = realTypeC;
aliasInfo["forwardDecl"] = "";
}
}
else
{
aliasInfo["forwardDecl"] = "";
aliasInfo["typenameName"] = "";
aliasInfo["unnamedName"] = getOutputName(aliasType);
switch (elementDataType->getDataType())
Expand Down Expand Up @@ -1351,11 +1365,18 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn)
info["isNonExternalFunction"] = !findAnnotation(fnSymbol, EXTERNAL_ANNOTATION);

// Get return value info
data_map returnInfo;
returnInfo["type"] = getTypeInfo(fn->getReturnType(), true);
StructMember *structMember = fn->getReturnStructMemberType();
DataType *dataType = fn->getReturnType();
DataType *trueDataType = dataType->getTrueDataType();
data_map returnInfo;
returnInfo["type"] = getTypeInfo(dataType, true);
StructMember *structMember = fn->getReturnStructMemberType();
// TODO: in case we want distinguish cpp and c type macro
// std::string retypeName = "";
// if (dataType->isArray())
// {
// retypeName = "*";
// }
// returnInfo["typename"] = getTypenameName(dataType, retypeName);
if (!trueDataType->isVoid())
{
string result = "result";
Expand Down Expand Up @@ -1568,6 +1589,29 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn)
paramInfo["shared"] = isShared;
paramInfo["pureName"] = name;
paramInfo["pureNameC"] = pureCName;
// TODO: in case we want distinguish cpp and c type macro
// std::string retypeParamName = "";
// bool isDoubleArray = false;
// if (paramType->isArray())
// {
// ArrayType *paramArrayType = dynamic_cast<ArrayType *>(paramType);
// retypeParamName = getTypenameName(paramArrayType->getElementType(), "*");
// isDoubleArray = paramArrayType->getElementType()->isArray();
// }
// else
// {
// retypeParamName = getTypenameName(paramType, "");
// }
// if (!paramType->getTrueContainerDataType()->isBuiltin() || paramType->isAlias())
// {
// retypeParamName = m_templateData["namespace"].get().get()->getvalue() + "::" + retypeParamName;
// }
// if ((param->getDirection() == kInDirection) && (isDoubleArray == false) &&
// (!paramType->getTrueContainerDataType()->isString()))
// {
// retypeParamName = "const " + retypeParamName;
// }
// paramInfo["typename"] = retypeParamName;
string encodeDecodeName;
if (isShared)
{
Expand Down Expand Up @@ -1887,6 +1931,10 @@ string CGenerator::getErrorReturnValue(FunctionBase *fn)
return (integerValue->getValue()) ? "true" : "false";
}
}
else if (dataType->isEnum())
{
return fn->getReturnType()->getName() + "::" + returnVal->toString();
}
return returnVal->toString();
}
else
Expand Down Expand Up @@ -2753,7 +2801,39 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT
for (auto unionCase : unionType->getCases())
{
data_map caseData;
caseData["name"] = unionCase->getCaseName();
DataType *caseDataType = unionCase->getCaseDataType();
std::string caseName;
caseData["caseCast"] = "";
if (caseDataType == nullptr)
{
caseName = "";
}
else
{
if (unionType->isNonEncapsulatedUnion())
{
caseData["caseCast"] = "int32_t";
}
else
{
DataType *disType = getDiscriminatorType(unionType, structType, structMember);
if (disType != nullptr)
{
std::string disName;
if (disType->isBuiltin())
{
disName = getBuiltinTypename(dynamic_cast<BuiltinType *>(disType));
}
else
{
disName = disType->getName();
}
caseData["caseCast"] = (disName == caseDataType->getName()) ? "" : disName;
}
}
caseName = caseDataType->getName() + "::";
}
caseData["name"] = caseName + unionCase->getCaseName();
caseData["value"] = unionCase->getCaseValue();
// if current case need call free function, default false
caseData["needCaseFreeingCall"] = false;
Expand Down Expand Up @@ -3344,6 +3424,37 @@ bool CGenerator::setDiscriminatorTemp(UnionType *unionType, StructType *structTy
return needTempVariableI32;
}

DataType *CGenerator::getDiscriminatorType(UnionType *unionType, StructType *structType, StructMember *structMember)
{
DataType *retVal = nullptr;

if (structType)
{
string discriminatorName;
Symbol *disSymbol;

if (unionType->isNonEncapsulatedUnion())
{
discriminatorName = getAnnStringValue(structMember, DISCRIMINATOR_ANNOTATION);
disSymbol = m_globals->getSymbol(discriminatorName, false);
ConstType *constType = dynamic_cast<ConstType *>(disSymbol);
assert(constType);
retVal = constType->getDataType();
}
else
{
discriminatorName = unionType->getDiscriminatorName();
disSymbol = structType->getScope().getSymbol(discriminatorName);
assert(disSymbol);
StructMember *disMember = dynamic_cast<StructMember *>(disSymbol);
assert(disMember);
retVal = disMember->getDataType();
}
}

return retVal;
}

string CGenerator::getScalarTypename(DataType *dataType)
{
if (dataType->getTrueDataType()->isScalar())
Expand Down
32 changes: 27 additions & 5 deletions erpcgen/src/CGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ class CGenerator : public Generator
cpptempl::data_list m_symbolsTemplate; /*!< List of all symbol templates */

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

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

/*!
* @brief Set template data related to discriminator
*
* @param unionType Union for which discriminator are data related
* @param structType Structure for which discriminator are data related
* @param structMember Structure member for which discriminator are data related
* @param isFunctionParam Is discriminator function parameter?
* @param templateData Object where data are stored.
*
* @return bool Return true if temporary variable need be generated.
*/
bool setDiscriminatorTemp(UnionType *unionType, StructType *structType, StructMember *structMember,
bool isFunctionParam, cpptempl::data_map &templateData);

/*!
* @brief Get the Discriminator type.
*
* @param unionType Union for which discriminator are data related
* @param structType Structure for which discriminator are data related
* @param structMember Structure member for which discriminator are data related
*
* @return DataType* Nullptr or discriminator data type.
*/
DataType *getDiscriminatorType(UnionType *unionType, StructType *structType, StructMember *structMember);

/*!
* @brief This function returns data type name for scalar data type.
*
Expand Down
19 changes: 18 additions & 1 deletion erpcgen/src/SymbolScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,24 @@ AstNode *SymbolScanner::handleUnionCase(AstNode *node, bottom_up)
caseIdIntValue = (uint32_t) dynamic_cast<IntegerValue *>(caseIdValue)->getValue();
const string caseIdName = caseIdTok.getStringValue();
Log::debug("union case id name: %s\n", caseIdName.c_str());
newCase = new UnionCase(caseIdName, caseIdIntValue);
DataType *caseDataType = nullptr;
for (Symbol *enumSymbol : m_globals->getSymbolsOfType(Symbol::kTypenameSymbol))
{
if (enumSymbol->isDatatypeSymbol())
{
DataType *datatype = dynamic_cast<DataType *>(enumSymbol);
if (datatype->isEnum())
{
EnumType *enumType = dynamic_cast<EnumType *>(enumSymbol);
EnumMember *enumMember = enumType->getMember(caseIdName);
if (enumMember != nullptr)
{
caseDataType = enumType;
}
}
}
}
newCase = new UnionCase(caseDataType, caseIdName, caseIdIntValue);
delete caseIdValue;
}
/* If there is no identifier, simply record the case value */
Expand Down
4 changes: 3 additions & 1 deletion erpcgen/src/templates/c_common_header.template
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ extern "C"
// Aliases data types declarations
{% for alias in aliases %}
{$> alias.mlComment}
{% if alias.typenameName == "" %}
{% if alias.forwardDecl != "" %}
typedef {$alias.forwardDecl};{$alias.ilComment}
{% elif alias.typenameName == "" %}
typedef {$alias.unnamedType}
{
{% for mem in alias.unnamed.members %}
Expand Down
Loading

0 comments on commit 393ea9b

Please sign in to comment.