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
isGraphicsRootRSFunc(unsigned int targetAPI,const clang::FunctionDecl * FD)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
validateSpecialFuncDecl(unsigned int targetAPI,slang::RSContext * Context,clang::FunctionDecl const * FD)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