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