Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2011-2012, 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 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_  // NOLINT
     18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_
     19 
     20 #include "llvm/ADT/StringRef.h"
     21 #include "llvm/Support/raw_ostream.h"
     22 
     23 #include "clang/AST/Decl.h"
     24 
     25 #include "slang_assert.h"
     26 #include "slang_rs_context.h"
     27 #include "slang_rs_exportable.h"
     28 #include "slang_rs_export_type.h"
     29 
     30 namespace clang {
     31   class FunctionDecl;
     32 }  // namespace clang
     33 
     34 namespace slang {
     35 
     36 // Base class for reflecting control-side forEach (currently for root()
     37 // functions that fit appropriate criteria)
     38 class RSExportForEach : public RSExportable {
     39  private:
     40   std::string mName;
     41   RSExportRecordType *mParamPacketType;
     42   RSExportType *mInType;
     43   RSExportType *mOutType;
     44   size_t numParams;
     45 
     46   unsigned int mSignatureMetadata;
     47 
     48   const clang::ParmVarDecl *mIn;
     49   const clang::ParmVarDecl *mOut;
     50   const clang::ParmVarDecl *mUsrData;
     51   const clang::ParmVarDecl *mX;
     52   const clang::ParmVarDecl *mY;
     53   const clang::ParmVarDecl *mZ;
     54   const clang::ParmVarDecl *mAr;
     55 
     56   clang::QualType mResultType;  // return type (if present).
     57   bool mReturn;  // does this kernel have a return type?
     58   bool mKernel;  // is this a pass-by-value kernel?
     59 
     60   bool mDummyRoot;
     61 
     62   // TODO(all): Add support for LOD/face when we have them
     63   RSExportForEach(RSContext *Context, const llvm::StringRef &Name)
     64     : RSExportable(Context, RSExportable::EX_FOREACH),
     65       mName(Name.data(), Name.size()), mParamPacketType(NULL), mInType(NULL),
     66       mOutType(NULL), numParams(0), mSignatureMetadata(0),
     67       mIn(NULL), mOut(NULL), mUsrData(NULL), mX(NULL), mY(NULL), mZ(NULL),
     68       mAr(NULL), mResultType(clang::QualType()), mReturn(false),
     69       mKernel(false), mDummyRoot(false) {
     70     return;
     71   }
     72 
     73   bool validateAndConstructParams(RSContext *Context,
     74                                   const clang::FunctionDecl *FD);
     75 
     76   bool validateAndConstructKernelParams(RSContext *Context,
     77                                         const clang::FunctionDecl *FD);
     78 
     79  public:
     80   static RSExportForEach *Create(RSContext *Context,
     81                                  const clang::FunctionDecl *FD);
     82 
     83   static RSExportForEach *CreateDummyRoot(RSContext *Context);
     84 
     85   inline const std::string &getName() const {
     86     return mName;
     87   }
     88 
     89   inline size_t getNumParameters() const {
     90     return numParams;
     91   }
     92 
     93   inline bool hasIn() const {
     94     return (mIn != NULL);
     95   }
     96 
     97   inline bool hasOut() const {
     98     return (mOut != NULL);
     99   }
    100 
    101   inline bool hasUsrData() const {
    102     return (mUsrData != NULL);
    103   }
    104 
    105   inline bool hasReturn() const {
    106     return mReturn;
    107   }
    108 
    109   inline const RSExportType *getInType() const {
    110     return mInType;
    111   }
    112 
    113   inline const RSExportType *getOutType() const {
    114     return mOutType;
    115   }
    116 
    117   inline const RSExportRecordType *getParamPacketType() const {
    118     return mParamPacketType;
    119   }
    120 
    121   inline unsigned int getSignatureMetadata() const {
    122     return mSignatureMetadata;
    123   }
    124 
    125   inline bool isDummyRoot() const {
    126     return mDummyRoot;
    127   }
    128 
    129   typedef RSExportRecordType::const_field_iterator const_param_iterator;
    130 
    131   inline const_param_iterator params_begin() const {
    132     slangAssert((mParamPacketType != NULL) &&
    133                 "Get parameter from export foreach having no parameter!");
    134     return mParamPacketType->fields_begin();
    135   }
    136 
    137   inline const_param_iterator params_end() const {
    138     slangAssert((mParamPacketType != NULL) &&
    139                 "Get parameter from export foreach having no parameter!");
    140     return mParamPacketType->fields_end();
    141   }
    142 
    143   inline static bool isInitRSFunc(const clang::FunctionDecl *FD) {
    144     if (!FD) {
    145       return false;
    146     }
    147     const llvm::StringRef Name = FD->getName();
    148     static llvm::StringRef FuncInit("init");
    149     return Name.equals(FuncInit);
    150   }
    151 
    152   inline static bool isRootRSFunc(const clang::FunctionDecl *FD) {
    153     if (!FD) {
    154       return false;
    155     }
    156     const llvm::StringRef Name = FD->getName();
    157     static llvm::StringRef FuncRoot("root");
    158     return Name.equals(FuncRoot);
    159   }
    160 
    161   inline static bool isDtorRSFunc(const clang::FunctionDecl *FD) {
    162     if (!FD) {
    163       return false;
    164     }
    165     const llvm::StringRef Name = FD->getName();
    166     static llvm::StringRef FuncDtor(".rs.dtor");
    167     return Name.equals(FuncDtor);
    168   }
    169 
    170   static bool isGraphicsRootRSFunc(int targetAPI,
    171                                    const clang::FunctionDecl *FD);
    172 
    173   static bool isRSForEachFunc(int targetAPI,
    174                               clang::DiagnosticsEngine *DiagEngine,
    175                               const clang::FunctionDecl *FD);
    176 
    177   inline static bool isSpecialRSFunc(int targetAPI,
    178                                      const clang::FunctionDecl *FD) {
    179     return isGraphicsRootRSFunc(targetAPI, FD) || isInitRSFunc(FD) ||
    180            isDtorRSFunc(FD);
    181   }
    182 
    183   static bool validateSpecialFuncDecl(int targetAPI,
    184                                       clang::DiagnosticsEngine *DiagEngine,
    185                                       const clang::FunctionDecl *FD);
    186 };  // RSExportForEach
    187 
    188 }  // namespace slang
    189 
    190 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_  NOLINT
    191