bool CheckSpecifier::visit(ClassSpecifierAST *ast) { unsigned sourceLocation = ast->firstToken(); if (ast->name) sourceLocation = ast->name->firstToken(); const Name *className = semantic()->check(ast->name, _scope); Class *klass = control()->newClass(sourceLocation, className); klass->setStartOffset(tokenAt(ast->firstToken()).offset); klass->setEndOffset(tokenAt(ast->lastToken()).offset); ast->symbol = klass; unsigned classKey = tokenKind(ast->classkey_token); if (classKey == T_CLASS) klass->setClassKey(Class::ClassKey); else if (classKey == T_STRUCT) klass->setClassKey(Class::StructKey); else if (classKey == T_UNION) klass->setClassKey(Class::UnionKey); klass->setVisibility(semantic()->currentVisibility()); _scope->enterSymbol(klass); _fullySpecifiedType.setType(klass); for (BaseSpecifierListAST *it = ast->base_clause_list; it; it = it->next) { BaseSpecifierAST *base = it->value; const Name *baseClassName = semantic()->check(base->name, _scope); BaseClass *baseClass = control()->newBaseClass(ast->firstToken(), baseClassName); base->symbol = baseClass; if (base->virtual_token) baseClass->setVirtual(true); if (base->access_specifier_token) { int accessSpecifier = tokenKind(base->access_specifier_token); int visibility = semantic()->visibilityForAccessSpecifier(accessSpecifier); baseClass->setVisibility(visibility); } klass->addBaseClass(baseClass); } int visibility = semantic()->visibilityForClassKey(classKey); int previousVisibility = semantic()->switchVisibility(visibility); int previousMethodKey = semantic()->switchMethodKey(Function::NormalMethod); DeclarationAST *previousDeclaration = 0; for (DeclarationListAST *it = ast->member_specifier_list; it; it = it->next) { DeclarationAST *declaration = it->value; semantic()->check(declaration, klass->members()); if (previousDeclaration && declaration && declaration->asEmptyDeclaration() != 0 && previousDeclaration->asFunctionDefinition() != 0) translationUnit()->warning(declaration->firstToken(), "unnecessary semicolon after function body"); previousDeclaration = declaration; } (void) semantic()->switchMethodKey(previousMethodKey); (void) semantic()->switchVisibility(previousVisibility); return false; }
bool CheckSpecifier::visit(ClassSpecifierAST *ast) { unsigned sourceLocation = ast->firstToken(); if (ast->name) sourceLocation = ast->name->firstToken(); Name *className = semantic()->check(ast->name, _scope); Class *klass = control()->newClass(sourceLocation, className); klass->setStartOffset(tokenAt(ast->firstToken()).offset); klass->setEndOffset(tokenAt(ast->lastToken()).offset); ast->symbol = klass; unsigned classKey = tokenKind(ast->classkey_token); if (classKey == T_CLASS) klass->setClassKey(Class::ClassKey); else if (classKey == T_STRUCT) klass->setClassKey(Class::StructKey); else if (classKey == T_UNION) klass->setClassKey(Class::UnionKey); klass->setVisibility(semantic()->currentVisibility()); _scope->enterSymbol(klass); _fullySpecifiedType.setType(klass); for (BaseSpecifierAST *base = ast->base_clause; base; base = base->next) { Name *baseClassName = semantic()->check(base->name, _scope); BaseClass *baseClass = control()->newBaseClass(ast->firstToken(), baseClassName); base->symbol = baseClass; if (base->token_virtual) baseClass->setVirtual(true); if (base->token_access_specifier) { int accessSpecifier = tokenKind(base->token_access_specifier); int visibility = semantic()->visibilityForAccessSpecifier(accessSpecifier); baseClass->setVisibility(visibility); } klass->addBaseClass(baseClass); } int visibility = semantic()->visibilityForClassKey(classKey); int previousVisibility = semantic()->switchVisibility(visibility); int previousMethodKey = semantic()->switchMethodKey(Function::NormalMethod); for (DeclarationAST *member = ast->member_specifiers; member; member = member->next) { semantic()->check(member, klass->members()); } (void) semantic()->switchMethodKey(previousMethodKey); (void) semantic()->switchVisibility(previousVisibility); accept(ast->next); return false; }