blob: 8be32a6fbd8f4d0769c9d45a4a1cd72ed89f297a [file] [log] [blame]
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001#ifndef _SLANG_COMPILER_SLANG_HPP
2# define _SLANG_COMPILER_SLANG_HPP
3
4#include "slang_backend.hpp"
5#include "slang_rs_context.hpp"
6#include "slang_rs_backend.hpp"
7#include "slang_pragma_recorder.hpp"
8#include "slang_diagnostic_buffer.hpp"
9
10#include <cstdio>
11#include <string>
12
13#include "llvm/Support/raw_ostream.h" /* for class llvm::raw_ostream */
14
15#include "llvm/ADT/OwningPtr.h" /* for class llvm::OwningPtr */
16#include "llvm/ADT/StringRef.h" /* for class llvm::StringRef */
17
18#include "clang/AST/ASTConsumer.h" /* for class clang::ASTConsumer */
19#include "clang/AST/ASTContext.h" /* for class clang::ASTContext */
20
21#include "clang/Lex/Preprocessor.h" /* for class clang::Preprocessor */
22#include "clang/Lex/HeaderSearch.h" /* for class clang::HeaderSearch */
23
24#include "clang/Basic/Diagnostic.h" /* for class clang::Diagnostic, class clang::DiagnosticClient, class clang::DiagnosticInfo */
25#include "clang/Basic/FileManager.h" /* for class clang::FileManager and class clang::FileEntry */
26#include "clang/Basic/TargetOptions.h" /* for class clang::TargetOptions */
27
28namespace llvm {
29
30class Twine;
31class TargetInfo;
32
33} /* namespace llvm */
34
35namespace clang {
36
37class LangOptions;
38class CodeGenOptions;
39
40} /* namespace clang */
41
42namespace slang {
43
44using namespace clang;
45
46class Slang {
47 static LangOptions LangOpts;
48 static CodeGenOptions CodeGenOpts;
49
50 static bool GlobalInitialized;
51
52 static void GlobalInitialization();
53
54 static void LLVMErrorHandler(void *UserData, const std::string &Message);
55
56private:
57 PragmaList mPragmas;
58
59 /* The diagnostics engine instance (for status reporting during compilation) */
60 llvm::OwningPtr<Diagnostic> mDiagnostics;
61
62 llvm::OwningPtr<DiagnosticBuffer> mDiagClient;
63 inline void createDiagnostic() {
64 mDiagClient.reset(new DiagnosticBuffer());
65 mDiagnostics.reset(new Diagnostic(mDiagClient.get()));
66 return;
67 }
68
69 /* The target being compiled for */
70 TargetOptions mTargetOpts;
71 llvm::OwningPtr<TargetInfo> mTarget;
72 void createTarget(const char* Triple, const char* CPU, const char** Features);
73
74 /**** Below is for parsing ****/
75
76 /* The file manager (for prepocessor doing the job such as header file search) */
77 llvm::OwningPtr<FileManager> mFileMgr;
78 inline void createFileManager() { mFileMgr.reset(new FileManager()); return; }
79
80 /* The source manager (responsible for the source code handling) */
81 llvm::OwningPtr<SourceManager> mSourceMgr; /* The source manager */
82 inline void createSourceManager() { mSourceMgr.reset(new SourceManager(*mDiagnostics)); return; }
83
84 /* The preprocessor (source code preprocessor) */
85 llvm::OwningPtr<Preprocessor> mPP;
86 inline void createPreprocessor() {
87 HeaderSearch* HeaderInfo = new HeaderSearch(*mFileMgr); /* Default only search header file in current dir */
88 mPP.reset(new Preprocessor( *mDiagnostics,
89 LangOpts,
90 *mTarget,
91 *mSourceMgr,
92 *HeaderInfo,
93 NULL,
94 true /* OwnsHeaderSearch */));
95 /* Initialize the prepocessor */
96 mPragmas.clear();
97 mPP->AddPragmaHandler(NULL, new PragmaRecorder(mPragmas));
98 /* ApplyHeaderSearchOptions */
99 return;
100 }
101
102 /* Context of Slang compiler for RenderScript */
103 llvm::OwningPtr<RSContext> mRSContext;
104 inline void createRSContext() {
105 mRSContext.reset(new RSContext(mPP.get(),
106 mTarget.get()));
107 return;
108 }
109
110 /* The AST context (the context to hold long-lived AST nodes) */
111 llvm::OwningPtr<ASTContext> mASTContext;
112 inline void createASTContext() {
113 mASTContext.reset(new ASTContext(LangOpts,
114 *mSourceMgr,
115 *mTarget,
116 mPP->getIdentifierTable(),
117 mPP->getSelectorTable(),
118 mPP->getBuiltinInfo()));
119 return;
120 }
121
122 /* The AST consumer, responsible for code generation */
123 llvm::OwningPtr<Backend> mBackend;
124 inline void createBackend() {
125 mBackend.reset(new Backend(*mDiagnostics,
126 CodeGenOpts,
127 mTargetOpts,
128 mPragmas,
129 mOS.take(),
130 mOutputType));
131
132 return;
133 }
134
135 inline void createRSBackend() {
136 mBackend.reset(new RSBackend(mRSContext.get(),
137 *mDiagnostics,
138 CodeGenOpts,
139 mTargetOpts,
140 mPragmas,
141 mOS.take(),
142 mOutputType));
143
144 return;
145 }
146
147 /* Input file name */
148 std::string mInputFileName;
149 std::string mOutputFileName;
150
151 SlangCompilerOutputTy mOutputType;
152
153 /* Output stream */
154 llvm::OwningPtr<llvm::raw_ostream> mOS;
155
156public:
157 static const std::string TargetDescription;
158
159 static const llvm::Twine PragmaMetadataName;
160
161 Slang(const char* Triple, const char* CPU, const char** Features);
162
163 bool setInputSource(llvm::StringRef inputFile, const char* text, size_t textLength);
164
165 bool setInputSource(llvm::StringRef inputFile);
166
167 void setOutputType(SlangCompilerOutputTy outputType);
168
169 inline bool setOutput(FILE* stream) {
170 if(stream == NULL)
171 return false;
172
173 mOS.reset( new llvm::raw_fd_ostream(fileno(stream), /* shouldClose */false) );
174 return true;
175 }
176
177 bool setOutput(const char* outputFile);
178
179 int compile();
180
181 bool reflectToJava(const char* outputPackageName);
182
183 inline const char* getErrorMessage() {
184 return mDiagClient->str().c_str();
185 }
186
187 void getPragmas(size_t* actualStringCount, size_t maxStringCount, char** strings);
188
189 /* Reset the slang compiler state such that it can be reused to compile another file */
190 inline void reset() {
191 /* Seems there's no way to clear the diagnostics. We just re-create it. */
192 createDiagnostic();
193 mOutputType = SlangCompilerOutput_Default;
194 return;
195 }
196
197 ~Slang();
198}; /* class Slang */
199
200} /* namespace slang */
201
202#endif /* _SLANG_COMPILER_SLANG_HPP */