Home | History | Annotate | Download | only in slang
      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