slang_rs_export_foreach.h revision 0f2a2397df53a1bb74609abe3c27719bc7e3c328
15baf6324a97430016026419deaef246ad75430fcStephen Hines/*
29999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines * Copyright 2011-2012, The Android Open Source Project
35baf6324a97430016026419deaef246ad75430fcStephen Hines *
45baf6324a97430016026419deaef246ad75430fcStephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
55baf6324a97430016026419deaef246ad75430fcStephen Hines * you may not use this file except in compliance with the License.
65baf6324a97430016026419deaef246ad75430fcStephen Hines * You may obtain a copy of the License at
75baf6324a97430016026419deaef246ad75430fcStephen Hines *
85baf6324a97430016026419deaef246ad75430fcStephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
95baf6324a97430016026419deaef246ad75430fcStephen Hines *
105baf6324a97430016026419deaef246ad75430fcStephen Hines * Unless required by applicable law or agreed to in writing, software
115baf6324a97430016026419deaef246ad75430fcStephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
125baf6324a97430016026419deaef246ad75430fcStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135baf6324a97430016026419deaef246ad75430fcStephen Hines * See the License for the specific language governing permissions and
145baf6324a97430016026419deaef246ad75430fcStephen Hines * limitations under the License.
155baf6324a97430016026419deaef246ad75430fcStephen Hines */
165baf6324a97430016026419deaef246ad75430fcStephen Hines
17593a894650e81be54173106ec266f0311cebebd3Stephen Hines#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_  // NOLINT
18593a894650e81be54173106ec266f0311cebebd3Stephen Hines#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_
195baf6324a97430016026419deaef246ad75430fcStephen Hines
205baf6324a97430016026419deaef246ad75430fcStephen Hines#include "llvm/ADT/StringRef.h"
215baf6324a97430016026419deaef246ad75430fcStephen Hines#include "llvm/Support/raw_ostream.h"
225baf6324a97430016026419deaef246ad75430fcStephen Hines
235baf6324a97430016026419deaef246ad75430fcStephen Hines#include "clang/AST/Decl.h"
245baf6324a97430016026419deaef246ad75430fcStephen Hines
255baf6324a97430016026419deaef246ad75430fcStephen Hines#include "slang_assert.h"
265baf6324a97430016026419deaef246ad75430fcStephen Hines#include "slang_rs_context.h"
27593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_exportable.h"
28593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_export_type.h"
295baf6324a97430016026419deaef246ad75430fcStephen Hines
305baf6324a97430016026419deaef246ad75430fcStephen Hinesnamespace clang {
315baf6324a97430016026419deaef246ad75430fcStephen Hines  class FunctionDecl;
325baf6324a97430016026419deaef246ad75430fcStephen Hines}  // namespace clang
335baf6324a97430016026419deaef246ad75430fcStephen Hines
345baf6324a97430016026419deaef246ad75430fcStephen Hinesnamespace slang {
355baf6324a97430016026419deaef246ad75430fcStephen Hines
36593a894650e81be54173106ec266f0311cebebd3Stephen Hines// Base class for reflecting control-side forEach (currently for root()
37593a894650e81be54173106ec266f0311cebebd3Stephen Hines// functions that fit appropriate criteria)
38593a894650e81be54173106ec266f0311cebebd3Stephen Hinesclass RSExportForEach : public RSExportable {
395baf6324a97430016026419deaef246ad75430fcStephen Hines private:
405baf6324a97430016026419deaef246ad75430fcStephen Hines  std::string mName;
41593a894650e81be54173106ec266f0311cebebd3Stephen Hines  RSExportRecordType *mParamPacketType;
42b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  RSExportType *mInType;
43b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  RSExportType *mOutType;
44593a894650e81be54173106ec266f0311cebebd3Stephen Hines  size_t numParams;
455baf6324a97430016026419deaef246ad75430fcStephen Hines
467b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines  unsigned int mSignatureMetadata;
474ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
48b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  const clang::ParmVarDecl *mIn;
49b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  const clang::ParmVarDecl *mOut;
50b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  const clang::ParmVarDecl *mUsrData;
51b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  const clang::ParmVarDecl *mX;
52b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  const clang::ParmVarDecl *mY;
53b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  const clang::ParmVarDecl *mZ;
54b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  const clang::ParmVarDecl *mAr;
55b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
569ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  clang::QualType mResultType;  // return type (if present).
570f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet  bool mHasReturnType;  // does this kernel have a return type?
580f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet  bool mIsKernelStyle;  // is this a pass-by-value kernel?
599ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
60c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  bool mDummyRoot;
61c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
62b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  // TODO(all): Add support for LOD/face when we have them
63c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  RSExportForEach(RSContext *Context, const llvm::StringRef &Name)
64593a894650e81be54173106ec266f0311cebebd3Stephen Hines    : RSExportable(Context, RSExportable::EX_FOREACH),
65b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines      mName(Name.data(), Name.size()), mParamPacketType(NULL), mInType(NULL),
667b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mOutType(NULL), numParams(0), mSignatureMetadata(0),
679ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines      mIn(NULL), mOut(NULL), mUsrData(NULL), mX(NULL), mY(NULL), mZ(NULL),
680f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet      mAr(NULL), mResultType(clang::QualType()), mHasReturnType(false),
690f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet      mIsKernelStyle(false), mDummyRoot(false) {
705baf6324a97430016026419deaef246ad75430fcStephen Hines    return;
715baf6324a97430016026419deaef246ad75430fcStephen Hines  }
725baf6324a97430016026419deaef246ad75430fcStephen Hines
73b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  bool validateAndConstructParams(RSContext *Context,
74b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                                  const clang::FunctionDecl *FD);
75b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
760f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet  bool validateAndConstructOldStyleParams(RSContext *Context,
770f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet                                        const clang::FunctionDecl *FD);
780f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet
799ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  bool validateAndConstructKernelParams(RSContext *Context,
809ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                                        const clang::FunctionDecl *FD);
819ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
820f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet  bool setSignatureMetadata(RSContext *Context,
830f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet                            const clang::FunctionDecl *FD);
845baf6324a97430016026419deaef246ad75430fcStephen Hines public:
85593a894650e81be54173106ec266f0311cebebd3Stephen Hines  static RSExportForEach *Create(RSContext *Context,
86593a894650e81be54173106ec266f0311cebebd3Stephen Hines                                 const clang::FunctionDecl *FD);
87593a894650e81be54173106ec266f0311cebebd3Stephen Hines
88c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  static RSExportForEach *CreateDummyRoot(RSContext *Context);
89c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
90593a894650e81be54173106ec266f0311cebebd3Stephen Hines  inline const std::string &getName() const {
91593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return mName;
92593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
93593a894650e81be54173106ec266f0311cebebd3Stephen Hines
94593a894650e81be54173106ec266f0311cebebd3Stephen Hines  inline size_t getNumParameters() const {
95593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return numParams;
96593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
97593a894650e81be54173106ec266f0311cebebd3Stephen Hines
98b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline bool hasIn() const {
99b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    return (mIn != NULL);
100b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
101b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
102b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline bool hasOut() const {
103b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    return (mOut != NULL);
104b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
105b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
106b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline bool hasUsrData() const {
107b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    return (mUsrData != NULL);
108b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
109b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
1109ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  inline bool hasReturn() const {
1110f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet    return mHasReturnType;
1129ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  }
1139ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
114b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline const RSExportType *getInType() const {
115b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    return mInType;
116b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
117b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
118b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline const RSExportType *getOutType() const {
119b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    return mOutType;
120b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
121b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
122b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline const RSExportRecordType *getParamPacketType() const {
123b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    return mParamPacketType;
124b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
125593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1267b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines  inline unsigned int getSignatureMetadata() const {
1277b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    return mSignatureMetadata;
1284ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  }
1294ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
130c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  inline bool isDummyRoot() const {
131c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    return mDummyRoot;
132c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  }
133c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
134593a894650e81be54173106ec266f0311cebebd3Stephen Hines  typedef RSExportRecordType::const_field_iterator const_param_iterator;
1355baf6324a97430016026419deaef246ad75430fcStephen Hines
136593a894650e81be54173106ec266f0311cebebd3Stephen Hines  inline const_param_iterator params_begin() const {
137593a894650e81be54173106ec266f0311cebebd3Stephen Hines    slangAssert((mParamPacketType != NULL) &&
138593a894650e81be54173106ec266f0311cebebd3Stephen Hines                "Get parameter from export foreach having no parameter!");
139593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return mParamPacketType->fields_begin();
140593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
141b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
142593a894650e81be54173106ec266f0311cebebd3Stephen Hines  inline const_param_iterator params_end() const {
143593a894650e81be54173106ec266f0311cebebd3Stephen Hines    slangAssert((mParamPacketType != NULL) &&
144593a894650e81be54173106ec266f0311cebebd3Stephen Hines                "Get parameter from export foreach having no parameter!");
145593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return mParamPacketType->fields_end();
1465baf6324a97430016026419deaef246ad75430fcStephen Hines  }
1475baf6324a97430016026419deaef246ad75430fcStephen Hines
1485baf6324a97430016026419deaef246ad75430fcStephen Hines  inline static bool isInitRSFunc(const clang::FunctionDecl *FD) {
1495baf6324a97430016026419deaef246ad75430fcStephen Hines    if (!FD) {
1505baf6324a97430016026419deaef246ad75430fcStephen Hines      return false;
1515baf6324a97430016026419deaef246ad75430fcStephen Hines    }
1525baf6324a97430016026419deaef246ad75430fcStephen Hines    const llvm::StringRef Name = FD->getName();
1535baf6324a97430016026419deaef246ad75430fcStephen Hines    static llvm::StringRef FuncInit("init");
1545baf6324a97430016026419deaef246ad75430fcStephen Hines    return Name.equals(FuncInit);
1555baf6324a97430016026419deaef246ad75430fcStephen Hines  }
1565baf6324a97430016026419deaef246ad75430fcStephen Hines
1575baf6324a97430016026419deaef246ad75430fcStephen Hines  inline static bool isRootRSFunc(const clang::FunctionDecl *FD) {
1585baf6324a97430016026419deaef246ad75430fcStephen Hines    if (!FD) {
1595baf6324a97430016026419deaef246ad75430fcStephen Hines      return false;
1605baf6324a97430016026419deaef246ad75430fcStephen Hines    }
1615baf6324a97430016026419deaef246ad75430fcStephen Hines    const llvm::StringRef Name = FD->getName();
1625baf6324a97430016026419deaef246ad75430fcStephen Hines    static llvm::StringRef FuncRoot("root");
1635baf6324a97430016026419deaef246ad75430fcStephen Hines    return Name.equals(FuncRoot);
1645baf6324a97430016026419deaef246ad75430fcStephen Hines  }
1655baf6324a97430016026419deaef246ad75430fcStephen Hines
166688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  inline static bool isDtorRSFunc(const clang::FunctionDecl *FD) {
167688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    if (!FD) {
168688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines      return false;
169688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    }
170688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    const llvm::StringRef Name = FD->getName();
171688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    static llvm::StringRef FuncDtor(".rs.dtor");
172688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    return Name.equals(FuncDtor);
173688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  }
174688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
1759999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines  static bool isGraphicsRootRSFunc(int targetAPI,
1769999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines                                   const clang::FunctionDecl *FD);
1779999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines
178089cde338148fbb75825aea4539ccdae8211ffefStephen Hines  static bool isRSForEachFunc(int targetAPI,
179089cde338148fbb75825aea4539ccdae8211ffefStephen Hines                              clang::DiagnosticsEngine *DiagEngine,
180089cde338148fbb75825aea4539ccdae8211ffefStephen Hines                              const clang::FunctionDecl *FD);
181593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1829999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines  inline static bool isSpecialRSFunc(int targetAPI,
1839999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines                                     const clang::FunctionDecl *FD) {
1849999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines    return isGraphicsRootRSFunc(targetAPI, FD) || isInitRSFunc(FD) ||
1859999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines           isDtorRSFunc(FD);
1865baf6324a97430016026419deaef246ad75430fcStephen Hines  }
1875baf6324a97430016026419deaef246ad75430fcStephen Hines
188f736d5a12269e7e74740b130cdca98d9839b31e6Stephen Hines  static bool validateSpecialFuncDecl(int targetAPI,
189fbfd7f5fd97458b6b23437556025ac1d55e98fd4Stephen Hines                                      clang::DiagnosticsEngine *DiagEngine,
1905baf6324a97430016026419deaef246ad75430fcStephen Hines                                      const clang::FunctionDecl *FD);
191593a894650e81be54173106ec266f0311cebebd3Stephen Hines};  // RSExportForEach
1925baf6324a97430016026419deaef246ad75430fcStephen Hines
1935baf6324a97430016026419deaef246ad75430fcStephen Hines}  // namespace slang
1945baf6324a97430016026419deaef246ad75430fcStephen Hines
195593a894650e81be54173106ec266f0311cebebd3Stephen Hines#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_  NOLINT
196