| /* |
| * Copyright 2010, The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_H_ // NOLINT |
| #define _FRAMEWORKS_COMPILE_SLANG_SLANG_H_ |
| |
| #include <cstdio> |
| #include <list> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "llvm/ADT/StringMap.h" |
| |
| #include "slang_rs_reflect_utils.h" |
| #include "slang_version.h" |
| |
| // Terrible workaround for TargetOptions.h not using llvm::RefCountedBase! |
| #include "llvm/ADT/IntrusiveRefCntPtr.h" |
| using llvm::RefCountedBase; |
| |
| #include "clang/Basic/LangOptions.h" |
| #include "clang/Basic/TargetOptions.h" |
| #include "clang/Frontend/CodeGenOptions.h" |
| #include "clang/Lex/ModuleLoader.h" |
| |
| #include "llvm/ADT/StringRef.h" |
| |
| #include "llvm/Target/TargetMachine.h" |
| |
| #include "slang_diagnostic_buffer.h" |
| #include "slang_pragma_recorder.h" |
| |
| namespace llvm { |
| class tool_output_file; |
| } |
| |
| namespace clang { |
| class ASTConsumer; |
| class ASTContext; |
| class Backend; |
| class CodeGenOptions; |
| class Diagnostic; |
| class DiagnosticsEngine; |
| class FileManager; |
| class FileSystemOptions; |
| class LangOptions; |
| class Preprocessor; |
| class SourceManager; |
| class TargetInfo; |
| } // namespace clang |
| |
| namespace slang { |
| |
| class RSCCOptions; |
| class RSContext; |
| class RSExportRecordType; |
| |
| class Slang : public clang::ModuleLoader { |
| public: |
| enum OutputType { |
| OT_Dependency, |
| OT_Assembly, |
| OT_LLVMAssembly, |
| OT_Bitcode, |
| OT_Nothing, |
| OT_Object, |
| |
| OT_Default = OT_Bitcode |
| }; |
| |
| private: |
| // Language options (define the language feature for compiler such as C99) |
| clang::LangOptions LangOpts; |
| // Code generation options for the compiler |
| clang::CodeGenOptions CodeGenOpts; |
| |
| // Returns true if this is a Filterscript file. |
| static bool isFilterscript(const char *Filename); |
| |
| // Diagnostics Engine (Producer and Diagnostics Reporter) |
| clang::DiagnosticsEngine *mDiagEngine; |
| |
| // Diagnostics Consumer |
| // NOTE: The ownership is taken by mDiagEngine after creation. |
| DiagnosticBuffer *mDiagClient; |
| |
| // The target being compiled for |
| std::shared_ptr<clang::TargetOptions> mTargetOpts; |
| std::unique_ptr<clang::TargetInfo> mTarget; |
| void createTarget(uint32_t BitWidth); |
| |
| // File manager (for prepocessor doing the job such as header file search) |
| std::unique_ptr<clang::FileManager> mFileMgr; |
| std::unique_ptr<clang::FileSystemOptions> mFileSysOpt; |
| void createFileManager(); |
| |
| // Source manager (responsible for the source code handling) |
| std::unique_ptr<clang::SourceManager> mSourceMgr; |
| void createSourceManager(); |
| |
| // Preprocessor (source code preprocessor) |
| std::unique_ptr<clang::Preprocessor> mPP; |
| void createPreprocessor(); |
| |
| // AST context (the context to hold long-lived AST nodes) |
| std::unique_ptr<clang::ASTContext> mASTContext; |
| void createASTContext(); |
| |
| // AST consumer, responsible for code generation |
| std::unique_ptr<clang::ASTConsumer> mBackend; |
| |
| // File names |
| std::string mInputFileName; |
| std::string mOutputFileName; |
| std::string mOutput32FileName; |
| |
| std::string mDepOutputFileName; |
| std::string mDepTargetBCFileName; |
| std::vector<std::string> mAdditionalDepTargets; |
| |
| OutputType mOT; |
| |
| // Output stream |
| std::unique_ptr<llvm::tool_output_file> mOS; |
| |
| // Dependency output stream |
| std::unique_ptr<llvm::tool_output_file> mDOS; |
| |
| std::vector<std::string> mIncludePaths; |
| |
| // Context for Renderscript |
| RSContext *mRSContext; |
| |
| bool mAllowRSPrefix; |
| |
| unsigned int mTargetAPI; |
| |
| bool mVerbose; |
| |
| bool mIsFilterscript; |
| |
| // Collect generated filenames (without the .java) for dependency generation |
| std::vector<std::string> mGeneratedFileNames; |
| |
| PragmaList mPragmas; |
| |
| // FIXME: Should be std::list<RSExportable *> here. But currently we only |
| // check ODR on record type. |
| // |
| // ReflectedDefinitions maps record type name to a pair: |
| // <its RSExportRecordType instance, |
| // the first file contains this record type definition> |
| typedef std::pair<RSExportRecordType*, const char*> ReflectedDefinitionTy; |
| typedef llvm::StringMap<ReflectedDefinitionTy> ReflectedDefinitionListTy; |
| ReflectedDefinitionListTy ReflectedDefinitions; |
| |
| bool generateJavaBitcodeAccessor(const std::string &OutputPathBase, |
| const std::string &PackageName, |
| const std::string *LicenseNote); |
| |
| // CurInputFile is the pointer to a char array holding the input filename |
| // and is valid before compile() ends. |
| bool checkODR(const char *CurInputFile); |
| |
| clang::DiagnosticsEngine &getDiagnostics() { return *mDiagEngine; } |
| clang::TargetInfo const &getTargetInfo() const { return *mTarget; } |
| clang::FileManager &getFileManager() { return *mFileMgr; } |
| clang::SourceManager &getSourceManager() { return *mSourceMgr; } |
| clang::Preprocessor &getPreprocessor() { return *mPP; } |
| clang::ASTContext &getASTContext() { return *mASTContext; } |
| |
| inline clang::TargetOptions const &getTargetOptions() const |
| { return *mTargetOpts.get(); } |
| |
| void initPreprocessor(); |
| void initASTContext(); |
| |
| clang::ASTConsumer *createBackend(const RSCCOptions &Opts, |
| const clang::CodeGenOptions &CodeGenOpts, |
| llvm::raw_ostream *OS, |
| OutputType OT); |
| |
| public: |
| static const llvm::StringRef PragmaMetadataName; |
| |
| static void GlobalInitialization(); |
| |
| static bool IsRSHeaderFile(const char *File); |
| // FIXME: Determine whether a location is in RS header (i.e., one of the RS |
| // built-in APIs) should only need its names (we need a "list" of RS |
| // built-in APIs). |
| static bool IsLocInRSHeaderFile(const clang::SourceLocation &Loc, |
| const clang::SourceManager &SourceMgr); |
| |
| Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine, |
| DiagnosticBuffer *DiagClient); |
| |
| virtual ~Slang(); |
| |
| bool setInputSource(llvm::StringRef InputFile); |
| |
| std::string const &getInputFileName() const { return mInputFileName; } |
| |
| void setIncludePaths(const std::vector<std::string> &IncludePaths) { |
| mIncludePaths = IncludePaths; |
| } |
| |
| void setOutputType(OutputType OT) { mOT = OT; } |
| |
| bool setOutput(const char *OutputFile); |
| |
| bool setDepOutput(const char *OutputFile); |
| |
| void setDepTargetBC(const char *TargetBCFile) { |
| mDepTargetBCFileName = TargetBCFile; |
| } |
| |
| void setAdditionalDepTargets( |
| std::vector<std::string> const &AdditionalDepTargets) { |
| mAdditionalDepTargets = AdditionalDepTargets; |
| } |
| |
| void appendGeneratedFileName(std::string const &GeneratedFileName) { |
| mGeneratedFileNames.push_back(GeneratedFileName); |
| } |
| |
| int generateDepFile(bool PhonyTarget); |
| |
| int compile(const RSCCOptions &Opts); |
| |
| char const *getErrorMessage() { return mDiagClient->str().c_str(); } |
| |
| void setDebugMetadataEmission(bool EmitDebug); |
| |
| void setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel); |
| |
| // Compile bunch of RS files given in the llvm-rs-cc arguments. Return true if |
| // all given input files are successfully compiled without errors. |
| // |
| // @IOFiles - List of pairs of <input file path, output file path>. |
| // |
| // @DepFiles - List of pairs of <output dep. file path, dependent bitcode |
| // target>. If @OutputDep is true, this parameter must be given |
| // with the same number of pairs given in @IOFiles. |
| // |
| // @Opts - Selection of options defined from invoking llvm-rs-cc |
| bool |
| compile(const std::list<std::pair<const char *, const char *>> &IOFiles64, |
| const std::list<std::pair<const char *, const char *>> &IOFiles32, |
| const std::list<std::pair<const char *, const char *>> &DepFiles, |
| const RSCCOptions &Opts, |
| clang::DiagnosticOptions &DiagOpts); |
| |
| clang::ModuleLoadResult loadModule(clang::SourceLocation ImportLoc, |
| clang::ModuleIdPath Path, |
| clang::Module::NameVisibilityKind VK, |
| bool IsInclusionDirective) override; |
| |
| void makeModuleVisible(clang::Module *Mod, |
| clang::Module::NameVisibilityKind Visibility, |
| clang::SourceLocation ImportLoc, |
| bool Complain = false) override {} |
| |
| clang::GlobalModuleIndex * |
| loadGlobalModuleIndex(clang::SourceLocation TriggerLoc) override { |
| // We don't support C++ modules for RenderScript. |
| return nullptr; |
| } |
| |
| bool lookupMissingImports(llvm::StringRef Name, |
| clang::SourceLocation TriggerLoc) override { |
| // We don't support C++ modules for RenderScript. |
| return false; |
| } |
| }; |
| |
| } // namespace slang |
| |
| #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_H_ NOLINT |