blob: 8796adebbc4669c2a918ee1dcdcc007c2ab782e9 [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#include "slang_rs_pragma_handler.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07003#include "clang/Basic/TokenKinds.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07004
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07005#include "clang/Lex/LiteralSupport.h"
6#include "clang/Lex/Preprocessor.h"
7#include "clang/Lex/Token.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07008
zonr6315f762010-10-05 15:35:14 +08009#include "slang_rs_context.h"
10
Shih-wei Liao462aefd2010-06-04 15:32:04 -070011using namespace slang;
12
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070013namespace { // Anonymous namespace
14
Shih-wei Liao462aefd2010-06-04 15:32:04 -070015class RSExportVarPragmaHandler : public RSPragmaHandler {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070016 private:
17 void handleItem(const std::string &Item) {
18 mContext->addExportVar(Item);
19 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070021 public:
zonr6315f762010-10-05 15:35:14 +080022 RSExportVarPragmaHandler(llvm::StringRef Name, RSContext *Context)
23 : RSPragmaHandler(Name, Context) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070024 return;
25 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070026
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070027 void HandlePragma(clang::Preprocessor &PP, clang::Token &FirstToken) {
28 this->handleItemListPragma(PP, FirstToken);
29 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070030};
31
Victor Hsiehc6718b32010-06-23 09:29:44 +080032class RSExportVarAllPragmaHandler : public RSPragmaHandler {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070033 public:
zonr6315f762010-10-05 15:35:14 +080034 RSExportVarAllPragmaHandler(llvm::StringRef Name, RSContext *Context)
35 : RSPragmaHandler(Name, Context) { return; }
Victor Hsiehc6718b32010-06-23 09:29:44 +080036
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070037 void HandlePragma(clang::Preprocessor &PP, clang::Token &FirstToken) {
38 this->handleNonParamPragma(PP, FirstToken);
39 mContext->setExportAllNonStaticVars(true);
40 }
Victor Hsiehc6718b32010-06-23 09:29:44 +080041};
42
Shih-wei Liao462aefd2010-06-04 15:32:04 -070043class RSExportFuncPragmaHandler : public RSPragmaHandler {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070044 private:
45 void handleItem(const std::string &Item) {
46 mContext->addExportFunc(Item);
47 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070048
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070049 public:
50 RSExportFuncPragmaHandler(llvm::StringRef Name,
zonr6315f762010-10-05 15:35:14 +080051 RSContext *Context)
52 : RSPragmaHandler(Name, Context) { return; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070053
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070054 void HandlePragma(clang::Preprocessor &PP, clang::Token &FirstToken) {
55 this->handleItemListPragma(PP, FirstToken);
56 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070057};
58
Victor Hsiehc6718b32010-06-23 09:29:44 +080059class RSExportFuncAllPragmaHandler : public RSPragmaHandler {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070060 public:
zonr6315f762010-10-05 15:35:14 +080061 RSExportFuncAllPragmaHandler(llvm::StringRef Name, RSContext *Context)
62 : RSPragmaHandler(Name, Context) { return; }
Victor Hsiehc6718b32010-06-23 09:29:44 +080063
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070064 void HandlePragma(clang::Preprocessor &PP, clang::Token &FirstToken) {
65 this->handleNonParamPragma(PP, FirstToken);
66 mContext->setExportAllNonStaticFuncs(true);
67 }
Victor Hsiehc6718b32010-06-23 09:29:44 +080068};
69
Shih-wei Liao462aefd2010-06-04 15:32:04 -070070class RSExportTypePragmaHandler : public RSPragmaHandler {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070071 private:
zonr6315f762010-10-05 15:35:14 +080072 void handleItem(const std::string &Item) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070073 mContext->addExportType(Item);
74 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070075
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070076 public:
zonr6315f762010-10-05 15:35:14 +080077 RSExportTypePragmaHandler(llvm::StringRef Name, RSContext *Context)
78 : RSPragmaHandler(Name, Context) { return; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070079
zonr6315f762010-10-05 15:35:14 +080080 void HandlePragma(clang::Preprocessor &PP, clang::Token &FirstToken) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070081 this->handleItemListPragma(PP, FirstToken);
82 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070083};
84
Shih-wei Liao537446c2010-06-11 16:05:55 -070085class RSJavaPackageNamePragmaHandler : public RSPragmaHandler {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070086 public:
zonr6315f762010-10-05 15:35:14 +080087 RSJavaPackageNamePragmaHandler(llvm::StringRef Name, RSContext *Context)
88 : RSPragmaHandler(Name, Context) { return; }
Shih-wei Liao537446c2010-06-11 16:05:55 -070089
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070090 void HandlePragma(clang::Preprocessor &PP, clang::Token &FirstToken) {
91 // FIXME: Need to validate the extracted package name from paragma.
92 // Currently "all chars" specified in pragma will be treated as package
93 // name.
94 //
95 // 18.1 The Grammar of the Java Programming Language
96 // (http://java.sun.com/docs/books/jls/third_edition/html/syntax.html#18.1)
97 //
98 // CompilationUnit:
99 // [[Annotations] package QualifiedIdentifier ; ] {ImportDeclaration}
100 // {TypeDeclaration}
101 //
102 // QualifiedIdentifier:
103 // Identifier { . Identifier }
104 //
105 // Identifier:
106 // IDENTIFIER
107 //
108 // 3.8 Identifiers
109 // (http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8)
110 //
111 //
Shih-wei Liao537446c2010-06-11 16:05:55 -0700112
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700113 clang::Token &PragmaToken = FirstToken;
114 std::string PackageName;
Shih-wei Liao537446c2010-06-11 16:05:55 -0700115
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700116 // Skip first token, "java_package_name"
117 PP.LexUnexpandedToken(PragmaToken);
Shih-wei Liao537446c2010-06-11 16:05:55 -0700118
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700119 // Now, the current token must be clang::tok::lpara
120 if (PragmaToken.isNot(clang::tok::l_paren))
121 return;
Shih-wei Liao537446c2010-06-11 16:05:55 -0700122
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700123 while (PragmaToken.isNot(clang::tok::eom)) {
124 // Lex package name
125 PP.LexUnexpandedToken(PragmaToken);
126
127 bool Invalid;
128 std::string Spelling = PP.getSpelling(PragmaToken, &Invalid);
129 if (!Invalid)
130 PackageName.append(Spelling);
131
132 // Pre-mature end (syntax error will be triggered by preprocessor later)
zonr6315f762010-10-05 15:35:14 +0800133 if (PragmaToken.is(clang::tok::eom) || PragmaToken.is(clang::tok::eof)) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700134 break;
zonr6315f762010-10-05 15:35:14 +0800135 } else {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700136 // Next token is ')' (end of paragma)
137 const clang::Token &NextTok = PP.LookAhead(0);
138 if (NextTok.is(clang::tok::r_paren)) {
139 mContext->setReflectJavaPackageName(PackageName);
140 // Lex until meets clang::tok::eom
141 do {
Shih-wei Liao537446c2010-06-11 16:05:55 -0700142 PP.LexUnexpandedToken(PragmaToken);
zonr6315f762010-10-05 15:35:14 +0800143 } while (PragmaToken.isNot(clang::tok::eom));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700144 break;
Shih-wei Liao537446c2010-06-11 16:05:55 -0700145 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700146 }
Shih-wei Liao537446c2010-06-11 16:05:55 -0700147 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700148 return;
149 }
Shih-wei Liao537446c2010-06-11 16:05:55 -0700150};
151
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800152class RSReflectLicensePragmaHandler : public RSPragmaHandler {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700153 private:
154 void handleItem(const std::string &Item) {
155 mContext->setLicenseNote(Item);
156 }
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800157
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700158 public:
159 RSReflectLicensePragmaHandler(llvm::StringRef Name, RSContext *Context)
160 : RSPragmaHandler(Name, Context) { return; }
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800161
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700162 void HandlePragma(clang::Preprocessor &PP, clang::Token &FirstToken) {
163 this->handleOptionalStringLiateralParamPragma(PP, FirstToken);
164 }
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800165};
166
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700167} // Anonymous namespace
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700168
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700169RSPragmaHandler *
170RSPragmaHandler::CreatePragmaExportVarHandler(RSContext *Context) {
171 return new RSExportVarPragmaHandler("export_var", Context);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700172}
173
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700174RSPragmaHandler *
175RSPragmaHandler::CreatePragmaExportVarAllHandler(RSContext *Context) {
176 return new RSExportVarPragmaHandler("export_var_all", Context);
Victor Hsiehc6718b32010-06-23 09:29:44 +0800177}
178
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700179RSPragmaHandler *
180RSPragmaHandler::CreatePragmaExportFuncHandler(RSContext *Context) {
181 return new RSExportFuncPragmaHandler("export_func", Context);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700182}
183
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700184RSPragmaHandler *
185RSPragmaHandler::CreatePragmaExportFuncAllHandler(RSContext *Context) {
186 return new RSExportFuncPragmaHandler("export_func_all", Context);
Victor Hsiehc6718b32010-06-23 09:29:44 +0800187}
188
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700189RSPragmaHandler *
190RSPragmaHandler::CreatePragmaExportTypeHandler(RSContext *Context) {
191 return new RSExportTypePragmaHandler("export_type", Context);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700192}
193
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700194RSPragmaHandler *
195RSPragmaHandler::CreatePragmaJavaPackageNameHandler(RSContext *Context) {
196 return new RSJavaPackageNamePragmaHandler("java_package_name", Context);
Shih-wei Liao537446c2010-06-11 16:05:55 -0700197}
198
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700199RSPragmaHandler *
200RSPragmaHandler::CreatePragmaReflectLicenseHandler(RSContext *Context) {
201 return new RSJavaPackageNamePragmaHandler("set_reflect_license", Context);
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800202}
203
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700204void RSPragmaHandler::handleItemListPragma(clang::Preprocessor &PP,
205 clang::Token &FirstToken) {
206 clang::Token &PragmaToken = FirstToken;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700207
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700208 // Skip first token, like "export_var"
209 PP.LexUnexpandedToken(PragmaToken);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700210
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700211 // Now, the current token must be clang::tok::lpara
212 if (PragmaToken.isNot(clang::tok::l_paren))
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700213 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700214
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700215 while (PragmaToken.isNot(clang::tok::eom)) {
216 // Lex variable name
217 PP.LexUnexpandedToken(PragmaToken);
218 if (PragmaToken.is(clang::tok::identifier))
zonr6315f762010-10-05 15:35:14 +0800219 this->handleItem(PP.getSpelling(PragmaToken));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700220 else
221 break;
Victor Hsiehc6718b32010-06-23 09:29:44 +0800222
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700223 assert(PragmaToken.isNot(clang::tok::eom));
224
Victor Hsiehc6718b32010-06-23 09:29:44 +0800225 PP.LexUnexpandedToken(PragmaToken);
226
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700227 if (PragmaToken.isNot(clang::tok::comma))
228 break;
229 }
230 return;
231}
232
zonr6315f762010-10-05 15:35:14 +0800233void RSPragmaHandler::handleNonParamPragma(clang::Preprocessor &PP,
234 clang::Token &FirstToken) {
235 clang::Token &PragmaToken = FirstToken;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700236
237 // Skip first token, like "export_var_all"
238 PP.LexUnexpandedToken(PragmaToken);
239
240 // Should be end immediately
241 if (PragmaToken.isNot(clang::tok::eom))
242 fprintf(stderr, "RSPragmaHandler::handleNonParamPragma: "
243 "expected a clang::tok::eom\n");
244 return;
245}
246
247void RSPragmaHandler::handleOptionalStringLiateralParamPragma(
248 clang::Preprocessor &PP, clang::Token &FirstToken) {
249 clang::Token &PragmaToken = FirstToken;
250
251 // Skip first token, like "set_reflect_license"
252 PP.LexUnexpandedToken(PragmaToken);
253
254 // Now, the current token must be clang::tok::lpara
255 if (PragmaToken.isNot(clang::tok::l_paren))
Victor Hsiehc6718b32010-06-23 09:29:44 +0800256 return;
Victor Hsiehc6718b32010-06-23 09:29:44 +0800257
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700258 // If not ')', eat the following string literal as the license
259 PP.LexUnexpandedToken(PragmaToken);
260 if (PragmaToken.isNot(clang::tok::r_paren)) {
261 // Eat the whole string literal
262 clang::StringLiteralParser StringLiteral(&PragmaToken, 1, PP);
263 if (StringLiteral.hadError)
264 fprintf(stderr, "RSPragmaHandler::handleOptionalStringLiateralParamPragma"
265 ": illegal string literal\n");
266 else
zonr6315f762010-10-05 15:35:14 +0800267 this->handleItem(std::string(StringLiteral.GetString()));
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800268
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700269 // The current token should be clang::tok::r_para
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800270 PP.LexUnexpandedToken(PragmaToken);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700271 if (PragmaToken.isNot(clang::tok::r_paren))
272 fprintf(stderr, "RSPragmaHandler::handleOptionalStringLiateralParamPragma"
273 ": expected a ')'\n");
274 } else {
275 // If no argument, remove the license
zonr6315f762010-10-05 15:35:14 +0800276 this->handleItem("");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700277 }
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800278}