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