blob: 70cf77542af410df3e65ed6c625c1f7ac84ce1d5 [file] [log] [blame]
Steven Morelandf1a35f72016-08-17 08:41:49 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "CompositeDeclaration.h"
18#include "FunctionDeclaration.h"
Diego Wilson2b38e892016-10-12 11:16:43 -070019#include "VarDeclaration.h"
Steven Morelandf1a35f72016-08-17 08:41:49 -070020#include "Declaration.h"
21
22#include <algorithm>
23#include <iostream>
24#include <string>
Steven Morelandf1a35f72016-08-17 08:41:49 -070025
26namespace android {
27
Steven Morelandf1a35f72016-08-17 08:41:49 -070028CompositeDeclaration::CompositeDeclaration(
29 const Type::Qualifier::Qualification qualifier,
30 const std::string &name,
31 std::vector<android::Declaration *> *fieldDeclarations)
Steven Moreland95b46232016-09-20 14:46:55 -070032 : Declaration(""),
33 mQualifier(qualifier),
34 mFieldDeclarations(fieldDeclarations)
35 {
36 setName(name);
37 }
Steven Morelandf1a35f72016-08-17 08:41:49 -070038
39CompositeDeclaration::~CompositeDeclaration() {
40 if(mFieldDeclarations != NULL) {
41 for(auto* decl : *mFieldDeclarations) {
42 delete decl;
43 }
44 }
45 delete mFieldDeclarations;
46}
47
Steven Moreland95b46232016-09-20 14:46:55 -070048void CompositeDeclaration::setName(const std::string &name) {
49 Declaration::setName(name);
50 forcePascalCase();
51}
Steven Morelandf1a35f72016-08-17 08:41:49 -070052
53const Type::Qualifier::Qualification &CompositeDeclaration::getQualifier() const {
54 return mQualifier;
55}
56const std::vector<android::Declaration *>*
57 CompositeDeclaration::getFieldDeclarations() const {
58 return mFieldDeclarations;
59}
60
61void CompositeDeclaration::generateInterface(Formatter &out) const {
62 generateCommentText(out);
63 out << "interface " << getInterfaceName() << " {\n\n";
64
65 generateBody(out);
66
67 out << "};\n";
68}
69
70void CompositeDeclaration::generateSource(Formatter &out) const {
71 CHECK(mQualifier == Type::Qualifier::STRUCT ||
72 mQualifier == Type::Qualifier::UNION ||
73 mQualifier == Type::Qualifier::ENUM);
74
75 out << Type::qualifierText(mQualifier) << " " << getName();
76
77 if (mQualifier == Type::Qualifier::ENUM) {
78 out << " : ";
79
80 if (mEnumTypeName.empty()) {
81 out << "int32_t /* NOTE: type is guessed */";
82 } else {
83 out << mEnumTypeName;
84 }
85
86 }
87
88 out << " {\n";
89
90 generateBody(out);
91
92 out << "};\n";
93}
94
95void CompositeDeclaration::generateBody(Formatter &out) const {
96 out.indent();
97
98 for (auto *declaration : *mFieldDeclarations) {
99 declaration->generateCommentText(out);
100 declaration->generateSource(out);
101 out << "\n";
102 }
103
104 out.unindent();
105}
106
107void CompositeDeclaration::processContents(AST &ast) {
108 for (auto &declaration : *mFieldDeclarations) {
109 declaration->processContents(ast);
110 }
111
112 if (isInterface()) {
113 // move non function fields into a containing struct
114
115 auto nonFpDecs = new std::vector<Declaration*>;
116
117 auto it = mFieldDeclarations->begin();
118 while (it != mFieldDeclarations->end()) {
119 if((*it)->decType() != FunctionDeclaration::type()) {
Diego Wilson2b38e892016-10-12 11:16:43 -0700120 bool keep = true;
121 if((*it)->decType() == VarDeclaration::type()) {
122 VarDeclaration* var = (VarDeclaration *)(*it);
123 // Conventional HALs were all required to have
124 // a member of this type.
125 // This member is no longer needed for HIDL
126 if(var->getType()->isHwDevice()) {
127 keep = false;
128 }
129 }
130
131 if (keep) {
132 nonFpDecs->push_back(*it);
133 }
Steven Morelandf1a35f72016-08-17 08:41:49 -0700134 it = mFieldDeclarations->erase(it);
135 } else {
136 it++;
137 }
138 }
139
140 if (!nonFpDecs->empty()) {
141 auto subStruct = new CompositeDeclaration(Type::Qualifier::STRUCT,
142 getName(),
143 nonFpDecs);
144
145 mFieldDeclarations->insert(mFieldDeclarations->begin(), subStruct);
146 }
147 }
148}
149
150std::string CompositeDeclaration::getInterfaceName() const {
Steven Moreland95b46232016-09-20 14:46:55 -0700151 return "I" + getName();
Steven Morelandf1a35f72016-08-17 08:41:49 -0700152}
153
154bool CompositeDeclaration::isInterface() const {
155 if (mQualifier != Type::Qualifier::STRUCT) {
156 return false;
157 }
158
159 for (auto &declaration : *mFieldDeclarations) {
160 if (declaration->decType() == FunctionDeclaration::type()) {
161 return true;
162 }
163 }
164 return false;
165}
166
167void CompositeDeclaration::setEnumTypeName(const std::string &name) {
168 CHECK(mQualifier == Type::Qualifier::ENUM);
169
170 mEnumTypeName = name;
171}
172
Diego Wilson2b38e892016-10-12 11:16:43 -0700173} //namespace android