123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- //===--- ParseHLSL.cpp - HLSL Parsing -------------------------------------===//
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // ParseHLSL.cpp //
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- // This file is distributed under the University of Illinois Open Source //
- // License. See LICENSE.TXT for details. //
- // //
- // This file implements the HLSLportions of the Parser interfaces. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include "clang/Parse/Parser.h"
- #include "RAIIObjectsForParser.h"
- #include "clang/Basic/CharInfo.h"
- #include "clang/Basic/OperatorKinds.h"
- #include "clang/AST/ASTContext.h"
- #include "clang/AST/DeclTemplate.h"
- #include "clang/Parse/ParseDiagnostic.h"
- #include "clang/Sema/DeclSpec.h"
- #include "clang/Sema/ParsedTemplate.h"
- #include "clang/Sema/PrettyDeclStackTrace.h"
- #include "clang/Sema/Scope.h"
- #include "clang/Sema/SemaDiagnostic.h"
- #include "llvm/ADT/SmallString.h"
- using namespace clang;
- Decl *Parser::ParseCTBuffer(unsigned Context, SourceLocation &DeclEnd,
- ParsedAttributesWithRange &CTBAttrs,
- SourceLocation InlineLoc) {
- assert((Tok.is(tok::kw_cbuffer) || Tok.is(tok::kw_tbuffer)) &&
- "Not a cbuffer or tbuffer!");
- bool isCBuffer = Tok.is(tok::kw_cbuffer);
- SourceLocation BufferLoc = ConsumeToken(); // eat the 'cbuffer or tbuffer'.
- if (!Tok.is(tok::identifier)) {
- Diag(Tok, diag::err_expected) << tok::identifier;
- return nullptr;
- }
- IdentifierInfo *identifier = Tok.getIdentifierInfo();
- SourceLocation identifierLoc = ConsumeToken(); // consume identifier
- std::vector<hlsl::UnusualAnnotation *> hlslAttrs;
- MaybeParseHLSLAttributes(hlslAttrs);
- ParseScope BufferScope(this, Scope::DeclScope);
- BalancedDelimiterTracker T(*this, tok::l_brace);
- if (T.consumeOpen()) {
- Diag(Tok, diag::err_expected) << tok::l_brace;
- return nullptr;
- }
- Decl *decl = Actions.ActOnStartHLSLBuffer(getCurScope(), isCBuffer, BufferLoc,
- identifier, identifierLoc,
- hlslAttrs, T.getOpenLocation());
- // Process potential C++11 attribute specifiers
- Actions.ProcessDeclAttributeList(getCurScope(), decl, CTBAttrs.getList());
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- ParsedAttributesWithRange attrs(AttrFactory);
- MaybeParseCXX11Attributes(attrs);
- MaybeParseHLSLAttributes(attrs);
- MaybeParseMicrosoftAttributes(attrs);
- ParseExternalDeclaration(attrs);
- }
- T.consumeClose();
- DeclEnd = T.getCloseLocation();
- BufferScope.Exit();
- Actions.ActOnFinishHLSLBuffer(decl, DeclEnd);
- return decl;
- }
- Decl *Parser::ParseConstBuffer(unsigned Context, SourceLocation &DeclEnd,
- ParsedAttributesWithRange &attrs,
- SourceLocation InlineLoc) {
- bool isCBuffer = Tok.is(tok::kw_ConstantBuffer);
- assert((isCBuffer || Tok.is(tok::kw_TextureBuffer)) && "Not a ConstantBuffer or TextureBuffer!");
- SourceLocation BufferLoc = ConsumeToken(); // eat the 'ConstantBuffer'.
- if (!Tok.is(tok::less)) {
- Diag(Tok, diag::err_expected) << tok::less;
- return nullptr;
- }
- ConsumeToken(); // eat the <
- ParsingDeclSpec PDS(*this);
- ParseDeclarationSpecifiers(PDS);
- if (!Tok.is(tok::greater)) {
- Diag(Tok, diag::err_expected) << tok::greater;
- return nullptr;
- }
- ConsumeToken(); // eat the >
- PDS.takeAttributesFrom(attrs);
- Actions.ActOnStartHLSLBufferView();
- Parser::DeclGroupPtrTy dcl = ParseDeclGroup(PDS, Declarator::FileContext);
- // Check if the register type is valid
- NamedDecl *namedDecl = cast<NamedDecl>(dcl.get().getSingleDecl());
- ArrayRef<hlsl::UnusualAnnotation*> annotations = namedDecl->getUnusualAnnotations();
- for (hlsl::UnusualAnnotation* annotation : annotations) {
- if (annotation->getKind() == hlsl::UnusualAnnotation::UnusualAnnotationKind::UA_RegisterAssignment) {
- hlsl::RegisterAssignment *regAssignment = (hlsl::RegisterAssignment *)(annotation);
- if (isCBuffer && regAssignment->RegisterType != 'b' && regAssignment->RegisterType != 'B') {
- Diag(namedDecl->getLocation(), diag::err_hlsl_unsupported_cbuffer_register);
- }
- else if (!isCBuffer && regAssignment->RegisterType != 't' && regAssignment->RegisterType != 'T') {
- Diag(namedDecl->getLocation(), diag::err_hlsl_unsupported_tbuffer_register);
- }
- }
- }
- Decl *decl = Actions.ActOnHLSLBufferView(getCurScope(), BufferLoc, dcl, isCBuffer);
- return decl;
- }
- /// ParseHLSLAttributeSpecifier - Parse an HLSL attribute-specifier.
- ///
- /// [HLSL] attribute-specifier:
- /// '[' attribute[opt] ']'
- ///
- /// [HLSL] attribute:
- /// attribute-token attribute-argument-clause[opt]
- ///
- /// [HLSL] attribute-token:
- /// identifier
- ///
- /// [HLSL] attribute-argument-clause:
- /// '(' attribute-params ')'
- ///
- /// [HLSL] attribute-params:
- /// constant-expr
- /// attribute-params ',' constant-expr
- ///
- void Parser::ParseHLSLAttributeSpecifier(ParsedAttributes &attrs,
- SourceLocation *endLoc) {
- assert(getLangOpts().HLSL);
- assert(Tok.is(tok::l_square) && "Not an HLSL attribute list");
- ConsumeBracket();
- llvm::SmallDenseMap<IdentifierInfo *, SourceLocation, 4> SeenAttrs;
- // '[]' is valid.
- if (Tok.is(tok::r_square)) {
- *endLoc = ConsumeBracket();
- return;
- }
- if (!Tok.isAnyIdentifier()) {
- Diag(Tok, diag::err_expected) << tok::identifier;
- SkipUntil(tok::r_square);
- return;
- }
- SourceLocation AttrLoc;
- IdentifierInfo *AttrName = 0;
- AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
- assert(AttrName != nullptr && "already called isAnyIdenfier before");
- // Parse attribute arguments
- if (Tok.is(tok::l_paren)) {
- if (AttrName == &this->Actions.getASTContext().Idents.get("clipplanes")) {
- ArgsVector ArgExprs;
- ConsumeParen();
- for (;;) {
- ExprResult ArgExpr(ParseAssignmentExpression());
- if (ArgExpr.isInvalid()) {
- SkipUntil(tok::r_paren, StopAtSemi);
- return;
- }
- ArgExprs.push_back(ArgExpr.get());
- // Consume a comma and process the next argument.
- if (!Tok.is(tok::comma)) {
- break;
- }
- ConsumeToken();
- }
- SourceLocation EndLoc = Tok.getLocation();
- if (ExpectAndConsume(tok::r_paren, diag::err_expected))
- SkipUntil(tok::r_paren);
- attrs.addNew(AttrName, SourceRange(AttrLoc, EndLoc), nullptr,
- SourceLocation(), ArgExprs.data(), ArgExprs.size(),
- AttributeList::AS_CXX11);
- } else {
- ParseGNUAttributeArgs(AttrName, AttrLoc, attrs, endLoc, nullptr,
- SourceLocation(), AttributeList::AS_CXX11, nullptr);
- }
- } else {
- attrs.addNew(AttrName, AttrLoc, nullptr, SourceLocation(), 0, 0,
- AttributeList::AS_CXX11);
- }
- if (endLoc)
- *endLoc = Tok.getLocation();
- if (ExpectAndConsume(tok::r_square, diag::err_expected))
- SkipUntil(tok::r_square);
- }
- /// ParseHLSLAttributes - Parse an HLSL attribute-specifier-seq.
- ///
- /// attribute-specifier-seq:
- /// attribute-specifier-seq[opt] attribute-specifier
- void Parser::ParseHLSLAttributes(ParsedAttributesWithRange &attrs,
- SourceLocation *endLoc) {
- assert(getLangOpts().HLSL);
- SourceLocation StartLoc = Tok.getLocation(), Loc;
- if (!endLoc)
- endLoc = &Loc;
- do {
- ParseHLSLAttributeSpecifier(attrs, endLoc);
- } while (Tok.is(tok::l_square));
- attrs.Range = SourceRange(StartLoc, *endLoc);
- }
|