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 195e306b944425a952fe744f59d828538137a59375David Gross#include <map> 203fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines#include <sstream> 21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string> 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 2365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross#include "clang/AST/ASTContext.h" 2465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/TokenKinds.h" 26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Lex/LiteralSupport.h" 289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Lex/Preprocessor.h" 299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Lex/Token.h" 30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 316e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 3315e44e66adc350adb4fe0533a442092c64333ab5David Gross#include "slang_rs_export_reduce.h" 3415e44e66adc350adb4fe0533a442092c64333ab5David Gross#include "slang_version.h" 356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 36e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaonamespace { // Anonymous namespace 39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclass RSExportTypePragmaHandler : public RSPragmaHandler { 419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao private: 426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr void handleItem(const std::string &Item) { 433fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mContext->addPragma(this->getName(), Item); 449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mContext->addExportType(Item); 459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao public: 486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportTypePragmaHandler(llvm::StringRef Name, RSContext *Context) 49796e7b1400d3f3f7c07496d88bb48129ea925bb9Jean-Luc Brouillet : RSPragmaHandler(Name, Context) { } 509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 51df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao void HandlePragma(clang::Preprocessor &PP, 52df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::PragmaIntroducerKind Introducer, 53df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::Token &FirstToken) { 549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao this->handleItemListPragma(PP, FirstToken); 559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 56462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 57462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 58537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liaoclass RSJavaPackageNamePragmaHandler : public RSPragmaHandler { 599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao public: 606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSJavaPackageNamePragmaHandler(llvm::StringRef Name, RSContext *Context) 61796e7b1400d3f3f7c07496d88bb48129ea925bb9Jean-Luc Brouillet : RSPragmaHandler(Name, Context) { } 629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 63df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao void HandlePragma(clang::Preprocessor &PP, 64df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::PragmaIntroducerKind Introducer, 65df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::Token &FirstToken) { 6635f5b39f0490953f1fe13ef803b43e3ced9a01d9Stephen Hines // FIXME: Need to validate the extracted package name from pragma. 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Currently "all chars" specified in pragma will be treated as package 689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // name. 699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 18.1 The Grammar of the Java Programming Language 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // (http://java.sun.com/docs/books/jls/third_edition/html/syntax.html#18.1) 729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // CompilationUnit: 749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // [[Annotations] package QualifiedIdentifier ; ] {ImportDeclaration} 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // {TypeDeclaration} 769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // QualifiedIdentifier: 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Identifier { . Identifier } 799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Identifier: 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // IDENTIFIER 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 3.8 Identifiers 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // (http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8) 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &PragmaToken = FirstToken; 899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string PackageName; 909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Skip first token, "java_package_name" 929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 93537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Now, the current token must be clang::tok::lpara 959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::l_paren)) 969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 98be27482cdeaf08576bc39b72a15d35d13014a636Logan while (PragmaToken.isNot(clang::tok::eod)) { 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lex package name 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Invalid; 1039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string Spelling = PP.getSpelling(PragmaToken, &Invalid); 1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Invalid) 1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PackageName.append(Spelling); 1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Pre-mature end (syntax error will be triggered by preprocessor later) 108be27482cdeaf08576bc39b72a15d35d13014a636Logan if (PragmaToken.is(clang::tok::eod) || PragmaToken.is(clang::tok::eof)) { 1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr } else { 11196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // Next token is ')' (end of pragma) 1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Token &NextTok = PP.LookAhead(0); 1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (NextTok.is(clang::tok::r_paren)) { 1143fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mContext->addPragma(this->getName(), PackageName); 1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mContext->setReflectJavaPackageName(PackageName); 116be27482cdeaf08576bc39b72a15d35d13014a636Logan // Lex until meets clang::tok::eod 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao do { 1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 119be27482cdeaf08576bc39b72a15d35d13014a636Logan } while (PragmaToken.isNot(clang::tok::eod)); 1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 121537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao } 1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 123537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao } 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 125537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao}; 126537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 12715e44e66adc350adb4fe0533a442092c64333ab5David Grossclass RSReducePragmaHandler : public RSPragmaHandler { 12815e44e66adc350adb4fe0533a442092c64333ab5David Gross public: 12915e44e66adc350adb4fe0533a442092c64333ab5David Gross RSReducePragmaHandler(llvm::StringRef Name, RSContext *Context) 13015e44e66adc350adb4fe0533a442092c64333ab5David Gross : RSPragmaHandler(Name, Context) { } 13115e44e66adc350adb4fe0533a442092c64333ab5David Gross 13215e44e66adc350adb4fe0533a442092c64333ab5David Gross void HandlePragma(clang::Preprocessor &PP, 13315e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::PragmaIntroducerKind Introducer, 13415e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::Token &FirstToken) override { 13515e44e66adc350adb4fe0533a442092c64333ab5David Gross // #pragma rs reduce(name) 13615e44e66adc350adb4fe0533a442092c64333ab5David Gross // initializer(initializename) 13715e44e66adc350adb4fe0533a442092c64333ab5David Gross // accumulator(accumulatename) 13815e44e66adc350adb4fe0533a442092c64333ab5David Gross // combiner(combinename) 13915e44e66adc350adb4fe0533a442092c64333ab5David Gross // outconverter(outconvertname) 14015e44e66adc350adb4fe0533a442092c64333ab5David Gross // halter(haltname) 14115e44e66adc350adb4fe0533a442092c64333ab5David Gross 14215e44e66adc350adb4fe0533a442092c64333ab5David Gross const clang::SourceLocation PragmaLocation = FirstToken.getLocation(); 14315e44e66adc350adb4fe0533a442092c64333ab5David Gross 14415e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::Token &PragmaToken = FirstToken; 14515e44e66adc350adb4fe0533a442092c64333ab5David Gross 14615e44e66adc350adb4fe0533a442092c64333ab5David Gross // Grab "reduce(name)" ("reduce" is already known to be the first 14715e44e66adc350adb4fe0533a442092c64333ab5David Gross // token) and all the "keyword(value)" contributions 1488ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross KeywordValueMapType KeywordValueMap({std::make_pair(RSExportReduce::KeyReduce, ""), 1498ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross std::make_pair(RSExportReduce::KeyInitializer, ""), 1508ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross std::make_pair(RSExportReduce::KeyAccumulator, ""), 1518ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross std::make_pair(RSExportReduce::KeyCombiner, ""), 1528ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross std::make_pair(RSExportReduce::KeyOutConverter, "")}); 15346a0334d8901576e20db68e15930a19f8f789cb8David Gross if (mContext->getTargetAPI() >= SLANG_FEATURE_GENERAL_REDUCTION_HALTER_API) { 15446a0334d8901576e20db68e15930a19f8f789cb8David Gross // Halter functionality has not been released, nor has its 15546a0334d8901576e20db68e15930a19f8f789cb8David Gross // specification been finalized with partners. We do not have a 15646a0334d8901576e20db68e15930a19f8f789cb8David Gross // specification that extends through the full RenderScript 15746a0334d8901576e20db68e15930a19f8f789cb8David Gross // software stack, either. 1588ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross KeywordValueMap.insert(std::make_pair(RSExportReduce::KeyHalter, "")); 15946a0334d8901576e20db68e15930a19f8f789cb8David Gross } 16015e44e66adc350adb4fe0533a442092c64333ab5David Gross while (PragmaToken.is(clang::tok::identifier)) { 16115e44e66adc350adb4fe0533a442092c64333ab5David Gross if (!ProcessKeywordAndValue(PP, PragmaToken, KeywordValueMap)) 16215e44e66adc350adb4fe0533a442092c64333ab5David Gross return; 16315e44e66adc350adb4fe0533a442092c64333ab5David Gross } 16415e44e66adc350adb4fe0533a442092c64333ab5David Gross 16515e44e66adc350adb4fe0533a442092c64333ab5David Gross // Make sure there's no end-of-line garbage 16615e44e66adc350adb4fe0533a442092c64333ab5David Gross if (PragmaToken.isNot(clang::tok::eod)) { 16715e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.Diag(PragmaToken.getLocation(), 16815e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.getDiagnostics().getCustomDiagID( 16915e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::DiagnosticsEngine::Error, 17015e44e66adc350adb4fe0533a442092c64333ab5David Gross "did not expect '%0' here for '#pragma rs %1'")) 17115e44e66adc350adb4fe0533a442092c64333ab5David Gross << PP.getSpelling(PragmaToken) << getName(); 17215e44e66adc350adb4fe0533a442092c64333ab5David Gross return; 17315e44e66adc350adb4fe0533a442092c64333ab5David Gross } 17415e44e66adc350adb4fe0533a442092c64333ab5David Gross 17565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross // Make sure we have an accumulator 1768ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross if (KeywordValueMap[RSExportReduce::KeyAccumulator].empty()) { 17715e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.Diag(PragmaLocation, PP.getDiagnostics().getCustomDiagID( 17815e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::DiagnosticsEngine::Error, 17915e44e66adc350adb4fe0533a442092c64333ab5David Gross "missing '%0' for '#pragma rs %1'")) 1808ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross << RSExportReduce::KeyAccumulator << getName(); 18115e44e66adc350adb4fe0533a442092c64333ab5David Gross return; 18215e44e66adc350adb4fe0533a442092c64333ab5David Gross } 18315e44e66adc350adb4fe0533a442092c64333ab5David Gross 18415e44e66adc350adb4fe0533a442092c64333ab5David Gross // Make sure the reduction kernel name is unique. (If we were 18515e44e66adc350adb4fe0533a442092c64333ab5David Gross // worried there might be a VERY large number of pragmas, then we 18615e44e66adc350adb4fe0533a442092c64333ab5David Gross // could do something more efficient than walking a list to search 18715e44e66adc350adb4fe0533a442092c64333ab5David Gross // for duplicates.) 1888ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross for (auto I = mContext->export_reduce_begin(), 1898ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross E = mContext->export_reduce_end(); 19015e44e66adc350adb4fe0533a442092c64333ab5David Gross I != E; ++I) { 1918ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross if ((*I)->getNameReduce() == KeywordValueMap[RSExportReduce::KeyReduce]) { 19215e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.Diag(PragmaLocation, PP.getDiagnostics().getCustomDiagID( 19315e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::DiagnosticsEngine::Error, 19415e44e66adc350adb4fe0533a442092c64333ab5David Gross "reduction kernel '%0' declared multiple " 19515e44e66adc350adb4fe0533a442092c64333ab5David Gross "times (first one is at %1)")) 1968ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross << KeywordValueMap[RSExportReduce::KeyReduce] 19715e44e66adc350adb4fe0533a442092c64333ab5David Gross << (*I)->getLocation().printToString(PP.getSourceManager()); 19815e44e66adc350adb4fe0533a442092c64333ab5David Gross return; 19915e44e66adc350adb4fe0533a442092c64333ab5David Gross } 20015e44e66adc350adb4fe0533a442092c64333ab5David Gross } 20115e44e66adc350adb4fe0533a442092c64333ab5David Gross 20215e44e66adc350adb4fe0533a442092c64333ab5David Gross // Check API version. 2031623659165bb24d733a40124e929cfd42aa917e3David Gross if (mContext->getTargetAPI() < SLANG_FEATURE_GENERAL_REDUCTION_API) { 20415e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.Diag(PragmaLocation, 20515e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.getDiagnostics().getCustomDiagID( 20615e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::DiagnosticsEngine::Error, 2071623659165bb24d733a40124e929cfd42aa917e3David Gross "reduction kernels are not supported in SDK levels %0-%1")) 2081623659165bb24d733a40124e929cfd42aa917e3David Gross << SLANG_MINIMUM_TARGET_API 2091623659165bb24d733a40124e929cfd42aa917e3David Gross << (SLANG_FEATURE_GENERAL_REDUCTION_API - 1); 21015e44e66adc350adb4fe0533a442092c64333ab5David Gross return; 21115e44e66adc350adb4fe0533a442092c64333ab5David Gross } 21215e44e66adc350adb4fe0533a442092c64333ab5David Gross 21365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross // Handle backward reference from pragma (see Backend::HandleTopLevelDecl for forward reference). 2148ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross MarkUsed(PP, KeywordValueMap[RSExportReduce::KeyInitializer]); 2158ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross MarkUsed(PP, KeywordValueMap[RSExportReduce::KeyAccumulator]); 2168ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross MarkUsed(PP, KeywordValueMap[RSExportReduce::KeyCombiner]); 2178ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross MarkUsed(PP, KeywordValueMap[RSExportReduce::KeyOutConverter]); 2188ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross MarkUsed(PP, KeywordValueMap[RSExportReduce::KeyHalter]); 2198ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross 2208ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross mContext->addExportReduce(RSExportReduce::Create(mContext, PragmaLocation, 2218ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross KeywordValueMap[RSExportReduce::KeyReduce], 2228ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross KeywordValueMap[RSExportReduce::KeyInitializer], 2238ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross KeywordValueMap[RSExportReduce::KeyAccumulator], 2248ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross KeywordValueMap[RSExportReduce::KeyCombiner], 2258ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross KeywordValueMap[RSExportReduce::KeyOutConverter], 2268ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross KeywordValueMap[RSExportReduce::KeyHalter])); 22715e44e66adc350adb4fe0533a442092c64333ab5David Gross } 22815e44e66adc350adb4fe0533a442092c64333ab5David Gross 22915e44e66adc350adb4fe0533a442092c64333ab5David Gross private: 23015e44e66adc350adb4fe0533a442092c64333ab5David Gross typedef std::map<std::string, std::string> KeywordValueMapType; 23115e44e66adc350adb4fe0533a442092c64333ab5David Gross 23265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross void MarkUsed(clang::Preprocessor &PP, const std::string &FunctionName) { 23365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (FunctionName.empty()) 23465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross return; 23565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 23665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross clang::ASTContext &ASTC = mContext->getASTContext(); 23765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross clang::TranslationUnitDecl *TUDecl = ASTC.getTranslationUnitDecl(); 23865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross slangAssert(TUDecl); 23965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (const clang::IdentifierInfo *II = PP.getIdentifierInfo(FunctionName)) { 24065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross for (auto Decl : TUDecl->lookup(II)) { 24165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross clang::FunctionDecl *FDecl = Decl->getAsFunction(); 24265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (!FDecl || !FDecl->isThisDeclarationADefinition()) 24365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross continue; 2445e306b944425a952fe744f59d828538137a59375David Gross // Handle backward reference from pragma (see 2455e306b944425a952fe744f59d828538137a59375David Gross // Backend::HandleTopLevelDecl for forward reference). 2465e306b944425a952fe744f59d828538137a59375David Gross mContext->markUsedByReducePragma(FDecl, RSContext::CheckNameNo); 24765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross } 24865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross } 24965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross } 25065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 25115e44e66adc350adb4fe0533a442092c64333ab5David Gross // Return comma-separated list of all keys in the map 25215e44e66adc350adb4fe0533a442092c64333ab5David Gross static std::string ListKeywords(const KeywordValueMapType &KeywordValueMap) { 25315e44e66adc350adb4fe0533a442092c64333ab5David Gross std::string Ret; 25415e44e66adc350adb4fe0533a442092c64333ab5David Gross bool First = true; 25515e44e66adc350adb4fe0533a442092c64333ab5David Gross for (auto const &entry : KeywordValueMap) { 25615e44e66adc350adb4fe0533a442092c64333ab5David Gross if (First) 25715e44e66adc350adb4fe0533a442092c64333ab5David Gross First = false; 25815e44e66adc350adb4fe0533a442092c64333ab5David Gross else 25915e44e66adc350adb4fe0533a442092c64333ab5David Gross Ret += ", "; 26015e44e66adc350adb4fe0533a442092c64333ab5David Gross Ret += "'"; 26115e44e66adc350adb4fe0533a442092c64333ab5David Gross Ret += entry.first; 26215e44e66adc350adb4fe0533a442092c64333ab5David Gross Ret += "'"; 26315e44e66adc350adb4fe0533a442092c64333ab5David Gross } 26415e44e66adc350adb4fe0533a442092c64333ab5David Gross return Ret; 26515e44e66adc350adb4fe0533a442092c64333ab5David Gross } 26615e44e66adc350adb4fe0533a442092c64333ab5David Gross 26715e44e66adc350adb4fe0533a442092c64333ab5David Gross // Parse "keyword(value)" and set KeywordValueMap[keyword] = value. (Both 26815e44e66adc350adb4fe0533a442092c64333ab5David Gross // "keyword" and "value" are identifiers.) 26915e44e66adc350adb4fe0533a442092c64333ab5David Gross // Does both syntactic validation and the following semantic validation: 27015e44e66adc350adb4fe0533a442092c64333ab5David Gross // - The keyword must be present in the map. 27115e44e66adc350adb4fe0533a442092c64333ab5David Gross // - The map entry for the keyword must not contain a value. 27215e44e66adc350adb4fe0533a442092c64333ab5David Gross bool ProcessKeywordAndValue(clang::Preprocessor &PP, 27315e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::Token &PragmaToken, 27415e44e66adc350adb4fe0533a442092c64333ab5David Gross KeywordValueMapType &KeywordValueMap) { 27515e44e66adc350adb4fe0533a442092c64333ab5David Gross // The current token must be an identifier in KeywordValueMap 27615e44e66adc350adb4fe0533a442092c64333ab5David Gross KeywordValueMapType::iterator Entry; 27715e44e66adc350adb4fe0533a442092c64333ab5David Gross if (PragmaToken.isNot(clang::tok::identifier) || 27815e44e66adc350adb4fe0533a442092c64333ab5David Gross ((Entry = KeywordValueMap.find( 27915e44e66adc350adb4fe0533a442092c64333ab5David Gross PragmaToken.getIdentifierInfo()->getName())) == 28015e44e66adc350adb4fe0533a442092c64333ab5David Gross KeywordValueMap.end())) { 28115e44e66adc350adb4fe0533a442092c64333ab5David Gross // Note that we should never get here for the "reduce" token 28215e44e66adc350adb4fe0533a442092c64333ab5David Gross // itself, which should already have been recognized. 28315e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.Diag(PragmaToken.getLocation(), 28415e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.getDiagnostics().getCustomDiagID( 28515e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::DiagnosticsEngine::Error, 28615e44e66adc350adb4fe0533a442092c64333ab5David Gross "did not recognize '%0' for '#pragma %1'; expected one of " 28715e44e66adc350adb4fe0533a442092c64333ab5David Gross "the following keywords: %2")) 28815e44e66adc350adb4fe0533a442092c64333ab5David Gross << PragmaToken.getIdentifierInfo()->getName() << getName() 28915e44e66adc350adb4fe0533a442092c64333ab5David Gross << ListKeywords(KeywordValueMap); 29015e44e66adc350adb4fe0533a442092c64333ab5David Gross return false; 29115e44e66adc350adb4fe0533a442092c64333ab5David Gross } 29215e44e66adc350adb4fe0533a442092c64333ab5David Gross // ... and there must be no value for this keyword yet 29315e44e66adc350adb4fe0533a442092c64333ab5David Gross if (!Entry->second.empty()) { 29415e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.Diag(PragmaToken.getLocation(), 29515e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.getDiagnostics().getCustomDiagID( 29615e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::DiagnosticsEngine::Error, 29715e44e66adc350adb4fe0533a442092c64333ab5David Gross "more than one '%0' for '#pragma rs %1'")) 29815e44e66adc350adb4fe0533a442092c64333ab5David Gross << Entry->first << getName(); 29915e44e66adc350adb4fe0533a442092c64333ab5David Gross return false; 30015e44e66adc350adb4fe0533a442092c64333ab5David Gross } 30115e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.LexUnexpandedToken(PragmaToken); 30215e44e66adc350adb4fe0533a442092c64333ab5David Gross 30315e44e66adc350adb4fe0533a442092c64333ab5David Gross // The current token must be clang::tok::l_paren 30415e44e66adc350adb4fe0533a442092c64333ab5David Gross if (PragmaToken.isNot(clang::tok::l_paren)) { 30515e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.Diag(PragmaToken.getLocation(), 30615e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.getDiagnostics().getCustomDiagID( 30715e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::DiagnosticsEngine::Error, 30815e44e66adc350adb4fe0533a442092c64333ab5David Gross "missing '(' after '%0' for '#pragma rs %1'")) 30915e44e66adc350adb4fe0533a442092c64333ab5David Gross << Entry->first << getName(); 31015e44e66adc350adb4fe0533a442092c64333ab5David Gross return false; 31115e44e66adc350adb4fe0533a442092c64333ab5David Gross } 31215e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.LexUnexpandedToken(PragmaToken); 31315e44e66adc350adb4fe0533a442092c64333ab5David Gross 31415e44e66adc350adb4fe0533a442092c64333ab5David Gross // The current token must be an identifier (a name) 31515e44e66adc350adb4fe0533a442092c64333ab5David Gross if (PragmaToken.isNot(clang::tok::identifier)) { 31615e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.Diag(PragmaToken.getLocation(), 31715e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.getDiagnostics().getCustomDiagID( 31815e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::DiagnosticsEngine::Error, 31915e44e66adc350adb4fe0533a442092c64333ab5David Gross "missing name after '%0(' for '#pragma rs %1'")) 32015e44e66adc350adb4fe0533a442092c64333ab5David Gross << Entry->first << getName(); 32115e44e66adc350adb4fe0533a442092c64333ab5David Gross return false; 32215e44e66adc350adb4fe0533a442092c64333ab5David Gross } 32315e44e66adc350adb4fe0533a442092c64333ab5David Gross const std::string Name = PragmaToken.getIdentifierInfo()->getName(); 32415e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.LexUnexpandedToken(PragmaToken); 32515e44e66adc350adb4fe0533a442092c64333ab5David Gross 32615e44e66adc350adb4fe0533a442092c64333ab5David Gross // The current token must be clang::tok::r_paren 32715e44e66adc350adb4fe0533a442092c64333ab5David Gross if (PragmaToken.isNot(clang::tok::r_paren)) { 32815e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.Diag(PragmaToken.getLocation(), 32915e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.getDiagnostics().getCustomDiagID( 33015e44e66adc350adb4fe0533a442092c64333ab5David Gross clang::DiagnosticsEngine::Error, 33115e44e66adc350adb4fe0533a442092c64333ab5David Gross "missing ')' after '%0(%1' for '#pragma rs %2'")) 33215e44e66adc350adb4fe0533a442092c64333ab5David Gross << Entry->first << Name << getName(); 33315e44e66adc350adb4fe0533a442092c64333ab5David Gross return false; 33415e44e66adc350adb4fe0533a442092c64333ab5David Gross } 33515e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.LexUnexpandedToken(PragmaToken); 33615e44e66adc350adb4fe0533a442092c64333ab5David Gross 33715e44e66adc350adb4fe0533a442092c64333ab5David Gross // Success 33815e44e66adc350adb4fe0533a442092c64333ab5David Gross Entry->second = Name; 33915e44e66adc350adb4fe0533a442092c64333ab5David Gross return true; 34015e44e66adc350adb4fe0533a442092c64333ab5David Gross } 34115e44e66adc350adb4fe0533a442092c64333ab5David Gross}; 34215e44e66adc350adb4fe0533a442092c64333ab5David Gross 343d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsiehclass RSReflectLicensePragmaHandler : public RSPragmaHandler { 3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao private: 3459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao void handleItem(const std::string &Item) { 3463fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mContext->addPragma(this->getName(), Item); 3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mContext->setLicenseNote(Item); 3489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao public: 3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSReflectLicensePragmaHandler(llvm::StringRef Name, RSContext *Context) 352796e7b1400d3f3f7c07496d88bb48129ea925bb9Jean-Luc Brouillet : RSPragmaHandler(Name, Context) { } 3539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 354df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao void HandlePragma(clang::Preprocessor &PP, 355df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::PragmaIntroducerKind Introducer, 356df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::Token &FirstToken) { 3579d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines this->handleOptionalStringLiteralParamPragma(PP, FirstToken); 3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 359d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh}; 360d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 36196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hinesclass RSVersionPragmaHandler : public RSPragmaHandler { 36296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines private: 3637aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines void handleInt(clang::Preprocessor &PP, 3647aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::Token &Tok, 3657aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines const int v) { 3667aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (v != 1) { 3677aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.Diag(Tok, 3687aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.getDiagnostics().getCustomDiagID( 3697aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine::Error, 3707aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "pragma for version in source file must be set to 1")); 3717aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines mContext->setVersion(1); 3727aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 3737aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 3743fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines std::stringstream ss; 3753fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines ss << v; 3763fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mContext->addPragma(this->getName(), ss.str()); 37796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines mContext->setVersion(v); 37896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 37996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 38096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines public: 38196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines RSVersionPragmaHandler(llvm::StringRef Name, RSContext *Context) 382796e7b1400d3f3f7c07496d88bb48129ea925bb9Jean-Luc Brouillet : RSPragmaHandler(Name, Context) { } 38396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 384df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao void HandlePragma(clang::Preprocessor &PP, 385df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::PragmaIntroducerKind Introducer, 386df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao clang::Token &FirstToken) { 38796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines this->handleIntegerParamPragma(PP, FirstToken); 38896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 38996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines}; 39096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 391109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet// Handles the pragmas rs_fp_full, rs_fp_relaxed, and rs_fp_imprecise. 392109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet// There's one instance of this handler for each of the above values. 393109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet// Only getName() differs between the instances. 394109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouilletclass RSPrecisionPragmaHandler : public RSPragmaHandler { 395109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouilletpublic: 396109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet RSPrecisionPragmaHandler(llvm::StringRef Name, RSContext *Context) 397109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet : RSPragmaHandler(Name, Context) {} 398462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 399109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet void HandlePragma(clang::Preprocessor &PP, 400109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet clang::PragmaIntroducerKind Introducer, 401109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet clang::Token &Token) { 402109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet std::string Precision = getName(); 403109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // We are deprecating rs_fp_imprecise. 404109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet if (Precision == "rs_fp_imprecise") { 405109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.Diag(Token, PP.getDiagnostics().getCustomDiagID( 406109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet clang::DiagnosticsEngine::Warning, 407109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "rs_fp_imprecise is deprecated. Assuming " 408109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "rs_fp_relaxed instead.")); 409109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet Precision = "rs_fp_relaxed"; 410109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet } 411109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // Check if we have already encountered a precision pragma already. 412109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet std::string PreviousPrecision = mContext->getPrecision(); 413109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet if (!PreviousPrecision.empty()) { 414109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // If the previous specified a different value, it's an error. 415109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet if (PreviousPrecision != Precision) { 416109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.Diag(Token, PP.getDiagnostics().getCustomDiagID( 417109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet clang::DiagnosticsEngine::Error, 418109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "Multiple float precisions specified. Encountered " 419109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "%0 previously.")) 420109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet << PreviousPrecision; 421109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet } 422109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // Otherwise we ignore redundant entries. 423109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet return; 424109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet } 425537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 426109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet mContext->addPragma(Precision, ""); 427109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet mContext->setPrecision(Precision); 428109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet } 429109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet}; 430d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 431109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet} // namespace 43296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 4339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid RSPragmaHandler::handleItemListPragma(clang::Preprocessor &PP, 4349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &FirstToken) { 4359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &PragmaToken = FirstToken; 436462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Skip first token, like "export_var" 4389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 439462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Now, the current token must be clang::tok::lpara 4419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::l_paren)) 4429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 443462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 444be27482cdeaf08576bc39b72a15d35d13014a636Logan while (PragmaToken.isNot(clang::tok::eod)) { 4459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lex variable name 4469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 4479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.is(clang::tok::identifier)) 4486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr this->handleItem(PP.getSpelling(PragmaToken)); 4499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 4509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 451462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 452be27482cdeaf08576bc39b72a15d35d13014a636Logan slangAssert(PragmaToken.isNot(clang::tok::eod)); 453462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 455462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::comma)) 4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 459462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 460462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrvoid RSPragmaHandler::handleNonParamPragma(clang::Preprocessor &PP, 4626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr clang::Token &FirstToken) { 4636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr clang::Token &PragmaToken = FirstToken; 464c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh 4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Skip first token, like "export_var_all" 4669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 467c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh 4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Should be end immediately 469be27482cdeaf08576bc39b72a15d35d13014a636Logan if (PragmaToken.isNot(clang::tok::eod)) 4707aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (PragmaToken.isNot(clang::tok::r_paren)) { 4717aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.Diag(PragmaToken, 4727aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.getDiagnostics().getCustomDiagID( 4737aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine::Error, 4747aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "expected a ')'")); 4757aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 4767aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 477c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh} 478c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh 4799d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hinesvoid RSPragmaHandler::handleOptionalStringLiteralParamPragma( 4809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Preprocessor &PP, clang::Token &FirstToken) { 4819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token &PragmaToken = FirstToken; 482d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 4839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Skip first token, like "set_reflect_license" 4849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 485d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 4869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Now, the current token must be clang::tok::lpara 4879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::l_paren)) 4889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 489d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh 4909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // If not ')', eat the following string literal as the license 4919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PP.LexUnexpandedToken(PragmaToken); 4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PragmaToken.isNot(clang::tok::r_paren)) { 4939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Eat the whole string literal 4942eb9a3f7c48fe54eb4e813d80e3363bc79553a1eStephen Hines clang::StringLiteralParser StringLiteral(PragmaToken, PP); 4957aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (StringLiteral.hadError) { 4967aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines // Diagnostics will be generated automatically 4977aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 498e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines } else { 4996315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr this->handleItem(std::string(StringLiteral.GetString())); 5007aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 5019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 5029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // The current token should be clang::tok::r_para 503d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh PP.LexUnexpandedToken(PragmaToken); 5047aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (PragmaToken.isNot(clang::tok::r_paren)) { 5057aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.Diag(PragmaToken, 5067aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.getDiagnostics().getCustomDiagID( 5077aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine::Error, 5087aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "expected a ')'")); 5097aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 5107aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 5119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 5129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // If no argument, remove the license 5136315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr this->handleItem(""); 5149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 515d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh} 516e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 51796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hinesvoid RSPragmaHandler::handleIntegerParamPragma( 51896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines clang::Preprocessor &PP, clang::Token &FirstToken) { 51996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines clang::Token &PragmaToken = FirstToken; 52096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 52196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // Skip first token, like "version" 52296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PP.LexUnexpandedToken(PragmaToken); 52396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 52496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // Now, the current token must be clang::tok::lpara 5257aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines if (PragmaToken.isNot(clang::tok::l_paren)) { 5267aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines // If no argument, set the version to 0 5277aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines this->handleInt(PP, PragmaToken, 0); 52896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines return; 5297aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } 53096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PP.LexUnexpandedToken(PragmaToken); 53196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 53296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines if (PragmaToken.is(clang::tok::numeric_constant)) { 53323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines llvm::SmallString<128> SpellingBuffer; 53423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines SpellingBuffer.resize(PragmaToken.getLength() + 1); 53523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines llvm::StringRef TokSpelling = PP.getSpelling(PragmaToken, SpellingBuffer); 53623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::NumericLiteralParser NumericLiteral(TokSpelling, 53796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PragmaToken.getLocation(), PP); 53896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines if (NumericLiteral.hadError) { 5397aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines // Diagnostics will be generated automatically 5407aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 54196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } else { 54296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines llvm::APInt Val(32, 0); 54396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines NumericLiteral.GetIntegerValue(Val); 5447aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines this->handleInt(PP, PragmaToken, static_cast<int>(Val.getSExtValue())); 54596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 54696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PP.LexUnexpandedToken(PragmaToken); 54796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } else { 54896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // If no argument, set the version to 0 5497aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines this->handleInt(PP, PragmaToken, 0); 55096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 55196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 55296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines if (PragmaToken.isNot(clang::tok::r_paren)) { 5537aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.Diag(PragmaToken, 5547aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines PP.getDiagnostics().getCustomDiagID( 5557aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine::Error, 5567aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "expected a ')'")); 5577aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines return; 55896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 55996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 56096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines do { 56196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PP.LexUnexpandedToken(PragmaToken); 562be27482cdeaf08576bc39b72a15d35d13014a636Logan } while (PragmaToken.isNot(clang::tok::eod)); 56396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines} 56496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 565109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouilletvoid AddPragmaHandlers(clang::Preprocessor &PP, RSContext *RsContext) { 566109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma rs export_type 567109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler("rs", 568109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet new RSExportTypePragmaHandler("export_type", RsContext)); 569109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 570109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma rs java_package_name 571109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler( 572109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "rs", new RSJavaPackageNamePragmaHandler("java_package_name", RsContext)); 573109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 57415e44e66adc350adb4fe0533a442092c64333ab5David Gross // For #pragma rs reduce 57515e44e66adc350adb4fe0533a442092c64333ab5David Gross PP.AddPragmaHandler( 5768ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross "rs", new RSReducePragmaHandler(RSExportReduce::KeyReduce, RsContext)); 57715e44e66adc350adb4fe0533a442092c64333ab5David Gross 578109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma rs set_reflect_license 579109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler( 580109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet "rs", new RSReflectLicensePragmaHandler("set_reflect_license", RsContext)); 581109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 582109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma version 583109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler(new RSVersionPragmaHandler("version", RsContext)); 584109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 585109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet // For #pragma rs_fp* 586109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler(new RSPrecisionPragmaHandler("rs_fp_full", RsContext)); 587109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler(new RSPrecisionPragmaHandler("rs_fp_relaxed", RsContext)); 588109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet PP.AddPragmaHandler(new RSPrecisionPragmaHandler("rs_fp_imprecise", RsContext)); 589109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet} 590109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 591109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet 592e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 593