slang_rs_export_foreach.h revision 9ca96e70657cf5437a294213f56ba4768dc08ad2
11d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong/*
21d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong * Copyright 2011-2012, The Android Open Source Project
31d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong *
41d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong * Licensed under the Apache License, Version 2.0 (the "License");
51d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong * you may not use this file except in compliance with the License.
61d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong * You may obtain a copy of the License at
71d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong *
81d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong *     http://www.apache.org/licenses/LICENSE-2.0
91d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong *
101d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong * Unless required by applicable law or agreed to in writing, software
111d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong * distributed under the License is distributed on an "AS IS" BASIS,
121d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong * See the License for the specific language governing permissions and
141d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong * limitations under the License.
151d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong */
161d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
171d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_  // NOLINT
181d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_
191d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
201d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong#include "llvm/ADT/StringRef.h"
211d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong#include "llvm/Support/raw_ostream.h"
221d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
231d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong#include "clang/AST/Decl.h"
241d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
251d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong#include "slang_assert.h"
26e8057dd8208f0a185109992339a995c518b12780Elliott Hughes#include "slang_rs_context.h"
271d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong#include "slang_rs_exportable.h"
28f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include "slang_rs_export_type.h"
296c6b4d0d2b98a7ceee8b697daaf611f8df3254fbJames Dong
301d7491b19516505e0754c66a3c8cd61811c9b6a6James Dongnamespace clang {
311d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  class FunctionDecl;
321d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong}  // namespace clang
331d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
341d7491b19516505e0754c66a3c8cd61811c9b6a6James Dongnamespace slang {
351d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
361d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong// Base class for reflecting control-side forEach (currently for root()
371d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong// functions that fit appropriate criteria)
381d7491b19516505e0754c66a3c8cd61811c9b6a6James Dongclass RSExportForEach : public RSExportable {
391d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong private:
401d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  std::string mName;
411d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  RSExportRecordType *mParamPacketType;
421d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  RSExportType *mInType;
431d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  RSExportType *mOutType;
44aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke  size_t numParams;
45aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
46aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke  unsigned int mSignatureMetadata;
47f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke
48f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke  const clang::ParmVarDecl *mIn;
491d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  const clang::ParmVarDecl *mOut;
501d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  const clang::ParmVarDecl *mUsrData;
511d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  const clang::ParmVarDecl *mX;
521d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  const clang::ParmVarDecl *mY;
531d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  const clang::ParmVarDecl *mZ;
541d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  const clang::ParmVarDecl *mAr;
551d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
561d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  clang::QualType mResultType;  // return type (if present).
571d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  bool mReturn;  // does this kernel have a return type?
581d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  bool mKernel;  // is this a pass-by-value kernel?
591d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
601d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  bool mDummyRoot;
611d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
621d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  // TODO(all): Add support for LOD/face when we have them
631d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  RSExportForEach(RSContext *Context, const llvm::StringRef &Name)
641d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    : RSExportable(Context, RSExportable::EX_FOREACH),
65c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra      mName(Name.data(), Name.size()), mParamPacketType(NULL), mInType(NULL),
661d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong      mOutType(NULL), numParams(0), mSignatureMetadata(0),
67c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra      mIn(NULL), mOut(NULL), mUsrData(NULL), mX(NULL), mY(NULL), mZ(NULL),
689783ed8f85af3d7c72030098acfed7e1d6638349Nipun Kwatra      mAr(NULL), mResultType(clang::QualType()), mReturn(false),
69c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra      mKernel(false), mDummyRoot(false) {
70c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra    return;
71c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra  }
725f6af1a8e34381ca2ac2527fcefe220a22f49b53Zhijun He
73669012d77b00a2aacb6fd12837f2870f9ec17865James Dong  bool validateAndConstructParams(RSContext *Context,
74c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra                                  const clang::FunctionDecl *FD);
75c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra
76c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra  bool validateAndConstructKernelParams(RSContext *Context,
77c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra                                        const clang::FunctionDecl *FD);
789783ed8f85af3d7c72030098acfed7e1d6638349Nipun Kwatra
79c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra public:
80c0a84782589eececdfa7e723e8aa0e572d0d79f5Nipun Kwatra  static RSExportForEach *Create(RSContext *Context,
81669012d77b00a2aacb6fd12837f2870f9ec17865James Dong                                 const clang::FunctionDecl *FD);
825f6af1a8e34381ca2ac2527fcefe220a22f49b53Zhijun He
83669012d77b00a2aacb6fd12837f2870f9ec17865James Dong  static RSExportForEach *CreateDummyRoot(RSContext *Context);
84e07909715b44cc56df723750af93f0608210f94dZhijun He
85e07909715b44cc56df723750af93f0608210f94dZhijun He  inline const std::string &getName() const {
86e07909715b44cc56df723750af93f0608210f94dZhijun He    return mName;
87e07909715b44cc56df723750af93f0608210f94dZhijun He  }
88e07909715b44cc56df723750af93f0608210f94dZhijun He
89e07909715b44cc56df723750af93f0608210f94dZhijun He  inline size_t getNumParameters() const {
909520aa609c505cf8a9ee105bd78dc186cfb7770bZhijun He    return numParams;
911d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  }
921d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
9380520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten  inline bool hasIn() const {
9480520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten    return (mIn != NULL);
9580520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten  }
9680520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten
9780520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten  inline bool hasOut() const {
9880520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten    return (mOut != NULL);
991d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  }
10080520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten
1011d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  inline bool hasUsrData() const {
1023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    return (mUsrData != NULL);
1033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  }
1043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  inline bool hasReturn() const {
1063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    return mReturn;
1073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  }
1081d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
1091d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  inline const RSExportType *getInType() const {
1101d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    return mInType;
11180520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten  }
1121d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
1133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  inline const RSExportType *getOutType() const {
1143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    return mOutType;
1153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  }
1163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  inline const RSExportRecordType *getParamPacketType() const {
1181d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    return mParamPacketType;
1191d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  }
1201d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
12180520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten  inline unsigned int getSignatureMetadata() const {
1221d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    return mSignatureMetadata;
1233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  }
1243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  inline bool isDummyRoot() const {
1263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    return mDummyRoot;
1273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  }
1283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1291d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  typedef RSExportRecordType::const_field_iterator const_param_iterator;
1301d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
1311d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  inline const_param_iterator params_begin() const {
13280520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten    slangAssert((mParamPacketType != NULL) &&
1331d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong                "Get parameter from export foreach having no parameter!");
1343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    return mParamPacketType->fields_begin();
1353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  }
1363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  inline const_param_iterator params_end() const {
1383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    slangAssert((mParamPacketType != NULL) &&
1391d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong                "Get parameter from export foreach having no parameter!");
1401d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    return mParamPacketType->fields_end();
1411d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  }
14280520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten
1431d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  inline static bool isInitRSFunc(const clang::FunctionDecl *FD) {
1443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    if (!FD) {
1453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block      return false;
1461d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    }
1471d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    const llvm::StringRef Name = FD->getName();
1481d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    static llvm::StringRef FuncInit("init");
14980520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten    return Name.equals(FuncInit);
1501d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  }
1513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  inline static bool isRootRSFunc(const clang::FunctionDecl *FD) {
1531d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    if (!FD) {
1541d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong      return false;
155cabd5f867ec69c0dfe8333cba46323cb58917402Hong Teng    }
15680520381d0bdf3451bd17c9ddef73d3fe71c58c2Glenn Kasten    const llvm::StringRef Name = FD->getName();
157cabd5f867ec69c0dfe8333cba46323cb58917402Hong Teng    static llvm::StringRef FuncRoot("root");
1583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    return Name.equals(FuncRoot);
1593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  }
1603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  inline static bool isDtorRSFunc(const clang::FunctionDecl *FD) {
1623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    if (!FD) {
163cabd5f867ec69c0dfe8333cba46323cb58917402Hong Teng      return false;
164cabd5f867ec69c0dfe8333cba46323cb58917402Hong Teng    }
1651d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    const llvm::StringRef Name = FD->getName();
1661d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    static llvm::StringRef FuncDtor(".rs.dtor");
1671d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    return Name.equals(FuncDtor);
1681d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  }
1691d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
1701d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  static bool isGraphicsRootRSFunc(int targetAPI,
1711d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong                                   const clang::FunctionDecl *FD);
1721d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
1731d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  static bool isRSForEachFunc(int targetAPI, const clang::FunctionDecl *FD);
1741d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
1751d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  inline static bool isSpecialRSFunc(int targetAPI,
1761d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong                                     const clang::FunctionDecl *FD) {
1771d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong    return isGraphicsRootRSFunc(targetAPI, FD) || isInitRSFunc(FD) ||
1781d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong           isDtorRSFunc(FD);
1791d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  }
1801d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
1811d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong  static bool validateSpecialFuncDecl(int targetAPI,
1821d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong                                      clang::DiagnosticsEngine *DiagEngine,
1831d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong                                      const clang::FunctionDecl *FD);
1841d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong};  // RSExportForEach
1851d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
1861d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong}  // namespace slang
1871d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong
1881d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_  NOLINT
1891d7491b19516505e0754c66a3c8cd61811c9b6a6James Dong