• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_H_  // NOLINT
18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_H_
19 
20 #include <cstdio>
21 #include <string>
22 #include <vector>
23 
24 #include "clang/Basic/TargetOptions.h"
25 #include "clang/Lex/ModuleLoader.h"
26 
27 #include "llvm/ADT/IntrusiveRefCntPtr.h"
28 #include "llvm/ADT/OwningPtr.h"
29 #include "llvm/ADT/StringRef.h"
30 
31 #include "llvm/Target/TargetMachine.h"
32 
33 #include "slang_diagnostic_buffer.h"
34 #include "slang_pragma_recorder.h"
35 
36 namespace llvm {
37   class tool_output_file;
38 }
39 
40 namespace clang {
41   class ASTConsumer;
42   class ASTContext;
43   class Backend;
44   class CodeGenOptions;
45   class Diagnostic;
46   class DiagnosticsEngine;
47   class FileManager;
48   class FileSystemOptions;
49   class LangOptions;
50   class Preprocessor;
51   class SourceManager;
52   class TargetInfo;
53   class TargetOptions;
54 }  // namespace clang
55 
56 namespace slang {
57 
58 class Slang : public clang::ModuleLoader {
59   static clang::LangOptions LangOpts;
60   static clang::CodeGenOptions CodeGenOpts;
61 
62   static bool GlobalInitialized;
63 
64   static void LLVMErrorHandler(void *UserData, const std::string &Message);
65 
66  public:
67   enum OutputType {
68     OT_Dependency,
69     OT_Assembly,
70     OT_LLVMAssembly,
71     OT_Bitcode,
72     OT_Nothing,
73     OT_Object,
74 
75     OT_Default = OT_Bitcode
76   };
77 
78  private:
79   bool mInitialized;
80 
81   // Diagnostics Mediator (An interface for both Producer and Consumer)
82   llvm::OwningPtr<clang::Diagnostic> mDiag;
83 
84   // Diagnostics Engine (Producer and Diagnostics Reporter)
85   clang::DiagnosticsEngine *mDiagEngine;
86 
87   // Diagnostics Consumer
88   // NOTE: The ownership is taken by mDiagEngine after creation.
89   DiagnosticBuffer *mDiagClient;
90 
91   // The target being compiled for
92   clang::TargetOptions mTargetOpts;
93   llvm::OwningPtr<clang::TargetInfo> mTarget;
94   void createTarget(std::string const &Triple, std::string const &CPU,
95                     std::vector<std::string> const &Features);
96 
97 
98   // File manager (for prepocessor doing the job such as header file search)
99   llvm::OwningPtr<clang::FileManager> mFileMgr;
100   llvm::OwningPtr<clang::FileSystemOptions> mFileSysOpt;
101   void createFileManager();
102 
103 
104   // Source manager (responsible for the source code handling)
105   llvm::OwningPtr<clang::SourceManager> mSourceMgr;
106   void createSourceManager();
107 
108 
109   // Preprocessor (source code preprocessor)
110   llvm::OwningPtr<clang::Preprocessor> mPP;
111   void createPreprocessor();
112 
113 
114   // AST context (the context to hold long-lived AST nodes)
115   llvm::OwningPtr<clang::ASTContext> mASTContext;
116   void createASTContext();
117 
118 
119   // AST consumer, responsible for code generation
120   llvm::OwningPtr<clang::ASTConsumer> mBackend;
121 
122 
123   // File names
124   std::string mInputFileName;
125   std::string mOutputFileName;
126 
127   std::string mDepOutputFileName;
128   std::string mDepTargetBCFileName;
129   std::vector<std::string> mAdditionalDepTargets;
130   std::vector<std::string> mGeneratedFileNames;
131 
132   OutputType mOT;
133 
134   // Output stream
135   llvm::OwningPtr<llvm::tool_output_file> mOS;
136 
137   // Dependency output stream
138   llvm::OwningPtr<llvm::tool_output_file> mDOS;
139 
140   std::vector<std::string> mIncludePaths;
141 
142  protected:
143   PragmaList mPragmas;
144 
getDiagnostics()145   clang::DiagnosticsEngine &getDiagnostics() { return *mDiagEngine; }
getTargetInfo()146   clang::TargetInfo const &getTargetInfo() const { return *mTarget; }
getFileManager()147   clang::FileManager &getFileManager() { return *mFileMgr; }
getSourceManager()148   clang::SourceManager &getSourceManager() { return *mSourceMgr; }
getPreprocessor()149   clang::Preprocessor &getPreprocessor() { return *mPP; }
getASTContext()150   clang::ASTContext &getASTContext() { return *mASTContext; }
151 
getTargetOptions()152   inline clang::TargetOptions const &getTargetOptions() const
153     { return mTargetOpts; }
154 
initDiagnostic()155   virtual void initDiagnostic() {}
initPreprocessor()156   virtual void initPreprocessor() {}
initASTContext()157   virtual void initASTContext() {}
158 
159   virtual clang::ASTConsumer *
160     createBackend(const clang::CodeGenOptions& CodeGenOpts,
161                   llvm::raw_ostream *OS,
162                   OutputType OT);
163 
164  public:
165   static const llvm::StringRef PragmaMetadataName;
166 
167   static void GlobalInitialization();
168 
169   Slang();
170 
171   void init(const std::string &Triple, const std::string &CPU,
172             const std::vector<std::string> &Features,
173             clang::DiagnosticsEngine *DiagEngine,
174             DiagnosticBuffer *DiagClient);
175 
176   virtual clang::Module *loadModule(clang::SourceLocation ImportLoc,
177                                     clang::ModuleIdPath Path,
178                                     clang::Module::NameVisibilityKind VK,
179                                     bool IsInclusionDirective);
180 
181   bool setInputSource(llvm::StringRef InputFile, const char *Text,
182                       size_t TextLength);
183 
184   bool setInputSource(llvm::StringRef InputFile);
185 
getInputFileName()186   std::string const &getInputFileName() const { return mInputFileName; }
187 
setIncludePaths(const std::vector<std::string> & IncludePaths)188   void setIncludePaths(const std::vector<std::string> &IncludePaths) {
189     mIncludePaths = IncludePaths;
190   }
191 
setOutputType(OutputType OT)192   void setOutputType(OutputType OT) { mOT = OT; }
193 
194   bool setOutput(const char *OutputFile);
195 
getOutputFileName()196   std::string const &getOutputFileName() const {
197     return mOutputFileName;
198   }
199 
200   bool setDepOutput(const char *OutputFile);
201 
setDepTargetBC(const char * TargetBCFile)202   void setDepTargetBC(const char *TargetBCFile) {
203     mDepTargetBCFileName = TargetBCFile;
204   }
205 
setAdditionalDepTargets(std::vector<std::string> const & AdditionalDepTargets)206   void setAdditionalDepTargets(
207       std::vector<std::string> const &AdditionalDepTargets) {
208     mAdditionalDepTargets = AdditionalDepTargets;
209   }
210 
appendGeneratedFileName(std::string const & GeneratedFileName)211   void appendGeneratedFileName(std::string const &GeneratedFileName) {
212     mGeneratedFileNames.push_back(GeneratedFileName);
213   }
214 
215   int generateDepFile();
216 
217   int compile();
218 
getErrorMessage()219   char const *getErrorMessage() { return mDiagClient->str().c_str(); }
220 
221   void setDebugMetadataEmission(bool EmitDebug);
222 
223   void setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel);
224 
225   // Reset the slang compiler state such that it can be reused to compile
226   // another file
227   virtual void reset();
228 
229   virtual ~Slang();
230 };
231 
232 }  // namespace slang
233 
234 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_H_  NOLINT
235