slang_rs_context.cpp revision a50704238e06bc72a7ea3e8282fb5d350f88fd08
1#include "slang.hpp" 2#include "slang_rs_context.hpp" 3#include "slang_rs_reflection.hpp" 4#include "slang_rs_export_var.hpp" 5#include "slang_rs_export_func.hpp" 6#include "slang_rs_export_type.hpp" 7#include "slang_rs_pragma_handler.hpp" 8 9#include "clang/AST/Type.h" /* for class clang::QualType */ 10#include "clang/AST/Decl.h" /* for class clang::*Decl */ 11#include "clang/Index/Utils.h" /* for class clang::idx::ResolveLocationInAST() */ 12#include "clang/AST/DeclBase.h" /* for class clang::Decl and clang::DeclContext */ 13#include "clang/AST/ASTContext.h" /* for class clang::ASTContext */ 14#include "clang/Basic/TargetInfo.h" /* for class clang::TargetInfo */ 15#include "clang/Index/ASTLocation.h" /* for class clang::idx::ASTLocation */ 16 17#include "llvm/LLVMContext.h" /* for function llvm::getGlobalContext() */ 18#include "llvm/Target/TargetData.h" /* for class llvm::TargetData */ 19 20using namespace clang::idx; 21 22namespace slang { 23 24RSContext::RSContext(Preprocessor* PP, ASTContext* Ctx, const TargetInfo* Target) : 25 mPP(PP), 26 mCtx(Ctx), 27 mTarget(Target), 28 mTargetData(NULL), 29 mLLVMContext(llvm::getGlobalContext()), 30 mRSExportVarPragma(NULL), 31 mRSExportVarAllPragma(NULL), 32 mRSExportFuncPragma(NULL), 33 mRSExportFuncAllPragma(NULL), 34 mRSExportTypePragma(NULL), 35 mRSJavaPackageNamePragma(NULL), 36 mRSReflectLicensePragma(NULL), 37 mExportAllNonStaticVars(false), 38 mExportAllNonStaticFuncs(false) 39{ 40 /* For #pragma rs export_var */ 41 mRSExportVarPragma = RSPragmaHandler::CreatePragmaExportVarHandler(this); 42 if(mRSExportVarPragma != NULL) 43 PP->AddPragmaHandler("rs", mRSExportVarPragma); 44 45 /* For #pragma rs export_var_all */ 46 mRSExportVarAllPragma = RSPragmaHandler::CreatePragmaExportVarAllHandler(this); 47 if(mRSExportVarAllPragma != NULL) 48 PP->AddPragmaHandler("rs", mRSExportVarAllPragma); 49 50 /* For #pragma rs export_func */ 51 mRSExportFuncPragma = RSPragmaHandler::CreatePragmaExportFuncHandler(this); 52 if(mRSExportFuncPragma != NULL) 53 PP->AddPragmaHandler("rs", mRSExportFuncPragma); 54 55 /* For #pragma rs export_func_all */ 56 mRSExportFuncAllPragma = RSPragmaHandler::CreatePragmaExportFuncAllHandler(this); 57 if(mRSExportFuncAllPragma != NULL) 58 PP->AddPragmaHandler("rs", mRSExportFuncAllPragma); 59 60 /* For #pragma rs export_type */ 61 mRSExportTypePragma = RSPragmaHandler::CreatePragmaExportTypeHandler(this); 62 if(mRSExportTypePragma != NULL) 63 PP->AddPragmaHandler("rs", mRSExportTypePragma); 64 65 /* For #pragma rs java_package_name */ 66 mRSJavaPackageNamePragma = RSPragmaHandler::CreatePragmaJavaPackageNameHandler(this); 67 if(mRSJavaPackageNamePragma != NULL) 68 PP->AddPragmaHandler("rs", mRSJavaPackageNamePragma); 69 70 /* For #pragma rs set_reflect_license */ 71 mRSReflectLicensePragma = RSPragmaHandler::RSPragmaHandler::CreatePragmaReflectLicenseHandler(this); 72 if (mRSReflectLicensePragma != NULL) 73 PP->AddPragmaHandler("rs", mRSReflectLicensePragma); 74 75 /* Prepare target data */ 76 mTargetData = new llvm::TargetData(Slang::TargetDescription); 77 78 return; 79} 80 81bool RSContext::processExportVar(const VarDecl* VD) { 82 assert(!VD->getName().empty() && "Variable name should not be empty"); 83 84 /* TODO: some check on variable */ 85 86 RSExportType* ET = RSExportType::CreateFromDecl(this, VD); 87 if(!ET) 88 return false; 89 90 RSExportVar* EV = new RSExportVar(this, VD, ET); 91 if(EV == NULL) 92 return false; 93 else 94 mExportVars.push_back(EV); 95 96 return true; 97} 98 99bool RSContext::processExportFunc(const FunctionDecl* FD) { 100 assert(!FD->getName().empty() && "Function name should not be empty"); 101 102 if(!FD->isThisDeclarationADefinition()) 103 return false; 104 105 if(FD->getStorageClass() != FunctionDecl::None) { 106 printf("RSContext::processExportFunc : cannot export extern or static function '%s'\n", FD->getName().str().c_str()); 107 return false; 108 } 109 110 RSExportFunc* EF = RSExportFunc::Create(this, FD); 111 if(EF == NULL) 112 return false; 113 else 114 mExportFuncs.push_back(EF); 115 116 return true; 117} 118 119 120bool RSContext::processExportType(const llvm::StringRef& Name) { 121 TranslationUnitDecl* TUDecl = mCtx->getTranslationUnitDecl(); 122 123 assert(TUDecl != NULL && "Translation unit declaration (top-level declaration) is null object"); 124 125 const IdentifierInfo* II = mPP->getIdentifierInfo(Name); 126 if(II == NULL) 127 /* TODO: error: identifier @Name mark as an exportable type cannot be found */ 128 return false; 129 130 DeclContext::lookup_const_result R = TUDecl->lookup(II); 131 bool Done = false; 132 RSExportType* ET = NULL; 133 134 RSExportPointerType::IntegerType = mCtx->IntTy.getTypePtr(); 135 136 for(DeclContext::lookup_const_iterator I = R.first; 137 I != R.second; 138 I++) 139 { 140 NamedDecl* const ND = *I; 141 ASTLocation* LastLoc = new ASTLocation(ND); 142 ASTLocation AL = ResolveLocationInAST(*mCtx, ND->getLocStart(), LastLoc); 143 144 delete LastLoc; 145 if(AL.isDecl()) { 146 Decl* D = AL.dyn_AsDecl(); 147 const Type* T = NULL; 148 149 switch(D->getKind()) { 150 case Decl::Typedef: 151 T = static_cast<const TypedefDecl*>(D)->getCanonicalDecl()->getUnderlyingType().getTypePtr(); 152 break; 153 154 case Decl::Record: 155 T = static_cast<const RecordDecl*>(D)->getTypeForDecl(); 156 break; 157 158 default: 159 /* unsupported, skip */ 160 break; 161 } 162 163 if(T != NULL) 164 ET = RSExportType::Create(this, T); 165 } 166 } 167 168 RSExportPointerType::IntegerType = NULL; 169 170 return (ET != NULL); 171} 172 173void RSContext::processExport() { 174 /* Export variable */ 175 TranslationUnitDecl* TUDecl = mCtx->getTranslationUnitDecl(); 176 for(DeclContext::decl_iterator DI = TUDecl->decls_begin(); 177 DI != TUDecl->decls_end(); 178 DI++) 179 { 180 if (DI->getKind() == Decl::Var) { 181 VarDecl* VD = (VarDecl*) (*DI); 182 if (mExportAllNonStaticVars && VD->getStorageClass() == VarDecl::None) { 183 if (!processExportVar(VD)) { 184 printf("RSContext::processExport : failed to export var '%s'\n", VD->getNameAsCString()); 185 } 186 } else { 187 NeedExportVarSet::iterator EI = mNeedExportVars.find(VD->getName()); 188 if(EI != mNeedExportVars.end() && processExportVar(VD)) 189 mNeedExportVars.erase(EI); 190 } 191 } else if (DI->getKind() == Decl::Function) { 192 FunctionDecl* FD = (FunctionDecl*) (*DI); 193 if (mExportAllNonStaticFuncs && FD->getStorageClass() == FunctionDecl::None) { 194 if (!processExportFunc(FD)) { 195 printf("RSContext::processExport : failed to export func '%s'\n", FD->getNameAsCString()); 196 } 197 } else { 198 NeedExportFuncSet::iterator EI = mNeedExportFuncs.find(FD->getName()); 199 if(EI != mNeedExportFuncs.end() && processExportFunc(FD)) 200 mNeedExportFuncs.erase(EI); 201 } 202 } 203 } 204 205 /* Finally, export type forcely set to be exported by user */ 206 for(NeedExportTypeSet::const_iterator EI = mNeedExportTypes.begin(); 207 EI != mNeedExportTypes.end(); 208 EI++) 209 if(!processExportType(EI->getKey())) 210 printf("RSContext::processExport : failed to export type '%s'\n", EI->getKey().str().c_str()); 211 212 213 return; 214} 215 216bool RSContext::insertExportType(const llvm::StringRef& TypeName, RSExportType* ET) { 217 ExportTypeMap::value_type* NewItem = ExportTypeMap::value_type::Create(TypeName.begin(), TypeName.end(), mExportTypes.getAllocator(), ET); 218 219 if(mExportTypes.insert(NewItem)) { 220 return true; 221 } else { 222 delete NewItem; 223 return false; 224 } 225} 226 227bool RSContext::reflectToJava(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName) { 228 if(OutputPackageName == NULL) 229 if(!mReflectJavaPackageName.empty()) 230 OutputPackageName = mReflectJavaPackageName.c_str(); 231 else 232 return true; /* no package name, just return */ 233 234 RSReflection* R = new RSReflection(this); 235 bool ret = R->reflect(OutputPackageName, InputFileName, OutputBCFileName); 236 if(!ret) 237 printf("RSContext::reflectToJava : failed to do reflection (%s)\n", R->getLastError()); 238 delete R; 239 return ret; 240} 241 242RSContext::~RSContext() { 243 delete mRSExportVarPragma; 244 delete mRSExportFuncPragma; 245 delete mRSExportTypePragma; 246 delete mRSJavaPackageNamePragma; 247 delete mRSReflectLicensePragma; 248 249 delete mLicenseNote; 250 delete mTargetData; 251} 252 253} /* namespace slang */ 254