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