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