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; }
void ClassDeclaration::interfaceSemantic(Scope *sc) { InterfaceDeclaration *id = isInterfaceDeclaration(); vtblInterfaces = new BaseClasses(); vtblInterfaces->reserve(interfaces_dim); for (size_t i = 0; i < interfaces_dim; i++) { BaseClass *b = interfaces[i]; // If this is an interface, and it derives from a COM interface, // then this is a COM interface too. if (b->base->isCOMinterface()) com = 1; #if 1 if (b->base->isCPPinterface() && id) id->cpp = 1; #else if (b->base->isCPPinterface()) cpp = 1; #endif vtblInterfaces->push(b); b->copyBaseInterfaces(vtblInterfaces); } }
/*! @brief Constructor @param[in] object Reference to the class instance that is creating this SubMonitor. @param[in] msg String that indicates what the SubMonitor is monitoring, e.g., "Build". @param[in] level The MueLu Level object. @param[in] msgLevel Governs whether information should be printed. @param[in] timerLevel Governs whether timing information should be *gathered*. Setting this to NoTimeReport prevents the creation of timers. TODO: code factorization */ FactoryMonitor(const BaseClass& object, const std::string & msg, const Level & level, MsgType msgLevel = static_cast<MsgType>(Test | Runtime0), MsgType timerLevel = Timings0) : Monitor(object, msg, msgLevel, timerLevel), timerMonitorExclusive_(object, object.ShortClassName() + " : " + msg, timerLevel) { if (IsPrint(TimingsByLevel)) { levelTimeMonitor_ = rcp(new TimeMonitor(object, object.ShortClassName() + ": " + msg + " (total, level=" + Teuchos::Utils::toString(level.GetLevelID()) + ")", timerLevel)); levelTimeMonitorExclusive_ = rcp(new MutuallyExclusiveTimeMonitor<Level>(object, object.ShortClassName() + " " + MUELU_TIMER_AS_STRING + " : " + msg + " (level=" + Teuchos::Utils::toString(level.GetLevelID()) + ")", timerLevel)); } }
int main(int argc, const char *argv[]) { BaseClass bcls; BaseClass bcls2(2.2); bcls.setLength(1.1); std::cout << bcls.getLength() << "\n"; std::cout << bcls2.getLength() << "\n"; return 0; }
bool BaseClass::operator==(const BaseClass& c) const { if(this == &c) return true; return (getNamespaceName() == c.getNamespaceName()) && (getClassName() == c.getClassName()) && (getTemplateName() == c.getTemplateName()); }
int main() { BaseClass b; DerivedClass d; b.showMessage(); d.showMessage(); return 0; }
int main() { SubClass* pSub = new SubClass; BaseClass* bClass = new SubClass; printf("SubClass pointer foo=%s bar=%s\n", pSub->foo(), pSub->bar() ); printf("BaseClass Pointer foo=%s bar=%s\n", bClass->foo(), bClass->bar() ); delete pSub; delete bClass; system("pause"); return 0; }
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; }
//! Constructor PrintMonitor(const BaseClass& object, const std::string& msg, MsgType msgLevel = Runtime0) { // Inherit verbosity from 'object' SetVerbLevel(object.GetVerbLevel()); setOStream(object.getOStream()); // Print description and new indent if (IsPrint(msgLevel)) { GetOStream(msgLevel, 0) << msg << std::endl; tab_ = rcp(new Teuchos::OSTab(getOStream())); } }
// /////////////////////////////////////////////////////////////////////// int main (int argc, char* argv[]) { BaseClass lBaseClass ("BaseClass"); InheritingClass<std::string> lInheritingClass ("InheritingClass"); lInheritingClass.addItem ("Hello "); lInheritingClass.addItem ("Anh Quan"); lInheritingClass.addItem ("!"); std::cout << "Base class: " << lBaseClass.toString() << std::endl; std::cout << "Inheriting class: " << lInheritingClass.toString() << std::endl; return 0; }
int main() { BaseClass *p; BaseClass ob(10); DerivedClass1 derivedObject1(10); DerivedClass2 derivedObject2(10); p = &ob; p->myFunction(); // use BaseClass's myFunction() p = &derivedObject1; p->myFunction(); // use DerivedClass1's myFunction() p = &derivedObject2; p->myFunction(); // use DerivedClass2's myFunction() return 0; }
/* Inherit class * */ void _tinherit() { BaseClass A; A.Print(); DerivedClass B(12,"nameb"); B.insertMap(1,"amd"); B.Print(); BaseClass *BA = &A; BA->Print(); BA->vprint(); BaseClass *BA1 = &B; BA1->Print(); BA1->vprint(); }
/*! @brief Constructor @param[in] object Reference to the class instance that is creating this SubMonitor. @param[in] msg String that indicates what the SubMonitor is monitoring, e.g., "Build" @param[in] level The MueLu Level object. @param[in] msgLevel Governs whether information should be printed. @param[in] timerLevel Governs whether timing information should be *gathered*. Setting this to NoTimeReport prevents the creation of timers. */ SubFactoryMonitor(const BaseClass& object, const std::string & msg, const Level & level, MsgType msgLevel = Runtime1, MsgType timerLevel = Timings1) : SubMonitor(object, msg, msgLevel, timerLevel) { if (IsPrint(TimingsByLevel)) { levelTimeMonitor_ = rcp(new TimeMonitor(object, object.ShortClassName() + ": " + msg + " (sub, total, level=" + Teuchos::Utils::toString(level.GetLevelID()) + ")", timerLevel)); } }
int main(int argc, char* argv[]) { numba a = another_file(); MyClass c; deep_thing d; Space::foo(); Bar::foo(); MACRO; var++; BaseClass* der = new DerivedClass; der->virtualFunc(); delete der; return 1; }
int _tmain(int argc, _TCHAR* argv[]) { cout<<"********BaseClass b = BaseClass()************\n"; BaseClass* b = new BaseClass(); cout<<"Address of Object = "<<(int*)b<<endl; for(int i=0;i<sizeof(BaseClass)/4;++i) cout<<"Memory["<<i<<"] "<<*((int**)(b)+i)<<endl; cout<<"Address of VTable = "<<*(int**)(b)<<endl; for(int i=0;i<3;++i) cout<<"Memory["<<i<<"] "<<*(*(int***)(b)+i)<<endl; cout<<"Address of function1 = "<<**(int***)(b)<<endl; cout<<"Address of function2 = "<<*(*(int***)(b)+1)<<endl; b->function1(); b->function2(); cout<<"\n********SubClass s = SubClass()************\n"; SubClass* s = new SubClass(); //SubClass* s = dynamic_cast<SubClass*>(b1); cout<<"Address of Object = "<<(int*)s<<endl; for(int i=0;i<sizeof(SubClass)/4;++i) cout<<"Memory["<<i<<"] "<<*((int**)(s)+i)<<endl; cout<<"Address of VTable = "<<*(int**)(s)<<endl; for(int i=0;i<3;++i) cout<<"Memory["<<i<<"] "<<*(*(int***)(s)+i)<<endl; cout<<"Address of function1 = "<<**(int***)(s)<<endl; cout<<"Address of function2 = "<<*(*(int***)(s)+1)<<endl; s->function1(); s->function2(); cout<<"\n********Class c = Class()************\n"; Class* c = new Class(); cout<<"Address of object: "<<(int*)c<<endl; //cout<<"Memory[0]: "<<*(int**)(c)<<endl; for(int i=0;i<sizeof(Class)/4;++i) cout<<"Memory["<<i<<"] "<<*((int**)(c)+i)<<endl; c->function1(); return 0; }
/*! @brief Constructor @param[in] object Reference to the class instance that is creating this MutuallyExclusiveTimeMonitor. @param[in] msg String that indicates what the Monitor is monitoring, e.g., "Build" @param[in] timerLevel Governs whether timing information should be *gathered*. Setting this to NoTimeReport prevents the creation of timers. */ MutuallyExclusiveTimeMonitor(const BaseClass& object, const std::string& msg, MsgType timerLevel = Timings0) { // Inherit verbosity from 'object' SetVerbLevel(object.GetVerbLevel()); setOStream(object.getOStream()); if (IsPrint(timerLevel) && /* disable timer if never printed: */ (IsPrint(RuntimeTimings) || (!IsPrint(NoTimeReport)))) { if (!IsPrint(NoTimeReport)) { timer_ = MutuallyExclusiveTime<TagName>::getNewTimer("MueLu: " + msg /*+ " (MutuallyExclusive)" */); } else { timer_ = rcp(new MutuallyExclusiveTime<TagName> ("MueLu: " + msg /*+ " (MutuallyExclusive)" */)); } timer_->start(); timer_->incrementNumCalls(); } }
unsigned ClassDeclaration::baseVtblOffset(BaseClass *bc) { unsigned csymoffset; //printf("ClassDeclaration::baseVtblOffset('%s', bc = %p)\n", toChars(), bc); csymoffset = global.params.isLP64 ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size csymoffset += vtblInterfaces->dim * (4 * Target::ptrsize); for (size_t i = 0; i < vtblInterfaces->dim; i++) { BaseClass *b = (*vtblInterfaces)[i]; if (b == bc) return csymoffset; csymoffset += b->base->vtbl.dim * Target::ptrsize; } // Put out the overriding interface vtbl[]s. // This must be mirrored with ClassDeclaration::baseVtblOffset() //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); ClassDeclaration *cd; FuncDeclarations bvtbl; for (cd = this->baseClass; cd; cd = cd->baseClass) { for (size_t k = 0; k < cd->vtblInterfaces->dim; k++) { BaseClass *bs = (*cd->vtblInterfaces)[k]; if (bs->fillVtbl(this, NULL, 0)) { if (bc == bs) { //printf("\tcsymoffset = x%x\n", csymoffset); return csymoffset; } csymoffset += bs->base->vtbl.dim * Target::ptrsize; } } } return ~0; }
int main() { BaseClass* bc = new BaseClass; InheritedClass* ic = new InheritedClass; cout << bc->getName() << endl; cout << bc->getFunctionName() << endl; cout << ic->getName() << endl; cout << ic->getFunctionName() << endl; //Now the tricky parts InheritedClass* fault_ic = dynamic_cast<InheritedClass*>(bc); assert(fault_ic == nullptr); // BaseClass is not InheritedClass BaseClass* bc_ptr = dynamic_cast<BaseClass*>(ic); assert(bc_ptr != nullptr); // InheritedClass is BaseClass assert(bc_ptr->getName() == ic->getName()); //because of virtual getName still calls the child object assert(bc_ptr->getFunctionName() != ic->getFunctionName()); //but getFunctionName is not virtual getchar(); return 1; }
TimeMonitor(const BaseClass& object, const std::string& msg, MsgType timerLevel = Timings0) { // Inherit verbosity from 'object' SetVerbLevel(object.GetVerbLevel()); setOStream(object.getOStream()); if (IsPrint(timerLevel) && /* disable timer if never printed: */ (IsPrint(RuntimeTimings) || (!IsPrint(NoTimeReport)))) { if (!IsPrint(NoTimeReport)) { // TODO: there is no function to register a timer in Teuchos::TimeMonitor after the creation of the timer. But would be useful... timer_ = Teuchos::TimeMonitor::getNewTimer("MueLu: " + msg); } else { timer_ = rcp(new Teuchos::Time("MueLu: " + msg)); } // Start the timer (this is what is done by Teuchos::TimeMonitor) timer_->start(); timer_->incrementNumCalls(); } }
unsigned baseVtblOffset(ClassDeclaration *cd, BaseClass *bc) { //printf("ClassDeclaration::baseVtblOffset('%s', bc = %p)\n", cd->toChars(), bc); unsigned csymoffset = Target::classinfosize; // must be ClassInfo.size csymoffset += cd->vtblInterfaces->dim * (4 * Target::ptrsize); for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) { BaseClass *b = (*cd->vtblInterfaces)[i]; if (b == bc) return csymoffset; csymoffset += b->sym->vtbl.dim * Target::ptrsize; } // Put out the overriding interface vtbl[]s. // This must be mirrored with ClassDeclaration::baseVtblOffset() //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); ClassDeclaration *cd2; for (cd2 = cd->baseClass; cd2; cd2 = cd2->baseClass) { for (size_t k = 0; k < cd2->vtblInterfaces->dim; k++) { BaseClass *bs = (*cd2->vtblInterfaces)[k]; if (bs->fillVtbl(cd, NULL, 0)) { if (bc == bs) { //printf("\tcsymoffset = x%x\n", csymoffset); return csymoffset; } csymoffset += bs->sym->vtbl.dim * Target::ptrsize; } } } return ~0; }
void BaseClass::copyBaseInterfaces(BaseClasses *vtblInterfaces) { //printf("+copyBaseInterfaces(), %s\n", base->toChars()); // if (baseInterfaces_dim) // return; baseInterfaces_dim = base->interfaces_dim; baseInterfaces = (BaseClass *)mem.calloc(baseInterfaces_dim, sizeof(BaseClass)); //printf("%s.copyBaseInterfaces()\n", base->toChars()); for (size_t i = 0; i < baseInterfaces_dim; i++) { BaseClass *b = &baseInterfaces[i]; BaseClass *b2 = base->interfaces[i]; assert(b2->vtbl.dim == 0); // should not be filled yet memcpy(b, b2, sizeof(BaseClass)); if (i) // single inheritance is i==0 vtblInterfaces->push(b); // only need for M.I. b->copyBaseInterfaces(vtblInterfaces); } //printf("-copyBaseInterfaces\n"); }
//some code block int main() { BaseClass* p = new BaseClass( BaseClass( BaseClass( BaseClass( BaseClass( 1 ) ) ) ) ); std::cout << "value=" << p->getValue() << std::endl; // BaseClass a; //, b, c; // wont compile /* if( (a = *p).increment()) ;*/ Derived d( 10 ); std::cout << "value=" << d.getValue() << std::endl; *p = d; std::cout << "value=" << p->getValue() << std::endl; std::cout << "testing virtual function access..." << std::endl; p->f(); // OK, calls BaseClass::f() BaseClass* q = &d; q->f(); // OK because BaseClass::f() is public, and vptr goes to Derived::f() // wont compile /* Derived* t = &d; t->f(); Derived::f() is private */ delete p; return 0; /* const A a1; A a2( a1 ); return 0;*/ }
/*! @brief Constructor. @param[in] object Reference to the class instance that is creating this Monitor. @param[in] msg String that indicates what the Monitor is monitoring, e.g., "Build" @param[in] msgLevel Governs whether information should be printed. @param[in] timerLevel Governs whether timing information should be *gathered*. Setting this to NoTimeReport prevents the creation of timers. */ Monitor(const BaseClass& object, const std::string & msg, MsgType msgLevel = Runtime0, MsgType timerLevel = Timings0) : printMonitor_(object, msg + " (" + object.description() + ")", msgLevel), timerMonitor_(object, object.ShortClassName() + ": " + msg + " (total)", timerLevel) { }
int main() { BaseClass* ptr = new DerivedClass(); ptr->method(); }
void visit(ClassDeclaration *cd) { //printf("ClassDeclaration::toObjFile('%s')\n", cd->toChars()); if (cd->type->ty == Terror) { cd->error("had semantic errors when compiling"); return; } if (!cd->members) return; if (multiobj && !cd->hasStaticCtorOrDtor()) { obj_append(cd); return; } if (global.params.symdebug) toDebug(cd); assert(!cd->scope); // semantic() should have been run to completion enum_SC scclass = SCglobal; if (cd->isInstantiated()) scclass = SCcomdat; // Put out the members for (size_t i = 0; i < cd->members->dim; i++) { Dsymbol *member = (*cd->members)[i]; /* There might be static ctors in the members, and they cannot * be put in separate obj files. */ member->accept(this); } // Generate C symbols toSymbol(cd); toVtblSymbol(cd); Symbol *sinit = toInitializer(cd); ////////////////////////////////////////////// // Generate static initializer sinit->Sclass = scclass; sinit->Sfl = FLdata; ClassDeclaration_toDt(cd, &sinit->Sdt); out_readonly(sinit); outdata(sinit); ////////////////////////////////////////////// // Put out the TypeInfo genTypeInfo(cd->type, NULL); //toObjFile(cd->type->vtinfo, multiobj); ////////////////////////////////////////////// // Put out the ClassInfo cd->csym->Sclass = scclass; cd->csym->Sfl = FLdata; /* The layout is: { void **vptr; monitor_t monitor; byte[] initializer; // static initialization data char[] name; // class name void *[] vtbl; Interface[] interfaces; ClassInfo *base; // base class void *destructor; void *invariant; // class invariant ClassFlags flags; void *deallocator; OffsetTypeInfo[] offTi; void *defaultConstructor; //const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function void *xgetRTInfo; //TypeInfo typeinfo; } */ dt_t *dt = NULL; unsigned offset = Target::classinfosize; // must be ClassInfo.size if (Type::typeinfoclass) { if (Type::typeinfoclass->structsize != Target::classinfosize) { #ifdef DEBUG printf("Target::classinfosize = x%x, Type::typeinfoclass->structsize = x%x\n", offset, Type::typeinfoclass->structsize); #endif cd->error("mismatch between dmd and object.d or object.di found. Check installation and import paths with -v compiler switch."); fatal(); } } if (Type::typeinfoclass) dtxoff(&dt, toVtblSymbol(Type::typeinfoclass), 0, TYnptr); // vtbl for ClassInfo else dtsize_t(&dt, 0); // BUG: should be an assert() dtsize_t(&dt, 0); // monitor // initializer[] assert(cd->structsize >= 8 || (cd->cpp && cd->structsize >= 4)); dtsize_t(&dt, cd->structsize); // size dtxoff(&dt, sinit, 0, TYnptr); // initializer // name[] const char *name = cd->ident->toChars(); size_t namelen = strlen(name); if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) { name = cd->toPrettyChars(); namelen = strlen(name); } dtsize_t(&dt, namelen); dtabytes(&dt, TYnptr, 0, namelen + 1, name); // vtbl[] dtsize_t(&dt, cd->vtbl.dim); dtxoff(&dt, cd->vtblsym, 0, TYnptr); // interfaces[] dtsize_t(&dt, cd->vtblInterfaces->dim); if (cd->vtblInterfaces->dim) dtxoff(&dt, cd->csym, offset, TYnptr); // (*) else dtsize_t(&dt, 0); // base if (cd->baseClass) dtxoff(&dt, toSymbol(cd->baseClass), 0, TYnptr); else dtsize_t(&dt, 0); // destructor if (cd->dtor) dtxoff(&dt, toSymbol(cd->dtor), 0, TYnptr); else dtsize_t(&dt, 0); // invariant if (cd->inv) dtxoff(&dt, toSymbol(cd->inv), 0, TYnptr); else dtsize_t(&dt, 0); // flags ClassFlags::Type flags = ClassFlags::hasOffTi; if (cd->isCOMclass()) flags |= ClassFlags::isCOMclass; if (cd->isCPPclass()) flags |= ClassFlags::isCPPclass; flags |= ClassFlags::hasGetMembers; flags |= ClassFlags::hasTypeInfo; if (cd->ctor) flags |= ClassFlags::hasCtor; for (ClassDeclaration *pc = cd; pc; pc = pc->baseClass) { if (pc->dtor) { flags |= ClassFlags::hasDtor; break; } } if (cd->isabstract) flags |= ClassFlags::isAbstract; for (ClassDeclaration *pc = cd; pc; pc = pc->baseClass) { if (pc->members) { for (size_t i = 0; i < pc->members->dim; i++) { Dsymbol *sm = (*pc->members)[i]; //printf("sm = %s %s\n", sm->kind(), sm->toChars()); if (sm->hasPointers()) goto L2; } } } flags |= ClassFlags::noPointers; L2: dtsize_t(&dt, flags); // deallocator if (cd->aggDelete) dtxoff(&dt, toSymbol(cd->aggDelete), 0, TYnptr); else dtsize_t(&dt, 0); // offTi[] dtsize_t(&dt, 0); dtsize_t(&dt, 0); // null for now, fix later // defaultConstructor if (cd->defaultCtor && !(cd->defaultCtor->storage_class & STCdisable)) dtxoff(&dt, toSymbol(cd->defaultCtor), 0, TYnptr); else dtsize_t(&dt, 0); // xgetRTInfo if (cd->getRTInfo) Expression_toDt(cd->getRTInfo, &dt); else if (flags & ClassFlags::noPointers) dtsize_t(&dt, 0); else dtsize_t(&dt, 1); //dtxoff(&dt, toSymbol(type->vtinfo), 0, TYnptr); // typeinfo ////////////////////////////////////////////// // Put out (*vtblInterfaces)[]. Must immediately follow csym, because // of the fixup (*) offset += cd->vtblInterfaces->dim * (4 * Target::ptrsize); for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) { BaseClass *b = (*cd->vtblInterfaces)[i]; ClassDeclaration *id = b->sym; /* The layout is: * struct Interface * { * ClassInfo *interface; * void *[] vtbl; * size_t offset; * } */ // Fill in vtbl[] b->fillVtbl(cd, &b->vtbl, 1); dtxoff(&dt, toSymbol(id), 0, TYnptr); // ClassInfo // vtbl[] dtsize_t(&dt, id->vtbl.dim); dtxoff(&dt, cd->csym, offset, TYnptr); dtsize_t(&dt, b->offset); // this offset offset += id->vtbl.dim * Target::ptrsize; } // Put out the (*vtblInterfaces)[].vtbl[] // This must be mirrored with ClassDeclaration::baseVtblOffset() //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces->dim, toChars()); for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) { BaseClass *b = (*cd->vtblInterfaces)[i]; ClassDeclaration *id = b->sym; //printf(" interface[%d] is '%s'\n", i, id->toChars()); size_t j = 0; if (id->vtblOffset()) { // First entry is ClassInfo reference //dtxoff(&dt, toSymbol(id), 0, TYnptr); // First entry is struct Interface reference dtxoff(&dt, cd->csym, Target::classinfosize + i * (4 * Target::ptrsize), TYnptr); j = 1; } assert(id->vtbl.dim == b->vtbl.dim); for (; j < id->vtbl.dim; j++) { assert(j < b->vtbl.dim); #if 0 RootObject *o = b->vtbl[j]; if (o) { printf("o = %p\n", o); assert(o->dyncast() == DYNCAST_DSYMBOL); Dsymbol *s = (Dsymbol *)o; printf("s->kind() = '%s'\n", s->kind()); } #endif FuncDeclaration *fd = b->vtbl[j]; if (fd) dtxoff(&dt, toThunkSymbol(fd, b->offset), 0, TYnptr); else dtsize_t(&dt, 0); } } // Put out the overriding interface vtbl[]s. // This must be mirrored with ClassDeclaration::baseVtblOffset() //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); ClassDeclaration *pc; for (pc = cd->baseClass; pc; pc = pc->baseClass) { for (size_t k = 0; k < pc->vtblInterfaces->dim; k++) { BaseClass *bs = (*pc->vtblInterfaces)[k]; FuncDeclarations bvtbl; if (bs->fillVtbl(cd, &bvtbl, 0)) { //printf("\toverriding vtbl[] for %s\n", bs->sym->toChars()); ClassDeclaration *id = bs->sym; size_t j = 0; if (id->vtblOffset()) { // First entry is ClassInfo reference //dtxoff(&dt, toSymbol(id), 0, TYnptr); // First entry is struct Interface reference dtxoff(&dt, toSymbol(pc), Target::classinfosize + k * (4 * Target::ptrsize), TYnptr); j = 1; } for (; j < id->vtbl.dim; j++) { assert(j < bvtbl.dim); FuncDeclaration *fd = bvtbl[j]; if (fd) dtxoff(&dt, toThunkSymbol(fd, bs->offset), 0, TYnptr); else dtsize_t(&dt, 0); } } } } cd->csym->Sdt = dt; // ClassInfo cannot be const data, because we use the monitor on it outdata(cd->csym); if (cd->isExport()) objmod->export_symbol(cd->csym, 0); ////////////////////////////////////////////// // Put out the vtbl[] //printf("putting out %s.vtbl[]\n", toChars()); dt = NULL; if (cd->vtblOffset()) dtxoff(&dt, cd->csym, 0, TYnptr); // first entry is ClassInfo reference for (size_t i = cd->vtblOffset(); i < cd->vtbl.dim; i++) { FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration(); //printf("\tvtbl[%d] = %p\n", i, fd); if (fd && (fd->fbody || !cd->isAbstract())) { // Ensure function has a return value (Bugzilla 4869) fd->functionSemantic(); Symbol *s = toSymbol(fd); if (cd->isFuncHidden(fd)) { /* fd is hidden from the view of this class. * If fd overlaps with any function in the vtbl[], then * issue 'hidden' error. */ for (size_t j = 1; j < cd->vtbl.dim; j++) { if (j == i) continue; FuncDeclaration *fd2 = cd->vtbl[j]->isFuncDeclaration(); if (!fd2->ident->equals(fd->ident)) continue; if (fd->leastAsSpecialized(fd2) || fd2->leastAsSpecialized(fd)) { TypeFunction *tf = (TypeFunction *)fd->type; if (tf->ty == Tfunction) cd->error("use of %s%s is hidden by %s; use 'alias %s = %s.%s;' to introduce base class overload set", fd->toPrettyChars(), parametersTypeToChars(tf->parameters, tf->varargs), cd->toChars(), fd->toChars(), fd->parent->toChars(), fd->toChars()); else cd->error("use of %s is hidden by %s", fd->toPrettyChars(), cd->toChars()); break; } } } dtxoff(&dt, s, 0, TYnptr); } else dtsize_t(&dt, 0); } cd->vtblsym->Sdt = dt; cd->vtblsym->Sclass = scclass; cd->vtblsym->Sfl = FLdata; out_readonly(cd->vtblsym); outdata(cd->vtblsym); if (cd->isExport()) objmod->export_symbol(cd->vtblsym,0); }
/*! @brief Constructor. @param[in] object Reference to the class instance that is creating this SubMonitor. @param[in] msg String that indicates what the SubMonitor is monitoring, e.g., "Build" @param[in] msgLevel Governs whether information should be printed. @param[in] timerLevel Governs whether timing information should be *gathered*. Setting this to NoTimeReport prevents the creation of timers. */ SubMonitor(const BaseClass& object, const std::string & msg, MsgType msgLevel = Runtime1, MsgType timerLevel = Timings1) : printMonitor_(object, msg, msgLevel), timerMonitor_(object, object.ShortClassName() + ": " + msg + " (sub, total)", timerLevel) { }
int executeMainLoop() { BaseClass * base = new SpecialClass; base->fastFunction(); return (base->timeConsumingJob() > 0)? 0 : -1; }
* * ===================================================================================== */ #include <stdlib.h> #include <stdio.h> #include <gtest/gtest.h> #include "test_class.h" const char test_string[] = "My test string"; const char new_string[] = "Another test string"; TEST(BaseClass, sizeof) { typedef struct { int32_t s; char* b; size_t sise; } base_class_t; BaseClass b; EXPECT_EQ(sizeof(b), sizeof(base_class_t)); EXPECT_EQ(b.GetS(), 10); EXPECT_EQ(b.GetBufferSize(), 0); EXPECT_EQ(b.GetBuffer(), nullptr); } TEST(BaseClass, Initialisation) { BaseClass b; EXPECT_EQ(b.GetS(), 10); } TEST(BaseClass, Copy) { BaseClass b(20);
void IrTypeClass::addBaseClassData( std::vector<llvm::Type *> & defaultTypes, ClassDeclaration * base, size_t & offset, size_t & field_index) { if (base->baseClass) { addBaseClassData(defaultTypes, base->baseClass, offset, field_index); } // FIXME: merge code with structs in IrTypeAggr // mirror the sd->fields array but only fill in contributors size_t n = base->fields.dim; LLSmallVector<VarDeclaration*, 16> data(n, NULL); default_fields.reserve(n); // first fill in the fields with explicit initializers VarDeclarationIter field_it(base->fields); for (; field_it.more(); field_it.next()) { // init is !null for explicit inits if (field_it->init != NULL) { IF_LOG Logger::println("adding explicit initializer for struct field %s", field_it->toChars()); data[field_it.index] = *field_it; size_t f_begin = field_it->offset; size_t f_end = f_begin + field_it->type->size(); // make sure there is no overlap for (size_t i = 0; i < field_it.index; i++) { if (data[i] != NULL) { VarDeclaration* vd = data[i]; size_t v_begin = vd->offset; size_t v_end = v_begin + vd->type->size(); if (v_begin >= f_end || v_end <= f_begin) continue; base->error(vd->loc, "has overlapping initialization for %s and %s", field_it->toChars(), vd->toChars()); } } } } if (global.errors) { fatal(); } // fill in default initializers field_it = VarDeclarationIter(base->fields); for (;field_it.more(); field_it.next()) { if (data[field_it.index]) continue; size_t f_begin = field_it->offset; size_t f_end = f_begin + field_it->type->size(); // make sure it doesn't overlap anything explicit bool overlaps = false; for (size_t i = 0; i < n; i++) { if (data[i]) { size_t v_begin = data[i]->offset; size_t v_end = v_begin + data[i]->type->size(); if (v_begin >= f_end || v_end <= f_begin) continue; overlaps = true; break; } } // if no overlap was found, add the default initializer if (!overlaps) { IF_LOG Logger::println("adding default initializer for struct field %s", field_it->toChars()); data[field_it.index] = *field_it; } } // ok. now we can build a list of llvm types. and make sure zeros are inserted if necessary. // first we sort the list by offset std::sort(data.begin(), data.end(), var_offset_sort_cb); // add types to list for (size_t i = 0; i < n; i++) { VarDeclaration* vd = data[i]; if (vd == NULL) continue; assert(vd->offset >= offset && "it's a bug... most likely DMD bug 2481"); // add to default field list if (cd == base) default_fields.push_back(vd); // get next aligned offset for this type size_t alignedoffset = realignOffset(offset, vd->type); // insert explicit padding? if (alignedoffset < vd->offset) { field_index += add_zeros(defaultTypes, vd->offset - alignedoffset); } // add default type defaultTypes.push_back(DtoType(vd->type)); // advance offset to right past this field offset = vd->offset + vd->type->size(); // create ir field vd->aggrIndex = (unsigned)field_index; ++field_index; } // any interface implementations? if (base->vtblInterfaces && base->vtblInterfaces->dim > 0) { bool new_instances = (base == cd); ArrayIter<BaseClass> it2(*base->vtblInterfaces); VarDeclarationIter interfaces_idx(ClassDeclaration::classinfo->fields, 3); Type* first = interfaces_idx->type->nextOf()->pointerTo(); // align offset offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); for (; !it2.done(); it2.next()) { BaseClass* b = it2.get(); IF_LOG Logger::println("Adding interface vtbl for %s", b->base->toPrettyChars()); FuncDeclarations arr; b->fillVtbl(cd, &arr, new_instances); llvm::Type* ivtbl_type = llvm::StructType::get(gIR->context(), buildVtblType(first, &arr)); defaultTypes.push_back(llvm::PointerType::get(ivtbl_type, 0)); offset += PTRSIZE; // add to the interface map addInterfaceToMap(b->base, field_index); field_index++; // inc count num_interface_vtbls++; } } #if 0 // tail padding? if (offset < base->structsize) { field_index += add_zeros(defaultTypes, base->structsize - offset); offset = base->structsize; } #endif }
uint32 Body::EngineMessageFn(uint32 messageID, void *pData, LTFLOAT fData) { switch(messageID) { case MID_UPDATE: { uint32 dwRet = Prop::EngineMessageFn(messageID, pData, fData); Update(); return dwRet; } break; case MID_LINKBROKEN : { HOBJECT hObject = (HOBJECT)pData; HATTACHMENT hAttachment = LTNULL; if ( LT_OK == g_pLTServer->FindAttachment(m_hObject, hObject, &hAttachment) ) { if ( LT_OK == g_pLTServer->RemoveAttachment(hAttachment) ) { } } if ( m_hChecker == hObject ) { m_hChecker = LTNULL; } if ( m_hWeaponItem == hObject ) { m_hWeaponItem = LTNULL; } for ( uint32 iSpear = 0 ; iSpear < kMaxSpears ; iSpear++ ) { if ( m_ahSpears[iSpear] == hObject ) { m_ahSpears[iSpear] = LTNULL; } } break; } case MID_MODELSTRINGKEY: { HandleModelString((ArgList*)pData); } break; case MID_INITIALUPDATE: { uint32 dwRet = Prop::EngineMessageFn(messageID, pData, fData); // Set up the animator m_Animator.Init(m_hObject); SetNextUpdate(s_fUpdateDelta); uint32 dwUsrFlags = g_pLTServer->GetObjectUserFlags(m_hObject); g_pLTServer->SetObjectUserFlags(m_hObject, dwUsrFlags | USRFLG_NIGHT_INFRARED); return dwRet; } break; case MID_TOUCHNOTIFY: { HOBJECT hObject = (HOBJECT)pData; if ( IsPlayer(hObject) ) { if ( m_hWeaponItem ) { BaseClass* pWeaponItem = (BaseClass*)g_pLTServer->HandleToObject(m_hWeaponItem); pWeaponItem->EngineMessageFn(messageID, pData, fData); } for ( uint32 iSpear = 0 ; iSpear < m_cSpears ; iSpear++ ) { if ( m_ahSpears[iSpear] ) { BaseClass* pSpear = (BaseClass*)g_pLTServer->HandleToObject(m_ahSpears[iSpear]); pSpear->EngineMessageFn(messageID, pData, fData); } } } if ( m_pState ) { m_pState->HandleTouch(hObject); } } break; case MID_SAVEOBJECT: { Save((HMESSAGEWRITE)pData, (uint32)fData); } break; case MID_LOADOBJECT: { Load((HMESSAGEREAD)pData, (uint32)fData); } break; default : break; } return Prop::EngineMessageFn(messageID, pData, fData); }