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 61 // Accumulator for metadata bits corresponding to special parameters. 62 unsigned int mSpecialParameterSignatureMetadata; 63 64 clang::QualType mResultType; // return type (if present). 65 bool mHasReturnType; // does this kernel have a return type? 66 bool mIsKernelStyle; // is this a pass-by-value kernel? 67 68 bool mDummyRoot; 69 70 // TODO(all): Add support for LOD/face when we have them RSExportForEach(RSContext * Context,const llvm::StringRef & Name)71 RSExportForEach(RSContext *Context, const llvm::StringRef &Name) 72 : RSExportable(Context, RSExportable::EX_FOREACH), 73 mName(Name.data(), Name.size()), mParamPacketType(nullptr), 74 mOutType(nullptr), numParams(0), mSignatureMetadata(0), 75 mOut(nullptr), mUsrData(nullptr), mSpecialParameterSignatureMetadata(0), 76 mResultType(clang::QualType()), mHasReturnType(false), 77 mIsKernelStyle(false), mDummyRoot(false) { 78 } 79 80 bool validateAndConstructParams(RSContext *Context, 81 const clang::FunctionDecl *FD); 82 83 bool validateAndConstructOldStyleParams(RSContext *Context, 84 const clang::FunctionDecl *FD); 85 86 bool validateAndConstructKernelParams(RSContext *Context, 87 const clang::FunctionDecl *FD); 88 89 bool processSpecialParameters(RSContext *Context, 90 const clang::FunctionDecl *FD, 91 size_t *IndexOfFirstSpecialParameter); 92 93 bool setSignatureMetadata(RSContext *Context, 94 const clang::FunctionDecl *FD); 95 public: 96 static RSExportForEach *Create(RSContext *Context, 97 const clang::FunctionDecl *FD); 98 99 static RSExportForEach *CreateDummyRoot(RSContext *Context); 100 getName()101 inline const std::string &getName() const { 102 return mName; 103 } 104 getNumParameters()105 inline size_t getNumParameters() const { 106 return numParams; 107 } 108 hasIns()109 inline bool hasIns() const { 110 return (!mIns.empty()); 111 } 112 hasOut()113 inline bool hasOut() const { 114 return (mOut != nullptr); 115 } 116 hasUsrData()117 inline bool hasUsrData() const { 118 return (mUsrData != nullptr); 119 } 120 hasReturn()121 inline bool hasReturn() const { 122 return mHasReturnType; 123 } 124 getIns()125 inline const InVec& getIns() const { 126 return mIns; 127 } 128 getInTypes()129 inline const InTypeVec& getInTypes() const { 130 return mInTypes; 131 } 132 getOutType()133 inline const RSExportType *getOutType() const { 134 return mOutType; 135 } 136 getParamPacketType()137 inline const RSExportRecordType *getParamPacketType() const { 138 return mParamPacketType; 139 } 140 getSignatureMetadata()141 inline unsigned int getSignatureMetadata() const { 142 return mSignatureMetadata; 143 } 144 isDummyRoot()145 inline bool isDummyRoot() const { 146 return mDummyRoot; 147 } 148 149 typedef RSExportRecordType::const_field_iterator const_param_iterator; 150 params_begin()151 inline const_param_iterator params_begin() const { 152 slangAssert((mParamPacketType != nullptr) && 153 "Get parameter from export foreach having no parameter!"); 154 return mParamPacketType->fields_begin(); 155 } 156 params_end()157 inline const_param_iterator params_end() const { 158 slangAssert((mParamPacketType != nullptr) && 159 "Get parameter from export foreach having no parameter!"); 160 return mParamPacketType->fields_end(); 161 } 162 isInitRSFunc(const clang::FunctionDecl * FD)163 inline static bool isInitRSFunc(const clang::FunctionDecl *FD) { 164 if (!FD) { 165 return false; 166 } 167 const llvm::StringRef Name = FD->getName(); 168 static llvm::StringRef FuncInit("init"); 169 return Name.equals(FuncInit); 170 } 171 isRootRSFunc(const clang::FunctionDecl * FD)172 inline static bool isRootRSFunc(const clang::FunctionDecl *FD) { 173 if (!FD) { 174 return false; 175 } 176 const llvm::StringRef Name = FD->getName(); 177 static llvm::StringRef FuncRoot("root"); 178 return Name.equals(FuncRoot); 179 } 180 isDtorRSFunc(const clang::FunctionDecl * FD)181 inline static bool isDtorRSFunc(const clang::FunctionDecl *FD) { 182 if (!FD) { 183 return false; 184 } 185 const llvm::StringRef Name = FD->getName(); 186 static llvm::StringRef FuncDtor(".rs.dtor"); 187 return Name.equals(FuncDtor); 188 } 189 190 static bool isGraphicsRootRSFunc(unsigned int targetAPI, 191 const clang::FunctionDecl *FD); 192 193 static bool isRSForEachFunc(unsigned int targetAPI, slang::RSContext *Context, 194 const clang::FunctionDecl *FD); 195 isSpecialRSFunc(unsigned int targetAPI,const clang::FunctionDecl * FD)196 inline static bool isSpecialRSFunc(unsigned int targetAPI, 197 const clang::FunctionDecl *FD) { 198 return isGraphicsRootRSFunc(targetAPI, FD) || isInitRSFunc(FD) || 199 isDtorRSFunc(FD); 200 } 201 202 static bool validateSpecialFuncDecl(unsigned int targetAPI, 203 slang::RSContext *Context, 204 const clang::FunctionDecl *FD); 205 }; // RSExportForEach 206 207 } // namespace slang 208 209 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_ NOLINT 210