xref: /freebsd-src/contrib/llvm-project/clang/lib/Sema/HLSLExternalSemaSource.cpp (revision 753f127f3ace09432b2baeffd71a308760641a62)
1*753f127fSDimitry Andric //===--- HLSLExternalSemaSource.cpp - HLSL Sema Source --------------------===//
2*753f127fSDimitry Andric //
3*753f127fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*753f127fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*753f127fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*753f127fSDimitry Andric //
7*753f127fSDimitry Andric //===----------------------------------------------------------------------===//
8*753f127fSDimitry Andric //
9*753f127fSDimitry Andric //
10*753f127fSDimitry Andric //===----------------------------------------------------------------------===//
11*753f127fSDimitry Andric 
12*753f127fSDimitry Andric #include "clang/Sema/HLSLExternalSemaSource.h"
13*753f127fSDimitry Andric #include "clang/AST/ASTContext.h"
14*753f127fSDimitry Andric #include "clang/AST/DeclCXX.h"
15*753f127fSDimitry Andric #include "clang/Basic/AttrKinds.h"
16*753f127fSDimitry Andric #include "clang/Sema/Sema.h"
17*753f127fSDimitry Andric 
18*753f127fSDimitry Andric using namespace clang;
19*753f127fSDimitry Andric 
20*753f127fSDimitry Andric HLSLExternalSemaSource::~HLSLExternalSemaSource() {}
21*753f127fSDimitry Andric 
22*753f127fSDimitry Andric void HLSLExternalSemaSource::InitializeSema(Sema &S) {
23*753f127fSDimitry Andric   SemaPtr = &S;
24*753f127fSDimitry Andric   ASTContext &AST = SemaPtr->getASTContext();
25*753f127fSDimitry Andric   IdentifierInfo &HLSL = AST.Idents.get("hlsl", tok::TokenKind::identifier);
26*753f127fSDimitry Andric   HLSLNamespace =
27*753f127fSDimitry Andric       NamespaceDecl::Create(AST, AST.getTranslationUnitDecl(), false,
28*753f127fSDimitry Andric                             SourceLocation(), SourceLocation(), &HLSL, nullptr);
29*753f127fSDimitry Andric   HLSLNamespace->setImplicit(true);
30*753f127fSDimitry Andric   AST.getTranslationUnitDecl()->addDecl(HLSLNamespace);
31*753f127fSDimitry Andric   defineHLSLVectorAlias();
32*753f127fSDimitry Andric 
33*753f127fSDimitry Andric   // This adds a `using namespace hlsl` directive. In DXC, we don't put HLSL's
34*753f127fSDimitry Andric   // built in types inside a namespace, but we are planning to change that in
35*753f127fSDimitry Andric   // the near future. In order to be source compatible older versions of HLSL
36*753f127fSDimitry Andric   // will need to implicitly use the hlsl namespace. For now in clang everything
37*753f127fSDimitry Andric   // will get added to the namespace, and we can remove the using directive for
38*753f127fSDimitry Andric   // future language versions to match HLSL's evolution.
39*753f127fSDimitry Andric   auto *UsingDecl = UsingDirectiveDecl::Create(
40*753f127fSDimitry Andric       AST, AST.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
41*753f127fSDimitry Andric       NestedNameSpecifierLoc(), SourceLocation(), HLSLNamespace,
42*753f127fSDimitry Andric       AST.getTranslationUnitDecl());
43*753f127fSDimitry Andric 
44*753f127fSDimitry Andric   AST.getTranslationUnitDecl()->addDecl(UsingDecl);
45*753f127fSDimitry Andric }
46*753f127fSDimitry Andric 
47*753f127fSDimitry Andric void HLSLExternalSemaSource::defineHLSLVectorAlias() {
48*753f127fSDimitry Andric   ASTContext &AST = SemaPtr->getASTContext();
49*753f127fSDimitry Andric 
50*753f127fSDimitry Andric   llvm::SmallVector<NamedDecl *> TemplateParams;
51*753f127fSDimitry Andric 
52*753f127fSDimitry Andric   auto *TypeParam = TemplateTypeParmDecl::Create(
53*753f127fSDimitry Andric       AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 0,
54*753f127fSDimitry Andric       &AST.Idents.get("element", tok::TokenKind::identifier), false, false);
55*753f127fSDimitry Andric   TypeParam->setDefaultArgument(AST.getTrivialTypeSourceInfo(AST.FloatTy));
56*753f127fSDimitry Andric 
57*753f127fSDimitry Andric   TemplateParams.emplace_back(TypeParam);
58*753f127fSDimitry Andric 
59*753f127fSDimitry Andric   auto *SizeParam = NonTypeTemplateParmDecl::Create(
60*753f127fSDimitry Andric       AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 1,
61*753f127fSDimitry Andric       &AST.Idents.get("element_count", tok::TokenKind::identifier), AST.IntTy,
62*753f127fSDimitry Andric       false, AST.getTrivialTypeSourceInfo(AST.IntTy));
63*753f127fSDimitry Andric   Expr *LiteralExpr =
64*753f127fSDimitry Andric       IntegerLiteral::Create(AST, llvm::APInt(AST.getIntWidth(AST.IntTy), 4),
65*753f127fSDimitry Andric                              AST.IntTy, SourceLocation());
66*753f127fSDimitry Andric   SizeParam->setDefaultArgument(LiteralExpr);
67*753f127fSDimitry Andric   TemplateParams.emplace_back(SizeParam);
68*753f127fSDimitry Andric 
69*753f127fSDimitry Andric   auto *ParamList =
70*753f127fSDimitry Andric       TemplateParameterList::Create(AST, SourceLocation(), SourceLocation(),
71*753f127fSDimitry Andric                                     TemplateParams, SourceLocation(), nullptr);
72*753f127fSDimitry Andric 
73*753f127fSDimitry Andric   IdentifierInfo &II = AST.Idents.get("vector", tok::TokenKind::identifier);
74*753f127fSDimitry Andric 
75*753f127fSDimitry Andric   QualType AliasType = AST.getDependentSizedExtVectorType(
76*753f127fSDimitry Andric       AST.getTemplateTypeParmType(0, 0, false, TypeParam),
77*753f127fSDimitry Andric       DeclRefExpr::Create(
78*753f127fSDimitry Andric           AST, NestedNameSpecifierLoc(), SourceLocation(), SizeParam, false,
79*753f127fSDimitry Andric           DeclarationNameInfo(SizeParam->getDeclName(), SourceLocation()),
80*753f127fSDimitry Andric           AST.IntTy, VK_LValue),
81*753f127fSDimitry Andric       SourceLocation());
82*753f127fSDimitry Andric 
83*753f127fSDimitry Andric   auto *Record = TypeAliasDecl::Create(AST, HLSLNamespace, SourceLocation(),
84*753f127fSDimitry Andric                                        SourceLocation(), &II,
85*753f127fSDimitry Andric                                        AST.getTrivialTypeSourceInfo(AliasType));
86*753f127fSDimitry Andric   Record->setImplicit(true);
87*753f127fSDimitry Andric 
88*753f127fSDimitry Andric   auto *Template =
89*753f127fSDimitry Andric       TypeAliasTemplateDecl::Create(AST, HLSLNamespace, SourceLocation(),
90*753f127fSDimitry Andric                                     Record->getIdentifier(), ParamList, Record);
91*753f127fSDimitry Andric 
92*753f127fSDimitry Andric   Record->setDescribedAliasTemplate(Template);
93*753f127fSDimitry Andric   Template->setImplicit(true);
94*753f127fSDimitry Andric   Template->setLexicalDeclContext(Record->getDeclContext());
95*753f127fSDimitry Andric   HLSLNamespace->addDecl(Template);
96*753f127fSDimitry Andric }
97