bool CheckDeclaration::visit(FunctionDefinitionAST *ast) { FullySpecifiedType ty = semantic()->check(ast->decl_specifier_seq, _scope); FullySpecifiedType qualTy = ty.qualifiedType(); Name *name = 0; FullySpecifiedType funTy = semantic()->check(ast->declarator, qualTy, _scope, &name); if (! (funTy && funTy->isFunctionType())) { translationUnit()->error(ast->firstToken(), "expected a function prototype"); return false; } Function *fun = funTy->asFunctionType(); fun->setVirtual(ty.isVirtual()); fun->setStartOffset(tokenAt(ast->firstToken()).offset); fun->setEndOffset(tokenAt(ast->lastToken()).offset); if (ast->declarator) fun->setSourceLocation(ast->declarator->firstToken()); fun->setName(name); fun->setTemplateParameters(_templateParameters); fun->setVisibility(semantic()->currentVisibility()); fun->setMethodKey(semantic()->currentMethodKey()); const bool isQ_SLOT = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT; const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL; if (isQ_SIGNAL) fun->setMethodKey(Function::SignalMethod); else if (isQ_SLOT) fun->setMethodKey(Function::SlotMethod); checkFunctionArguments(fun); ast->symbol = fun; _scope->enterSymbol(fun); if (! semantic()->skipFunctionBodies()) { if (ast->ctor_initializer) { bool looksLikeCtor = false; if (ty.isValid() || ! fun->identity()) looksLikeCtor = false; else if (fun->identity()->isNameId() || fun->identity()->isTemplateNameId()) looksLikeCtor = true; if (! looksLikeCtor) { translationUnit()->error(ast->ctor_initializer->firstToken(), "only constructors take base initializers"); } accept(ast->ctor_initializer); } const int previousVisibility = semantic()->switchVisibility(Symbol::Public); const int previousMethodKey = semantic()->switchMethodKey(Function::NormalMethod); semantic()->check(ast->function_body, fun->members()); semantic()->switchMethodKey(previousMethodKey); semantic()->switchVisibility(previousVisibility); } return false; }
bool CheckDeclaration::visit(SimpleDeclarationAST *ast) { FullySpecifiedType ty = semantic()->check(ast->decl_specifier_seq, _scope); FullySpecifiedType qualTy = ty.qualifiedType(); if (_templateParameters && ty) { if (Class *klass = ty->asClassType()) { klass->setTemplateParameters(_templateParameters); } } if (! ast->declarators && ast->decl_specifier_seq && ! ast->decl_specifier_seq->next) { if (ElaboratedTypeSpecifierAST *elab_type_spec = ast->decl_specifier_seq->asElaboratedTypeSpecifier()) { unsigned sourceLocation = elab_type_spec->firstToken(); if (elab_type_spec->name) sourceLocation = elab_type_spec->name->firstToken(); Name *name = semantic()->check(elab_type_spec->name, _scope); ForwardClassDeclaration *symbol = control()->newForwardClassDeclaration(sourceLocation, name); if (_templateParameters) { symbol->setTemplateParameters(_templateParameters); _templateParameters = 0; } _scope->enterSymbol(symbol); return false; } } const bool isQ_SLOT = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT; const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL; List<Declaration *> **decl_it = &ast->symbols; for (DeclaratorListAST *it = ast->declarators; it; it = it->next) { Name *name = 0; FullySpecifiedType declTy = semantic()->check(it->declarator, qualTy, _scope, &name); unsigned location = locationOfDeclaratorId(it->declarator); if (! location) { if (it->declarator) location = it->declarator->firstToken(); else location = ast->firstToken(); } Function *fun = 0; if (declTy && 0 != (fun = declTy->asFunctionType())) { fun->setSourceLocation(location); fun->setScope(_scope); fun->setName(name); fun->setMethodKey(semantic()->currentMethodKey()); fun->setVirtual(ty.isVirtual()); if (isQ_SIGNAL) fun->setMethodKey(Function::SignalMethod); else if (isQ_SLOT) fun->setMethodKey(Function::SlotMethod); fun->setVisibility(semantic()->currentVisibility()); } else if (semantic()->currentMethodKey() != Function::NormalMethod) { translationUnit()->warning(ast->firstToken(), "expected a function declaration"); } Declaration *symbol = control()->newDeclaration(location, name); symbol->setStartOffset(tokenAt(ast->firstToken()).offset); symbol->setEndOffset(tokenAt(ast->lastToken()).offset); symbol->setType(control()->integerType(IntegerType::Int)); symbol->setType(declTy); if (_templateParameters && it == ast->declarators && ty && ! ty->isClassType()) symbol->setTemplateParameters(_templateParameters); symbol->setVisibility(semantic()->currentVisibility()); if (ty.isFriend()) symbol->setStorage(Symbol::Friend); else if (ty.isRegister()) symbol->setStorage(Symbol::Register); else if (ty.isStatic()) symbol->setStorage(Symbol::Static); else if (ty.isExtern()) symbol->setStorage(Symbol::Extern); else if (ty.isMutable()) symbol->setStorage(Symbol::Mutable); else if (ty.isTypedef()) symbol->setStorage(Symbol::Typedef); if (it->declarator && it->declarator->initializer) { FullySpecifiedType initTy = semantic()->check(it->declarator->initializer, _scope); } *decl_it = new (translationUnit()->memoryPool()) List<Declaration *>(); (*decl_it)->value = symbol; decl_it = &(*decl_it)->next; _scope->enterSymbol(symbol); } return false; }