slang.h revision 3a9ca1f0d6bd8f12c2bb2adea51f95c255996180
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_Assembly,
50    OT_LLVMAssembly,
51    OT_Bitcode,
52    OT_Nothing,
53    OT_Object,
54
55    OT_Default = OT_Bitcode
56  } OutputType;
57
58 private:
59  // The diagnostics engine instance (for status reporting during compilation)
60  llvm::IntrusiveRefCntPtr<clang::Diagnostic> mDiagnostics;
61  // The clients of diagnostics engine. The ownership is taken by the
62  // mDiagnostics after creation.
63  DiagnosticBuffer *mDiagClient;
64  void createDiagnostic();
65
66  // The target being compiled for
67  clang::TargetOptions mTargetOpts;
68  llvm::OwningPtr<clang::TargetInfo> mTarget;
69  void createTarget(const char *Triple, const char *CPU, const char **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  OutputType mOT;
97
98  // Output stream
99  llvm::OwningPtr<llvm::raw_ostream> mOS;
100
101  std::vector<std::string> mIncludePaths;
102
103 protected:
104  PragmaList mPragmas;
105
106  inline clang::Diagnostic &getDiagnostics() { return *mDiagnostics; }
107  inline const clang::TargetInfo &getTargetInfo() const { return *mTarget; }
108  inline clang::FileManager &getFileManager() { return *mFileMgr; }
109  inline clang::SourceManager &getSourceManager() { return *mSourceMgr; }
110  inline clang::Preprocessor &getPreprocessor() { return *mPP; }
111  inline clang::ASTContext &getASTContext() { return *mASTContext; }
112
113  inline const clang::TargetOptions &getTargetOptions() const
114    { return mTargetOpts; }
115
116  virtual void initDiagnostic() {}
117  virtual void initPreprocessor() {}
118  virtual void initASTContext() {}
119
120  virtual clang::ASTConsumer
121  *createBackend(const clang::CodeGenOptions& CodeGenOpts,
122                 llvm::raw_ostream *OS,
123                 OutputType OT);
124
125 public:
126  static const std::string TargetDescription;
127
128  static const llvm::StringRef PragmaMetadataName;
129
130  Slang(const char *Triple, const char *CPU, const char **Features);
131
132  bool setInputSource(llvm::StringRef InputFile, const char *Text,
133                      size_t TextLength);
134
135  bool setInputSource(llvm::StringRef InputFile);
136
137  inline const std::string &getInputFileName() const { return mInputFileName; }
138
139  inline void addIncludePath(const char *Path) {
140    mIncludePaths.push_back(Path);
141  }
142
143  inline void setOutputType(OutputType OT) { mOT = OT; }
144
145  bool setOutput(const char *outputFile);
146  inline const std::string &getOutputFileName() const {
147    return mOutputFileName;
148  }
149
150  int compile();
151
152  inline const char *getErrorMessage() { return mDiagClient->str().c_str(); }
153
154  // Reset the slang compiler state such that it can be reused to compile
155  // another file
156  virtual void reset();
157
158  virtual ~Slang();
159};
160}
161
162#endif  // _SLANG_COMPILER_SLANG_H
163