slang_rs_context.h revision 277fd5e6545c8ba1272027ee6e6bc55a96316dc0
1/*
2 * Copyright 2010-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_CONTEXT_H_  // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_CONTEXT_H_
19
20#include <cstdio>
21#include <list>
22#include <map>
23#include <string>
24#include <unordered_set>
25#include <vector>
26
27#include "clang/Lex/Preprocessor.h"
28#include "clang/AST/Mangle.h"
29
30#include "llvm/ADT/StringSet.h"
31#include "llvm/ADT/StringMap.h"
32
33#include "slang_pragma_list.h"
34
35namespace llvm {
36  class LLVMContext;
37  class DataLayout;
38}   // namespace llvm
39
40namespace clang {
41  class VarDecl;
42  class ASTContext;
43  class TargetInfo;
44  class FunctionDecl;
45  class QualType;
46  class SourceManager;
47  class TypeDecl;
48  class FunctionDecl;
49}   // namespace clang
50
51namespace slang {
52  class RSExportable;
53  class RSExportVar;
54  class RSExportFunc;
55  class RSExportForEach;
56  class RSExportReduce;
57  class RSExportReduceNew;
58  class RSExportType;
59
60class RSContext {
61  typedef llvm::StringSet<> NeedExportVarSet;
62  typedef llvm::StringSet<> NeedExportFuncSet;
63  typedef llvm::StringSet<> NeedExportTypeSet;
64
65 public:
66  typedef std::list<RSExportable*> ExportableList;
67  typedef std::list<RSExportVar*> ExportVarList;
68  typedef std::list<RSExportFunc*> ExportFuncList;
69  typedef std::vector<RSExportForEach*> ExportForEachVector;
70  typedef std::list<RSExportReduce*> ExportReduceList;
71  typedef std::list<RSExportReduceNew*> ExportReduceNewList;
72
73  // WARNING: Sorted by pointer value, resulting in unpredictable order
74  typedef std::unordered_set<RSExportType*> ExportReduceNewResultTypeSet;
75
76  typedef llvm::StringMap<RSExportType*> ExportTypeMap;
77
78 private:
79  clang::Preprocessor &mPP;
80  clang::ASTContext &mCtx;
81  PragmaList *mPragmas;
82  // Precision specified via pragma, either rs_fp_full or rs_fp_relaxed. If
83  // empty, rs_fp_full is assumed.
84  std::string mPrecision;
85  unsigned int mTargetAPI;
86  bool mVerbose;
87
88  llvm::DataLayout *mDataLayout;
89  llvm::LLVMContext &mLLVMContext;
90
91  ExportableList mExportables;
92
93  NeedExportTypeSet mNeedExportTypes;
94
95  std::string *mLicenseNote;
96  std::string mReflectJavaPackageName;
97  std::string mReflectJavaPathName;
98
99  std::string mRSPackageName;
100
101  int version;
102
103  std::unique_ptr<clang::MangleContext> mMangleCtx;
104
105  bool mIs64Bit;
106
107  bool processExportVar(const clang::VarDecl *VD);
108  bool processExportFunc(const clang::FunctionDecl *FD);
109  bool processExportType(const llvm::StringRef &Name);
110
111  int getForEachSlotNumber(const clang::StringRef& funcName);
112  unsigned mNextSlot;
113
114  ExportVarList mExportVars;
115  ExportFuncList mExportFuncs;
116  std::map<llvm::StringRef, unsigned> mExportForEachMap;
117  ExportForEachVector mExportForEach;
118  ExportReduceList mExportReduce;
119  ExportReduceNewList mExportReduceNew;
120  ExportReduceNewResultTypeSet mExportReduceNewResultType;
121  ExportTypeMap mExportTypes;
122
123  clang::QualType mAllocationType;
124  clang::QualType mScriptCallType;
125
126 public:
127  RSContext(clang::Preprocessor &PP,
128            clang::ASTContext &Ctx,
129            const clang::TargetInfo &Target,
130            PragmaList *Pragmas,
131            unsigned int TargetAPI,
132            bool Verbose);
133
134  inline clang::Preprocessor &getPreprocessor() const { return mPP; }
135  inline clang::ASTContext &getASTContext() const { return mCtx; }
136  inline clang::MangleContext &getMangleContext() const {
137    return *mMangleCtx;
138  }
139  inline const llvm::DataLayout *getDataLayout() const { return mDataLayout; }
140  inline llvm::LLVMContext &getLLVMContext() const { return mLLVMContext; }
141  inline const clang::SourceManager *getSourceManager() const {
142    return &mPP.getSourceManager();
143  }
144  inline clang::DiagnosticsEngine *getDiagnostics() const {
145    return &mPP.getDiagnostics();
146  }
147  inline unsigned int getTargetAPI() const {
148    return mTargetAPI;
149  }
150
151  inline bool getVerbose() const {
152    return mVerbose;
153  }
154  inline bool is64Bit() const {
155    return mIs64Bit;
156  }
157
158  inline void setLicenseNote(const std::string &S) {
159    mLicenseNote = new std::string(S);
160  }
161  inline const std::string *getLicenseNote() const { return mLicenseNote; }
162
163  inline void addExportType(const std::string &S) {
164    mNeedExportTypes.insert(S);
165  }
166
167  inline void setReflectJavaPackageName(const std::string &S) {
168    mReflectJavaPackageName = S;
169  }
170  inline const std::string &getReflectJavaPackageName() const {
171    return mReflectJavaPackageName;
172  }
173
174  inline void setRSPackageName(const std::string &S) {
175    mRSPackageName = S;
176  }
177
178  inline const std::string &getRSPackageName() const { return mRSPackageName; }
179
180  void setAllocationType(const clang::TypeDecl* TD);
181  inline const clang::QualType& getAllocationType() const {
182    return mAllocationType;
183  }
184
185  void setScriptCallType(const clang::TypeDecl* TD);
186  inline const clang::QualType& getScriptCallType() const {
187    return mScriptCallType;
188  }
189
190  bool addForEach(const clang::FunctionDecl* FD);
191  bool processExports();
192  inline void newExportable(RSExportable *E) {
193    if (E != nullptr)
194      mExportables.push_back(E);
195  }
196  typedef ExportableList::iterator exportable_iterator;
197  exportable_iterator exportable_begin() {
198    return mExportables.begin();
199  }
200  exportable_iterator exportable_end() {
201    return mExportables.end();
202  }
203
204  typedef ExportVarList::const_iterator const_export_var_iterator;
205  const_export_var_iterator export_vars_begin() const {
206    return mExportVars.begin();
207  }
208  const_export_var_iterator export_vars_end() const {
209    return mExportVars.end();
210  }
211  inline bool hasExportVar() const {
212    return !mExportVars.empty();
213  }
214
215  typedef ExportFuncList::const_iterator const_export_func_iterator;
216  const_export_func_iterator export_funcs_begin() const {
217    return mExportFuncs.begin();
218  }
219  const_export_func_iterator export_funcs_end() const {
220    return mExportFuncs.end();
221  }
222  inline bool hasExportFunc() const { return !mExportFuncs.empty(); }
223
224  typedef ExportForEachVector::const_iterator const_export_foreach_iterator;
225  const_export_foreach_iterator export_foreach_begin() const {
226    return mExportForEach.begin();
227  }
228  const_export_foreach_iterator export_foreach_end() const {
229    return mExportForEach.end();
230  }
231  inline bool hasExportForEach() const { return !mExportForEach.empty(); }
232  int getForEachSlotNumber(const clang::FunctionDecl* FD);
233
234  typedef ExportReduceList::const_iterator const_export_reduce_iterator;
235  const_export_reduce_iterator export_reduce_begin() const {
236    return mExportReduce.begin();
237  }
238  const_export_reduce_iterator export_reduce_end() const {
239    return mExportReduce.end();
240  }
241  inline bool hasExportReduce() const { return !mExportReduce.empty(); }
242
243  typedef ExportReduceNewList::const_iterator const_export_reduce_new_iterator;
244  const_export_reduce_new_iterator export_reduce_new_begin() const {
245    return mExportReduceNew.begin();
246  }
247  const_export_reduce_new_iterator export_reduce_new_end() const {
248    return mExportReduceNew.end();
249  }
250  inline bool hasExportReduceNew() const { return !mExportReduceNew.empty(); }
251  void addExportReduceNew(RSExportReduceNew *ReduceNew) {
252    mExportReduceNew.push_back(ReduceNew);
253  }
254  bool processReducePragmas();
255  bool isReferencedByReducePragma(const clang::FunctionDecl *FD) const;
256
257  // If the type has already been inserted, has no effect.
258  void insertExportReduceNewResultType(RSExportType *Type) { mExportReduceNewResultType.insert(Type); }
259
260  template <class FilterIn, class Compare>
261  std::vector<RSExportType *> getReduceNewResultTypes(FilterIn Filt, Compare Comp) const {
262    std::vector<RSExportType *> Return;
263    std::copy_if(mExportReduceNewResultType.begin(), mExportReduceNewResultType.end(), std::back_inserter(Return), Filt);
264    std::sort(Return.begin(), Return.end(), Comp);
265    return Return;
266  }
267
268  typedef ExportTypeMap::iterator export_type_iterator;
269  typedef ExportTypeMap::const_iterator const_export_type_iterator;
270  export_type_iterator export_types_begin() { return mExportTypes.begin(); }
271  export_type_iterator export_types_end() { return mExportTypes.end(); }
272  const_export_type_iterator export_types_begin() const {
273    return mExportTypes.begin();
274  }
275  const_export_type_iterator export_types_end() const {
276    return mExportTypes.end();
277  }
278  inline bool hasExportType() const { return !mExportTypes.empty(); }
279  export_type_iterator findExportType(const llvm::StringRef &TypeName) {
280    return mExportTypes.find(TypeName);
281  }
282  const_export_type_iterator findExportType(const llvm::StringRef &TypeName)
283      const {
284    return mExportTypes.find(TypeName);
285  }
286
287  // Insert the specified Typename/Type pair into the map. If the key already
288  // exists in the map, return false and ignore the request, otherwise insert it
289  // and return true.
290  bool insertExportType(const llvm::StringRef &TypeName, RSExportType *Type);
291
292  int getVersion() const { return version; }
293  void setVersion(int v) {
294    version = v;
295  }
296
297  bool isCompatLib() const {
298    // If we are not targeting the actual Android Renderscript classes,
299    // we should reflect code that works with the compatibility library.
300    return (mRSPackageName.compare("android.renderscript") != 0);
301  }
302
303  void addPragma(const std::string &T, const std::string &V) {
304    mPragmas->push_back(make_pair(T, V));
305  }
306  void setPrecision(const std::string &P) { mPrecision = P; }
307  std::string getPrecision() { return mPrecision; }
308
309  // Report an error or a warning to the user.
310  template <unsigned N>
311  clang::DiagnosticBuilder Report(clang::DiagnosticsEngine::Level Level,
312                                             const char (&Message)[N]) {
313  clang::DiagnosticsEngine *DiagEngine = getDiagnostics();
314  return DiagEngine->Report(DiagEngine->getCustomDiagID(Level, Message));
315}
316
317  template <unsigned N>
318  clang::DiagnosticBuilder Report(clang::DiagnosticsEngine::Level Level,
319                                             const clang::SourceLocation Loc,
320                                             const char (&Message)[N]) {
321  clang::DiagnosticsEngine *DiagEngine = getDiagnostics();
322  const clang::SourceManager *SM = getSourceManager();
323  return DiagEngine->Report(clang::FullSourceLoc(Loc, *SM),
324                            DiagEngine->getCustomDiagID(Level, Message));
325}
326
327  // Utility functions to report errors and warnings to make the calling code
328  // easier to read.
329  template <unsigned N>
330  clang::DiagnosticBuilder ReportError(const char (&Message)[N]) {
331    return Report<N>(clang::DiagnosticsEngine::Error, Message);
332  }
333
334  template <unsigned N>
335  clang::DiagnosticBuilder ReportError(const clang::SourceLocation Loc,
336                                       const char (&Message)[N]) {
337    return Report<N>(clang::DiagnosticsEngine::Error, Loc, Message);
338  }
339
340  template <unsigned N>
341  clang::DiagnosticBuilder ReportWarning(const char (&Message)[N]) {
342    return Report<N>(clang::DiagnosticsEngine::Warning, Message);
343  }
344
345  template <unsigned N>
346  clang::DiagnosticBuilder ReportWarning(const clang::SourceLocation Loc,
347                                         const char (&Message)[N]) {
348    return Report<N>(clang::DiagnosticsEngine::Warning, Loc, Message);
349  }
350
351  ~RSContext();
352};
353
354}   // namespace slang
355
356#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_CONTEXT_H_  NOLINT
357