1f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland/*
2f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * Copyright (C) 2016 The Android Open Source Project
3f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland *
4f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * Licensed under the Apache License, Version 2.0 (the "License");
5f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * you may not use this file except in compliance with the License.
6f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * You may obtain a copy of the License at
7f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland *
8f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland *      http://www.apache.org/licenses/LICENSE-2.0
9f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland *
10f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * Unless required by applicable law or agreed to in writing, software
11f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * distributed under the License is distributed on an "AS IS" BASIS,
12f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * See the License for the specific language governing permissions and
14f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * limitations under the License.
15f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland */
16f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
17f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include "AST.h"
18f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
19f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include "FunctionDeclaration.h"
20f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include "EnumVarDeclaration.h"
21f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include "Scope.h"
22f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include "Declaration.h"
23f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include "CompositeDeclaration.h"
243449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong#include "VarDeclaration.h"
25f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include "Define.h"
26f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include "Include.h"
273449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong#include "Note.h"
28f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
29f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <string>
30f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <algorithm>
31f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <stdlib.h>
32f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <sys/dir.h>
33f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <sys/stat.h>
34f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
35f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandnamespace android {
36f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
37f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven MorelandAST::AST(const std::string &path,
38f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland         const std::string &outputDir,
39f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland         const std::string &package,
40f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland         bool isOpenGl)
41f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    : mScanner(NULL),
42f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland      mPath(path),
43f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland      mOutputDir(outputDir),
44f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland      mPackage(package),
45f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland      mIsOpenGl(isOpenGl)
46f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    {}
47f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
48f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven MorelandAST::~AST() {
49f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    delete mExpression;
50f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
51f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    if(mDeclarations != NULL) {
52f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        for(auto* decl : *mDeclarations) {
53f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            delete decl;
54f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        }
55f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
56f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    delete mDeclarations;
57f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
58f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    if(mInterfaces != NULL) {
59f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        for(auto* inter : *mInterfaces) {
60f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            delete inter;
61f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        }
62f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
63f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    delete mInterfaces;
64f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
65f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    if(mIncludes != NULL) {
66f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        for(auto* incl : *mIncludes) {
67f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            delete incl;
68f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        }
69f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
70f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    delete mIncludes;
71f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
72f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
73f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid *AST::scanner() {
74f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return mScanner;
75f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
76f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
77f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::setScanner(void *scanner) {
78f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    mScanner = scanner;
79f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
80f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
81f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandbool AST::isOpenGl() const {
82f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return mIsOpenGl;
83f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
84f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
85f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandconst std::string& AST::getFilename() const {
86f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return mPath;
87f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
88f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
89f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::setDeclarations(std::vector<Declaration *> *declarations) {
903449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong    // on the top level, no var declarations are allowed.
913449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong    for(size_t i = 0; i < declarations->size(); i++) {
923449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong        if(declarations->at(i)->decType() == VarDeclaration::type()) {
933449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong            declarations->at(i) = new Note(declarations->at(i));
943449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong        }
953449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong    }
963449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong
97f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    mDeclarations = declarations;
98f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
99f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
100f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::setIncludes(std::vector<Include *> *includes) {
101f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    mIncludes = includes;
102f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
103f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
104f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven MorelandExpression *AST::getExpression() const {
105f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return mExpression;
106f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
107f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::setExpression(Expression *expression) {
108f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    mExpression = expression;
109f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
110f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
111f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandconst Scope<Define *> &AST::getDefinesScope() const {
112f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return mDefinesScope;
113f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
114f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
115f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven MorelandScope<Define *> &AST::getDefinesScope() {
116f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return mDefinesScope;
117f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
118f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
119f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::processContents() {
120f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    CHECK(mDeclarations != NULL);
121f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
122f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    for (auto &declaration : *mDeclarations) {
123f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        CHECK(declaration != NULL);
124f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
125f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        declaration->processContents(*this);
126f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
127f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
128f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    isolateInterfaces();
129f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    isolateGlobalInterface();
130f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    isolateIncludes();
131f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
132f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    isolateConstants(Expression::Type::U64);
133f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    isolateConstants(Expression::Type::S64);
134f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    isolateConstants(Expression::Type::U32);
135f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    isolateConstants(Expression::Type::S32);
136f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
137f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
138f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland/* take interface-like structs out of the type file */
139f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::isolateInterfaces() {
140f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    mInterfaces = new std::vector<CompositeDeclaration*>;
141f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
142f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    auto it = mDeclarations->begin();
143f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    while (it != mDeclarations->end()) {
144f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        if ((*it)->decType() == CompositeDeclaration::type()
145f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            && ((CompositeDeclaration *) (*it))->isInterface()) {
146f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
147f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            mInterfaces->push_back((CompositeDeclaration *) *it);
148f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            it = mDeclarations->erase(it);
149f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        } else {
150f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            it++;
151f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        }
152f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
153f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
154f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
155f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland/* take global function declarations out of the type file and into a new
156f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * interface
157f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland */
158f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::isolateGlobalInterface() {
159f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    auto globalFuns = new std::vector<Declaration*>;
160f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
161f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    auto it = mDeclarations->begin();
162f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    while (it != mDeclarations->end()) {
163f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        if ((*it)->decType() == FunctionDeclaration::type()) {
164f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
165f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            globalFuns->push_back(*it);
166f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            it = mDeclarations->erase(it);
167f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        } else {
168f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            it++;
169f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        }
170f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
171f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
172f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    if (!globalFuns->empty()) {
173f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        std::string path = mPackage.substr(0, mPackage.find_first_of('@'));
174f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        std::string name = path.substr(path.find_last_of('.') + 1);
175f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
176f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        auto interface = new CompositeDeclaration(
177f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            Type::Qualifier::STRUCT,
178f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            name + "_global_t",
179f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            globalFuns);
180f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
181f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        mInterfaces->push_back(interface);
182f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
183f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
184f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
185f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::isolateIncludes() {
186f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    mIncludes = new std::vector<Include*>;
187f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
188f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    auto it = mDeclarations->begin();
189f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    while (it != mDeclarations->end()) {
190f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        if ((*it)->decType() == Include::type()) {
191f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
192f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            mIncludes->push_back((Include *) *it);
193f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            it = mDeclarations->erase(it);
194f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        } else {
195f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            it++;
196f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        }
197f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
198f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
199f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
200f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::isolateConstants(Expression::Type ofType) {
201f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    auto constants = new std::vector<Declaration*>;
202f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
203f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    auto it = mDeclarations->begin();
204f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    while (it != mDeclarations->end()) {
205f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        if ((*it)->decType() == Define::type() &&
206f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            ((Define *)*it)->getExpressionType() == ofType) {
207f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
208f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            Define* define = (Define *)*it;
209f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
210f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            auto var = new EnumVarDeclaration(define->getName(),
211f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland                                              define->getExpression());
212f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
213f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            define->setExpression(NULL);
214f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
215f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            constants->push_back(var);
216f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            it = mDeclarations->erase(it);
217f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
218f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            delete define;
219f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        } else {
220f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            it++;
221f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        }
222f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
223f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
224f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    if (!constants->empty()) {
225f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        auto constEnum = new CompositeDeclaration(
226f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            Type::Qualifier::ENUM,
227f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            "Const" + Expression::getTypeDescription(ofType),
228f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            constants);
229f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
230f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        constEnum->setEnumTypeName(Expression::getTypeName(ofType));
231f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
232f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        mDeclarations->insert(mDeclarations->begin(), constEnum);
233f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
234f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
235f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
236f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandstatus_t AST::generateCode() const {
237f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    CHECK(mDeclarations != NULL);
238f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
239f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    status_t err;
240f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
241f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    for (auto &interface : *mInterfaces) {
242f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        err = generateFile(interface);
243f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
244f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        if (err != OK) {
245f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            return err;
246f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        }
247f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
248f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
249f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    err = generateTypesFile();
250f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
251f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    if (err != OK) {
252f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        return err;
253f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
254f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
255f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return OK;
256f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
257f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
258f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandstatus_t AST::generateFile(CompositeDeclaration* declaration) const {
259f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    std::string fileName = declaration->getInterfaceName() + ".hal";
260f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
261f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    FILE *file = fopen((getFileDir() + fileName).c_str(), "w");
262f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
263f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    if(file == NULL) {
264f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        return -errno;
265f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
266f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
267f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    Formatter out(file); // formatter closes out
268f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
269f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    generatePackageLine(out);
270f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    generateIncludes(out);
271f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
272f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    declaration->generateInterface(out);
273f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
274f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return OK;
275f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
276f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
277f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandstatus_t AST::generateTypesFile() const {
278f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    if (mDeclarations->empty()) {
279f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        return OK;
280f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
281f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
282f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    FILE *file = fopen((getFileDir() + "types.hal").c_str(), "w");
283f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
284f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    if(file == NULL) {
285f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        return -errno;
286f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
287f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
288f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    Formatter out(file); // formatter closes out
289f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
290f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    generatePackageLine(out);
291f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    generateIncludes(out);
292f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
293f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    for (auto &declaration : *mDeclarations) {
294f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        declaration->generateCommentText(out);
295f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        declaration->generateSource(out);
296f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        out << "\n";
297f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
298f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
299f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return OK;
300f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
301f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
302f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::generateIncludes(Formatter &out) const {
303f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    for (auto &include : *mIncludes) {
304f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        include->generateSource(out);
305f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        out << "\n";
306f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
307f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
308f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
309f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandvoid AST::generatePackageLine(Formatter &out) const {
310f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    out << "package "
311f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        << mPackage
312f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        << ";\n\n";
313f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
314f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
315f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandbool MakeParentHierarchy(const std::string &path) {
316f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    static const mode_t kMode = 0755;
317f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
318f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    size_t start = 1;  // Ignore leading '/'
319f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    size_t slashPos;
320f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    while ((slashPos = path.find("/", start)) != std::string::npos) {
321f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        std::string partial = path.substr(0, slashPos);
322f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
323f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        struct stat st;
324f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        if (stat(partial.c_str(), &st) < 0) {
325f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            if (errno != ENOENT) {
326f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland                return false;
327f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            }
328f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
329f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            int res = mkdir(partial.c_str(), kMode);
330f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            if (res < 0) {
331f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland                return false;
332f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            }
333f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        } else if (!S_ISDIR(st.st_mode)) {
334f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland            return false;
335f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        }
336f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
337f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland        start = slashPos + 1;
338f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    }
339f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
340f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return true;
341f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
342f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
343f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandconst std::string AST::getFileDir() const {
344f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    CHECK(MakeParentHierarchy(mOutputDir));
345f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland    return mOutputDir;
346f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland}
347f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland
3483449bba54cc43e23c6e0e2a687ad686d82ad37f3Yifan Hong} // namespace android
349