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