slang.h revision e8c263a1c5df81594cf302ecadd813909c894487
1#ifndef _SLANG_COMPILER_SLANG_H
2#define _SLANG_COMPILER_SLANG_H
3
4#include <cstdio>
5#include <string>
6#include <vector>
7
8#include "llvm/ADT/OwningPtr.h"
9#include "llvm/ADT/StringRef.h"
10#include "llvm/ADT/IntrusiveRefCntPtr.h"
11
12#include "clang/Basic/TargetOptions.h"
13
14#include "slang_pragma_recorder.h"
15#include "slang_diagnostic_buffer.h"
16
17namespace llvm {
18  class tool_output_file;
19}
20
21namespace clang {
22  class Diagnostic;
23  class FileManager;
24  class SourceManager;
25  class LangOptions;
26  class Preprocessor;
27  class TargetOptions;
28  class CodeGenOptions;
29  class ASTContext;
30  class ASTConsumer;
31  class Backend;
32  class TargetInfo;
33}
34
35namespace slang {
36
37class Slang {
38  static clang::LangOptions LangOpts;
39  static clang::CodeGenOptions CodeGenOpts;
40
41  static bool GlobalInitialized;
42
43  static void LLVMErrorHandler(void *UserData, const std::string &Message);
44
45 public:
46  typedef enum {
47    OT_Dependency,
48    OT_Assembly,
49    OT_LLVMAssembly,
50    OT_Bitcode,
51    OT_Nothing,
52    OT_Object,
53
54    OT_Default = OT_Bitcode
55  } OutputType;
56
57 private:
58  // The diagnostics engine instance (for status reporting during compilation)
59  llvm::IntrusiveRefCntPtr<clang::Diagnostic> mDiagnostics;
60  // The clients of diagnostics engine. The ownership is taken by the
61  // mDiagnostics after creation.
62  DiagnosticBuffer *mDiagClient;
63  void createDiagnostic();
64
65  // The target being compiled for
66  clang::TargetOptions mTargetOpts;
67  llvm::OwningPtr<clang::TargetInfo> mTarget;
68  void createTarget(const std::string &Triple, const std::string &CPU,
69                    const std::vector<std::string> &Features);
70
71  // Below is for parsing and code generation
72
73  // The file manager (for prepocessor doing the job such as header file search)
74  llvm::OwningPtr<clang::FileManager> mFileMgr;
75  void createFileManager();
76
77  // The source manager (responsible for the source code handling)
78  llvm::OwningPtr<clang::SourceManager> mSourceMgr;
79  void createSourceManager();
80
81  // The preprocessor (source code preprocessor)
82  llvm::OwningPtr<clang::Preprocessor> mPP;
83  void createPreprocessor();
84
85  // The AST context (the context to hold long-lived AST nodes)
86  llvm::OwningPtr<clang::ASTContext> mASTContext;
87  void createASTContext();
88
89  // The AST consumer, responsible for code generation
90  llvm::OwningPtr<clang::ASTConsumer> mBackend;
91
92  // Input file name
93  std::string mInputFileName;
94  std::string mOutputFileName;
95
96  std::string mDepOutputFileName;
97  std::string mDepTargetBCFileName;
98  std::vector<std::string> mAdditionalDepTargets;
99
100  OutputType mOT;
101
102  // Output stream
103  llvm::OwningPtr<llvm::tool_output_file> mOS;
104  // Dependency output stream
105  llvm::OwningPtr<llvm::tool_output_file> mDOS;
106
107  std::vector<std::string> mIncludePaths;
108
109 protected:
110  PragmaList mPragmas;
111
112  inline clang::Diagnostic &getDiagnostics() { return *mDiagnostics; }
113  inline const clang::TargetInfo &getTargetInfo() const { return *mTarget; }
114  inline clang::FileManager &getFileManager() { return *mFileMgr; }
115  inline clang::SourceManager &getSourceManager() { return *mSourceMgr; }
116  inline clang::Preprocessor &getPreprocessor() { return *mPP; }
117  inline clang::ASTContext &getASTContext() { return *mASTContext; }
118
119  inline const clang::TargetOptions &getTargetOptions() const
120    { return mTargetOpts; }
121
122  virtual void initDiagnostic() {}
123  virtual void initPreprocessor() {}
124  virtual void initASTContext() {}
125
126  virtual clang::ASTConsumer
127  *createBackend(const clang::CodeGenOptions& CodeGenOpts,
128                 llvm::raw_ostream *OS,
129                 OutputType OT);
130
131 public:
132  static const std::string TargetDescription;
133
134  static const llvm::StringRef PragmaMetadataName;
135
136  static void GlobalInitialization();
137
138  Slang(const std::string &Triple, const std::string &CPU,
139        const std::vector<std::string> &Features);
140
141  bool setInputSource(llvm::StringRef InputFile, const char *Text,
142                      size_t TextLength);
143
144  bool setInputSource(llvm::StringRef InputFile);
145
146  inline const std::string &getInputFileName() const { return mInputFileName; }
147
148  inline void setIncludePaths(const std::vector<std::string> &IncludePaths) {
149    mIncludePaths = IncludePaths;
150  }
151
152  inline void setOutputType(OutputType OT) { mOT = OT; }
153
154  bool setOutput(const char *OutputFile);
155  inline const std::string &getOutputFileName() const {
156    return mOutputFileName;
157  }
158
159  bool setDepOutput(const char *OutputFile);
160  inline void setDepTargetBC(const char *TargetBCFile) {
161    mDepTargetBCFileName = TargetBCFile;
162  }
163  inline void setAdditionalDepTargets(
164      const std::vector<std::string> &AdditionalDepTargets) {
165    mAdditionalDepTargets = AdditionalDepTargets;
166  }
167
168  int generateDepFile();
169  int compile();
170
171  inline const char *getErrorMessage() { return mDiagClient->str().c_str(); }
172
173  // Reset the slang compiler state such that it can be reused to compile
174  // another file
175  virtual void reset();
176
177  virtual ~Slang();
178};
179}
180
181#endif  // _SLANG_COMPILER_SLANG_H
182