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::RenderScriptKernelAttr>()) {
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