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_rs_pragma_handler.h" 18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 193fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines#include <sstream> 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string> 21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/TokenKinds.h" 23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Lex/LiteralSupport.h" 259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Lex/Preprocessor.h" 269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Lex/Token.h" 27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 286e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 296315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 306315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaonamespace { // Anonymous namespace 34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass RSExportTypePragmaHandler : public RSPragmaHandler { 369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao private: 376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr void handleItem(const std::string &Item) { 383fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mContext->addPragma(this->getName(), Item); 399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mContext->addExportType(Item); 409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao public: 436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportTypePragmaHandler(llvm::StringRef Name, RSContext *Context) 44796e7b1400d3f3f7c07496d88bb48129ea925bb9Jean-Luc Brouillet : RSPragmaHandler(Name, Context) { } 459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 46df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao void HandlePragma(clang::Preprocessor &PP, 47df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::PragmaIntroducerKind Introducer, 48df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::Token &FirstToken) { 499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao this->handleItemListPragma(PP, FirstToken); 509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 52462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 53537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liaoclass RSJavaPackageNamePragmaHandler : public RSPragmaHandler { 549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao public: 556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSJavaPackageNamePragmaHandler(llvm::StringRef Name, RSContext *Context) 56796e7b1400d3f3f7c07496d88bb48129ea925bb9Jean-Luc Brouillet : RSPragmaHandler(Name, Context) { } 579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 58df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao void HandlePragma(clang::Preprocessor &PP, 59df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::PragmaIntroducerKind Introducer, 60df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::Token &FirstToken) { 6135f5b39f0490953f1fe13ef803b43e3ced9a01d9Stephen Hines // FIXME: Need to validate the extracted package name from pragma. 629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Currently "all chars" specified in pragma will be treated as package 639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // name. 649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 18.1 The Grammar of the Java Programming Language 669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // (http://java.sun.com/docs/books/jls/third_edition/html/syntax.html#18.1) 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // CompilationUnit: 699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // [[Annotations] package QualifiedIdentifier ; ] {ImportDeclaration} 709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // {TypeDeclaration} 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // QualifiedIdentifier: 739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Identifier { . Identifier } 749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Identifier: 769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // IDENTIFIER 779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 3.8 Identifiers 799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // (http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8) 809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &PragmaToken = FirstToken; 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string PackageName; 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Skip first token, "java_package_name" 879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 88537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Now, the current token must be clang::tok::lpara 909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::l_paren)) 919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 93be27482cdeaf08576bc39b72a15d35d13014a636Logan while (PragmaToken.isNot(clang::tok::eod)) { 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lex package name 959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Invalid; 989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string Spelling = PP.getSpelling(PragmaToken, &Invalid); 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Invalid) 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PackageName.append(Spelling); 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Pre-mature end (syntax error will be triggered by preprocessor later) 103be27482cdeaf08576bc39b72a15d35d13014a636Logan if (PragmaToken.is(clang::tok::eod) || PragmaToken.is(clang::tok::eof)) { 1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1056315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr } else { 10696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // Next token is ')' (end of pragma) 1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Token &NextTok = PP.LookAhead(0); 1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (NextTok.is(clang::tok::r_paren)) { 1093fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mContext->addPragma(this->getName(), PackageName); 1109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mContext->setReflectJavaPackageName(PackageName); 111be27482cdeaf08576bc39b72a15d35d13014a636Logan // Lex until meets clang::tok::eod 1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao do { 1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 114be27482cdeaf08576bc39b72a15d35d13014a636Logan } while (PragmaToken.isNot(clang::tok::eod)); 1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 116537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao } 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 118537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao } 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 120537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao}; 121537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 122d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsiehclass RSReflectLicensePragmaHandler : public RSPragmaHandler { 1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao private: 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao void handleItem(const std::string &Item) { 1253fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mContext->addPragma(this->getName(), Item); 1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mContext->setLicenseNote(Item); 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao public: 1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSReflectLicensePragmaHandler(llvm::StringRef Name, RSContext *Context) 131796e7b1400d3f3f7c07496d88bb48129ea925bb9Jean-Luc Brouillet : RSPragmaHandler(Name, Context) { } 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 133df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao void HandlePragma(clang::Preprocessor &PP, 134df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::PragmaIntroducerKind Introducer, 135df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::Token &FirstToken) { 1369d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines this->handleOptionalStringLiteralParamPragma(PP, FirstToken); 1379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 138d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh}; 139d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 14096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hinesclass RSVersionPragmaHandler : public RSPragmaHandler { 14196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines private: 1427aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines void handleInt(clang::Preprocessor &PP, 1437aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::Token &Tok, 1447aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines const int v) { 1457aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (v != 1) { 1467aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.Diag(Tok, 1477aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.getDiagnostics().getCustomDiagID( 1487aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine::Error, 1497aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "pragma for version in source file must be set to 1")); 1507aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines mContext->setVersion(1); 1517aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 1527aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 1533fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines std::stringstream ss; 1543fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines ss << v; 1553fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mContext->addPragma(this->getName(), ss.str()); 15696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines mContext->setVersion(v); 15796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 15896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 15996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines public: 16096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines RSVersionPragmaHandler(llvm::StringRef Name, RSContext *Context) 161796e7b1400d3f3f7c07496d88bb48129ea925bb9Jean-Luc Brouillet : RSPragmaHandler(Name, Context) { } 16296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 163df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao void HandlePragma(clang::Preprocessor &PP, 164df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::PragmaIntroducerKind Introducer, 165df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::Token &FirstToken) { 16696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines this->handleIntegerParamPragma(PP, FirstToken); 16796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 16896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines}; 16996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 170109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet// Handles the pragmas rs_fp_full, rs_fp_relaxed, and rs_fp_imprecise. 171109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet// There's one instance of this handler for each of the above values. 172109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet// Only getName() differs between the instances. 173109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouilletclass RSPrecisionPragmaHandler : public RSPragmaHandler { 174109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouilletpublic: 175109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet RSPrecisionPragmaHandler(llvm::StringRef Name, RSContext *Context) 176109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet : RSPragmaHandler(Name, Context) {} 177462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 178109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet void HandlePragma(clang::Preprocessor &PP, 179109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet clang::PragmaIntroducerKind Introducer, 180109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet clang::Token &Token) { 181109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet std::string Precision = getName(); 182109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // We are deprecating rs_fp_imprecise. 183109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet if (Precision == "rs_fp_imprecise") { 184109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.Diag(Token, PP.getDiagnostics().getCustomDiagID( 185109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet clang::DiagnosticsEngine::Warning, 186109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "rs_fp_imprecise is deprecated. Assuming " 187109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "rs_fp_relaxed instead.")); 188109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet Precision = "rs_fp_relaxed"; 189109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet } 190109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // Check if we have already encountered a precision pragma already. 191109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet std::string PreviousPrecision = mContext->getPrecision(); 192109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet if (!PreviousPrecision.empty()) { 193109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // If the previous specified a different value, it's an error. 194109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet if (PreviousPrecision != Precision) { 195109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.Diag(Token, PP.getDiagnostics().getCustomDiagID( 196109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet clang::DiagnosticsEngine::Error, 197109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "Multiple float precisions specified. Encountered " 198109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "%0 previously.")) 199109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet << PreviousPrecision; 200109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet } 201109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // Otherwise we ignore redundant entries. 202109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet return; 203109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet } 204537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 205109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet mContext->addPragma(Precision, ""); 206109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet mContext->setPrecision(Precision); 207109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet } 208109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet}; 209d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 210109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet} // namespace 21196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid RSPragmaHandler::handleItemListPragma(clang::Preprocessor &PP, 2139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &FirstToken) { 2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &PragmaToken = FirstToken; 215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Skip first token, like "export_var" 2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 218462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Now, the current token must be clang::tok::lpara 2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::l_paren)) 2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 222462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 223be27482cdeaf08576bc39b72a15d35d13014a636Logan while (PragmaToken.isNot(clang::tok::eod)) { 2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lex variable name 2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.is(clang::tok::identifier)) 2276315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr this->handleItem(PP.getSpelling(PragmaToken)); 2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 230462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 231be27482cdeaf08576bc39b72a15d35d13014a636Logan slangAssert(PragmaToken.isNot(clang::tok::eod)); 232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::comma)) 2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 2379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2406315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrvoid RSPragmaHandler::handleNonParamPragma(clang::Preprocessor &PP, 2416315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr clang::Token &FirstToken) { 2426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr clang::Token &PragmaToken = FirstToken; 243c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh 2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Skip first token, like "export_var_all" 2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 246c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh 2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Should be end immediately 248be27482cdeaf08576bc39b72a15d35d13014a636Logan if (PragmaToken.isNot(clang::tok::eod)) 2497aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (PragmaToken.isNot(clang::tok::r_paren)) { 2507aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.Diag(PragmaToken, 2517aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.getDiagnostics().getCustomDiagID( 2527aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine::Error, 2537aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "expected a ')'")); 2547aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 2557aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 256c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh} 257c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh 2589d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hinesvoid RSPragmaHandler::handleOptionalStringLiteralParamPragma( 2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Preprocessor &PP, clang::Token &FirstToken) { 2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &PragmaToken = FirstToken; 261d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 2629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Skip first token, like "set_reflect_license" 2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 264d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Now, the current token must be clang::tok::lpara 2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::l_paren)) 2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 268d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // If not ')', eat the following string literal as the license 2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::r_paren)) { 2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Eat the whole string literal 2732eb9a3f7c48fe54eb4e813d80e3363bc79553a1eStephen Hines clang::StringLiteralParser StringLiteral(PragmaToken, PP); 2747aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (StringLiteral.hadError) { 2757aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines // Diagnostics will be generated automatically 2767aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 277e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines } else { 2786315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr this->handleItem(std::string(StringLiteral.GetString())); 2797aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 2809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // The current token should be clang::tok::r_para 282d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh PP.LexUnexpandedToken(PragmaToken); 2837aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (PragmaToken.isNot(clang::tok::r_paren)) { 2847aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.Diag(PragmaToken, 2857aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.getDiagnostics().getCustomDiagID( 2867aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine::Error, 2877aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "expected a ')'")); 2887aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 2897aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // If no argument, remove the license 2926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr this->handleItem(""); 2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 294d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh} 295e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 29696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hinesvoid RSPragmaHandler::handleIntegerParamPragma( 29796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines clang::Preprocessor &PP, clang::Token &FirstToken) { 29896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines clang::Token &PragmaToken = FirstToken; 29996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 30096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // Skip first token, like "version" 30196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PP.LexUnexpandedToken(PragmaToken); 30296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 30396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // Now, the current token must be clang::tok::lpara 3047aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (PragmaToken.isNot(clang::tok::l_paren)) { 3057aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines // If no argument, set the version to 0 3067aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines this->handleInt(PP, PragmaToken, 0); 30796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines return; 3087aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 30996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PP.LexUnexpandedToken(PragmaToken); 31096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 31196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines if (PragmaToken.is(clang::tok::numeric_constant)) { 31223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines llvm::SmallString<128> SpellingBuffer; 31323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines SpellingBuffer.resize(PragmaToken.getLength() + 1); 31423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines llvm::StringRef TokSpelling = PP.getSpelling(PragmaToken, SpellingBuffer); 31523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::NumericLiteralParser NumericLiteral(TokSpelling, 31696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PragmaToken.getLocation(), PP); 31796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines if (NumericLiteral.hadError) { 3187aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines // Diagnostics will be generated automatically 3197aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 32096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } else { 32196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines llvm::APInt Val(32, 0); 32296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines NumericLiteral.GetIntegerValue(Val); 3237aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines this->handleInt(PP, PragmaToken, static_cast<int>(Val.getSExtValue())); 32496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 32596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PP.LexUnexpandedToken(PragmaToken); 32696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } else { 32796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // If no argument, set the version to 0 3287aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines this->handleInt(PP, PragmaToken, 0); 32996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 33096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 33196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines if (PragmaToken.isNot(clang::tok::r_paren)) { 3327aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.Diag(PragmaToken, 3337aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.getDiagnostics().getCustomDiagID( 3347aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine::Error, 3357aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "expected a ')'")); 3367aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 33796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 33896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 33996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines do { 34096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PP.LexUnexpandedToken(PragmaToken); 341be27482cdeaf08576bc39b72a15d35d13014a636Logan } while (PragmaToken.isNot(clang::tok::eod)); 34296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines} 34396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 344109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouilletvoid AddPragmaHandlers(clang::Preprocessor &PP, RSContext *RsContext) { 345109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma rs export_type 346109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler("rs", 347109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet new RSExportTypePragmaHandler("export_type", RsContext)); 348109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 349109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma rs java_package_name 350109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler( 351109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "rs", new RSJavaPackageNamePragmaHandler("java_package_name", RsContext)); 352109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 353109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma rs set_reflect_license 354109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler( 355109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "rs", new RSReflectLicensePragmaHandler("set_reflect_license", RsContext)); 356109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 357109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma version 358109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler(new RSVersionPragmaHandler("version", RsContext)); 359109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 360109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma rs_fp* 361109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler(new RSPrecisionPragmaHandler("rs_fp_full", RsContext)); 362109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler(new RSPrecisionPragmaHandler("rs_fp_relaxed", RsContext)); 363109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler(new RSPrecisionPragmaHandler("rs_fp_imprecise", RsContext)); 364109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet} 365109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 366109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 367e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 368