111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines/* 211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * Copyright 2012, The Android Open Source Project 311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * 411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * you may not use this file except in compliance with the License. 611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * You may obtain a copy of the License at 711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * 811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * http://www.apache.org/licenses/LICENSE-2.0 911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * 1011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * Unless required by applicable law or agreed to in writing, software 1111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 1211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * See the License for the specific language governing permissions and 1411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines * limitations under the License. 1511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines */ 1611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 1711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines#include "slang_rs_check_ast.h" 1811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 1911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines#include "slang_assert.h" 2011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines#include "slang_rs.h" 21089cde338148fbb75825aea4539ccdae8211ffefStephen Hines#include "slang_rs_export_foreach.h" 2211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines#include "slang_rs_export_type.h" 2311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 2411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesnamespace slang { 2511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 2611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesvoid RSCheckAST::VisitStmt(clang::Stmt *S) { 2711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // This function does the actual iteration through all sub-Stmt's within 2811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // a given Stmt. Note that this function is skipped by all of the other 2911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // Visit* functions if we have already found a higher-level match. 3011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 3111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines I != E; 3211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines I++) { 3311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (clang::Stmt *Child = *I) { 3411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines Visit(Child); 3511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 3611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 3711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 3811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 39616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosservoid RSCheckAST::WarnOnSetElementAt(clang::CallExpr *E) { 40616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser clang::FunctionDecl *Decl; 41616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Decl = clang::dyn_cast_or_null<clang::FunctionDecl>(E->getCalleeDecl()); 42616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 43616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (!Decl || Decl->getNameAsString() != std::string("rsSetElementAt")) { 44616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 45616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 46616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 47616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser clang::Expr *Expr; 48616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser clang::ImplicitCastExpr *ImplCast; 49616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Expr = E->getArg(1); 50616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser ImplCast = clang::dyn_cast_or_null<clang::ImplicitCastExpr>(Expr); 51616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 52616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (!ImplCast) { 53616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 54616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 55616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 56616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser const clang::Type *Ty; 57616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser const clang::VectorType *VectorTy; 58616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser const clang::BuiltinType *ElementTy; 59616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Ty = ImplCast->getSubExpr()->getType()->getPointeeType() 60616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser ->getUnqualifiedDesugaredType(); 61616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser VectorTy = clang::dyn_cast_or_null<clang::VectorType>(Ty); 62616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 63616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (VectorTy) { 64616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser ElementTy = clang::dyn_cast_or_null<clang::BuiltinType>( 65616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser VectorTy->getElementType()->getUnqualifiedDesugaredType()); 66616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } else { 67616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser ElementTy = clang::dyn_cast_or_null<clang::BuiltinType>( 68616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Ty->getUnqualifiedDesugaredType()); 69616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 70616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 71616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (!ElementTy) { 72616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 73616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 74616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 75616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser // We only support vectors with 2, 3 or 4 elements. 76616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (VectorTy) { 77616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser switch (VectorTy->getNumElements()) { 78616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser default: 79616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 80616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case 2: 81616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case 3: 82616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case 4: 83616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 84616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 85616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 86616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 87616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser const char *Name; 88616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 89616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser switch (ElementTy->getKind()) { 90616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Float: 91616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "float"; 92616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 93616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Double: 94616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "double"; 95616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 96616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Char_S: 97616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "char"; 98616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 99616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Short: 100616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "short"; 101616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 102616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Int: 103616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "int"; 104616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 105616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Long: 106616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "long"; 107616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 108616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::UChar: 109616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "uchar"; 110616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 111616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::UShort: 112616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "ushort"; 113616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 114616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::UInt: 115616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "uint"; 116616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 117616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::ULong: 118616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "ulong"; 119616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 120616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser default: 121616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 122616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 123616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 124d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::DiagnosticBuilder DiagBuilder = 125d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportWarning(E->getLocStart(), 126d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "untyped rsSetElementAt() can reduce performance. " 127d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Use rsSetElementAt_%0%1() instead."); 128616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser DiagBuilder << Name; 129616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 130616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (VectorTy) { 131616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser DiagBuilder << VectorTy->getNumElements(); 132616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } else { 133616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser DiagBuilder << ""; 134616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 135616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser} 136616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 137616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosservoid RSCheckAST::VisitCallExpr(clang::CallExpr *E) { 138616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser WarnOnSetElementAt(E); 139616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 140616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser for (clang::CallExpr::arg_iterator AI = E->arg_begin(), AE = E->arg_end(); 141616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser AI != AE; ++AI) { 142616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Visit(*AI); 143616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 144616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser} 145616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 14611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesvoid RSCheckAST::ValidateFunctionDecl(clang::FunctionDecl *FD) { 14711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!FD) { 14811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return; 14911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 15011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 151089cde338148fbb75825aea4539ccdae8211ffefStephen Hines if (mIsFilterscript) { 152089cde338148fbb75825aea4539ccdae8211ffefStephen Hines // Validate parameters for Filterscript. 153089cde338148fbb75825aea4539ccdae8211ffefStephen Hines size_t numParams = FD->getNumParams(); 15411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 155ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray clang::QualType resultType = FD->getReturnType().getCanonicalType(); 15611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 157089cde338148fbb75825aea4539ccdae8211ffefStephen Hines // We use FD as our NamedDecl in the case of a bad return type. 158d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (!RSExportType::ValidateType(Context, C, resultType, FD, 159089cde338148fbb75825aea4539ccdae8211ffefStephen Hines FD->getLocStart(), mTargetAPI, 160089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mIsFilterscript)) { 16111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mValid = false; 16211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 163089cde338148fbb75825aea4539ccdae8211ffefStephen Hines 164089cde338148fbb75825aea4539ccdae8211ffefStephen Hines for (size_t i = 0; i < numParams; i++) { 165089cde338148fbb75825aea4539ccdae8211ffefStephen Hines clang::ParmVarDecl *PVD = FD->getParamDecl(i); 166089cde338148fbb75825aea4539ccdae8211ffefStephen Hines clang::QualType QT = PVD->getType().getCanonicalType(); 167d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (!RSExportType::ValidateType(Context, C, QT, PVD, PVD->getLocStart(), 168089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mTargetAPI, mIsFilterscript)) { 169089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mValid = false; 170089cde338148fbb75825aea4539ccdae8211ffefStephen Hines } 171089cde338148fbb75825aea4539ccdae8211ffefStephen Hines } 17211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 17311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 174089cde338148fbb75825aea4539ccdae8211ffefStephen Hines bool saveKernel = mInKernel; 175d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet mInKernel = RSExportForEach::isRSForEachFunc(mTargetAPI, Context, FD); 176089cde338148fbb75825aea4539ccdae8211ffefStephen Hines 17711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (clang::Stmt *Body = FD->getBody()) { 17811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines Visit(Body); 17911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 180089cde338148fbb75825aea4539ccdae8211ffefStephen Hines 181089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mInKernel = saveKernel; 18211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 18311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 18411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 18511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesvoid RSCheckAST::ValidateVarDecl(clang::VarDecl *VD) { 18611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!VD) { 18711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return; 18811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 18911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 190089cde338148fbb75825aea4539ccdae8211ffefStephen Hines clang::QualType QT = VD->getType(); 19111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 19244f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines if (VD->getFormalLinkage() == clang::ExternalLinkage) { 19311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines llvm::StringRef TypeName; 194089cde338148fbb75825aea4539ccdae8211ffefStephen Hines const clang::Type *T = QT.getTypePtr(); 19548d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (!RSExportType::NormalizeType(T, TypeName, Context, VD)) { 19611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mValid = false; 19711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 19811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 19911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 200089cde338148fbb75825aea4539ccdae8211ffefStephen Hines // We don't allow static (non-const) variables within kernels. 201089cde338148fbb75825aea4539ccdae8211ffefStephen Hines if (mInKernel && VD->isStaticLocal()) { 202089cde338148fbb75825aea4539ccdae8211ffefStephen Hines if (!QT.isConstQualified()) { 203d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 204d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet VD->getLocation(), 205d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Non-const static variables are not allowed in kernels: '%0'") 206089cde338148fbb75825aea4539ccdae8211ffefStephen Hines << VD->getName(); 207089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mValid = false; 208089cde338148fbb75825aea4539ccdae8211ffefStephen Hines } 209089cde338148fbb75825aea4539ccdae8211ffefStephen Hines } 210089cde338148fbb75825aea4539ccdae8211ffefStephen Hines 211d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (!RSExportType::ValidateVarDecl(Context, VD, mTargetAPI, mIsFilterscript)) { 21211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mValid = false; 21311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (clang::Expr *Init = VD->getInit()) { 21411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // Only check the initializer if the decl is already ok. 21511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines Visit(Init); 21611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 21711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 21811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 21911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 22011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesvoid RSCheckAST::VisitDeclStmt(clang::DeclStmt *DS) { 22111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!SlangRS::IsLocInRSHeaderFile(DS->getLocStart(), mSM)) { 22211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), 22311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines E = DS->decl_end(); 22411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines I != E; 22511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ++I) { 22611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*I)) { 22711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ValidateVarDecl(VD); 22811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (clang::FunctionDecl *FD = 22911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines llvm::dyn_cast<clang::FunctionDecl>(*I)) { 23011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ValidateFunctionDecl(FD); 23111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 23211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 23311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 23411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 23511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 23611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 237dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hinesvoid RSCheckAST::VisitCastExpr(clang::CastExpr *CE) { 238dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines if (CE->getCastKind() == clang::CK_BitCast) { 239dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines clang::QualType QT = CE->getType(); 240dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines const clang::Type *T = QT.getTypePtr(); 241dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines if (T->isVectorType()) { 242dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines if (llvm::isa<clang::ImplicitCastExpr>(CE)) { 243d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(CE->getExprLoc(), "invalid implicit vector cast"); 244dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines } else { 245d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(CE->getExprLoc(), "invalid vector cast"); 246dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines } 247dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines mValid = false; 248dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines } 249dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines } 250dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines Visit(CE->getSubExpr()); 251dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines} 252dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines 253dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines 25411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesvoid RSCheckAST::VisitExpr(clang::Expr *E) { 25511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // This is where FS checks for code using pointer and/or 64-bit expressions 25611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // (i.e. things like casts). 25711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 25811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // First we skip implicit casts (things like function calls and explicit 25911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // array accesses rely heavily on them and they are valid. 26011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines E = E->IgnoreImpCasts(); 26111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (mIsFilterscript && 26211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines !SlangRS::IsLocInRSHeaderFile(E->getExprLoc(), mSM) && 263d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet !RSExportType::ValidateType(Context, C, E->getType(), NULL, E->getExprLoc(), 26411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mTargetAPI, mIsFilterscript)) { 26511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mValid = false; 26611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 26711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // Only visit sub-expressions if we haven't already seen a violation. 26811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines VisitStmt(E); 26911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 27011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 27111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 27211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 27311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesbool RSCheckAST::Validate() { 27411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 27511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(), 27611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DE = TUDecl->decls_end(); 27711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DI != DE; 27811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DI++) { 27911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!SlangRS::IsLocInRSHeaderFile(DI->getLocStart(), mSM)) { 28011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*DI)) { 28111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ValidateVarDecl(VD); 28211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (clang::FunctionDecl *FD = 28311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines llvm::dyn_cast<clang::FunctionDecl>(*DI)) { 28411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ValidateFunctionDecl(FD); 28511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (clang::Stmt *Body = (*DI)->getBody()) { 28611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines Visit(Body); 28711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 28811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 28911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 29011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 29111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return mValid; 29211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 29311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 29411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} // namespace slang 295