| //===--- HLSLExternalSemaSource.cpp - HLSL Sema Source --------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/Sema/HLSLExternalSemaSource.h" |
| #include "clang/AST/ASTContext.h" |
| #include "clang/AST/DeclCXX.h" |
| #include "clang/Basic/AttrKinds.h" |
| #include "clang/Sema/Sema.h" |
| |
| using namespace clang; |
| |
| HLSLExternalSemaSource::~HLSLExternalSemaSource() {} |
| |
| void HLSLExternalSemaSource::InitializeSema(Sema &S) { |
| SemaPtr = &S; |
| ASTContext &AST = SemaPtr->getASTContext(); |
| IdentifierInfo &HLSL = AST.Idents.get("hlsl", tok::TokenKind::identifier); |
| HLSLNamespace = |
| NamespaceDecl::Create(AST, AST.getTranslationUnitDecl(), false, |
| SourceLocation(), SourceLocation(), &HLSL, nullptr); |
| HLSLNamespace->setImplicit(true); |
| AST.getTranslationUnitDecl()->addDecl(HLSLNamespace); |
| defineHLSLVectorAlias(); |
| |
| // This adds a `using namespace hlsl` directive. In DXC, we don't put HLSL's |
| // built in types inside a namespace, but we are planning to change that in |
| // the near future. In order to be source compatible older versions of HLSL |
| // will need to implicitly use the hlsl namespace. For now in clang everything |
| // will get added to the namespace, and we can remove the using directive for |
| // future language versions to match HLSL's evolution. |
| auto *UsingDecl = UsingDirectiveDecl::Create( |
| AST, AST.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), |
| NestedNameSpecifierLoc(), SourceLocation(), HLSLNamespace, |
| AST.getTranslationUnitDecl()); |
| |
| AST.getTranslationUnitDecl()->addDecl(UsingDecl); |
| } |
| |
| void HLSLExternalSemaSource::defineHLSLVectorAlias() { |
| ASTContext &AST = SemaPtr->getASTContext(); |
| |
| llvm::SmallVector<NamedDecl *> TemplateParams; |
| |
| auto *TypeParam = TemplateTypeParmDecl::Create( |
| AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 0, |
| &AST.Idents.get("element", tok::TokenKind::identifier), false, false); |
| TypeParam->setDefaultArgument(AST.getTrivialTypeSourceInfo(AST.FloatTy)); |
| |
| TemplateParams.emplace_back(TypeParam); |
| |
| auto *SizeParam = NonTypeTemplateParmDecl::Create( |
| AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 1, |
| &AST.Idents.get("element_count", tok::TokenKind::identifier), AST.IntTy, |
| false, AST.getTrivialTypeSourceInfo(AST.IntTy)); |
| Expr *LiteralExpr = |
| IntegerLiteral::Create(AST, llvm::APInt(AST.getIntWidth(AST.IntTy), 4), |
| AST.IntTy, SourceLocation()); |
| SizeParam->setDefaultArgument(LiteralExpr); |
| TemplateParams.emplace_back(SizeParam); |
| |
| auto *ParamList = |
| TemplateParameterList::Create(AST, SourceLocation(), SourceLocation(), |
| TemplateParams, SourceLocation(), nullptr); |
| |
| IdentifierInfo &II = AST.Idents.get("vector", tok::TokenKind::identifier); |
| |
| QualType AliasType = AST.getDependentSizedExtVectorType( |
| AST.getTemplateTypeParmType(0, 0, false, TypeParam), |
| DeclRefExpr::Create( |
| AST, NestedNameSpecifierLoc(), SourceLocation(), SizeParam, false, |
| DeclarationNameInfo(SizeParam->getDeclName(), SourceLocation()), |
| AST.IntTy, VK_LValue), |
| SourceLocation()); |
| |
| auto *Record = TypeAliasDecl::Create(AST, HLSLNamespace, SourceLocation(), |
| SourceLocation(), &II, |
| AST.getTrivialTypeSourceInfo(AliasType)); |
| Record->setImplicit(true); |
| |
| auto *Template = |
| TypeAliasTemplateDecl::Create(AST, HLSLNamespace, SourceLocation(), |
| Record->getIdentifier(), ParamList, Record); |
| |
| Record->setDescribedAliasTemplate(Template); |
| Template->setImplicit(true); |
| Template->setLexicalDeclContext(Record->getDeclContext()); |
| HLSLNamespace->addDecl(Template); |
| } |