@@ -5272,29 +5272,33 @@ auto Parser::parse_static_assert_declaration(DeclarationAST*& yyast) -> bool {
52725272
52735273 expect (TokenKind::T_SEMICOLON, ast->semicolonLoc );
52745274
5275- bool value = false ;
5275+ if (!inTemplate_) {
5276+ // not in a template context
52765277
5277- if (constValue.has_value ()) {
5278- value = visit (to_bool, *constValue);
5279- }
5278+ bool value = false ;
52805279
5281- if (!value && config_.staticAssert ) {
5282- SourceLocation loc = ast->firstSourceLocation ();
5280+ if (constValue.has_value ()) {
5281+ value = visit (to_bool, *constValue);
5282+ }
52835283
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 ();
5284+ if (!value && config_.staticAssert ) {
5285+ SourceLocation loc = ast->firstSourceLocation ();
5286+
5287+ if (!ast->expression || !constValue.has_value ()) {
5288+ parse_error (loc,
5289+ " static assertion expression is not an integral constant "
5290+ " expression" );
5291+ } else {
5292+ if (ast->literalLoc )
5293+ loc = ast->literalLoc ;
5294+ else if (ast->expression )
5295+ ast->expression ->firstSourceLocation ();
52935296
5294- std::string message =
5295- ast->literal ? ast->literal ->value () : " static assert failed" ;
5297+ std::string message =
5298+ ast->literal ? ast->literal ->value () : " static assert failed" ;
52965299
5297- unit->error (loc, std::move (message));
5300+ unit->error (loc, std::move (message));
5301+ }
52985302 }
52995303 }
53005304
@@ -9431,66 +9435,11 @@ auto Parser::parse_class_specifier(
94319435 expect (TokenKind::T_RBRACE, ast->rbraceLoc );
94329436 }
94339437
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 ());
9438+ if (!inTemplate_) {
9439+ auto status = classSymbol->buildClassLayout (control_);
9440+ if (!status.has_value () && config_.checkTypes ) {
9441+ parse_error (classSymbol->location (), status.error ());
94889442 }
9489-
9490- offset = align_to (offset, alignment);
9491-
9492- classSymbol->setAlignment (alignment);
9493- classSymbol->setSizeInBytes (offset);
94949443 }
94959444
94969445 classSymbol->setComplete (true );
@@ -11506,7 +11455,18 @@ void Parser::completePendingFunctionDefinitions() {
1150611455 }
1150711456}
1150811457
11509- void Parser::setScope (Scope* scope) { scope_ = scope; }
11458+ void Parser::setScope (Scope* scope) {
11459+ scope_ = scope;
11460+
11461+ inTemplate_ = false ;
11462+
11463+ for (auto current = scope_; current; current = current->parent ()) {
11464+ if (current->isTemplateParametersScope ()) {
11465+ inTemplate_ = true ;
11466+ break ;
11467+ }
11468+ }
11469+ }
1151011470
1151111471void Parser::setScope (ScopedSymbol* symbol) { setScope (symbol->scope ()); }
1151211472
0 commit comments