xref: /llvm-project/clang/lib/Sema/SemaSPIRV.cpp (revision 0fe8e70c6609ff86cd40fbb45a85a8ed04c153c2)
121edac25SFarzon Lotfi //===- SemaSPIRV.cpp - Semantic Analysis for SPIRV constructs--------------===//
221edac25SFarzon Lotfi //
321edac25SFarzon Lotfi // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
421edac25SFarzon Lotfi // See https://llvm.org/LICENSE.txt for license information.
521edac25SFarzon Lotfi // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
621edac25SFarzon Lotfi //
721edac25SFarzon Lotfi //===----------------------------------------------------------------------===//
821edac25SFarzon Lotfi // This implements Semantic Analysis for SPIRV constructs.
921edac25SFarzon Lotfi //===----------------------------------------------------------------------===//
1021edac25SFarzon Lotfi 
1121edac25SFarzon Lotfi #include "clang/Sema/SemaSPIRV.h"
1221edac25SFarzon Lotfi #include "clang/Basic/TargetBuiltins.h"
1321edac25SFarzon Lotfi #include "clang/Sema/Sema.h"
1421edac25SFarzon Lotfi 
1521edac25SFarzon Lotfi namespace clang {
1621edac25SFarzon Lotfi 
1721edac25SFarzon Lotfi SemaSPIRV::SemaSPIRV(Sema &S) : SemaBase(S) {}
1821edac25SFarzon Lotfi 
1921edac25SFarzon Lotfi bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID,
2021edac25SFarzon Lotfi                                               CallExpr *TheCall) {
2121edac25SFarzon Lotfi   switch (BuiltinID) {
2221edac25SFarzon Lotfi   case SPIRV::BI__builtin_spirv_distance: {
2321edac25SFarzon Lotfi     if (SemaRef.checkArgCount(TheCall, 2))
2421edac25SFarzon Lotfi       return true;
2521edac25SFarzon Lotfi 
2621edac25SFarzon Lotfi     ExprResult A = TheCall->getArg(0);
2721edac25SFarzon Lotfi     QualType ArgTyA = A.get()->getType();
2821edac25SFarzon Lotfi     auto *VTyA = ArgTyA->getAs<VectorType>();
2921edac25SFarzon Lotfi     if (VTyA == nullptr) {
3021edac25SFarzon Lotfi       SemaRef.Diag(A.get()->getBeginLoc(),
3121edac25SFarzon Lotfi                    diag::err_typecheck_convert_incompatible)
3221edac25SFarzon Lotfi           << ArgTyA
3321edac25SFarzon Lotfi           << SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1
3421edac25SFarzon Lotfi           << 0 << 0;
3521edac25SFarzon Lotfi       return true;
3621edac25SFarzon Lotfi     }
3721edac25SFarzon Lotfi 
3821edac25SFarzon Lotfi     ExprResult B = TheCall->getArg(1);
3921edac25SFarzon Lotfi     QualType ArgTyB = B.get()->getType();
4021edac25SFarzon Lotfi     auto *VTyB = ArgTyB->getAs<VectorType>();
4121edac25SFarzon Lotfi     if (VTyB == nullptr) {
4221edac25SFarzon Lotfi       SemaRef.Diag(A.get()->getBeginLoc(),
4321edac25SFarzon Lotfi                    diag::err_typecheck_convert_incompatible)
4421edac25SFarzon Lotfi           << ArgTyB
4521edac25SFarzon Lotfi           << SemaRef.Context.getVectorType(ArgTyB, 2, VectorKind::Generic) << 1
4621edac25SFarzon Lotfi           << 0 << 0;
4721edac25SFarzon Lotfi       return true;
4821edac25SFarzon Lotfi     }
4921edac25SFarzon Lotfi 
5021edac25SFarzon Lotfi     QualType RetTy = VTyA->getElementType();
5121edac25SFarzon Lotfi     TheCall->setType(RetTy);
5221edac25SFarzon Lotfi     break;
5321edac25SFarzon Lotfi   }
54*eddeb36cSFarzon Lotfi   case SPIRV::BI__builtin_spirv_length: {
55*eddeb36cSFarzon Lotfi     if (SemaRef.checkArgCount(TheCall, 1))
56*eddeb36cSFarzon Lotfi       return true;
57*eddeb36cSFarzon Lotfi     ExprResult A = TheCall->getArg(0);
58*eddeb36cSFarzon Lotfi     QualType ArgTyA = A.get()->getType();
59*eddeb36cSFarzon Lotfi     auto *VTy = ArgTyA->getAs<VectorType>();
60*eddeb36cSFarzon Lotfi     if (VTy == nullptr) {
61*eddeb36cSFarzon Lotfi       SemaRef.Diag(A.get()->getBeginLoc(),
62*eddeb36cSFarzon Lotfi                    diag::err_typecheck_convert_incompatible)
63*eddeb36cSFarzon Lotfi           << ArgTyA
64*eddeb36cSFarzon Lotfi           << SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1
65*eddeb36cSFarzon Lotfi           << 0 << 0;
66*eddeb36cSFarzon Lotfi       return true;
67*eddeb36cSFarzon Lotfi     }
68*eddeb36cSFarzon Lotfi     QualType RetTy = VTy->getElementType();
69*eddeb36cSFarzon Lotfi     TheCall->setType(RetTy);
70*eddeb36cSFarzon Lotfi     break;
71*eddeb36cSFarzon Lotfi   }
7221edac25SFarzon Lotfi   }
7321edac25SFarzon Lotfi   return false;
7421edac25SFarzon Lotfi }
7521edac25SFarzon Lotfi } // namespace clang
76