97 lines
4.0 KiB
C++
97 lines
4.0 KiB
C++
//===--- 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);
|
|
}
|