blob: c445994aac256841ba41ce35cd83e1a68e822a93 [file] [log] [blame]
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001#include "slang_pragma_recorder.hpp"
2
3#include "clang/Lex/Token.h" /* for class clang::Token */
4
5#include "clang/Basic/TokenKinds.h" /* for enum clang::tok::* */
6
7#include "clang/Lex/Preprocessor.h" /* for class clang::Preprocessor */
8
9namespace slang {
10
11bool PragmaRecorder::GetPragmaNameFromToken(const Token& Token, 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(), Token.getIdentifierInfo()->getLength());
16 else
17 return false;
18 return true;
19}
20
21bool PragmaRecorder::GetPragmaValueFromToken(const Token& Token, std::string& PragmaValue) {
22 /* Same as the GetPragmaName() */
23 if(Token.is(clang::tok::r_paren))
24 PragmaValue.clear();
25 else
26 return GetPragmaNameFromToken(Token, PragmaValue);
27 return true;
28}
29
30PragmaRecorder::PragmaRecorder(PragmaList& Pragmas) : PragmaHandler(NULL), mPragmas(Pragmas) { return; }
31
32void PragmaRecorder::HandlePragma(Preprocessor &PP, Token &FirstToken) {
33 Token& CurrentToken = FirstToken;
34 std::string PragmaName, PragmaValue = "";
35 /* Pragma in ACC should be a name/value pair */
36
37 if(GetPragmaNameFromToken(FirstToken, PragmaName)) {
38 /* start parsing the value '(' PragmaValue ')' */
39 const Token* NextToken = &PP.LookAhead(0);
40
41 if(NextToken->is(clang::tok::l_paren))
42 PP.LexUnexpandedToken(CurrentToken);
43 else
44 goto end_parsing_pragma_value;
45
46 NextToken = &PP.LookAhead(0);
47 if(GetPragmaValueFromToken(*NextToken, PragmaValue))
48 PP.Lex(CurrentToken);
49 else
50 goto end_parsing_pragma_value;
51
52 if(!NextToken->is(clang::tok::r_paren)) {
53 NextToken = &PP.LookAhead(0);
54 if(NextToken->is(clang::tok::r_paren))
55 PP.LexUnexpandedToken(CurrentToken);
56 else
57 goto end_parsing_pragma_value;
58 }
59
60 /* Until now, we ensure that we have a pragma name/value pair */
61 mPragmas.push_back( make_pair(PragmaName, PragmaValue) );
62 }
63
64end_parsing_pragma_value:
65 /* Infor lex to eat the token */
66 PP.LexUnexpandedToken(CurrentToken);
67
68 return;
69}
70
71} /* namespace slang */