1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright 2010, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_pragma_recorder.h" 18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string> 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/TokenKinds.h" 22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Lex/Preprocessor.h" 246315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Lex/Token.h" 25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool PragmaRecorder::GetPragmaNameFromToken(const clang::Token &Token, 299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string &PragmaName) { 309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (Token.isLiteral()) 319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PragmaName.assign(Token.getLiteralData(), Token.getLength()); 329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else if (Token.is(clang::tok::identifier)) 339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PragmaName.assign(Token.getIdentifierInfo()->getNameStart(), 349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Token.getIdentifierInfo()->getLength()); 359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool PragmaRecorder::GetPragmaValueFromToken(const clang::Token &Token, 419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string &PragmaValue) { 429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Same as the GetPragmaName() 436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr if (Token.is(clang::tok::r_paren)) 449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PragmaValue.clear(); 459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return GetPragmaNameFromToken(Token, PragmaValue); 479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 49462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 503fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen HinesPragmaRecorder::PragmaRecorder(PragmaList *Pragmas) 516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr : PragmaHandler(), 526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mPragmas(Pragmas) { 531ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao} 54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid PragmaRecorder::HandlePragma(clang::Preprocessor &PP, 56df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::PragmaIntroducerKind Introducer, 579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &FirstToken) { 589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &CurrentToken = FirstToken; 599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string PragmaName, PragmaValue = ""; 609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Pragma in ACC should be a name/value pair 61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (GetPragmaNameFromToken(FirstToken, PragmaName)) { 63f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines // start parsing the value '(' PragmaValue ')', if we have one. 649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Token* NextToken = &PP.LookAhead(0); 65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (NextToken->is(clang::tok::l_paren)) 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(CurrentToken); 689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao goto end_parsing_pragma_value; 70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao NextToken = &PP.LookAhead(0); 72f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines if (GetPragmaValueFromToken(*NextToken, PragmaValue)) { 739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.Lex(CurrentToken); 74f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines } else { 75f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines PP.LexUnexpandedToken(CurrentToken); 76f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines PP.Diag(NextToken->getLocation(), 77f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines PP.getDiagnostics().getCustomDiagID( 78f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines clang::DiagnosticsEngine::Error, 79f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines "expected value after '#pragma %0('")) << PragmaName; 80f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines return; 81f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines } 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!NextToken->is(clang::tok::r_paren)) { 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao NextToken = &PP.LookAhead(0); 85f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines if (NextToken->is(clang::tok::r_paren)) { 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(CurrentToken); 87f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines } else { 88f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines PP.LexUnexpandedToken(CurrentToken); 89f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines PP.Diag(NextToken->getLocation(), 90f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines PP.getDiagnostics().getCustomDiagID( 91f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines clang::DiagnosticsEngine::Error, 92f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines "missing ')' after '#pragma %0(%1'")) 93f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines << PragmaName << PragmaValue; 94f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines return; 95f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines } 96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 97f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines } else { 98f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines PP.Diag(FirstToken.getLocation(), 99f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines PP.getDiagnostics().getCustomDiagID( 100f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines clang::DiagnosticsEngine::Error, 101f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines "no pragma name or value")); 102f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines return; 1039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1056315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr end_parsing_pragma_value: 106f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines 107f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines // PragmaValue may be an empty string. 108f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines mPragmas->push_back(make_pair(PragmaName, PragmaValue)); 109f4ea4fd843acd4eacbc89973fedf8bcf692fe73cStephen Hines 1103fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines // Inform lex to eat the token 1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(CurrentToken); 112462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 113e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 114e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 115