xref: /llvm-project/clang/lib/Sema/SemaSPIRV.cpp (revision 0fe8e70c6609ff86cd40fbb45a85a8ed04c153c2)
1 //===- SemaSPIRV.cpp - Semantic Analysis for SPIRV constructs--------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // This implements Semantic Analysis for SPIRV constructs.
9 //===----------------------------------------------------------------------===//
10 
11 #include "clang/Sema/SemaSPIRV.h"
12 #include "clang/Basic/TargetBuiltins.h"
13 #include "clang/Sema/Sema.h"
14 
15 namespace clang {
16 
17 SemaSPIRV::SemaSPIRV(Sema &S) : SemaBase(S) {}
18 
19 bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID,
20                                               CallExpr *TheCall) {
21   switch (BuiltinID) {
22   case SPIRV::BI__builtin_spirv_distance: {
23     if (SemaRef.checkArgCount(TheCall, 2))
24       return true;
25 
26     ExprResult A = TheCall->getArg(0);
27     QualType ArgTyA = A.get()->getType();
28     auto *VTyA = ArgTyA->getAs<VectorType>();
29     if (VTyA == nullptr) {
30       SemaRef.Diag(A.get()->getBeginLoc(),
31                    diag::err_typecheck_convert_incompatible)
32           << ArgTyA
33           << SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1
34           << 0 << 0;
35       return true;
36     }
37 
38     ExprResult B = TheCall->getArg(1);
39     QualType ArgTyB = B.get()->getType();
40     auto *VTyB = ArgTyB->getAs<VectorType>();
41     if (VTyB == nullptr) {
42       SemaRef.Diag(A.get()->getBeginLoc(),
43                    diag::err_typecheck_convert_incompatible)
44           << ArgTyB
45           << SemaRef.Context.getVectorType(ArgTyB, 2, VectorKind::Generic) << 1
46           << 0 << 0;
47       return true;
48     }
49 
50     QualType RetTy = VTyA->getElementType();
51     TheCall->setType(RetTy);
52     break;
53   }
54   case SPIRV::BI__builtin_spirv_length: {
55     if (SemaRef.checkArgCount(TheCall, 1))
56       return true;
57     ExprResult A = TheCall->getArg(0);
58     QualType ArgTyA = A.get()->getType();
59     auto *VTy = ArgTyA->getAs<VectorType>();
60     if (VTy == nullptr) {
61       SemaRef.Diag(A.get()->getBeginLoc(),
62                    diag::err_typecheck_convert_incompatible)
63           << ArgTyA
64           << SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1
65           << 0 << 0;
66       return true;
67     }
68     QualType RetTy = VTy->getElementType();
69     TheCall->setType(RetTy);
70     break;
71   }
72   }
73   return false;
74 }
75 } // namespace clang
76