slang.h revision 0b7ef1a176b9ddd1e0d437efdce20743373fd7db
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 raw_ostream;
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 GlobalInitialization();
44
45  static void LLVMErrorHandler(void *UserData, const std::string &Message);
46
47 public:
48  typedef enum {
49    OT_Dependency,
50    OT_Assembly,
51    OT_LLVMAssembly,
52    OT_Bitcode,
53    OT_Nothing,
54    OT_Object,
55
56    OT_Default = OT_Bitcode
57  } OutputType;
58
59 private:
60  // The diagnostics engine instance (for status reporting during compilation)
61  llvm::IntrusiveRefCntPtr<clang::Diagnostic> mDiagnostics;
62  // The clients of diagnostics engine. The ownership is taken by the
63  // mDiagnostics after creation.
64  DiagnosticBuffer *mDiagClient;
65  void createDiagnostic();
66
67  // The target being compiled for
68  clang::TargetOptions mTargetOpts;
69  llvm::OwningPtr<clang::TargetInfo> mTarget;
70  void createTarget(const char *Triple, const char *CPU, const char **Features);
71
72  // Below is for parsing and code generation
73
74  // The file manager (for prepocessor doing the job such as header file search)
75  llvm::OwningPtr<clang::FileManager> mFileMgr;
76  void createFileManager();
77
78  // The source manager (responsible for the source code handling)
79  llvm::OwningPtr<clang::SourceManager> mSourceMgr;
80  void createSourceManager();
81
82  // The preprocessor (source code preprocessor)
83  llvm::OwningPtr<clang::Preprocessor> mPP;
84  void createPreprocessor();
85
86  // The AST context (the context to hold long-lived AST nodes)
87  llvm::OwningPtr<clang::ASTContext> mASTContext;
88  void createASTContext();
89
90  // The AST consumer, responsible for code generation
91  llvm::OwningPtr<clang::ASTConsumer> mBackend;
92
93  // Input file name
94  std::string mInputFileName;
95  std::string mOutputFileName;
96  std::string mDepOutputFileName;
97  std::string mDepTargetBCFileName;
98
99  OutputType mOT;
100
101  // Output stream
102  llvm::OwningPtr<llvm::raw_ostream> mOS;
103  // Dependency output stream
104  llvm::OwningPtr<llvm::raw_ostream> mDOS;
105
106  std::vector<std::string> mIncludePaths;
107
108 protected:
109  PragmaList mPragmas;
110
111  inline clang::Diagnostic &getDiagnostics() { return *mDiagnostics; }
112  inline const clang::TargetInfo &getTargetInfo() const { return *mTarget; }
113  inline clang::FileManager &getFileManager() { return *mFileMgr; }
114  inline clang::SourceManager &getSourceManager() { return *mSourceMgr; }
115  inline clang::Preprocessor &getPreprocessor() { return *mPP; }
116  inline clang::ASTContext &getASTContext() { return *mASTContext; }
117
118  inline const clang::TargetOptions &getTargetOptions() const
119    { return mTargetOpts; }
120
121  virtual void initDiagnostic() {}
122  virtual void initPreprocessor() {}
123  virtual void initASTContext() {}
124
125  virtual clang::ASTConsumer
126  *createBackend(const clang::CodeGenOptions& CodeGenOpts,
127                 llvm::raw_ostream *OS,
128                 OutputType OT);
129
130 public:
131  static const std::string TargetDescription;
132
133  static const llvm::StringRef PragmaMetadataName;
134
135  Slang(const char *Triple, const char *CPU, const char **Features);
136
137  bool setInputSource(llvm::StringRef InputFile, const char *Text,
138                      size_t TextLength);
139
140  bool setInputSource(llvm::StringRef InputFile);
141
142  inline const std::string &getInputFileName() const { return mInputFileName; }
143
144  inline void addIncludePath(const char *Path) {
145    mIncludePaths.push_back(Path);
146  }
147
148  inline void setOutputType(OutputType OT) { mOT = OT; }
149
150  bool setOutput(const char *OutputFile);
151  inline const std::string &getOutputFileName() const {
152    return mOutputFileName;
153  }
154
155  bool setDepOutput(const char *OutputFile);
156  bool setDepTargetBC(const char *TargetBCFile);
157
158  int generateDepFile();
159  int compile();
160
161  inline const char *getErrorMessage() { return mDiagClient->str().c_str(); }
162
163  // Reset the slang compiler state such that it can be reused to compile
164  // another file
165  virtual void reset();
166
167  virtual ~Slang();
168};
169}
170
171#endif  // _SLANG_COMPILER_SLANG_H
172