clang 19.0.0git
SemaRISCVVectorLookup.cpp
Go to the documentation of this file.
1//==- SemaRISCVVectorLookup.cpp - Name Lookup for RISC-V Vector Intrinsic -==//
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//
9// This file implements name lookup for RISC-V vector intrinsic.
10//
11//===----------------------------------------------------------------------===//
12
14#include "clang/AST/Decl.h"
18#include "clang/Sema/Lookup.h"
20#include "clang/Sema/Sema.h"
22#include "llvm/ADT/SmallVector.h"
23#include <optional>
24#include <string>
25#include <vector>
26
27using namespace llvm;
28using namespace clang;
29using namespace clang::RISCV;
30
32
33namespace {
34
35// Function definition of a RVV intrinsic.
36struct RVVIntrinsicDef {
37 /// Mapping to which clang built-in function, e.g. __builtin_rvv_vadd.
38 std::string BuiltinName;
39
40 /// Function signature, first element is return type.
41 RVVTypes Signature;
42};
43
44struct RVVOverloadIntrinsicDef {
45 // Indexes of RISCVIntrinsicManagerImpl::IntrinsicList.
47};
48
49} // namespace
50
52#define DECL_SIGNATURE_TABLE
53#include "clang/Basic/riscv_vector_builtin_sema.inc"
54#undef DECL_SIGNATURE_TABLE
55};
56
58#define DECL_SIGNATURE_TABLE
59#include "clang/Basic/riscv_sifive_vector_builtin_sema.inc"
60#undef DECL_SIGNATURE_TABLE
61};
62
64#define DECL_INTRINSIC_RECORDS
65#include "clang/Basic/riscv_vector_builtin_sema.inc"
66#undef DECL_INTRINSIC_RECORDS
67};
68
70#define DECL_INTRINSIC_RECORDS
71#include "clang/Basic/riscv_sifive_vector_builtin_sema.inc"
72#undef DECL_INTRINSIC_RECORDS
73};
74
75// Get subsequence of signature table.
77ProtoSeq2ArrayRef(IntrinsicKind K, uint16_t Index, uint8_t Length) {
78 switch (K) {
79 case IntrinsicKind::RVV:
80 return ArrayRef(&RVVSignatureTable[Index], Length);
81 case IntrinsicKind::SIFIVE_VECTOR:
82 return ArrayRef(&RVSiFiveVectorSignatureTable[Index], Length);
83 }
84 llvm_unreachable("Unhandled IntrinsicKind");
85}
86
87static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type) {
88 QualType QT;
89 switch (Type->getScalarType()) {
90 case ScalarTypeKind::Void:
91 QT = Context.VoidTy;
92 break;
93 case ScalarTypeKind::Size_t:
94 QT = Context.getSizeType();
95 break;
96 case ScalarTypeKind::Ptrdiff_t:
97 QT = Context.getPointerDiffType();
98 break;
99 case ScalarTypeKind::UnsignedLong:
100 QT = Context.UnsignedLongTy;
101 break;
102 case ScalarTypeKind::SignedLong:
103 QT = Context.LongTy;
104 break;
105 case ScalarTypeKind::Boolean:
106 QT = Context.BoolTy;
107 break;
108 case ScalarTypeKind::SignedInteger:
109 QT = Context.getIntTypeForBitwidth(Type->getElementBitwidth(), true);
110 break;
111 case ScalarTypeKind::UnsignedInteger:
112 QT = Context.getIntTypeForBitwidth(Type->getElementBitwidth(), false);
113 break;
114 case ScalarTypeKind::BFloat:
115 QT = Context.BFloat16Ty;
116 break;
117 case ScalarTypeKind::Float:
118 switch (Type->getElementBitwidth()) {
119 case 64:
120 QT = Context.DoubleTy;
121 break;
122 case 32:
123 QT = Context.FloatTy;
124 break;
125 case 16:
126 QT = Context.Float16Ty;
127 break;
128 default:
129 llvm_unreachable("Unsupported floating point width.");
130 }
131 break;
132 case Invalid:
133 case Undefined:
134 llvm_unreachable("Unhandled type.");
135 }
136 if (Type->isVector()) {
137 if (Type->isTuple())
138 QT = Context.getScalableVectorType(QT, *Type->getScale(), Type->getNF());
139 else
140 QT = Context.getScalableVectorType(QT, *Type->getScale());
141 }
142
143 if (Type->isConstant())
144 QT = Context.getConstType(QT);
145
146 // Transform the type to a pointer as the last step, if necessary.
147 if (Type->isPointer())
148 QT = Context.getPointerType(QT);
149
150 return QT;
151}
152
153namespace {
154class RISCVIntrinsicManagerImpl : public sema::RISCVIntrinsicManager {
155private:
156 Sema &S;
157 ASTContext &Context;
158 RVVTypeCache TypeCache;
159 bool ConstructedRISCVVBuiltins;
160 bool ConstructedRISCVSiFiveVectorBuiltins;
161
162 // List of all RVV intrinsic.
163 std::vector<RVVIntrinsicDef> IntrinsicList;
164 // Mapping function name to index of IntrinsicList.
165 StringMap<uint16_t> Intrinsics;
166 // Mapping function name to RVVOverloadIntrinsicDef.
167 StringMap<RVVOverloadIntrinsicDef> OverloadIntrinsics;
168
169
170 // Create RVVIntrinsicDef.
171 void InitRVVIntrinsic(const RVVIntrinsicRecord &Record, StringRef SuffixStr,
172 StringRef OverloadedSuffixStr, bool IsMask,
173 RVVTypes &Types, bool HasPolicy, Policy PolicyAttrs);
174
175 // Create FunctionDecl for a vector intrinsic.
176 void CreateRVVIntrinsicDecl(LookupResult &LR, IdentifierInfo *II,
177 Preprocessor &PP, uint32_t Index,
178 bool IsOverload);
179
180 void ConstructRVVIntrinsics(ArrayRef<RVVIntrinsicRecord> Recs,
181 IntrinsicKind K);
182
183public:
184 RISCVIntrinsicManagerImpl(clang::Sema &S) : S(S), Context(S.Context) {
185 ConstructedRISCVVBuiltins = false;
186 ConstructedRISCVSiFiveVectorBuiltins = false;
187 }
188
189 // Initialize IntrinsicList
190 void InitIntrinsicList() override;
191
192 // Create RISC-V vector intrinsic and insert into symbol table if found, and
193 // return true, otherwise return false.
195 Preprocessor &PP) override;
196};
197} // namespace
198
199void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
201 const TargetInfo &TI = Context.getTargetInfo();
202 static const std::pair<const char *, RVVRequire> FeatureCheckList[] = {
203 {"64bit", RVV_REQ_RV64},
204 {"xsfvcp", RVV_REQ_Xsfvcp},
205 {"xsfvfnrclipxfqf", RVV_REQ_Xsfvfnrclipxfqf},
206 {"xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq},
207 {"xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod},
208 {"xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq},
209 {"zvbb", RVV_REQ_Zvbb},
210 {"zvbc", RVV_REQ_Zvbc},
211 {"zvkb", RVV_REQ_Zvkb},
212 {"zvkg", RVV_REQ_Zvkg},
213 {"zvkned", RVV_REQ_Zvkned},
214 {"zvknha", RVV_REQ_Zvknha},
215 {"zvknhb", RVV_REQ_Zvknhb},
216 {"zvksed", RVV_REQ_Zvksed},
217 {"zvksh", RVV_REQ_Zvksh},
218 {"zvfbfwma", RVV_REQ_Zvfbfwma},
219 {"zvfbfmin", RVV_REQ_Zvfbfmin},
220 {"experimental", RVV_REQ_Experimental}};
221
222 // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
223 // in RISCVVEmitter.cpp.
224 for (auto &Record : Recs) {
225 // Check requirements.
226 if (llvm::any_of(FeatureCheckList, [&](const auto &Item) {
227 return (Record.RequiredExtensions & Item.second) == Item.second &&
228 !TI.hasFeature(Item.first);
229 }))
230 continue;
231
232 // Create Intrinsics for each type and LMUL.
233 BasicType BaseType = BasicType::Unknown;
234 ArrayRef<PrototypeDescriptor> BasicProtoSeq =
235 ProtoSeq2ArrayRef(K, Record.PrototypeIndex, Record.PrototypeLength);
237 ProtoSeq2ArrayRef(K, Record.SuffixIndex, Record.SuffixLength);
238 ArrayRef<PrototypeDescriptor> OverloadedSuffixProto = ProtoSeq2ArrayRef(
239 K, Record.OverloadedSuffixIndex, Record.OverloadedSuffixSize);
240
241 PolicyScheme UnMaskedPolicyScheme =
242 static_cast<PolicyScheme>(Record.UnMaskedPolicyScheme);
243 PolicyScheme MaskedPolicyScheme =
244 static_cast<PolicyScheme>(Record.MaskedPolicyScheme);
245
246 const Policy DefaultPolicy;
247
250 BasicProtoSeq, /*IsMasked=*/false,
251 /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
252 UnMaskedPolicyScheme, DefaultPolicy, Record.IsTuple);
253
255 if (Record.HasMasked)
257 BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
258 Record.HasVL, Record.NF, MaskedPolicyScheme, DefaultPolicy,
259 Record.IsTuple);
260
261 bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
262 bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
263 SmallVector<Policy> SupportedUnMaskedPolicies =
265 SmallVector<Policy> SupportedMaskedPolicies =
267 Record.HasMaskPolicy);
268
269 for (unsigned int TypeRangeMaskShift = 0;
270 TypeRangeMaskShift <= static_cast<unsigned int>(BasicType::MaxOffset);
271 ++TypeRangeMaskShift) {
272 unsigned int BaseTypeI = 1 << TypeRangeMaskShift;
273 BaseType = static_cast<BasicType>(BaseTypeI);
274
275 if ((BaseTypeI & Record.TypeRangeMask) != BaseTypeI)
276 continue;
277
278 if (BaseType == BasicType::Float16) {
279 if ((Record.RequiredExtensions & RVV_REQ_Zvfhmin) == RVV_REQ_Zvfhmin) {
280 if (!TI.hasFeature("zvfhmin"))
281 continue;
282 } else if (!TI.hasFeature("zvfh")) {
283 continue;
284 }
285 }
286
287 // Expanded with different LMUL.
288 for (int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) {
289 if (!(Record.Log2LMULMask & (1 << (Log2LMUL + 3))))
290 continue;
291
292 std::optional<RVVTypes> Types =
293 TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoSeq);
294
295 // Ignored to create new intrinsic if there are any illegal types.
296 if (!Types.has_value())
297 continue;
298
299 std::string SuffixStr = RVVIntrinsic::getSuffixStr(
300 TypeCache, BaseType, Log2LMUL, SuffixProto);
301 std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
302 TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
303
304 // Create non-masked intrinsic.
305 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, false, *Types,
306 UnMaskedHasPolicy, DefaultPolicy);
307
308 // Create non-masked policy intrinsic.
309 if (Record.UnMaskedPolicyScheme != PolicyScheme::SchemeNone) {
310 for (auto P : SupportedUnMaskedPolicies) {
313 BasicProtoSeq, /*IsMasked=*/false,
314 /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
315 UnMaskedPolicyScheme, P, Record.IsTuple);
316 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
317 BaseType, Log2LMUL, Record.NF, PolicyPrototype);
318 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
319 /*IsMask=*/false, *PolicyTypes, UnMaskedHasPolicy,
320 P);
321 }
322 }
323 if (!Record.HasMasked)
324 continue;
325 // Create masked intrinsic.
326 std::optional<RVVTypes> MaskTypes =
327 TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoMaskSeq);
328 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, true,
329 *MaskTypes, MaskedHasPolicy, DefaultPolicy);
330 if (Record.MaskedPolicyScheme == PolicyScheme::SchemeNone)
331 continue;
332 // Create masked policy intrinsic.
333 for (auto P : SupportedMaskedPolicies) {
336 BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
337 Record.HasVL, Record.NF, MaskedPolicyScheme, P,
338 Record.IsTuple);
339 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
340 BaseType, Log2LMUL, Record.NF, PolicyPrototype);
341 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
342 /*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P);
343 }
344 } // End for different LMUL
345 } // End for different TypeRange
346 }
347}
348
349void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
350
351 if (S.DeclareRISCVVBuiltins && !ConstructedRISCVVBuiltins) {
352 ConstructedRISCVVBuiltins = true;
353 ConstructRVVIntrinsics(RVVIntrinsicRecords,
354 IntrinsicKind::RVV);
355 }
357 !ConstructedRISCVSiFiveVectorBuiltins) {
358 ConstructedRISCVSiFiveVectorBuiltins = true;
359 ConstructRVVIntrinsics(RVSiFiveVectorIntrinsicRecords,
360 IntrinsicKind::SIFIVE_VECTOR);
361 }
362}
363
364// Compute name and signatures for intrinsic with practical types.
365void RISCVIntrinsicManagerImpl::InitRVVIntrinsic(
366 const RVVIntrinsicRecord &Record, StringRef SuffixStr,
367 StringRef OverloadedSuffixStr, bool IsMasked, RVVTypes &Signature,
368 bool HasPolicy, Policy PolicyAttrs) {
369 // Function name, e.g. vadd_vv_i32m1.
370 std::string Name = Record.Name;
371 if (!SuffixStr.empty())
372 Name += "_" + SuffixStr.str();
373
374 // Overloaded function name, e.g. vadd.
375 std::string OverloadedName;
376 if (!Record.OverloadedName)
377 OverloadedName = StringRef(Record.Name).split("_").first.str();
378 else
379 OverloadedName = Record.OverloadedName;
380 if (!OverloadedSuffixStr.empty())
381 OverloadedName += "_" + OverloadedSuffixStr.str();
382
383 // clang built-in function name, e.g. __builtin_rvv_vadd.
384 std::string BuiltinName = std::string(Record.Name);
385
386 RVVIntrinsic::updateNamesAndPolicy(IsMasked, HasPolicy, Name, BuiltinName,
387 OverloadedName, PolicyAttrs,
388 Record.HasFRMRoundModeOp);
389
390 // Put into IntrinsicList.
391 uint16_t Index = IntrinsicList.size();
392 assert(IntrinsicList.size() == (size_t)Index &&
393 "Intrinsics indices overflow.");
394 IntrinsicList.push_back({BuiltinName, Signature});
395
396 // Creating mapping to Intrinsics.
397 Intrinsics.insert({Name, Index});
398
399 // Get the RVVOverloadIntrinsicDef.
400 RVVOverloadIntrinsicDef &OverloadIntrinsicDef =
401 OverloadIntrinsics[OverloadedName];
402
403 // And added the index.
404 OverloadIntrinsicDef.Indexes.push_back(Index);
405}
406
407void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(LookupResult &LR,
408 IdentifierInfo *II,
409 Preprocessor &PP,
410 uint32_t Index,
411 bool IsOverload) {
412 ASTContext &Context = S.Context;
413 RVVIntrinsicDef &IDef = IntrinsicList[Index];
414 RVVTypes Sigs = IDef.Signature;
415 size_t SigLength = Sigs.size();
416 RVVType *ReturnType = Sigs[0];
417 QualType RetType = RVVType2Qual(Context, ReturnType);
419 QualType BuiltinFuncType;
420
421 // Skip return type, and convert RVVType to QualType for arguments.
422 for (size_t i = 1; i < SigLength; ++i)
423 ArgTypes.push_back(RVVType2Qual(Context, Sigs[i]));
424
426 Context.getDefaultCallingConvention(false, false, true));
427
428 PI.Variadic = false;
429
430 SourceLocation Loc = LR.getNameLoc();
431 BuiltinFuncType = Context.getFunctionType(RetType, ArgTypes, PI);
433
434 FunctionDecl *RVVIntrinsicDecl = FunctionDecl::Create(
435 Context, Parent, Loc, Loc, II, BuiltinFuncType, /*TInfo=*/nullptr,
437 /*isInlineSpecified*/ false,
438 /*hasWrittenPrototype*/ true);
439
440 // Create Decl objects for each parameter, adding them to the
441 // FunctionDecl.
442 const auto *FP = cast<FunctionProtoType>(BuiltinFuncType);
444 for (unsigned IParm = 0, E = FP->getNumParams(); IParm != E; ++IParm) {
445 ParmVarDecl *Parm =
446 ParmVarDecl::Create(Context, RVVIntrinsicDecl, Loc, Loc, nullptr,
447 FP->getParamType(IParm), nullptr, SC_None, nullptr);
448 Parm->setScopeInfo(0, IParm);
449 ParmList.push_back(Parm);
450 }
451 RVVIntrinsicDecl->setParams(ParmList);
452
453 // Add function attributes.
454 if (IsOverload)
455 RVVIntrinsicDecl->addAttr(OverloadableAttr::CreateImplicit(Context));
456
457 // Setup alias to __builtin_rvv_*
458 IdentifierInfo &IntrinsicII =
459 PP.getIdentifierTable().get("__builtin_rvv_" + IDef.BuiltinName);
460 RVVIntrinsicDecl->addAttr(
461 BuiltinAliasAttr::CreateImplicit(S.Context, &IntrinsicII));
462
463 // Add to symbol table.
464 LR.addDecl(RVVIntrinsicDecl);
465}
466
467bool RISCVIntrinsicManagerImpl::CreateIntrinsicIfFound(LookupResult &LR,
468 IdentifierInfo *II,
469 Preprocessor &PP) {
470 StringRef Name = II->getName();
471 if (!Name.consume_front("__riscv_"))
472 return false;
473
474 // Lookup the function name from the overload intrinsics first.
475 auto OvIItr = OverloadIntrinsics.find(Name);
476 if (OvIItr != OverloadIntrinsics.end()) {
477 const RVVOverloadIntrinsicDef &OvIntrinsicDef = OvIItr->second;
478 for (auto Index : OvIntrinsicDef.Indexes)
479 CreateRVVIntrinsicDecl(LR, II, PP, Index,
480 /*IsOverload*/ true);
481
482 // If we added overloads, need to resolve the lookup result.
483 LR.resolveKind();
484 return true;
485 }
486
487 // Lookup the function name from the intrinsics.
488 auto Itr = Intrinsics.find(Name);
489 if (Itr != Intrinsics.end()) {
490 CreateRVVIntrinsicDecl(LR, II, PP, Itr->second,
491 /*IsOverload*/ false);
492 return true;
493 }
494
495 // It's not an RVV intrinsics.
496 return false;
497}
498
499namespace clang {
500std::unique_ptr<clang::sema::RISCVIntrinsicManager>
502 return std::make_unique<RISCVIntrinsicManagerImpl>(S);
503}
504} // namespace clang
Defines the clang::ASTContext interface.
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
Defines enum values for all the target-independent builtin functions.
llvm::MachO::Record Record
Definition: MachO.h:31
Defines the clang::Preprocessor interface.
static const RVVIntrinsicRecord RVSiFiveVectorIntrinsicRecords[]
static const RVVIntrinsicRecord RVVIntrinsicRecords[]
static const PrototypeDescriptor RVSiFiveVectorSignatureTable[]
static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type)
static ArrayRef< PrototypeDescriptor > ProtoSeq2ArrayRef(IntrinsicKind K, uint16_t Index, uint8_t Length)
static const PrototypeDescriptor RVVSignatureTable[]
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1073
CanQualType LongTy
Definition: ASTContext.h:1100
QualType getScalableVectorType(QualType EltTy, unsigned NumElts, unsigned NumFields=1) const
Return the unique reference to a scalable vector type of the specified element type and scalable numb...
CanQualType FloatTy
Definition: ASTContext.h:1103
CanQualType DoubleTy
Definition: ASTContext.h:1103
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getConstType(QualType T) const
Return the uniqued reference to the type for a const qualified type.
Definition: ASTContext.h:1298
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CanQualType BoolTy
Definition: ASTContext.h:1092
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
CanQualType UnsignedLongTy
Definition: ASTContext.h:1101
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType Float16Ty
Definition: ASTContext.h:1117
CanQualType VoidTy
Definition: ASTContext.h:1091
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1568
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:757
CanQualType BFloat16Ty
Definition: ASTContext.h:1116
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
void addAttr(Attr *A)
Definition: DeclBase.cpp:975
bool isFPConstrained() const
Definition: LangOptions.h:843
Represents a function declaration or definition.
Definition: Decl.h:1971
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, Expr *TrailingRequiresClause=nullptr)
Definition: Decl.h:2161
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Represents the results of name lookup.
Definition: Lookup.h:46
void addDecl(NamedDecl *D)
Add a declaration to these results with its natural access.
Definition: Lookup.h:475
void resolveKind()
Resolves the result kind of the lookup, possibly hiding decls.
Definition: SemaLookup.cpp:484
SourceLocation getNameLoc() const
Gets the location of the identifier.
Definition: Lookup.h:664
Represents a parameter to a function.
Definition: Decl.h:1761
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition: Decl.h:1794
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition: Decl.cpp:2915
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
Definition: Type.h:940
static llvm::SmallVector< Policy > getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy)
static llvm::SmallVector< PrototypeDescriptor > computeBuiltinTypes(llvm::ArrayRef< PrototypeDescriptor > Prototype, bool IsMasked, bool HasMaskedOffOperand, bool HasVL, unsigned NF, PolicyScheme DefaultScheme, Policy PolicyAttrs, bool IsTuple)
static void updateNamesAndPolicy(bool IsMasked, bool HasPolicy, std::string &Name, std::string &BuiltinName, std::string &OverloadedName, Policy &PolicyAttrs, bool HasFRMRoundModeOp)
static std::string getSuffixStr(RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL, llvm::ArrayRef< PrototypeDescriptor > PrototypeDescriptors)
static llvm::SmallVector< Policy > getSupportedUnMaskedPolicies()
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:457
ASTContext & Context
Definition: Sema.h:858
bool DeclareRISCVSiFiveVectorBuiltins
Indicate RISC-V SiFive vector builtin functions enabled or not.
Definition: Sema.h:12821
FPOptions & getCurFPFeatures()
Definition: Sema.h:522
bool DeclareRISCVVBuiltins
Indicate RISC-V vector builtin functions enabled or not.
Definition: Sema.h:12818
Encodes a location in the source.
Exposes information about the current target.
Definition: TargetInfo.h:214
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
Definition: TargetInfo.h:1452
The base class of the type hierarchy.
Definition: Type.h:1813
virtual bool CreateIntrinsicIfFound(LookupResult &LR, IdentifierInfo *II, Preprocessor &PP)=0
Defines the clang::TargetInfo interface.
RISCV builtins.
std::vector< RVVTypePtr > RVVTypes
The JSON file list parser is used to communicate input to InstallAPI.
std::unique_ptr< sema::RISCVIntrinsicManager > CreateRISCVIntrinsicManager(Sema &S)
@ SC_Extern
Definition: Specifiers.h:248
@ SC_None
Definition: Specifiers.h:247
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
Extra information about a function prototype.
Definition: Type.h:4735