slang_rs_check_ast.cpp revision 616854341745b958e0c409cdb6e21abb6225aa21
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 clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 42616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Decl = clang::dyn_cast_or_null<clang::FunctionDecl>(E->getCalleeDecl()); 43616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 44616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (!Decl || Decl->getNameAsString() != std::string("rsSetElementAt")) { 45616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 46616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 47616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 48616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser clang::Expr *Expr; 49616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser clang::ImplicitCastExpr *ImplCast; 50616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Expr = E->getArg(1); 51616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser ImplCast = clang::dyn_cast_or_null<clang::ImplicitCastExpr>(Expr); 52616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 53616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (!ImplCast) { 54616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 55616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 56616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 57616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser const clang::Type *Ty; 58616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser const clang::VectorType *VectorTy; 59616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser const clang::BuiltinType *ElementTy; 60616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Ty = ImplCast->getSubExpr()->getType()->getPointeeType() 61616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser ->getUnqualifiedDesugaredType(); 62616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser VectorTy = clang::dyn_cast_or_null<clang::VectorType>(Ty); 63616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 64616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (VectorTy) { 65616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser ElementTy = clang::dyn_cast_or_null<clang::BuiltinType>( 66616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser VectorTy->getElementType()->getUnqualifiedDesugaredType()); 67616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } else { 68616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser ElementTy = clang::dyn_cast_or_null<clang::BuiltinType>( 69616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Ty->getUnqualifiedDesugaredType()); 70616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 71616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 72616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (!ElementTy) { 73616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 74616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 75616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 76616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser // We only support vectors with 2, 3 or 4 elements. 77616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (VectorTy) { 78616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser switch (VectorTy->getNumElements()) { 79616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser default: 80616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 81616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case 2: 82616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case 3: 83616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case 4: 84616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 85616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 86616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 87616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 88616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser const char *Name; 89616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 90616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser switch (ElementTy->getKind()) { 91616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Float: 92616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "float"; 93616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 94616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Double: 95616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "double"; 96616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 97616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Char_S: 98616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "char"; 99616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 100616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Short: 101616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "short"; 102616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 103616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Int: 104616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "int"; 105616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 106616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::Long: 107616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "long"; 108616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 109616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::UChar: 110616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "uchar"; 111616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 112616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::UShort: 113616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "ushort"; 114616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 115616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::UInt: 116616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "uint"; 117616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 118616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser case clang::BuiltinType::ULong: 119616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Name = "ulong"; 120616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser break; 121616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser default: 122616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 123616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 124616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 125616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser clang::DiagnosticBuilder DiagBuilder = DiagEngine.Report( 126616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser clang::FullSourceLoc(E->getLocStart(), mSM), 127616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser mDiagEngine.getCustomDiagID( clang::DiagnosticsEngine::Warning, 128616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser "untyped rsSetElementAt() can reduce performance. " 129616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser "Use rsSetElementAt_%0%1() instead.")); 130616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser DiagBuilder << Name; 131616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 132616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser if (VectorTy) { 133616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser DiagBuilder << VectorTy->getNumElements(); 134616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } else { 135616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser DiagBuilder << ""; 136616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 137616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 138616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser return; 139616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser} 140616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 141616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosservoid RSCheckAST::VisitCallExpr(clang::CallExpr *E) { 142616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser WarnOnSetElementAt(E); 143616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 144616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser for (clang::CallExpr::arg_iterator AI = E->arg_begin(), AE = E->arg_end(); 145616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser AI != AE; ++AI) { 146616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser Visit(*AI); 147616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser } 148616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser} 149616854341745b958e0c409cdb6e21abb6225aa21Tobias Grosser 15011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesvoid RSCheckAST::ValidateFunctionDecl(clang::FunctionDecl *FD) { 15111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!FD) { 15211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return; 15311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 15411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 155089cde338148fbb75825aea4539ccdae8211ffefStephen Hines if (mIsFilterscript) { 156089cde338148fbb75825aea4539ccdae8211ffefStephen Hines // Validate parameters for Filterscript. 157089cde338148fbb75825aea4539ccdae8211ffefStephen Hines size_t numParams = FD->getNumParams(); 15811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 159089cde338148fbb75825aea4539ccdae8211ffefStephen Hines clang::QualType resultType = FD->getResultType().getCanonicalType(); 16011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 161089cde338148fbb75825aea4539ccdae8211ffefStephen Hines // We use FD as our NamedDecl in the case of a bad return type. 162089cde338148fbb75825aea4539ccdae8211ffefStephen Hines if (!RSExportType::ValidateType(C, resultType, FD, 163089cde338148fbb75825aea4539ccdae8211ffefStephen Hines FD->getLocStart(), mTargetAPI, 164089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mIsFilterscript)) { 16511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mValid = false; 16611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 167089cde338148fbb75825aea4539ccdae8211ffefStephen Hines 168089cde338148fbb75825aea4539ccdae8211ffefStephen Hines for (size_t i = 0; i < numParams; i++) { 169089cde338148fbb75825aea4539ccdae8211ffefStephen Hines clang::ParmVarDecl *PVD = FD->getParamDecl(i); 170089cde338148fbb75825aea4539ccdae8211ffefStephen Hines clang::QualType QT = PVD->getType().getCanonicalType(); 171089cde338148fbb75825aea4539ccdae8211ffefStephen Hines if (!RSExportType::ValidateType(C, QT, PVD, PVD->getLocStart(), 172089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mTargetAPI, mIsFilterscript)) { 173089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mValid = false; 174089cde338148fbb75825aea4539ccdae8211ffefStephen Hines } 175089cde338148fbb75825aea4539ccdae8211ffefStephen Hines } 17611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 17711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 178089cde338148fbb75825aea4539ccdae8211ffefStephen Hines bool saveKernel = mInKernel; 179089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mInKernel = RSExportForEach::isRSForEachFunc(mTargetAPI, &mDiagEngine, FD); 180089cde338148fbb75825aea4539ccdae8211ffefStephen Hines 18111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (clang::Stmt *Body = FD->getBody()) { 18211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines Visit(Body); 18311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 184089cde338148fbb75825aea4539ccdae8211ffefStephen Hines 185089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mInKernel = saveKernel; 18611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 18711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 18811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 18911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesvoid RSCheckAST::ValidateVarDecl(clang::VarDecl *VD) { 19011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!VD) { 19111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return; 19211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 19311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 194089cde338148fbb75825aea4539ccdae8211ffefStephen Hines clang::QualType QT = VD->getType(); 19511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 19644f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines if (VD->getFormalLinkage() == clang::ExternalLinkage) { 19711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines llvm::StringRef TypeName; 198089cde338148fbb75825aea4539ccdae8211ffefStephen Hines const clang::Type *T = QT.getTypePtr(); 19911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!RSExportType::NormalizeType(T, TypeName, &mDiagEngine, VD)) { 20011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mValid = false; 20111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 20211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 20311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 204089cde338148fbb75825aea4539ccdae8211ffefStephen Hines // We don't allow static (non-const) variables within kernels. 205089cde338148fbb75825aea4539ccdae8211ffefStephen Hines if (mInKernel && VD->isStaticLocal()) { 206089cde338148fbb75825aea4539ccdae8211ffefStephen Hines if (!QT.isConstQualified()) { 207089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mDiagEngine.Report( 208089cde338148fbb75825aea4539ccdae8211ffefStephen Hines clang::FullSourceLoc(VD->getLocation(), mSM), 209089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mDiagEngine.getCustomDiagID( 210089cde338148fbb75825aea4539ccdae8211ffefStephen Hines clang::DiagnosticsEngine::Error, 211089cde338148fbb75825aea4539ccdae8211ffefStephen Hines "Non-const static variables are not allowed in kernels: '%0'")) 212089cde338148fbb75825aea4539ccdae8211ffefStephen Hines << VD->getName(); 213089cde338148fbb75825aea4539ccdae8211ffefStephen Hines mValid = false; 214089cde338148fbb75825aea4539ccdae8211ffefStephen Hines } 215089cde338148fbb75825aea4539ccdae8211ffefStephen Hines } 216089cde338148fbb75825aea4539ccdae8211ffefStephen Hines 21711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!RSExportType::ValidateVarDecl(VD, mTargetAPI, mIsFilterscript)) { 21811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mValid = false; 21911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (clang::Expr *Init = VD->getInit()) { 22011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // Only check the initializer if the decl is already ok. 22111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines Visit(Init); 22211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 22311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 22411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 22511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 22611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesvoid RSCheckAST::VisitDeclStmt(clang::DeclStmt *DS) { 22711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!SlangRS::IsLocInRSHeaderFile(DS->getLocStart(), mSM)) { 22811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), 22911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines E = DS->decl_end(); 23011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines I != E; 23111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ++I) { 23211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*I)) { 23311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ValidateVarDecl(VD); 23411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (clang::FunctionDecl *FD = 23511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines llvm::dyn_cast<clang::FunctionDecl>(*I)) { 23611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ValidateFunctionDecl(FD); 23711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 23811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 23911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 24011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 24111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 24211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 243dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hinesvoid RSCheckAST::VisitCastExpr(clang::CastExpr *CE) { 244dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines if (CE->getCastKind() == clang::CK_BitCast) { 245dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines clang::QualType QT = CE->getType(); 246dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines const clang::Type *T = QT.getTypePtr(); 247dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines if (T->isVectorType()) { 248dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 249dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines if (llvm::isa<clang::ImplicitCastExpr>(CE)) { 250dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines DiagEngine.Report( 251dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines clang::FullSourceLoc(CE->getExprLoc(), 252dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines DiagEngine.getSourceManager()), 253dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines DiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error, 254dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines "invalid implicit vector cast")); 255dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines } else { 256dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines DiagEngine.Report( 257dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines clang::FullSourceLoc(CE->getExprLoc(), 258dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines DiagEngine.getSourceManager()), 259dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines DiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error, 260dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines "invalid vector cast")); 261dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines } 262dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines mValid = false; 263dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines } 264dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines } 265dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines Visit(CE->getSubExpr()); 266dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines} 267dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines 268dbb6dc37c377f8dd183f2069a6e27610d1202d98Stephen Hines 26911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesvoid RSCheckAST::VisitExpr(clang::Expr *E) { 27011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // This is where FS checks for code using pointer and/or 64-bit expressions 27111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // (i.e. things like casts). 27211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 27311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // First we skip implicit casts (things like function calls and explicit 27411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // array accesses rely heavily on them and they are valid. 27511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines E = E->IgnoreImpCasts(); 27611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (mIsFilterscript && 27711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines !SlangRS::IsLocInRSHeaderFile(E->getExprLoc(), mSM) && 27811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines !RSExportType::ValidateType(C, E->getType(), NULL, E->getExprLoc(), 27911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mTargetAPI, mIsFilterscript)) { 28011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mValid = false; 28111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 28211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // Only visit sub-expressions if we haven't already seen a violation. 28311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines VisitStmt(E); 28411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 28511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 28611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 28711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 28811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesbool RSCheckAST::Validate() { 28911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 29011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(), 29111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DE = TUDecl->decls_end(); 29211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DI != DE; 29311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DI++) { 29411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!SlangRS::IsLocInRSHeaderFile(DI->getLocStart(), mSM)) { 29511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*DI)) { 29611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ValidateVarDecl(VD); 29711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (clang::FunctionDecl *FD = 29811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines llvm::dyn_cast<clang::FunctionDecl>(*DI)) { 29911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ValidateFunctionDecl(FD); 30011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (clang::Stmt *Body = (*DI)->getBody()) { 30111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines Visit(Body); 30211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 30311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 30411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 30511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 30611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return mValid; 30711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 30811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 30911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} // namespace slang 310