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