1 /* 2 * Copyright 2015, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "slang_rs_special_func.h" 18 19 #include "clang/AST/ASTContext.h" 20 #include "clang/AST/Attr.h" 21 22 #include "slang_assert.h" 23 #include "slang_version.h" 24 25 namespace slang { 26 27 bool RSSpecialFunc::isGraphicsRootRSFunc(unsigned int targetAPI, 28 const clang::FunctionDecl *FD) { 29 if (FD->hasAttr<clang::KernelAttr>()) { 30 return false; 31 } 32 33 if (!FD->getName().equals("root")) { 34 return false; 35 } 36 37 if (FD->getNumParams() == 0) { 38 // Graphics root function 39 return true; 40 } 41 42 // Check for legacy graphics root function (with single parameter). 43 if ((targetAPI < SLANG_ICS_TARGET_API) && (FD->getNumParams() == 1)) { 44 const clang::QualType &IntType = FD->getASTContext().IntTy; 45 if (FD->getReturnType().getCanonicalType() == IntType) { 46 return true; 47 } 48 } 49 50 return false; 51 } 52 53 bool 54 RSSpecialFunc::validateSpecialFuncDecl(unsigned int targetAPI, 55 slang::RSContext *Context, 56 clang::FunctionDecl const *FD) { 57 slangAssert(Context && FD); 58 bool valid = true; 59 const clang::ASTContext &C = FD->getASTContext(); 60 const clang::QualType &IntType = FD->getASTContext().IntTy; 61 62 if (isGraphicsRootRSFunc(targetAPI, FD)) { 63 if ((targetAPI < SLANG_ICS_TARGET_API) && (FD->getNumParams() == 1)) { 64 // Legacy graphics root function 65 const clang::ParmVarDecl *PVD = FD->getParamDecl(0); 66 clang::QualType QT = PVD->getType().getCanonicalType(); 67 if (QT != IntType) { 68 Context->ReportError(PVD->getLocation(), 69 "invalid parameter type for legacy " 70 "graphics root() function: %0") 71 << PVD->getType(); 72 valid = false; 73 } 74 } 75 76 // Graphics root function, so verify that it returns an int 77 if (FD->getReturnType().getCanonicalType() != IntType) { 78 Context->ReportError(FD->getLocation(), 79 "root() is required to return " 80 "an int for graphics usage"); 81 valid = false; 82 } 83 } else if (isInitRSFunc(FD) || isDtorRSFunc(FD)) { 84 if (FD->getNumParams() != 0) { 85 Context->ReportError(FD->getLocation(), 86 "%0(void) is required to have no " 87 "parameters") 88 << FD->getName(); 89 valid = false; 90 } 91 92 if (FD->getReturnType().getCanonicalType() != C.VoidTy) { 93 Context->ReportError(FD->getLocation(), 94 "%0(void) is required to have a void " 95 "return type") 96 << FD->getName(); 97 valid = false; 98 } 99 } else { 100 slangAssert(false && "must be called on root, init or .rs.dtor function!"); 101 } 102 103 return valid; 104 } 105 106 } // namespace slang 107