blob: 7d007ccff54f0bf4269e883812b61a1974410efa [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#include "slang_pragma_recorder.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/Preprocessor.h"
zonr6315f762010-10-05 15:35:14 +08006#include "clang/Lex/Token.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07007
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07008using namespace slang;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07009
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070010bool PragmaRecorder::GetPragmaNameFromToken(const clang::Token &Token,
11 std::string &PragmaName) {
12 if (Token.isLiteral())
13 PragmaName.assign(Token.getLiteralData(), Token.getLength());
14 else if (Token.is(clang::tok::identifier))
15 PragmaName.assign(Token.getIdentifierInfo()->getNameStart(),
16 Token.getIdentifierInfo()->getLength());
17 else
18 return false;
19 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020}
21
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070022bool PragmaRecorder::GetPragmaValueFromToken(const clang::Token &Token,
23 std::string &PragmaValue) {
24 // Same as the GetPragmaName()
zonr6315f762010-10-05 15:35:14 +080025 if (Token.is(clang::tok::r_paren))
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070026 PragmaValue.clear();
27 else
28 return GetPragmaNameFromToken(Token, PragmaValue);
29 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070030}
31
zonr6315f762010-10-05 15:35:14 +080032PragmaRecorder::PragmaRecorder(PragmaList &Pragmas)
33 : PragmaHandler(),
34 mPragmas(Pragmas) {
Shih-wei Liao1ebc0ca2010-09-14 10:57:21 -070035 return;
36}
Shih-wei Liao462aefd2010-06-04 15:32:04 -070037
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070038void PragmaRecorder::HandlePragma(clang::Preprocessor &PP,
39 clang::Token &FirstToken) {
40 clang::Token &CurrentToken = FirstToken;
41 std::string PragmaName, PragmaValue = "";
42 // Pragma in ACC should be a name/value pair
Shih-wei Liao462aefd2010-06-04 15:32:04 -070043
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070044 if (GetPragmaNameFromToken(FirstToken, PragmaName)) {
45 // start parsing the value '(' PragmaValue ')'
46 const clang::Token* NextToken = &PP.LookAhead(0);
Shih-wei Liao462aefd2010-06-04 15:32:04 -070047
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070048 if (NextToken->is(clang::tok::l_paren))
49 PP.LexUnexpandedToken(CurrentToken);
50 else
51 goto end_parsing_pragma_value;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070052
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070053 NextToken = &PP.LookAhead(0);
54 if (GetPragmaValueFromToken(*NextToken, PragmaValue))
55 PP.Lex(CurrentToken);
56 else
57 goto end_parsing_pragma_value;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070058
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070059 if (!NextToken->is(clang::tok::r_paren)) {
60 NextToken = &PP.LookAhead(0);
61 if (NextToken->is(clang::tok::r_paren))
62 PP.LexUnexpandedToken(CurrentToken);
63 else
64 goto end_parsing_pragma_value;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070065 }
66
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070067 // Until now, we ensure that we have a pragma name/value pair
zonr6315f762010-10-05 15:35:14 +080068 mPragmas.push_back(make_pair(PragmaName, PragmaValue));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070069 }
70
zonr6315f762010-10-05 15:35:14 +080071 end_parsing_pragma_value:
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070072 // Infor lex to eat the token
73 PP.LexUnexpandedToken(CurrentToken);
Shih-wei Liao462aefd2010-06-04 15:32:04 -070074
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070075 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070076}