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