1 /* 2 * Copyright 2010, 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_BACKEND_H_ // NOLINT 18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_BACKEND_H_ 19 20 #include "clang/AST/ASTConsumer.h" 21 22 #include "llvm/IR/LegacyPassManager.h" 23 24 #include "llvm/Support/raw_ostream.h" 25 26 #include "slang.h" 27 #include "slang_pragma_recorder.h" 28 #include "slang_rs_check_ast.h" 29 #include "slang_rs_object_ref_count.h" 30 #include "slang_version.h" 31 32 namespace llvm { 33 class buffer_ostream; 34 class LLVMContext; 35 class NamedMDNode; 36 class Module; 37 } 38 39 namespace clang { 40 class ASTConsumer; 41 class ASTContext; 42 class CodeGenOptions; 43 class CodeGenerator; 44 class DeclGroupRef; 45 class DiagnosticsEngine; 46 class FunctionDecl; 47 class TagDecl; 48 class TargetOptions; 49 class VarDecl; 50 } 51 52 namespace slang { 53 54 class RSContext; 55 56 class Backend : public clang::ASTConsumer { 57 private: 58 const clang::TargetOptions &mTargetOpts; 59 60 llvm::Module *mpModule; 61 62 // Output stream 63 llvm::raw_ostream *mpOS; 64 Slang::OutputType mOT; 65 66 // This helps us translate Clang AST using into LLVM IR 67 clang::CodeGenerator *mGen; 68 69 // Passes 70 71 // Passes apply on function scope in a translation unit 72 llvm::legacy::FunctionPassManager *mPerFunctionPasses; 73 // Passes apply on module scope 74 llvm::legacy::PassManager *mPerModulePasses; 75 // Passes for code emission 76 llvm::legacy::FunctionPassManager *mCodeGenPasses; 77 78 llvm::buffer_ostream mBufferOutStream; 79 80 void CreateFunctionPasses(); 81 void CreateModulePasses(); 82 bool CreateCodeGenPasses(); 83 84 void WrapBitcode(llvm::raw_string_ostream &Bitcode); 85 86 RSContext *mContext; 87 88 clang::SourceManager &mSourceMgr; 89 90 bool mAllowRSPrefix; 91 92 bool mIsFilterscript; 93 94 llvm::NamedMDNode *mExportVarMetadata; 95 llvm::NamedMDNode *mExportFuncMetadata; 96 llvm::NamedMDNode *mExportForEachNameMetadata; 97 llvm::NamedMDNode *mExportForEachSignatureMetadata; 98 llvm::NamedMDNode *mExportTypeMetadata; 99 llvm::NamedMDNode *mRSObjectSlotsMetadata; 100 101 RSObjectRefCount mRefCount; 102 103 RSCheckAST mASTChecker; 104 105 void AnnotateFunction(clang::FunctionDecl *FD); 106 107 void dumpExportVarInfo(llvm::Module *M); 108 void dumpExportFunctionInfo(llvm::Module *M); 109 void dumpExportForEachInfo(llvm::Module *M); 110 void dumpExportTypeInfo(llvm::Module *M); 111 112 protected: 113 llvm::LLVMContext &mLLVMContext; 114 clang::DiagnosticsEngine &mDiagEngine; 115 const clang::CodeGenOptions &mCodeGenOpts; 116 117 PragmaList *mPragmas; 118 getTargetAPI()119 unsigned int getTargetAPI() const { return mContext->getTargetAPI(); } 120 121 // TODO These are no longer virtual from base. Look into merging into caller. 122 123 // This handler will be invoked before Clang translates @Ctx to LLVM IR. This 124 // give you an opportunity to modified the IR in AST level (scope information, 125 // unoptimized IR, etc.). After the return from this method, slang will start 126 // translate @Ctx into LLVM IR. One should not operate on @Ctx afterwards 127 // since the changes applied on that never reflects to the LLVM module used 128 // in the final codegen. 129 void HandleTranslationUnitPre(clang::ASTContext &Ctx); 130 131 // This handler will be invoked when Clang have converted AST tree to LLVM IR. 132 // The @M contains the resulting LLVM IR tree. After the return from this 133 // method, slang will start doing optimization and code generation for @M. 134 void HandleTranslationUnitPost(llvm::Module *M); 135 136 public: 137 Backend(RSContext *Context, 138 clang::DiagnosticsEngine *DiagEngine, 139 const clang::CodeGenOptions &CodeGenOpts, 140 const clang::TargetOptions &TargetOpts, 141 PragmaList *Pragmas, 142 llvm::raw_ostream *OS, 143 Slang::OutputType OT, 144 clang::SourceManager &SourceMgr, 145 bool AllowRSPrefix, 146 bool IsFilterscript); 147 148 virtual ~Backend(); 149 150 // Initialize - This is called to initialize the consumer, providing the 151 // ASTContext. 152 void Initialize(clang::ASTContext &Ctx) override; 153 154 // TODO Clean up what should be private, protected 155 // TODO Also clean up the include files 156 157 // HandleTopLevelDecl - Handle the specified top-level declaration. This is 158 // called by the parser to process every top-level Decl*. Note that D can be 159 // the head of a chain of Decls (e.g. for `int a, b` the chain will have two 160 // elements). Use Decl::getNextDeclarator() to walk the chain. 161 bool HandleTopLevelDecl(clang::DeclGroupRef D) override; 162 163 // HandleTranslationUnit - This method is called when the ASTs for entire 164 // translation unit have been parsed. 165 void HandleTranslationUnit(clang::ASTContext &Ctx) override; 166 167 // HandleTagDeclDefinition - This callback is invoked each time a TagDecl 168 // (e.g. struct, union, enum, class) is completed. This allows the client to 169 // hack on the type, which can occur at any point in the file (because these 170 // can be defined in declspecs). 171 void HandleTagDeclDefinition(clang::TagDecl *D) override; 172 173 // CompleteTentativeDefinition - Callback invoked at the end of a translation 174 // unit to notify the consumer that the given tentative definition should be 175 // completed. 176 void CompleteTentativeDefinition(clang::VarDecl *D) override; 177 }; 178 179 } // namespace slang 180 181 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_BACKEND_H_ NOLINT 182