@@ -5272,29 +5272,41 @@ auto Parser::parse_static_assert_declaration(DeclarationAST*& yyast) -> bool {
52725272
52735273 expect (TokenKind::T_SEMICOLON, ast->semicolonLoc );
52745274
5275- bool value = false ;
5276-
5277- if (constValue.has_value ()) {
5278- value = visit (to_bool, *constValue);
5275+ bool inTemplate = false ;
5276+ for (auto current = scope_; current; current = current->parent ()) {
5277+ if (current->isTemplateParametersScope ()) {
5278+ inTemplate = true ;
5279+ break ;
5280+ }
52795281 }
52805282
5281- if (!value && config_. staticAssert ) {
5282- SourceLocation loc = ast-> firstSourceLocation ();
5283+ if (!inTemplate ) {
5284+ // not in a template context
52835285
5284- if (!ast->expression || !constValue.has_value ()) {
5285- parse_error (
5286- loc,
5287- " static assertion expression is not an integral constant expression" );
5288- } else {
5289- if (ast->literalLoc )
5290- loc = ast->literalLoc ;
5291- else if (ast->expression )
5292- ast->expression ->firstSourceLocation ();
5286+ bool value = false ;
5287+
5288+ if (constValue.has_value ()) {
5289+ value = visit (to_bool, *constValue);
5290+ }
5291+
5292+ if (!value && config_.staticAssert ) {
5293+ SourceLocation loc = ast->firstSourceLocation ();
5294+
5295+ if (!ast->expression || !constValue.has_value ()) {
5296+ parse_error (loc,
5297+ " static assertion expression is not an integral constant "
5298+ " expression" );
5299+ } else {
5300+ if (ast->literalLoc )
5301+ loc = ast->literalLoc ;
5302+ else if (ast->expression )
5303+ ast->expression ->firstSourceLocation ();
52935304
5294- std::string message =
5295- ast->literal ? ast->literal ->value () : " static assert failed" ;
5305+ std::string message =
5306+ ast->literal ? ast->literal ->value () : " static assert failed" ;
52965307
5297- unit->error (loc, std::move (message));
5308+ unit->error (loc, std::move (message));
5309+ }
52985310 }
52995311 }
53005312
@@ -9431,66 +9443,20 @@ auto Parser::parse_class_specifier(
94319443 expect (TokenKind::T_RBRACE, ast->rbraceLoc );
94329444 }
94339445
9434- if (!is_template (classSymbol)) {
9435- int offset = 0 ;
9436- int alignment = 1 ;
9437-
9438- for (auto base : classSymbol->baseClasses ()) {
9439- auto baseClassSymbol = symbol_cast<ClassSymbol>(base->symbol ());
9440-
9441- if (!baseClassSymbol) {
9442- if (config_.checkTypes ) {
9443- parse_error (base->location (), std::format (" base class '{}' not found" ,
9444- to_string (base->name ())));
9445- }
9446- continue ;
9447- }
9448-
9449- offset = align_to (offset, baseClassSymbol->alignment ());
9450- offset += baseClassSymbol->sizeInBytes ();
9451- alignment = std::max (alignment, baseClassSymbol->alignment ());
9452- }
9453-
9454- for (auto member : classSymbol->scope ()->symbols ()) {
9455- auto field = symbol_cast<FieldSymbol>(member);
9456- if (!field) continue ;
9457- if (field->isStatic ()) continue ;
9458-
9459- if (!field->alignment ()) {
9460- if (config_.checkTypes ) {
9461- parse_error (field->location (),
9462- std::format (" alignment of incomplete type '{}'" ,
9463- to_string (field->type (), field->name ())));
9464- }
9465- continue ;
9466- }
9467-
9468- auto size = control_->memoryLayout ()->sizeOf (field->type ());
9469-
9470- if (!size.has_value ()) {
9471- if (config_.checkTypes ) {
9472- parse_error (field->location (),
9473- std::format (" size of incomplete type '{}'" ,
9474- to_string (field->type (), field->name ())));
9475- }
9476- continue ;
9477- }
9478-
9479- if (classSymbol->isUnion ()) {
9480- offset = std::max (offset, int (size.value ()));
9481- } else {
9482- offset = align_to (offset, field->alignment ());
9483- field->setOffset (offset);
9484- offset += size.value ();
9485- }
9486-
9487- alignment = std::max (alignment, field->alignment ());
9446+ bool inTemplate = false ;
9447+ for (auto current = scope_; current; current = current->parent ()) {
9448+ if (current->isTemplateParametersScope ()) {
9449+ inTemplate = true ;
9450+ break ;
94889451 }
9452+ }
94899453
9490- offset = align_to (offset, alignment);
9491-
9492- classSymbol->setAlignment (alignment);
9493- classSymbol->setSizeInBytes (offset);
9454+ if (!inTemplate) {
9455+ auto _ = classSymbol->buildClassLayout (control_).transform_error (
9456+ [&](const std::string& e) {
9457+ parse_error (classSymbol->location (), e);
9458+ return false ;
9459+ });
94949460 }
94959461
94969462 classSymbol->setComplete (true );
0 commit comments