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