bool CheckDeclaration::visit(ExceptionDeclarationAST *ast) { FullySpecifiedType ty = semantic()->check(ast->type_specifier, _scope); FullySpecifiedType qualTy = ty.qualifiedType(); Name *name = 0; FullySpecifiedType declTy = semantic()->check(ast->declarator, qualTy, _scope, &name); unsigned location = locationOfDeclaratorId(ast->declarator); if (! location) { if (ast->declarator) location = ast->declarator->firstToken(); else location = ast->firstToken(); } Declaration *symbol = control()->newDeclaration(location, name); symbol->setStartOffset(tokenAt(ast->firstToken()).offset); symbol->setEndOffset(tokenAt(ast->lastToken()).offset); symbol->setType(declTy); _scope->enterSymbol(symbol); return false; }
bool CheckDeclaration::visit(ParameterDeclarationAST *ast) { unsigned sourceLocation = locationOfDeclaratorId(ast->declarator); if (! sourceLocation) { if (ast->declarator) sourceLocation = ast->declarator->firstToken(); else sourceLocation = ast->firstToken(); } const Name *argName = 0; FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope); FullySpecifiedType argTy = semantic()->check(ast->declarator, ty.qualifiedType(), _scope, &argName); FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope); Argument *arg = control()->newArgument(sourceLocation, argName); ast->symbol = arg; if (ast->expression) { unsigned startOfExpression = ast->expression->firstToken(); unsigned endOfExpression = ast->expression->lastToken(); std::string buffer; for (unsigned index = startOfExpression; index != endOfExpression; ++index) { const Token &tk = tokenAt(index); if (tk.whitespace() || tk.newline()) buffer += ' '; buffer += tk.spell(); } const StringLiteral *initializer = control()->findOrInsertStringLiteral(buffer.c_str(), buffer.size()); arg->setInitializer(initializer); } arg->setType(argTy); _scope->enterSymbol(arg); return false; }
bool CheckExpression::visit(TypeIdAST *ast) { FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope); FullySpecifiedType declTy = semantic()->check(ast->declarator, typeSpecTy.qualifiedType(), _scope); _fullySpecifiedType = declTy; return false; }
bool CheckExpression::visit(ConditionAST *ast) { FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope); const Name *name = 0; FullySpecifiedType declTy = semantic()->check(ast->declarator, typeSpecTy.qualifiedType(), _scope, &name); Declaration *decl = control()->newDeclaration(ast->declarator->firstToken(), name); decl->setType(declTy); _scope->enterSymbol(decl); return false; }
bool CheckDeclaration::visit(ParameterDeclarationAST *ast) { unsigned sourceLocation = locationOfDeclaratorId(ast->declarator); if (! sourceLocation) { if (ast->declarator) sourceLocation = ast->declarator->firstToken(); else sourceLocation = ast->firstToken(); } Name *argName = 0; FullySpecifiedType ty = semantic()->check(ast->type_specifier, _scope); FullySpecifiedType argTy = semantic()->check(ast->declarator, ty.qualifiedType(), _scope, &argName); FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope); Argument *arg = control()->newArgument(sourceLocation, argName); ast->symbol = arg; if (ast->expression) arg->setInitializer(true); arg->setType(argTy); _scope->enterSymbol(arg); return false; }
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; }