slang_rs.cpp revision cf6af6abc1de499920571308b14a27e19cf57097
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
173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_rs.h"
183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
19b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include <cstring>
20b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
21cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang#include "clang/Frontend/FrontendDiagnostic.h"
22cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Sema/SemaDiagnostic.h"
243a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
253a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_rs_backend.h"
263a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_rs_context.h"
273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
283a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changusing namespace slang;
293a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
303c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang#define RS_HEADER_SUFFIX  "rsh"
313c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang
323c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang#define ENUM_RS_HEADER()  \
333c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  RS_HEADER_ENTRY(rs_types) \
343c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  RS_HEADER_ENTRY(rs_cl) \
353c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  RS_HEADER_ENTRY(rs_core) \
363c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  RS_HEADER_ENTRY(rs_math)
373c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang
383c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang#define RS_HEADER_ENTRY(x)  \
393c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  extern const char x ## _header[]; \
403c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  extern unsigned x ## _header_size;
413c250c5d6cbf4123e959a3466990fda9fa50987aZonr ChangENUM_RS_HEADER()
423c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang#undef RS_HEADER_ENTRY
433c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang
44cf6af6abc1de499920571308b14a27e19cf57097Zonr Changbool SlangRS::reflectToJava(const std::string &OutputPathBase,
45cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                            const std::string &OutputPackageName,
46cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                            std::string *RealPackageName) {
47cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  return mRSContext->reflectToJava(OutputPathBase,
48cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                                   OutputPackageName,
49cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                                   getInputFileName(),
50cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                                   getOutputFileName(),
51cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                                   RealPackageName);
52cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang}
53cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
54cf6af6abc1de499920571308b14a27e19cf57097Zonr Changbool SlangRS::generateBitcodeAccessor(const std::string &OutputPathBase,
55cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                                      const std::string &PackageName) {
56cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
57cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
58cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  BCAccessorContext.rsFileName = getInputFileName().c_str();
59cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  BCAccessorContext.bcFileName = getOutputFileName().c_str();
60cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  BCAccessorContext.reflectPath = OutputPathBase.c_str();
61cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  BCAccessorContext.packageName = PackageName.c_str();
62cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  BCAccessorContext.bcStorage = BCST_JAVA_CODE;   // Must be BCST_JAVA_CODE
63cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
64cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  return RSSlangReflectUtils::GenerateBitCodeAccessor(BCAccessorContext);
65cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang}
66cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
67cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
683a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid SlangRS::initDiagnostic() {
693a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  clang::Diagnostic &Diag = getDiagnostics();
70cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  if (Diag.setDiagnosticGroupMapping("implicit-function-declaration",
71cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                                     clang::diag::MAP_ERROR))
72cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    Diag.Report(clang::diag::warn_unknown_warning_option)
73cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        << "implicit-function-declaration";
74cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
753a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  Diag.setDiagnosticMapping(
763a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      clang::diag::ext_typecheck_convert_discards_qualifiers,
773a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      clang::diag::MAP_ERROR);
783a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid SlangRS::initPreprocessor() {
823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  clang::Preprocessor &PP = getPreprocessor();
833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
843c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  std::string RSH;
853c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang#define RS_HEADER_ENTRY(x)  \
863c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  RSH.append("#line 1 \"" #x "."RS_HEADER_SUFFIX"\"\n"); \
873c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  RSH.append(x ## _header, x ## _header_size);
883c250c5d6cbf4123e959a3466990fda9fa50987aZonr ChangENUM_RS_HEADER()
893c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang#undef RS_HEADER_ENTRY
903c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang  PP.setPredefines(RSH);
913c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang
923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
953a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid SlangRS::initASTContext() {
963a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mRSContext = new RSContext(&getPreprocessor(),
973a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                             &getASTContext(),
983a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                             &getTargetInfo());
993a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1023a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changclang::ASTConsumer
1033a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang*SlangRS::createBackend(const clang::CodeGenOptions& CodeGenOpts,
1043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                        llvm::raw_ostream *OS,
1053a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                        Slang::OutputType OT) {
1063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    return new RSBackend(mRSContext,
1073a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                         getDiagnostics(),
1083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                         CodeGenOpts,
1093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                         getTargetOptions(),
1103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                         mPragmas,
1113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                         OS,
1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                         OT,
1133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                         getSourceManager(),
1143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                         mAllowRSPrefix);
1153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
117592a954aae4cb946970b557e94afd5ee453fd57eZonr Changbool SlangRS::IsRSHeaderFile(const char *File) {
118592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#define RS_HEADER_ENTRY(x)  \
119b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (::strcmp(File, #x "."RS_HEADER_SUFFIX) == 0)  \
120592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang    return true;
121592a954aae4cb946970b557e94afd5ee453fd57eZonr ChangENUM_RS_HEADER()
122592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#undef RS_HEADER_ENTRY
123592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang  // Deal with rs_graphics.rsh special case
124b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (::strcmp(File, "rs_graphics."RS_HEADER_SUFFIX) == 0)
125592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang    return true;
126592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang  return false;
127592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang}
128592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang
129b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei LiaoSlangRS::SlangRS(const std::string &Triple, const std::string &CPU,
130b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                 const std::vector<std::string> &Features)
131b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    : Slang(Triple, CPU, Features),
132b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      mRSContext(NULL),
133b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      mAllowRSPrefix(false) {
1343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1363a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
137cf6af6abc1de499920571308b14a27e19cf57097Zonr Changbool SlangRS::compile(
138cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const std::list<std::pair<const char*, const char*> > &IOFiles,
139cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const std::list<std::pair<const char*, const char*> > &DepFiles,
140cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const std::vector<std::string> &IncludePaths,
141cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const std::vector<std::string> &AdditionalDepTargets,
142cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    Slang::OutputType OutputType, BitCodeStorageType BitcodeStorage,
143cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    bool AllowRSPrefix, bool OutputDep,
144cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const std::string &JavaReflectionPathBase,
145cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const std::string &JavaReflectionPackageName) {
146cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  if (IOFiles.empty())
147cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    return true;
148cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
149cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  if (OutputDep && (DepFiles.size() != IOFiles.size())) {
150cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    fprintf(stderr, "SlangRS::compile() : Invalid parameter for output "
151cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                    "dependencies files.\n");
1523a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    return false;
153cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  }
1543a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
155cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::string RealPackageName;
156cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
157cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  const char *InputFile, *OutputFile, *BCOutputFile, *DepOutputFile;
158cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> >::const_iterator
159cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      IOFileIter = IOFiles.begin(), DepFileIter = DepFiles.begin();
160cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
161cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  setIncludePaths(IncludePaths);
162cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  setOutputType(OutputType);
163cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  if (OutputDep)
164cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    setAdditionalDepTargets(AdditionalDepTargets);
165cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
166cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  mAllowRSPrefix = AllowRSPrefix;
167cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
168cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  for (unsigned i = 0, e = IOFiles.size(); i != e; i++) {
169cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    InputFile = IOFileIter->first;
170cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    OutputFile = IOFileIter->second;
171cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
172cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    reset();
173cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
174cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    if (!setInputSource(InputFile))
175cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      return false;
176cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
177cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    if (!setOutput(OutputFile))
178cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      return false;
179cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
180cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    if (OutputDep) {
181cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      BCOutputFile = DepFileIter->first;
182cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      DepOutputFile = DepFileIter->second;
183cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
184cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      setDepTargetBC(BCOutputFile);
185cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
186cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      if (!setDepOutput(DepOutputFile))
187cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        return false;
188cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
189cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      if (generateDepFile() > 0)
190cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        return false;
191cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
192cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      DepFileIter++;
193cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    }
194cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
195cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    if (Slang::compile() > 0)
196cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      return false;
197cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
198cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    if (OutputType != Slang::OT_Dependency) {
199cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      if (!reflectToJava(JavaReflectionPathBase,
200cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         JavaReflectionPackageName,
201cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         &RealPackageName))
202cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        return false;
203cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
204cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      if ((OutputType == Slang::OT_Bitcode) &&
205cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang          (BitcodeStorage == BCST_JAVA_CODE) &&
206cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang          !generateBitcodeAccessor(JavaReflectionPathBase,
207cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                                     RealPackageName.c_str()))
208cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang          return false;
209cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    }
210cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
211cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    IOFileIter++;
212cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  }
213cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
214cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  return true;
2153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr ChangSlangRS::~SlangRS() {
2183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  delete mRSContext;
2193a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
2203a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
221