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