• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "codegen/c_code_emitter.h"
10 #include "util/options.h"
11 
12 namespace OHOS {
13 namespace HDI {
GetStdlibInclusions(HeaderFile::HeaderFileSet & headerFiles)14 void CCodeEmitter::GetStdlibInclusions(HeaderFile::HeaderFileSet &headerFiles)
15 {
16     const AST::TypeStringMap &types = ast_->GetTypes();
17     for (const auto &pair : types) {
18         AutoPtr<ASTType> type = pair.second;
19         if (type->IsNativeBufferType()) {
20             headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "base/buffer_util");
21         }
22     }
23 }
24 
GetImportInclusions(HeaderFile::HeaderFileSet & headerFiles)25 void CCodeEmitter::GetImportInclusions(HeaderFile::HeaderFileSet &headerFiles)
26 {
27     for (const auto &importPair : ast_->GetImports()) {
28         AutoPtr<AST> importAst = importPair.second;
29         std::string fileName = PackageToFilePath(importAst->GetFullName());
30         headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, fileName);
31     }
32 }
33 
EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> & parameter,StringBuilder & sb,const std::string & prefix) const34 void CCodeEmitter::EmitInterfaceMethodParameter(
35     const AutoPtr<ASTParameter> &parameter, StringBuilder &sb, const std::string &prefix) const
36 {
37     sb.Append(prefix).Append(parameter->EmitCParameter());
38 }
39 
EmitMethodNeedLoopVar(const AutoPtr<ASTMethod> & method,bool needRW,bool needFree,StringBuilder & sb,const std::string & prefix) const40 void CCodeEmitter::EmitMethodNeedLoopVar(
41     const AutoPtr<ASTMethod> &method, bool needRW, bool needFree, StringBuilder &sb, const std::string &prefix) const
42 {
43     if (mode_ != GenMode::KERNEL) {
44         return;
45     }
46 
47     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
48         AutoPtr<ASTParameter> param = method->GetParameter(i);
49         if (EmitNeedLoopVar(param->GetType(), needRW, needFree)) {
50             sb.Append(prefix).Append("uint32_t i = 0;\n");
51             break;
52         }
53     }
54 }
55 
EmitNeedLoopVar(const AutoPtr<ASTType> & type,bool needRW,bool needFree) const56 bool CCodeEmitter::EmitNeedLoopVar(const AutoPtr<ASTType> &type, bool needRW, bool needFree) const
57 {
58     if (type == nullptr) {
59         return false;
60     }
61 
62     auto rwNeedLoopVar = [needRW](const AutoPtr<ASTType> &elementType) -> bool {
63         if (!needRW) {
64             return false;
65         }
66 
67         if (elementType->IsPod()) {
68             return elementType->IsBooleanType() ? true : false;
69         }
70 
71         return elementType->IsStringType() ? false : true;
72     };
73 
74     auto freeNeedLoopVar = [needFree](const AutoPtr<ASTType> &elementType) -> bool {
75         if (!needFree) {
76             return false;
77         }
78         return elementType->IsPod() ? false : true;
79     };
80 
81     if (type->IsArrayType()) {
82         AutoPtr<ASTArrayType> arrType = dynamic_cast<ASTArrayType *>(type.Get());
83         if (rwNeedLoopVar(arrType->GetElementType()) || freeNeedLoopVar(arrType->GetElementType())) {
84             return true;
85         }
86     } else if (type->IsListType()) {
87         AutoPtr<ASTListType> listType = dynamic_cast<ASTListType *>(type.Get());
88         if (rwNeedLoopVar(listType->GetElementType()) || freeNeedLoopVar(listType->GetElementType())) {
89             return true;
90         }
91     }
92 
93     return false;
94 }
95 
EmitErrorHandle(const AutoPtr<ASTMethod> & method,const std::string & gotoLabel,bool isClient,StringBuilder & sb,const std::string & prefix) const96 void CCodeEmitter::EmitErrorHandle(const AutoPtr<ASTMethod> &method, const std::string &gotoLabel, bool isClient,
97     StringBuilder &sb, const std::string &prefix) const
98 {
99     if (!isClient) {
100         sb.Append(prefix).AppendFormat("%s:\n", gotoLabel.c_str());
101         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
102             AutoPtr<ASTParameter> param = method->GetParameter(i);
103             AutoPtr<ASTType> paramType = param->GetType();
104             paramType->EmitMemoryRecycle(param->GetName(), true, sb, prefix + TAB);
105         }
106         return;
107     }
108 }
109 
EmitLicense(StringBuilder & sb)110 void CCodeEmitter::EmitLicense(StringBuilder &sb)
111 {
112     if (ast_->GetLicense().empty()) {
113         return;
114     }
115     sb.Append(ast_->GetLicense()).Append("\n\n");
116 }
117 
EmitHeadMacro(StringBuilder & sb,const std::string & fullName) const118 void CCodeEmitter::EmitHeadMacro(StringBuilder &sb, const std::string &fullName) const
119 {
120     std::string macroName = MacroName(fullName);
121     sb.Append("#ifndef ").Append(macroName).Append("\n");
122     sb.Append("#define ").Append(macroName).Append("\n");
123 }
124 
EmitTailMacro(StringBuilder & sb,const std::string & fullName) const125 void CCodeEmitter::EmitTailMacro(StringBuilder &sb, const std::string &fullName) const
126 {
127     std::string macroName = MacroName(fullName);
128     sb.Append("#endif // ").Append(macroName);
129 }
130 
EmitHeadExternC(StringBuilder & sb) const131 void CCodeEmitter::EmitHeadExternC(StringBuilder &sb) const
132 {
133     sb.Append("#ifdef __cplusplus\n");
134     sb.Append("extern \"C\" {\n");
135     sb.Append("#endif /* __cplusplus */\n");
136 }
137 
EmitTailExternC(StringBuilder & sb) const138 void CCodeEmitter::EmitTailExternC(StringBuilder &sb) const
139 {
140     sb.Append("#ifdef __cplusplus\n");
141     sb.Append("}\n");
142     sb.Append("#endif /* __cplusplus */\n");
143 }
144 
MacroName(const std::string & name) const145 std::string CCodeEmitter::MacroName(const std::string &name) const
146 {
147     if (name.empty()) {
148         return name;
149     }
150 
151     std::string macro = StringHelper::StrToUpper(StringHelper::Replace(name, '.', '_')) + "_H";
152     return macro;
153 }
154 
SpecificationParam(StringBuilder & paramSb,const std::string & prefix) const155 std::string CCodeEmitter::SpecificationParam(StringBuilder &paramSb, const std::string &prefix) const
156 {
157     size_t maxLineLen = 120;
158     size_t replaceLen = 2;
159     std::string paramStr = paramSb.ToString();
160     size_t preIndex = 0;
161     size_t curIndex = 0;
162 
163     std::string insertStr = StringHelper::Format("\n%s", prefix.c_str());
164     for (; curIndex < paramStr.size(); curIndex++) {
165         if (curIndex == maxLineLen && preIndex > 0) {
166             StringHelper::Replace(paramStr, preIndex, replaceLen, ",");
167             paramStr.insert(preIndex + 1, insertStr);
168         } else {
169             if (paramStr[curIndex] == ',') {
170                 preIndex = curIndex;
171             }
172         }
173     }
174     return paramStr;
175 }
176 } // namespace HDI
177 } // namespace OHOS