slang_rs_export_foreach.cpp revision 688e64b2d56e4218c680b9d6523c5de672f55757
1593a894650e81be54173106ec266f0311cebebd3Stephen Hines/* 2593a894650e81be54173106ec266f0311cebebd3Stephen Hines * Copyright 2011, The Android Open Source Project 3593a894650e81be54173106ec266f0311cebebd3Stephen Hines * 4593a894650e81be54173106ec266f0311cebebd3Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 5593a894650e81be54173106ec266f0311cebebd3Stephen Hines * you may not use this file except in compliance with the License. 6593a894650e81be54173106ec266f0311cebebd3Stephen Hines * You may obtain a copy of the License at 7593a894650e81be54173106ec266f0311cebebd3Stephen Hines * 8593a894650e81be54173106ec266f0311cebebd3Stephen Hines * http://www.apache.org/licenses/LICENSE-2.0 9593a894650e81be54173106ec266f0311cebebd3Stephen Hines * 10593a894650e81be54173106ec266f0311cebebd3Stephen Hines * Unless required by applicable law or agreed to in writing, software 11593a894650e81be54173106ec266f0311cebebd3Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 12593a894650e81be54173106ec266f0311cebebd3Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13593a894650e81be54173106ec266f0311cebebd3Stephen Hines * See the License for the specific language governing permissions and 14593a894650e81be54173106ec266f0311cebebd3Stephen Hines * limitations under the License. 15593a894650e81be54173106ec266f0311cebebd3Stephen Hines */ 16593a894650e81be54173106ec266f0311cebebd3Stephen Hines 17593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_export_foreach.h" 18593a894650e81be54173106ec266f0311cebebd3Stephen Hines 19593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include <string> 20593a894650e81be54173106ec266f0311cebebd3Stephen Hines 21593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "clang/AST/ASTContext.h" 22593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "clang/AST/Decl.h" 23b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines#include "clang/AST/TypeLoc.h" 24593a894650e81be54173106ec266f0311cebebd3Stephen Hines 25593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "llvm/DerivedTypes.h" 26593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "llvm/Target/TargetData.h" 27593a894650e81be54173106ec266f0311cebebd3Stephen Hines 28593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_assert.h" 29593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_context.h" 30593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_export_type.h" 31593a894650e81be54173106ec266f0311cebebd3Stephen Hines 32593a894650e81be54173106ec266f0311cebebd3Stephen Hinesnamespace slang { 33593a894650e81be54173106ec266f0311cebebd3Stephen Hines 34b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hinesnamespace { 35b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 36b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hinesstatic void ReportNameError(clang::Diagnostic *Diags, 37b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::ParmVarDecl *PVD) { 38b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines slangAssert(Diags && PVD); 39b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::SourceManager &SM = Diags->getSourceManager(); 40b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 41b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines Diags->Report(clang::FullSourceLoc(PVD->getLocation(), SM), 42b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 43b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines "Duplicate parameter entry (by position/name): '%0'")) 44b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines << PVD->getName(); 45b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines return; 46b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines} 47b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 48b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines} // namespace 49b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 50b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines// This function takes care of additional validation and construction of 51b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines// parameters related to forEach_* reflection. 52b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hinesbool RSExportForEach::validateAndConstructParams( 53b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines RSContext *Context, const clang::FunctionDecl *FD) { 54b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines slangAssert(Context && FD); 55b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines bool valid = true; 56b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines clang::ASTContext &C = Context->getASTContext(); 57b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 58b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 59b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (!isRootRSFunc(FD)) { 60b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines slangAssert(false && "must be called on compute root function!"); 61b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 62b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 63b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines numParams = FD->getNumParams(); 64b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines slangAssert(numParams > 0); 65b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 66b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines // Compute root functions are required to return a void type for now 67b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (FD->getResultType().getCanonicalType() != C.VoidTy) { 68b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines Diags->Report( 69b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines clang::FullSourceLoc(FD->getLocation(), Diags->getSourceManager()), 70b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 71b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines "compute root() is required to return a " 72b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines "void type")); 73b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines valid = false; 74b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 75b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 76b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines // Validate remaining parameter types 77b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines // TODO(all): Add support for LOD/face when we have them 78b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 794ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines size_t i = 0; 804ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(i); 814ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines clang::QualType QT = PVD->getType().getCanonicalType(); 824ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 834ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines // Check for const T1 *in 844ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines if (QT->isPointerType() && QT->getPointeeType().isConstQualified()) { 854ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines mIn = PVD; 864ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines i++; // advance parameter pointer 874ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } 884ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 894ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines // Check for T2 *out 904ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines if (i < numParams) { 914ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines PVD = FD->getParamDecl(i); 924ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines QT = PVD->getType().getCanonicalType(); 934ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines if (QT->isPointerType() && !QT->getPointeeType().isConstQualified()) { 944ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines mOut = PVD; 954ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines i++; // advance parameter pointer 964ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } 974ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } 984ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 994ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines if (!mIn && !mOut) { 1004ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines Diags->Report( 1014ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines clang::FullSourceLoc(FD->getLocation(), 1024ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines Diags->getSourceManager()), 1034ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 1044ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines "Compute root() must have at least one " 1054ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines "parameter for in or out")); 1064ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines valid = false; 1074ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } 1084ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 1094ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines // Check for T3 *usrData 1104ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines if (i < numParams) { 1114ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines PVD = FD->getParamDecl(i); 1124ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines QT = PVD->getType().getCanonicalType(); 1134ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines if (QT->isPointerType() && QT->getPointeeType().isConstQualified()) { 1144ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines mUsrData = PVD; 1154ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines i++; // advance parameter pointer 1164ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } 1174ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } 1184ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 1194ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines while (i < numParams) { 1204ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines PVD = FD->getParamDecl(i); 1214ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines QT = PVD->getType().getCanonicalType(); 1224ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 1234ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines if (QT.getUnqualifiedType() != C.UnsignedIntTy) { 1244ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines Diags->Report( 1254ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines clang::FullSourceLoc(PVD->getLocation(), 1264ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines Diags->getSourceManager()), 1274ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 1284ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines "Unexpected root() parameter '%0' " 1294ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines "of type '%1'")) 1304ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines << PVD->getName() << PVD->getType().getAsString(); 1314ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines valid = false; 1324ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } else { 1334ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines llvm::StringRef ParamName = PVD->getName(); 134b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (ParamName.equals("x")) { 135b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (mX) { 136b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines ReportNameError(Diags, PVD); 137b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines valid = false; 1384ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } else if (mY) { 1394ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines // Can't go back to X after skipping Y 1404ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines ReportNameError(Diags, PVD); 1414ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines valid = false; 142b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } else { 143b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines mX = PVD; 144b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 145b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } else if (ParamName.equals("y")) { 146b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (mY) { 147b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines ReportNameError(Diags, PVD); 148b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines valid = false; 149b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } else { 150b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines mY = PVD; 151b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 152b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } else { 1534ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines if (!mX && !mY) { 154b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines mX = PVD; 155b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } else if (!mY) { 156b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines mY = PVD; 157b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } else { 158b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines Diags->Report( 159b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines clang::FullSourceLoc(PVD->getLocation(), 160b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines Diags->getSourceManager()), 161b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 162b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines "Unexpected root() parameter '%0' " 163b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines "of type '%1'")) 164b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines << PVD->getName() << PVD->getType().getAsString(); 165b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines valid = false; 166b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 167b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 168b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 1694ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 1704ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines i++; 171b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 172b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 1734ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines mMetadataEncoding = 0; 1744ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines if (valid) { 1754ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines // Set up the bitwise metadata encoding for runtime argument passing. 1764ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines mMetadataEncoding |= (mIn ? 0x01 : 0); 1774ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines mMetadataEncoding |= (mOut ? 0x02 : 0); 1784ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines mMetadataEncoding |= (mUsrData ? 0x04 : 0); 1794ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines mMetadataEncoding |= (mX ? 0x08 : 0); 1804ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines mMetadataEncoding |= (mY ? 0x10 : 0); 181b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 182b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 183b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines return valid; 184b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines} 185b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 186593a894650e81be54173106ec266f0311cebebd3Stephen HinesRSExportForEach *RSExportForEach::Create(RSContext *Context, 187593a894650e81be54173106ec266f0311cebebd3Stephen Hines const clang::FunctionDecl *FD) { 188b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines slangAssert(Context && FD); 189593a894650e81be54173106ec266f0311cebebd3Stephen Hines llvm::StringRef Name = FD->getName(); 190b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines RSExportForEach *FE; 191593a894650e81be54173106ec266f0311cebebd3Stephen Hines 192593a894650e81be54173106ec266f0311cebebd3Stephen Hines slangAssert(!Name.empty() && "Function must have a name"); 193593a894650e81be54173106ec266f0311cebebd3Stephen Hines 194b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines FE = new RSExportForEach(Context, Name, FD); 195593a894650e81be54173106ec266f0311cebebd3Stephen Hines 196b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (!FE->validateAndConstructParams(Context, FD)) { 197b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines return NULL; 198593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 199593a894650e81be54173106ec266f0311cebebd3Stephen Hines 200593a894650e81be54173106ec266f0311cebebd3Stephen Hines clang::ASTContext &Ctx = Context->getASTContext(); 201593a894650e81be54173106ec266f0311cebebd3Stephen Hines 202593a894650e81be54173106ec266f0311cebebd3Stephen Hines std::string Id(DUMMY_RS_TYPE_NAME_PREFIX"helper_foreach_param:"); 203b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines Id.append(FE->getName()).append(DUMMY_RS_TYPE_NAME_POSTFIX); 204593a894650e81be54173106ec266f0311cebebd3Stephen Hines 205593a894650e81be54173106ec266f0311cebebd3Stephen Hines // Extract the usrData parameter (if we have one) 206b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (FE->mUsrData) { 207b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::ParmVarDecl *PVD = FE->mUsrData; 208593a894650e81be54173106ec266f0311cebebd3Stephen Hines clang::QualType QT = PVD->getType().getCanonicalType(); 209593a894650e81be54173106ec266f0311cebebd3Stephen Hines slangAssert(QT->isPointerType() && 210593a894650e81be54173106ec266f0311cebebd3Stephen Hines QT->getPointeeType().isConstQualified()); 211593a894650e81be54173106ec266f0311cebebd3Stephen Hines 212593a894650e81be54173106ec266f0311cebebd3Stephen Hines const clang::ASTContext &C = Context->getASTContext(); 213593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (QT->getPointeeType().getCanonicalType().getUnqualifiedType() == 214593a894650e81be54173106ec266f0311cebebd3Stephen Hines C.VoidTy) { 215593a894650e81be54173106ec266f0311cebebd3Stephen Hines // In the case of using const void*, we can't reflect an appopriate 216593a894650e81be54173106ec266f0311cebebd3Stephen Hines // Java type, so we fall back to just reflecting the ain/aout parameters 217b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines FE->mUsrData = NULL; 218593a894650e81be54173106ec266f0311cebebd3Stephen Hines } else { 219b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines clang::RecordDecl *RD = 220b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines clang::RecordDecl::Create(Ctx, clang::TTK_Struct, 221b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines Ctx.getTranslationUnitDecl(), 222b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines clang::SourceLocation(), 223b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines clang::SourceLocation(), 224b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines &Ctx.Idents.get(Id)); 225b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 226593a894650e81be54173106ec266f0311cebebd3Stephen Hines llvm::StringRef ParamName = PVD->getName(); 227593a894650e81be54173106ec266f0311cebebd3Stephen Hines clang::FieldDecl *FD = 228593a894650e81be54173106ec266f0311cebebd3Stephen Hines clang::FieldDecl::Create(Ctx, 229593a894650e81be54173106ec266f0311cebebd3Stephen Hines RD, 230593a894650e81be54173106ec266f0311cebebd3Stephen Hines clang::SourceLocation(), 231593a894650e81be54173106ec266f0311cebebd3Stephen Hines clang::SourceLocation(), 232593a894650e81be54173106ec266f0311cebebd3Stephen Hines PVD->getIdentifier(), 233593a894650e81be54173106ec266f0311cebebd3Stephen Hines QT->getPointeeType(), 234593a894650e81be54173106ec266f0311cebebd3Stephen Hines NULL, 2351688a3c56851f235866d6870c89ddb20650cc030Shih-wei Liao /* BitWidth = */ NULL, 2361688a3c56851f235866d6870c89ddb20650cc030Shih-wei Liao /* Mutable = */ false, 2371688a3c56851f235866d6870c89ddb20650cc030Shih-wei Liao /* HasInit = */ false); 238593a894650e81be54173106ec266f0311cebebd3Stephen Hines RD->addDecl(FD); 239b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines RD->completeDefinition(); 240b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 241b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines // Create an export type iff we have a valid usrData type 242b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines clang::QualType T = Ctx.getTagDeclType(RD); 243b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines slangAssert(!T.isNull()); 244b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 245b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines RSExportType *ET = RSExportType::Create(Context, T.getTypePtr()); 246b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 247b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (ET == NULL) { 248b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines fprintf(stderr, "Failed to export the function %s. There's at least " 249b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines "one parameter whose type is not supported by the " 250b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines "reflection\n", FE->getName().c_str()); 251b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines return NULL; 252b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 253b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 254b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines slangAssert((ET->getClass() == RSExportType::ExportClassRecord) && 255b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines "Parameter packet must be a record"); 256b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 257b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines FE->mParamPacketType = static_cast<RSExportRecordType *>(ET); 258593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 259593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 260593a894650e81be54173106ec266f0311cebebd3Stephen Hines 261b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (FE->mIn) { 262b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::Type *T = FE->mIn->getType().getCanonicalType().getTypePtr(); 263b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines FE->mInType = RSExportType::Create(Context, T); 264b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 265593a894650e81be54173106ec266f0311cebebd3Stephen Hines 266b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (FE->mOut) { 267b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::Type *T = FE->mOut->getType().getCanonicalType().getTypePtr(); 268b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines FE->mOutType = RSExportType::Create(Context, T); 269593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 270593a894650e81be54173106ec266f0311cebebd3Stephen Hines 271b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines return FE; 272593a894650e81be54173106ec266f0311cebebd3Stephen Hines} 273593a894650e81be54173106ec266f0311cebebd3Stephen Hines 274593a894650e81be54173106ec266f0311cebebd3Stephen Hinesbool RSExportForEach::isRSForEachFunc(const clang::FunctionDecl *FD) { 275593a894650e81be54173106ec266f0311cebebd3Stephen Hines // We currently support only compute root() being exported via forEach 276593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (!isRootRSFunc(FD)) { 277593a894650e81be54173106ec266f0311cebebd3Stephen Hines return false; 278593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 279593a894650e81be54173106ec266f0311cebebd3Stephen Hines 280b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines if (FD->getNumParams() == 0) { 281593a894650e81be54173106ec266f0311cebebd3Stephen Hines // Graphics compute function 282593a894650e81be54173106ec266f0311cebebd3Stephen Hines return false; 283593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 284593a894650e81be54173106ec266f0311cebebd3Stephen Hines return true; 285593a894650e81be54173106ec266f0311cebebd3Stephen Hines} 286593a894650e81be54173106ec266f0311cebebd3Stephen Hines 287593a894650e81be54173106ec266f0311cebebd3Stephen Hinesbool RSExportForEach::validateSpecialFuncDecl(clang::Diagnostic *Diags, 288593a894650e81be54173106ec266f0311cebebd3Stephen Hines const clang::FunctionDecl *FD) { 289b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines slangAssert(Diags && FD); 290593a894650e81be54173106ec266f0311cebebd3Stephen Hines bool valid = true; 291593a894650e81be54173106ec266f0311cebebd3Stephen Hines const clang::ASTContext &C = FD->getASTContext(); 292593a894650e81be54173106ec266f0311cebebd3Stephen Hines 293593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (isRootRSFunc(FD)) { 294593a894650e81be54173106ec266f0311cebebd3Stephen Hines unsigned int numParams = FD->getNumParams(); 295593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (numParams == 0) { 296593a894650e81be54173106ec266f0311cebebd3Stephen Hines // Graphics root function, so verify that it returns an int 297593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (FD->getResultType().getCanonicalType() != C.IntTy) { 298593a894650e81be54173106ec266f0311cebebd3Stephen Hines Diags->Report( 299593a894650e81be54173106ec266f0311cebebd3Stephen Hines clang::FullSourceLoc(FD->getLocation(), Diags->getSourceManager()), 300593a894650e81be54173106ec266f0311cebebd3Stephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 301593a894650e81be54173106ec266f0311cebebd3Stephen Hines "root(void) is required to return " 302593a894650e81be54173106ec266f0311cebebd3Stephen Hines "an int for graphics usage")); 303593a894650e81be54173106ec266f0311cebebd3Stephen Hines valid = false; 304593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 305593a894650e81be54173106ec266f0311cebebd3Stephen Hines } else { 306b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines slangAssert(false && 307b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines "Should not call validateSpecialFuncDecl() on compute root()"); 308593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 309688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } else if (isInitRSFunc(FD) || isDtorRSFunc(FD)) { 310593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (FD->getNumParams() != 0) { 311593a894650e81be54173106ec266f0311cebebd3Stephen Hines Diags->Report( 312593a894650e81be54173106ec266f0311cebebd3Stephen Hines clang::FullSourceLoc(FD->getLocation(), Diags->getSourceManager()), 313593a894650e81be54173106ec266f0311cebebd3Stephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 314688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines "%0(void) is required to have no " 315688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines "parameters")) << FD->getName(); 316593a894650e81be54173106ec266f0311cebebd3Stephen Hines valid = false; 317593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 318593a894650e81be54173106ec266f0311cebebd3Stephen Hines 319593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (FD->getResultType().getCanonicalType() != C.VoidTy) { 320593a894650e81be54173106ec266f0311cebebd3Stephen Hines Diags->Report( 321593a894650e81be54173106ec266f0311cebebd3Stephen Hines clang::FullSourceLoc(FD->getLocation(), Diags->getSourceManager()), 322593a894650e81be54173106ec266f0311cebebd3Stephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 323688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines "%0(void) is required to have a void " 324688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines "return type")) << FD->getName(); 325593a894650e81be54173106ec266f0311cebebd3Stephen Hines valid = false; 326593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 327593a894650e81be54173106ec266f0311cebebd3Stephen Hines } else { 328688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines slangAssert(false && "must be called on root, init or .rs.dtor function!"); 329593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 330593a894650e81be54173106ec266f0311cebebd3Stephen Hines 331593a894650e81be54173106ec266f0311cebebd3Stephen Hines return valid; 332593a894650e81be54173106ec266f0311cebebd3Stephen Hines} 333593a894650e81be54173106ec266f0311cebebd3Stephen Hines 334593a894650e81be54173106ec266f0311cebebd3Stephen Hines} // namespace slang 335