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)
446315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      : RSPragmaHandler(Name, Context) { return; }
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)
566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      : RSPragmaHandler(Name, Context) { return; }
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    return;
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
121537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao};
122537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
123d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsiehclass RSReflectLicensePragmaHandler : public RSPragmaHandler {
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao private:
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  void handleItem(const std::string &Item) {
1263fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines    mContext->addPragma(this->getName(), Item);
1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mContext->setLicenseNote(Item);
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao public:
1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSReflectLicensePragmaHandler(llvm::StringRef Name, RSContext *Context)
1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      : RSPragmaHandler(Name, Context) { return; }
1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
134df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  void HandlePragma(clang::Preprocessor &PP,
135df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao                    clang::PragmaIntroducerKind Introducer,
136df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao                    clang::Token &FirstToken) {
1379d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines    this->handleOptionalStringLiteralParamPragma(PP, FirstToken);
1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
139d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh};
140d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh
14196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hinesclass RSVersionPragmaHandler : public RSPragmaHandler {
14296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines private:
1437aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines  void handleInt(clang::Preprocessor &PP,
1447aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                 clang::Token &Tok,
1457aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                 const int v) {
1467aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    if (v != 1) {
1477aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      PP.Diag(Tok,
1487aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines              PP.getDiagnostics().getCustomDiagID(
1497aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                  clang::DiagnosticsEngine::Error,
1507aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                  "pragma for version in source file must be set to 1"));
1517aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      mContext->setVersion(1);
1527aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      return;
1537aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    }
1543fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines    std::stringstream ss;
1553fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines    ss << v;
1563fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines    mContext->addPragma(this->getName(), ss.str());
15796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    mContext->setVersion(v);
15896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
15996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
16096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines public:
16196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  RSVersionPragmaHandler(llvm::StringRef Name, RSContext *Context)
16296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines      : RSPragmaHandler(Name, Context) { return; }
16396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
164df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  void HandlePragma(clang::Preprocessor &PP,
165df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao                    clang::PragmaIntroducerKind Introducer,
166df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao                    clang::Token &FirstToken) {
16796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    this->handleIntegerParamPragma(PP, FirstToken);
16896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
16996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines};
17096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
171e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace
172462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSPragmaHandler *
1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSPragmaHandler::CreatePragmaExportTypeHandler(RSContext *Context) {
1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return new RSExportTypePragmaHandler("export_type", Context);
176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
177462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSPragmaHandler *
1799ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSPragmaHandler::CreatePragmaJavaPackageNameHandler(RSContext *Context) {
1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return new RSJavaPackageNamePragmaHandler("java_package_name", Context);
181537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao}
182537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSPragmaHandler *
1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSPragmaHandler::CreatePragmaReflectLicenseHandler(RSContext *Context) {
185d09df09ae1e354c4fa595ab421b365ce5cd58cf3Stephen Hines  return new RSReflectLicensePragmaHandler("set_reflect_license", Context);
186d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh}
187d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh
18896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen HinesRSPragmaHandler *
18996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen HinesRSPragmaHandler::CreatePragmaVersionHandler(RSContext *Context) {
19096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  return new RSVersionPragmaHandler("version", Context);
19196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines}
19296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid RSPragmaHandler::handleItemListPragma(clang::Preprocessor &PP,
1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                           clang::Token &FirstToken) {
1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::Token &PragmaToken = FirstToken;
196462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Skip first token, like "export_var"
1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  PP.LexUnexpandedToken(PragmaToken);
199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Now, the current token must be clang::tok::lpara
2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (PragmaToken.isNot(clang::tok::l_paren))
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
204be27482cdeaf08576bc39b72a15d35d13014a636Logan  while (PragmaToken.isNot(clang::tok::eod)) {
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // Lex variable name
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    PP.LexUnexpandedToken(PragmaToken);
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (PragmaToken.is(clang::tok::identifier))
2086315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      this->handleItem(PP.getSpelling(PragmaToken));
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    else
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
211462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
212be27482cdeaf08576bc39b72a15d35d13014a636Logan    slangAssert(PragmaToken.isNot(clang::tok::eod));
213462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    PP.LexUnexpandedToken(PragmaToken);
215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (PragmaToken.isNot(clang::tok::comma))
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
220462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
221462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2226315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrvoid RSPragmaHandler::handleNonParamPragma(clang::Preprocessor &PP,
2236315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                           clang::Token &FirstToken) {
2246315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  clang::Token &PragmaToken = FirstToken;
225c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh
2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Skip first token, like "export_var_all"
2279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  PP.LexUnexpandedToken(PragmaToken);
228c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh
2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Should be end immediately
230be27482cdeaf08576bc39b72a15d35d13014a636Logan  if (PragmaToken.isNot(clang::tok::eod))
2317aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    if (PragmaToken.isNot(clang::tok::r_paren)) {
2327aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      PP.Diag(PragmaToken,
2337aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines              PP.getDiagnostics().getCustomDiagID(
2347aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                  clang::DiagnosticsEngine::Error,
2357aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                  "expected a ')'"));
2367aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      return;
2377aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    }
2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
239c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh}
240c6718b312b793ea76ac6b61479090c33ba9f2ba6Victor Hsieh
2419d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hinesvoid RSPragmaHandler::handleOptionalStringLiteralParamPragma(
2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    clang::Preprocessor &PP, clang::Token &FirstToken) {
2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::Token &PragmaToken = FirstToken;
244d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh
2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Skip first token, like "set_reflect_license"
2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  PP.LexUnexpandedToken(PragmaToken);
247d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Now, the current token must be clang::tok::lpara
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (PragmaToken.isNot(clang::tok::l_paren))
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
251d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // If not ')', eat the following string literal as the license
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  PP.LexUnexpandedToken(PragmaToken);
2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (PragmaToken.isNot(clang::tok::r_paren)) {
2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // Eat the whole string literal
2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    clang::StringLiteralParser StringLiteral(&PragmaToken, 1, PP);
2577aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    if (StringLiteral.hadError) {
2587aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      // Diagnostics will be generated automatically
2597aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      return;
260e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines    } else {
2616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      this->handleItem(std::string(StringLiteral.GetString()));
2627aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    }
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // The current token should be clang::tok::r_para
265d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh    PP.LexUnexpandedToken(PragmaToken);
2667aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    if (PragmaToken.isNot(clang::tok::r_paren)) {
2677aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      PP.Diag(PragmaToken,
2687aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines              PP.getDiagnostics().getCustomDiagID(
2697aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                  clang::DiagnosticsEngine::Error,
2707aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                  "expected a ')'"));
2717aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      return;
2727aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    }
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // If no argument, remove the license
2756315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    this->handleItem("");
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
277d8a0d186a362739f385f1a4af35360d5da69e47bVictor Hsieh}
278e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
27996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hinesvoid RSPragmaHandler::handleIntegerParamPragma(
28096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    clang::Preprocessor &PP, clang::Token &FirstToken) {
28196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  clang::Token &PragmaToken = FirstToken;
28296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
28396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  // Skip first token, like "version"
28496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  PP.LexUnexpandedToken(PragmaToken);
28596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
28696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  // Now, the current token must be clang::tok::lpara
2877aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines  if (PragmaToken.isNot(clang::tok::l_paren)) {
2887aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    // If no argument, set the version to 0
2897aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    this->handleInt(PP, PragmaToken, 0);
29096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    return;
2917aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines  }
29296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  PP.LexUnexpandedToken(PragmaToken);
29396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
29496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (PragmaToken.is(clang::tok::numeric_constant)) {
29596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    clang::NumericLiteralParser NumericLiteral(PragmaToken.getLiteralData(),
29696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines        PragmaToken.getLiteralData() + PragmaToken.getLength(),
29796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines        PragmaToken.getLocation(), PP);
29896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    if (NumericLiteral.hadError) {
2997aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      // Diagnostics will be generated automatically
3007aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      return;
30196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    } else {
30296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines      llvm::APInt Val(32, 0);
30396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines      NumericLiteral.GetIntegerValue(Val);
3047aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines      this->handleInt(PP, PragmaToken, static_cast<int>(Val.getSExtValue()));
30596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    }
30696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    PP.LexUnexpandedToken(PragmaToken);
30796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  } else {
30896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // If no argument, set the version to 0
3097aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    this->handleInt(PP, PragmaToken, 0);
31096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
31196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
31296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (PragmaToken.isNot(clang::tok::r_paren)) {
3137aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    PP.Diag(PragmaToken,
3147aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            PP.getDiagnostics().getCustomDiagID(
3157aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                clang::DiagnosticsEngine::Error,
3167aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines                "expected a ')'"));
3177aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    return;
31896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
31996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
32096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  do {
32196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    PP.LexUnexpandedToken(PragmaToken);
322be27482cdeaf08576bc39b72a15d35d13014a636Logan  } while (PragmaToken.isNot(clang::tok::eod));
32396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines}
32496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
325e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
326