Home | History | Annotate | Download | only in c2hal
      1 /*
      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"
     19 #include "VarDeclaration.h"
     20 #include "Declaration.h"
     21 
     22 #include <algorithm>
     23 #include <iostream>
     24 #include <string>
     25 
     26 namespace android {
     27 
     28 CompositeDeclaration::CompositeDeclaration(
     29         const Type::Qualifier::Qualification qualifier,
     30         const std::string &name,
     31         std::vector<android::Declaration *> *fieldDeclarations)
     32     : Declaration(""),
     33       mQualifier(qualifier),
     34       mFieldDeclarations(fieldDeclarations)
     35     {
     36         setName(name);
     37     }
     38 
     39 CompositeDeclaration::~CompositeDeclaration() {
     40     if(mFieldDeclarations != NULL) {
     41         for(auto* decl : *mFieldDeclarations) {
     42             delete decl;
     43         }
     44     }
     45     delete mFieldDeclarations;
     46 }
     47 
     48 void CompositeDeclaration::setName(const std::string &name) {
     49     Declaration::setName(name);
     50     forcePascalCase();
     51 }
     52 
     53 const Type::Qualifier::Qualification &CompositeDeclaration::getQualifier() const {
     54     return mQualifier;
     55 }
     56 const std::vector<android::Declaration *>*
     57     CompositeDeclaration::getFieldDeclarations() const {
     58     return mFieldDeclarations;
     59 }
     60 
     61 void CompositeDeclaration::generateInterface(Formatter &out) const {
     62     generateCommentText(out);
     63     out << "interface " << getInterfaceName() << " {\n\n";
     64 
     65     generateBody(out);
     66 
     67     out << "};\n";
     68 }
     69 
     70 void 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 
     95 void 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 
    107 void 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()) {
    120                 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                 }
    134                 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 
    150 std::string CompositeDeclaration::getInterfaceName() const {
    151     return "I" + getName();
    152 }
    153 
    154 bool 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 
    167 void CompositeDeclaration::setEnumTypeName(const std::string &name) {
    168     CHECK(mQualifier == Type::Qualifier::ENUM);
    169 
    170     mEnumTypeName = name;
    171 }
    172 
    173 } //namespace android
    174