blob: 4f4ff44626d3526ca72e43072ea376106b38cae9 [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()));
Kirk Stewart6322c932010-06-10 16:34:34 -070066 bool optionNotFound = mDiagnostics->setDiagnosticGroupMapping("implicit-function-declaration", clang::diag::MAP_ERROR);
67 assert(!optionNotFound && "Unable find option group implicit-function-declaration");
Shih-wei Liao462aefd2010-06-04 15:32:04 -070068 return;
69 }
70
71 /* The target being compiled for */
72 TargetOptions mTargetOpts;
73 llvm::OwningPtr<TargetInfo> mTarget;
74 void createTarget(const char* Triple, const char* CPU, const char** Features);
75
76 /**** Below is for parsing ****/
77
78 /* The file manager (for prepocessor doing the job such as header file search) */
79 llvm::OwningPtr<FileManager> mFileMgr;
80 inline void createFileManager() { mFileMgr.reset(new FileManager()); return; }
81
82 /* The source manager (responsible for the source code handling) */
83 llvm::OwningPtr<SourceManager> mSourceMgr; /* The source manager */
84 inline void createSourceManager() { mSourceMgr.reset(new SourceManager(*mDiagnostics)); return; }
85
86 /* The preprocessor (source code preprocessor) */
87 llvm::OwningPtr<Preprocessor> mPP;
88 inline void createPreprocessor() {
89 HeaderSearch* HeaderInfo = new HeaderSearch(*mFileMgr); /* Default only search header file in current dir */
90 mPP.reset(new Preprocessor( *mDiagnostics,
91 LangOpts,
92 *mTarget,
93 *mSourceMgr,
94 *HeaderInfo,
95 NULL,
96 true /* OwnsHeaderSearch */));
97 /* Initialize the prepocessor */
98 mPragmas.clear();
99 mPP->AddPragmaHandler(NULL, new PragmaRecorder(mPragmas));
100 /* ApplyHeaderSearchOptions */
101 return;
102 }
103
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700104 /* The AST context (the context to hold long-lived AST nodes) */
105 llvm::OwningPtr<ASTContext> mASTContext;
106 inline void createASTContext() {
107 mASTContext.reset(new ASTContext(LangOpts,
108 *mSourceMgr,
109 *mTarget,
110 mPP->getIdentifierTable(),
111 mPP->getSelectorTable(),
112 mPP->getBuiltinInfo()));
113 return;
114 }
115
Shih-wei Liao001fb6d2010-06-21 11:17:11 -0700116 /* Context for RenderScript */
117 llvm::OwningPtr<RSContext> mRSContext;
118 inline void createRSContext() {
119 mRSContext.reset(new RSContext(mPP.get(),
120 mASTContext.get(),
121 mTarget.get()));
122 return;
123 }
124
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700125 /* The AST consumer, responsible for code generation */
126 llvm::OwningPtr<Backend> mBackend;
127 inline void createBackend() {
128 mBackend.reset(new Backend(*mDiagnostics,
129 CodeGenOpts,
130 mTargetOpts,
131 mPragmas,
132 mOS.take(),
Kirk Stewart6b226742010-06-11 10:51:12 -0700133 mOutputType,
Kirk Stewart1fd85792010-07-07 09:51:23 -0700134 *mSourceMgr,
135 mAllowRSPrefix));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700136
137 return;
138 }
139
140 inline void createRSBackend() {
141 mBackend.reset(new RSBackend(mRSContext.get(),
142 *mDiagnostics,
143 CodeGenOpts,
144 mTargetOpts,
145 mPragmas,
146 mOS.take(),
Kirk Stewart6b226742010-06-11 10:51:12 -0700147 mOutputType,
Kirk Stewart1fd85792010-07-07 09:51:23 -0700148 *mSourceMgr,
149 mAllowRSPrefix));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700150
151 return;
152 }
153
154 /* Input file name */
155 std::string mInputFileName;
156 std::string mOutputFileName;
157
158 SlangCompilerOutputTy mOutputType;
159
160 /* Output stream */
161 llvm::OwningPtr<llvm::raw_ostream> mOS;
162
Kirk Stewart1fd85792010-07-07 09:51:23 -0700163 bool mAllowRSPrefix;
164
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700165public:
166 static const std::string TargetDescription;
167
168 static const llvm::Twine PragmaMetadataName;
169
170 Slang(const char* Triple, const char* CPU, const char** Features);
171
172 bool setInputSource(llvm::StringRef inputFile, const char* text, size_t textLength);
173
174 bool setInputSource(llvm::StringRef inputFile);
175
176 void setOutputType(SlangCompilerOutputTy outputType);
177
178 inline bool setOutput(FILE* stream) {
179 if(stream == NULL)
180 return false;
181
182 mOS.reset( new llvm::raw_fd_ostream(fileno(stream), /* shouldClose */false) );
183 return true;
184 }
185
186 bool setOutput(const char* outputFile);
187
Kirk Stewart1fd85792010-07-07 09:51:23 -0700188 inline void allowRSPrefix() {
189 mAllowRSPrefix = true;
190 }
191
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700192 int compile();
193
194 bool reflectToJava(const char* outputPackageName);
195
196 inline const char* getErrorMessage() {
197 return mDiagClient->str().c_str();
198 }
199
200 void getPragmas(size_t* actualStringCount, size_t maxStringCount, char** strings);
201
202 /* Reset the slang compiler state such that it can be reused to compile another file */
203 inline void reset() {
204 /* Seems there's no way to clear the diagnostics. We just re-create it. */
205 createDiagnostic();
206 mOutputType = SlangCompilerOutput_Default;
207 return;
208 }
209
210 ~Slang();
211}; /* class Slang */
212
213} /* namespace slang */
214
215#endif /* _SLANG_COMPILER_SLANG_HPP */