Synopsis - Cross-Reference
File: /Synopsis/Parsers/IDL/idlast.cc1// -*- c++ -*- 2// Package : omniidl 3// idlast.cc Created on: 1999/10/20 4// Author : Duncan Grisby (dpg1) 5// 6// Copyright (C) 1999 AT&T Laboratories Cambridge 7// 8// This file is part of omniidl. 9// 10// omniidl is free software; you can redistribute it and/or modify it 11// under the terms of the GNU General Public License as published by 12// the Free Software Foundation; either version 2 of the License, or 13// (at your option) any later version. 14// 15// This program is distributed in the hope that it will be useful, 16// but WITHOUT ANY WARRANTY; without even the implied warranty of 17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18// General Public License for more details. 19// 20// You should have received a copy of the GNU General Public License 21// along with this program; if not, write to the Free Software 22// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 23// 02111-1307, USA. 24// 25// Description: 26// 27// Abstract Syntax Tree objects and support functions 28 29// $Id: idlast.cc,v 1.22.2.4 2005/05/10 22:07:31 dgrisby Exp $ 30// $Log: idlast.cc,v $ 31// Revision 1.22.2.4 2005/05/10 22:07:31 dgrisby 32// Merge again. 33// 34// Revision 1.22.2.3 2004/02/16 10:10:33 dgrisby 35// More valuetype, including value boxes. C++ mapping updates. 36// 37// Revision 1.22.2.2 2003/09/04 14:00:24 dgrisby 38// ValueType IDL updates. 39// 40// Revision 1.22.2.1 2003/03/23 21:01:48 dgrisby 41// Start of omniORB 4.1.x development branch. 42// 43// Revision 1.16.2.12 2002/04/30 14:59:37 dgrisby 44// omniidl segfault when checking a non-existent identifier is not a forward. 45// 46// Revision 1.16.2.11 2001/11/08 16:31:20 dpg1 47// Minor tweaks. 48// 49// Revision 1.16.2.10 2001/10/29 17:42:42 dpg1 50// Support forward-declared structs/unions, ORB::create_recursive_tc(). 51// 52// Revision 1.16.2.9 2001/10/17 16:48:32 dpg1 53// Minor error message tweaks 54// 55// Revision 1.16.2.8 2001/08/29 11:55:22 dpg1 56// Enumerator nodes record their value. 57// 58// Revision 1.16.2.7 2001/06/12 11:35:25 dpg1 59// Minor omniidl tweaks for valuetype. 60// 61// Revision 1.16.2.6 2001/06/08 17:12:22 dpg1 62// Merge all the bug fixes from omni3_develop. 63// 64// Revision 1.16.2.5 2001/03/13 10:32:11 dpg1 65// Fixed point support. 66// 67// Revision 1.16.2.4 2000/11/01 12:45:56 dpg1 68// Update to CORBA 2.4 specification. 69// 70// Revision 1.16.2.3 2000/10/27 16:31:08 dpg1 71// Clean up of omniidl dependencies and types, from omni3_develop. 72// 73// Revision 1.16.2.2 2000/10/10 10:18:50 dpg1 74// Update omniidl front-end from omni3_develop. 75// 76// Revision 1.14.2.9 2000/08/29 10:20:26 dpg1 77// Operations and attributes now have repository ids. 78// 79// Revision 1.14.2.8 2000/08/25 13:33:02 dpg1 80// Multiple comments preceding a declaration are now properly attached on 81// all platforms 82// 83// Revision 1.14.2.7 2000/08/07 15:34:36 dpg1 84// Partial back-port of long long from omni3_1_develop. 85// 86// Revision 1.14.2.6 2000/07/26 10:59:14 dpg1 87// Incorrect error report when inheriting typedef to forward declared 88// interface 89// 90// Revision 1.14.2.5 2000/06/08 14:36:19 dpg1 91// Comments and pragmas are now objects rather than plain strings, so 92// they can have file,line associated with them. 93// 94// Revision 1.14.2.4 2000/06/05 18:13:26 dpg1 95// Comments can be attached to subsequent declarations (with -K). Better 96// idea of most recent decl in operation declarations 97// 98// Revision 1.14.2.3 2000/03/16 17:35:21 dpg1 99// Bug with comments in input when keepComments is false. 100// 101// Revision 1.14.2.2 2000/03/07 10:31:26 dpg1 102// More sensible idea of the "most recent" declaration. 103// 104// Revision 1.14.2.1 2000/03/06 15:03:49 dpg1 105// Minor bug fixes to omniidl. New -nf and -k flags. 106// 107// Revision 1.14 2000/02/03 14:50:07 dpg1 108// Native declarations can now be used as types. 109// 110// Revision 1.13 2000/01/05 11:21:08 dpg1 111// Removed warning about signed/unsigned comparison. 112// * can only be the last character of a context key. 113// 114// Revision 1.12 1999/12/28 18:15:45 dpg1 115// Bounds of string constants now checked. 116// 117// Revision 1.11 1999/11/30 18:06:19 dpg1 118// Alias dereferencing bugs. 119// 120// Revision 1.10 1999/11/22 11:07:46 dpg1 121// Correctly report error with interface which tries to inherit from 122// CORBA::Object. 123// 124// Revision 1.9 1999/11/17 17:17:00 dpg1 125// Changes to remove static initialisation of objects. 126// 127// Revision 1.8 1999/11/04 17:15:52 dpg1 128// Typo. 129// 130// Revision 1.7 1999/11/02 17:07:27 dpg1 131// Changes to compile on Solaris. 132// 133// Revision 1.6 1999/11/01 20:19:57 dpg1 134// Support for union switch types declared inside the switch statement. 135// 136// Revision 1.5 1999/11/01 16:38:40 dpg1 137// Missed an update when adding recursive union detection. 138// 139// Revision 1.4 1999/11/01 10:05:00 dpg1 140// New file attribute to AST. 141// 142// Revision 1.3 1999/10/29 15:42:43 dpg1 143// DeclaredType() now takes extra DeclRepoId* argument. 144// Code to detect recursive structs and unions. 145// 146// Revision 1.2 1999/10/29 10:00:43 dpg1 147// Added code to find a value for the default case in a union. 148// 149// Revision 1.1 1999/10/27 14:05:59 dpg1 150// *** empty log message *** 151// 152 153#include <idlast.h> 154#include <idlrepoId.h> 155#include <idlvalidate.h> 156#include <idlerr.h> 157#include <idlconfig.h> 158 159#include <string.h> 160#include <ctype.h> 161 162// Globals from lexer 163extern FILE* yyin; 164extern char* currentFile; 165extern int yylineno; 166 167AST* AST::tree_ = 0; 168Decl* Decl::mostRecent_ = 0; 169Comment* Comment::mostRecent_ = 0; 170Comment* Comment::saved_ = 0; 171 172 173// Static error message functions 174static void 175checkNotForward(const char* file, int line, IdlType* t) 176{ 177 if (!t) return; 178 179 if (t->kind() == IdlType::ot_structforward) { 180 StructForward* f = (StructForward*)((DeclaredType*)t)->decl(); 181 182 if (!f->definition()) { 183 char* ssn = f->scopedName()->toString(); 184 IdlError(file, line, 185 "Cannot use forward-declared struct '%s' before it is " 186 "fully defined", ssn); 187 IdlErrorCont(f->file(), f->line(), 188 "('%s' forward-declared here)", f->identifier()); 189 delete [] ssn; 190 } 191 } 192 else if (t->kind() == IdlType::ot_unionforward) { 193 UnionForward* f = (UnionForward*)((DeclaredType*)t)->decl(); 194 195 if (!f->definition()) { 196 char* ssn = f->scopedName()->toString(); 197 IdlError(file, line, 198 "Cannot use forward-declared union '%s' before it is " 199 "fully defined", ssn); 200 IdlErrorCont(f->file(), f->line(), 201 "('%s' forward-declared here)", f->identifier()); 202 delete [] ssn; 203 } 204 } 205} 206 207static 208void 209checkValidType(const char* file, int line, IdlType* t) 210{ 211 t = t->unalias(); 212 if (!t) return; // Ignore if earlier errors. 213 214 checkNotForward(file, line, t); 215 216 if (t && t->kind() == IdlType::tk_sequence) { 217 218 while (t && t->kind() == IdlType::tk_sequence) 219 t = ((SequenceType*)t)->seqType()->unalias(); 220 221 checkNotForward(file, line, t); 222 } 223} 224 225 226// Pragma 227void 228Pragma:: 229add(const char* pragmaText, const char* file, int line) 230{ 231 if (Decl::mostRecent()) 232 Decl::mostRecent()->addPragma(pragmaText, file, line); 233 else 234 AST::tree()->addPragma(pragmaText, file, line); 235} 236 237// Comment 238 239void 240Comment:: 241add(const char* commentText, const char* file, int line) 242{ 243 if (Config::keepComments) { 244 if (Config::commentsFirst) { 245 if (saved_) { 246 // C++ says that the order of value evaluation is undefined. 247 // Comment's constructor sets mostRecent_, so the innocent- 248 // looking mostRecent_->next_ = new Comment... does the wrong 249 // thing with some compilers :-( 250 Comment* mr = mostRecent_; 251 mr->next_ = new Comment(commentText, file, line); 252 } 253 else 254 saved_ = new Comment(commentText, file, line); 255 } 256 else { 257 if (Decl::mostRecent()) 258 Decl::mostRecent()->addComment(commentText, file, line); 259 else 260 AST::tree()->addComment(commentText, file, line); 261 } 262 } 263} 264 265void 266Comment:: 267append(const char* commentText) 268{ 269 if (Config::keepComments) { 270 assert(mostRecent_ != 0); 271 char* newText = new char[(strlen(mostRecent_->commentText_) + 272 strlen(commentText) + 1)]; 273 strcpy(newText, mostRecent_->commentText_); 274 strcat(newText, commentText); 275 delete [] mostRecent_->commentText_; 276 mostRecent_->commentText_ = newText; 277 } 278} 279 280Comment* 281Comment:: 282grabSaved() 283{ 284 Comment* ret = saved_; 285 saved_ = 0; 286 return ret; 287} 288 289 290// AST 291AST::AST() : declarations_(0), file_(0), 292 pragmas_(0), lastPragma_(0), 293 comments_(0), lastComment_(0) {} 294 295AST::~AST() { 296 if (declarations_) delete declarations_; 297 if (file_) delete [] file_; 298 if (pragmas_) delete pragmas_; 299 if (comments_) delete comments_; 300} 301 302void 303AST:: 304addPragma(const char* pragmaText, const char* file, int line) 305{ 306 Pragma* p = new Pragma(pragmaText, file, line); 307 if (pragmas_) 308 lastPragma_->next_ = p; 309 else 310 pragmas_ = p; 311 lastPragma_ = p; 312} 313 314void 315AST:: 316addComment(const char* commentText, const char* file, int line) 317{ 318 Comment* p = new Comment(commentText, file, line); 319 if (comments_) 320 lastComment_->next_ = p; 321 else 322 comments_ = p; 323 lastComment_ = p; 324} 325 326 327AST* 328AST:: 329tree() 330{ 331 if (!tree_) tree_ = new AST(); 332 assert(tree_ != 0); 333 return tree_; 334} 335 336IDL_Boolean 337AST:: 338process(FILE* f, const char* name) 339{ 340 IdlType::init(); 341 Scope::init(); 342 343 yyin = f; 344 currentFile = idl_strdup(name); 345 Prefix::newFile(); 346 347 tree()->setFile(name); 348 349 int yr = yyparse(); 350 if (yr) IdlError(currentFile, yylineno, "Syntax error"); 351 352 if (Config::keepComments && Config::commentsFirst) 353 tree()->comments_ = Comment::grabSaved(); 354 355 Prefix::endOuterFile(); 356 357 return IdlReportErrors(); 358} 359 360void 361AST:: 362clear() 363{ 364 if (tree_) { 365 delete tree_; 366 tree_ = 0; 367 } 368 Scope::clear(); 369 Decl::clear(); 370 Comment::clear(); 371} 372 373void 374AST:: 375setFile(const char* file) 376{ 377 if (file_) { 378 if (!strcmp(file_, file)) return; 379 delete [] file_; 380 } 381 file_ = idl_strdup(file); 382} 383 384void 385AST:: 386setDeclarations(Decl* d) 387{ 388 assert(declarations_ == 0); 389 declarations_ = d; 390 391 // Validate the declarations 392 AstValidateVisitor v; 393 accept(v); 394} 395 396 397// Base Decl 398Decl:: 399Decl(Kind kind, const char* file, int line, IDL_Boolean mainFile) 400 401 : kind_(kind), file_(idl_strdup(file)), line_(line), 402 mainFile_(mainFile), inScope_(Scope::current()), 403 pragmas_(0), lastPragma_(0), 404 comments_(0), lastComment_(0), 405 next_(0) 406{ 407 last_ = this; 408 mostRecent_ = this; 409 410 if (Config::keepComments && Config::commentsFirst) 411 comments_ = Comment::grabSaved(); 412} 413 414Decl:: 415~Decl() 416{ 417 if (file_) delete [] file_; 418 if (pragmas_) delete pragmas_; 419 if (comments_) delete comments_; 420 if (next_) delete next_; 421} 422 423Decl* 424Decl:: 425scopedNameToDecl(const char* file, int line, const ScopedName* sn) 426{ 427 const Scope::Entry* se = Scope::current()->findScopedName(sn, file, line); 428 429 if (se) { 430 switch (se->kind()) { 431 432 case Scope::Entry::E_MODULE: 433 case Scope::Entry::E_DECL: 434 case Scope::Entry::E_CALLABLE: 435 case Scope::Entry::E_INHERITED: 436 return se->decl(); 437 438 default: 439 { 440 char* ssn = sn->toString(); 441 IdlError(file, line, "'%s' is not a declaration", ssn); 442 IdlErrorCont(se->file(), se->line(), "('%s' created here)", ssn); 443 delete [] ssn; 444 } 445 } 446 } 447 return 0; 448} 449 450void 451Decl:: 452addPragma(const char* pragmaText, const char* file, int line) 453{ 454 Pragma* p = new Pragma(pragmaText, file, line); 455 if (pragmas_) 456 lastPragma_->next_ = p; 457 else 458 pragmas_ = p; 459 lastPragma_ = p; 460} 461 462void 463Decl:: 464addComment(const char* commentText, const char* file, int line) 465{ 466 Comment* p = new Comment(commentText, file, line); 467 if (comments_) 468 lastComment_->next_ = p; 469 else 470 comments_ = p; 471 lastComment_ = p; 472} 473 474 475 476// Module 477Module:: 478Module(const char* file, int line, IDL_Boolean mainFile, 479 const char* identifier) 480 481 : Decl(D_MODULE, file, line, mainFile), 482 DeclRepoId(identifier), 483 definitions_(0) 484{ 485 Scope* s = Scope::current()->newModuleScope(identifier, file, line); 486 Scope::current()->addModule(identifier, s, this, file, line); 487 Scope::startScope(s); 488 Prefix::newScope(identifier); 489} 490 491Module:: 492~Module() 493{ 494 if (definitions_) delete definitions_; 495} 496 497void 498Module:: 499finishConstruction(Decl* defs) 500{ 501 definitions_ = defs; 502 Prefix::endScope(); 503 Scope::endScope(); 504 mostRecent_ = this; 505} 506 507 508// Interface 509InheritSpec:: 510InheritSpec(const ScopedName* sn, const char* file, int line) 511 512 : interface_(0), decl_(0), scope_(0), next_(0) 513{ 514 const Scope::Entry* se = Scope::current()->findScopedName(sn, file, line); 515 516 if (se) { 517 if (se->kind() == Scope::Entry::E_DECL) { 518 519 decl_ = se->decl(); 520 IdlType* t = se->idltype()->unalias(); 521 522 if (!t) return; 523 524 if (t->kind() == IdlType::tk_objref || 525 t->kind() == IdlType::tk_abstract_interface || 526 t->kind() == IdlType::tk_local_interface) { 527 528 Decl* d = ((DeclaredType*)t)->decl(); 529 530 if (!d) { 531 char* ssn = sn->toString(); 532 IdlError(file, line, "Cannot inherit from CORBA::Object"); 533 IdlErrorCont(se->file(), se->line(), 534 "(accessed through typedef '%s')", ssn); 535 delete [] ssn; 536 return; 537 } 538 else if (d->kind() == Decl::D_INTERFACE) { 539 interface_ = (Interface*)d; 540 scope_ = interface_->scope(); 541 return; 542 } 543 else if (d->kind() == Decl::D_FORWARD) { 544 Interface* def = ((Forward*)d)->definition(); 545 if (def) { 546 interface_ = def; 547 scope_ = interface_->scope(); 548 return; 549 } 550 else { 551 char* ssn = ((Forward*)d)->scopedName()->toString(); 552 IdlError(file, line, 553 "Inherited interface '%s' must be fully defined", ssn); 554 555 if (decl_ != d) { 556 char* tssn = sn->toString(); 557 IdlErrorCont(se->file(), se->line(), 558 "('%s' reached through typedef '%s')", 559 ssn, tssn); 560 delete [] tssn; 561 } 562 IdlErrorCont(d->file(), d->line(), 563 "('%s' forward declared here)", ssn); 564 delete [] ssn; 565 return; 566 } 567 } 568 } 569 } 570 char* ssn = sn->toString(); 571 IdlError(file, line, 572 "'%s' used in inheritance specification is not an interface", 573 ssn); 574 IdlErrorCont(se->file(), se->line(), "('%s' declared here)", ssn); 575 delete [] ssn; 576 } 577} 578 579void 580InheritSpec:: 581append(InheritSpec* is, const char* file, int line) 582{ 583 InheritSpec *i, *last; 584 585 if (is->interface()) { 586 for (i=this; i; i = i->next_) { 587 last = i; 588 if (is->interface() == i->interface()) { 589 char* ssn = is->interface()->scopedName()->toString(); 590 IdlError(file, line, 591 "Cannot specify '%s' as a direct base interface " 592 "more than once", ssn); 593 delete [] ssn; 594 delete is; 595 return; 596 } 597 } 598 last->next_ = is; 599 } 600} 601 602Interface:: 603Interface(const char* file, int line, IDL_Boolean mainFile, 604 const char* identifier, IDL_Boolean abstract, IDL_Boolean local, 605 InheritSpec* inherits) 606 607 : Decl(D_INTERFACE, file, line, mainFile), 608 DeclRepoId(identifier), 609 abstract_(abstract), 610 local_(local), 611 inherits_(inherits), 612 contents_(0) 613{ 614 // Look for forward interface 615 Scope::Entry* se = Scope::current()->find(identifier); 616 617 if (se && 618 se->kind() == Scope::Entry::E_DECL && 619 se->decl() && 620 se->decl()->kind() == Decl::D_FORWARD) { 621 622 Forward* f = (Forward*)se->decl(); 623 624 if (strcmp(f->prefix(), prefix())) { 625 626 IdlError(file, line, 627 "In declaration of interface '%s', repository id " 628 "prefix '%s' differs from that of forward declaration", 629 identifier, prefix()); 630 631 IdlErrorCont(f->file(), f->line(), 632 "('%s' forward declared here with prefix '%s')", 633 f->identifier(), f->prefix()); 634 } 635 if (abstract && !f->abstract()) { 636 IdlError(file, line, 637 "Declaration of abstract interface '%s' conflicts with " 638 "forward declaration as non-abstract", identifier); 639 IdlErrorCont(f->file(), f->line(), 640 "('%s' forward declared as non-abstract here)"); 641 } 642 else if (!abstract && f->abstract()) { 643 IdlError(file, line, 644 "Declaration of non-abstract interface '%s' conflicts with " 645 "forward declaration as abstract", identifier); 646 IdlErrorCont(f->file(), f->line(), 647 "('%s' forward declared as abstract here)"); 648 } 649 if (local && !f->local()) { 650 IdlError(file, line, 651 "Declaration of local interface '%s' conflicts with " 652 "forward declaration as unconstrained", identifier); 653 IdlErrorCont(f->file(), f->line(), 654 "('%s' forward declared as unconstrained here)"); 655 } 656 else if (!local && f->local()) { 657 IdlError(file, line, 658 "Declaration of unconstrained interface '%s' conflicts with " 659 "forward declaration as local", identifier); 660 IdlErrorCont(f->file(), f->line(), 661 "('%s' forward declared as local here)"); 662 } 663 if (f->repoIdSet()) setRepoId(f->repoId(), f->rifile(), f->riline()); 664 665 f->setDefinition(this); 666 Scope::current()->remEntry(se); 667 } 668 scope_ = Scope::current()->newInterfaceScope(identifier, file, line); 669 670 if (abstract_) { 671 thisType_ = new DeclaredType(IdlType::tk_abstract_interface, this, this); 672 673 // Check that all inherited interfaces are abstract 674 for (InheritSpec* inh = inherits; inh; inh = inh->next()) { 675 if (!inh->interface()->abstract()) { 676 char* ssn = inh->scope()->scopedName()->toString(); 677 IdlError(file, line, 678 "In declaration of abstract interface '%s', inherited " 679 "interface '%s' is not abstract", identifier, ssn); 680 IdlErrorCont(inh->interface()->file(), inh->interface()->line(), 681 "(%s declared here)", ssn); 682 delete [] ssn; 683 } 684 } 685 } 686 else if (local_) { 687 thisType_ = new DeclaredType(IdlType::tk_local_interface, this, this); 688 thisType_->setLocal(); 689 } 690 else { 691 thisType_ = new DeclaredType(IdlType::tk_objref, this, this); 692 693 // Check that all inherited interfaces are unconstrained 694 for (InheritSpec* inh = inherits; inh; inh = inh->next()) { 695 if (inh->interface() && inh->interface()->local()) { 696 char* ssn = inh->scope()->scopedName()->toString(); 697 IdlError(file, line, 698 "In declaration of unconstrained interface '%s', inherited " 699 "interface '%s' is local", identifier, ssn); 700 IdlErrorCont(inh->interface()->file(), inh->interface()->line(), 701 "(%s declared here)", ssn); 702 delete [] ssn; 703 } 704 } 705 } 706 scope_->setInherited(inherits, file, line); 707 Scope::current()->addDecl(identifier, scope_, this, thisType_, file, line); 708 Scope::startScope(scope_); 709 Prefix::newScope(identifier); 710} 711 712Interface:: 713~Interface() 714{ 715 if (inherits_) delete inherits_; 716 if (contents_) delete contents_; 717 delete thisType_; 718} 719 720IDL_Boolean 721Interface::isDerived(const Interface* base) const 722{ 723 if (base == this) 724 return 1; 725 726 for (InheritSpec* is = inherits_; is; is = is->next()) { 727 if (is->interface() == base || is->interface()->isDerived(base)) 728 return 1; 729 } 730 return 0; 731} 732 733 734void 735Interface:: 736finishConstruction(Decl* decls) 737{ 738 contents_ = decls; 739 Prefix::endScope(); 740 Scope::endScope(); 741 mostRecent_ = this; 742 743 if (!local_) { 744 for (Decl* d = decls; d; d = d->next()) { 745 746 if (d->kind() == D_ATTRIBUTE) { 747 Attribute* a = (Attribute*)d; 748 749 if (a->attrType() && a->attrType()->local()) { 750 DeclaredType* dt = (DeclaredType*)a->attrType(); 751 assert(dt->declRepoId()); 752 char* ssn = dt->declRepoId()->scopedName()->toString(); 753 754 IdlError(a->file(), a->line(), 755 "In unconstrained interface '%s', attribute '%s' has " 756 "local type '%s'", 757 identifier(), a->declarators()->identifier(), ssn); 758 IdlErrorCont(dt->decl()->file(), dt->decl()->line(), 759 "(%s declared here)", ssn); 760 delete [] ssn; 761 } 762 } 763 else if (d->kind() == D_OPERATION) { 764 Operation* o = (Operation*)d; 765 766 if (o->returnType() && o->returnType()->local()) { 767 DeclaredType* dt = (DeclaredType*)o->returnType(); 768 assert(dt->declRepoId()); 769 char* ssn = dt->declRepoId()->scopedName()->toString(); 770 771 IdlError(o->file(), o->line(), 772 "In unconstrained interface '%s', operation '%s' has " 773 "local return type '%s'", 774 identifier(), o->identifier(), ssn); 775 IdlErrorCont(dt->decl()->file(), dt->decl()->line(), 776 "(%s declared here)", ssn); 777 delete [] ssn; 778 } 779 for (Parameter* p = o->parameters(); p; p = (Parameter*)p->next()) { 780 if (p->paramType() && p->paramType()->local()) { 781 DeclaredType* dt = (DeclaredType*)p->paramType(); 782 assert(dt->declRepoId()); 783 char* ssn = dt->declRepoId()->scopedName()->toString(); 784 785 IdlError(p->file(), p->line(), 786 "In unconstrained interface '%s', operation '%s' has " 787 "parameter '%s' with local type '%s'", 788 identifier(), o->identifier(), p->identifier(), ssn); 789 IdlErrorCont(dt->decl()->file(), dt->decl()->line(), 790 "(%s declared here)", ssn); 791 delete [] ssn; 792 } 793 } 794 for (RaisesSpec* r = o->raises(); r; r = r->next()) { 795 if (r->exception() && r->exception()->local()) { 796 char* ssn = r->exception()->scopedName()->toString(); 797 798 IdlError(o->file(), o->line(), 799 "In unconstrained interface '%s', operation '%s' raises " 800 "local exception '%s'", identifier(), 801 o->identifier(), ssn); 802 IdlErrorCont(r->exception()->file(), r->exception()->line(), 803 "(%s declared here)", ssn); 804 delete [] ssn; 805 } 806 } 807 } 808 } 809 } 810} 811 812 813// Forward 814Forward:: 815Forward(const char* file, int line, IDL_Boolean mainFile, 816 const char* identifier, IDL_Boolean abstract, IDL_Boolean local) 817 818 : Decl(D_FORWARD, file, line, mainFile), 819 DeclRepoId(identifier), 820 abstract_(abstract), 821 local_(local), 822 definition_(0), 823 firstForward_(0), 824 thisType_(0) 825{ 826 Scope::Entry* se = Scope::current()->find(identifier); 827 IDL_Boolean reg = 1; 828 829 if (se && se->kind() == Scope::Entry::E_DECL) { 830 831 if (se->decl()->kind() == D_INTERFACE) { 832 Interface* i = (Interface*)se->decl(); 833 definition_ = i; 834 835 if (strcmp(i->prefix(), prefix())) { 836 837 IdlError(file, line, 838 "In forward declaration of interface '%s', repository " 839 "id prefix '%s' differs from that of earlier declaration", 840 identifier, prefix()); 841 842 IdlErrorCont(i->file(), i->line(), 843 "('%s' fully declared here with prefix '%s')", 844 i->identifier(), i->prefix()); 845 } 846 if (abstract && !i->abstract()) { 847 IdlError(file, line, 848 "Forward declaration of abstract interface '%s' conflicts " 849 "with earlier full declaration as non-abstract", 850 identifier); 851 IdlErrorCont(i->file(), i->line(), 852 "('%s' declared as non-abstract here)"); 853 } 854 else if (!abstract && i->abstract()) { 855 IdlError(file, line, 856 "Forward declaration of non-abstract interface '%s' " 857 "conflicts with earlier full declaration as abstract", 858 identifier); 859 IdlErrorCont(i->file(), i->line(), 860 "('%s' declared as abstract here)"); 861 } 862 if (local && !i->local()) { 863 IdlError(file, line, 864 "Forward declaration of local interface '%s' conflicts " 865 "with earlier full declaration as unconstrained", 866 identifier); 867 IdlErrorCont(i->file(), i->line(), 868 "('%s' declared as unconstrained here)"); 869 } 870 else if (!local && i->local()) { 871 IdlError(file, line, 872 "Forward declaration of unconstrained interface '%s' " 873 "conflicts with earlier full declaration as local", 874 identifier); 875 IdlErrorCont(i->file(), i->line(), 876 "('%s' declared as abstract here)"); 877 } 878 reg = 0; 879 } 880 else if (se->decl()->kind() == D_FORWARD) { 881 Forward* f = (Forward*)se->decl(); 882 firstForward_ = f; 883 884 if (strcmp(f->prefix(), prefix())) { 885 IdlError(file, line, 886 "In forward declaration of interface '%s', repository " 887 "id prefix '%s' differs from that of earlier declaration", 888 identifier, prefix()); 889 890 IdlErrorCont(f->file(), f->line(), 891 "('%s' forward declared here with prefix '%s')", 892 f->identifier(), f->prefix()); 893 } 894 if (abstract && !f->abstract()) { 895 IdlError(file, line, 896 "Forward declaration of abstract interface '%s' conflicts " 897 "with earlier forward declaration as non-abstract", 898 identifier); 899 IdlErrorCont(f->file(), f->line(), 900 "('%s' forward declared as non-abstract here)"); 901 } 902 else if (!abstract && f->abstract()) { 903 IdlError(file, line, 904 "Forward declaration of non-abstract interface '%s' " 905 "conflicts with earlier forward declaration as abstract", 906 identifier); 907 IdlErrorCont(f->file(), f->line(), 908 "('%s' forward declared as abstract here)"); 909 } 910 if (local && !f->local()) { 911 IdlError(file, line, 912 "Forward declaration of local interface '%s' conflicts " 913 "with earlier forward declaration as unconstrained", 914 identifier); 915 IdlErrorCont(f->file(), f->line(), 916 "('%s' forward declared as unconstrained here)"); 917 } 918 else if (!local && f->local()) { 919 IdlError(file, line, 920 "Forward declaration of unconstrained interface '%s' " 921 "conflicts with earlier forward declaration as local", 922 identifier); 923 IdlErrorCont(f->file(), f->line(), 924 "('%s' forward declared as local here)"); 925 } 926 //***? if (f->repoIdSet()) setRepoId(f->repoId(), f->rifile(), f->riline()); 927 reg = 0; 928 } 929 } 930 if (reg) { 931 if (abstract) { 932 thisType_ = new DeclaredType(IdlType::tk_abstract_interface, this, this); 933 } 934 else if (local) { 935 thisType_ = new DeclaredType(IdlType::tk_local_interface, this, this); 936 thisType_->setLocal(); 937 } 938 else { 939 thisType_ = new DeclaredType(IdlType::tk_objref, this, this); 940 } 941 Scope::current()->addDecl(identifier, 0, this, thisType_, file, line); 942 } 943} 944 945Forward:: 946~Forward() 947{ 948 delete thisType_; 949} 950 951Interface* 952Forward:: 953definition() const 954{ 955 if (firstForward_) 956 return firstForward_->definition(); 957 else 958 return definition_; 959} 960 961void 962Forward:: 963setDefinition(Interface* defn) 964{ 965 definition_ = defn; 966} 967 968 969// Const 970 971Const:: 972Const(const char* file, int line, IDL_Boolean mainFile, 973 IdlType* constType, const char* identifier, IdlExpr* expr) 974 975 : Decl(D_CONST, file, line, mainFile), 976 DeclRepoId(identifier), 977 constType_(constType) 978{ 979 if (constType) delType_ = constType->shouldDelete(); 980 else delType_ = 0; 981 982 if (!constType || !expr) return; // Ignore nulls due to earlier errors 983 984 IdlType* t = constType->unalias(); 985 986 if (!t) { // Broken alias due to earlier error 987 constKind_ = IdlType::tk_null; 988 delete expr; 989 return; 990 } 991 constKind_ = t->kind(); 992 993 switch (constKind_) { 994 case IdlType::tk_short: v_.short_ = expr->evalAsShort(); break; 995 case IdlType::tk_long: v_.long_ = expr->evalAsLong(); break; 996 case IdlType::tk_ushort: v_.ushort_ = expr->evalAsUShort(); break; 997 case IdlType::tk_ulong: v_.ulong_ = expr->evalAsULong(); break; 998 case IdlType::tk_float: v_.float_ = expr->evalAsFloat(); break; 999 case IdlType::tk_double: v_.double_ = expr->evalAsDouble(); break; 1000 case IdlType::tk_boolean: v_.boolean_ = expr->evalAsBoolean(); break; 1001 case IdlType::tk_char: v_.char_ = expr->evalAsChar(); break; 1002 case IdlType::tk_octet: v_.octet_ = expr->evalAsOctet(); break; 1003 case IdlType::tk_string: 1004 { 1005 v_.string_ = idl_strdup(expr->evalAsString()); 1006 IDL_ULong bound = ((StringType*)t)->bound(); 1007 1008 if (bound && strlen(v_.string_) > bound) { 1009 IdlError(file, line, 1010 "Length of bounded string constant exceeds bound"); 1011 } 1012 break; 1013 } 1014#ifdef HAS_LongLong 1015 case IdlType::tk_longlong: v_.longlong_ = expr->evalAsLongLong(); break; 1016 case IdlType::tk_ulonglong: v_.ulonglong_ = expr->evalAsULongLong(); break; 1017#endif 1018#ifdef HAS_LongDouble 1019 case IdlType::tk_longdouble: v_.longdouble_ = expr->evalAsLongDouble();break; 1020#endif 1021 case IdlType::tk_wchar: v_.wchar_ = expr->evalAsWChar(); break; 1022 case IdlType::tk_wstring: 1023 { 1024 v_.wstring_ = idl_wstrdup(expr->evalAsWString()); 1025 IDL_ULong bound = ((WStringType*)t)->bound(); 1026 1027 if (bound && (unsigned)idl_wstrlen(v_.wstring_) > bound) { 1028 IdlError(file, line, 1029 "Length of bounded wide string constant exceeds bound"); 1030 } 1031 break; 1032 } 1033 case IdlType::tk_fixed: 1034 { 1035 IDL_Fixed* f = expr->evalAsFixed(); 1036 1037 FixedType* ft = (FixedType*)t; 1038 if (ft->digits()) { 1039 // Check constant fits in the target type 1040 IDL_Fixed* g = new IDL_Fixed(f->truncate(ft->scale())); 1041 1042 if (g->fixed_digits() > ft->digits()) { 1043 IdlError(file, line, 1044 "Fixed point constant has too many digits to " 1045 "fit fixed<%u,%u>", 1046 ft->digits(), ft->scale()); 1047 } 1048 else if (f->fixed_scale() > g->fixed_scale()) { 1049 IdlWarning(file, line, 1050 "Fixed point constant truncated to fit fixed<%u,%u>", 1051 ft->digits(), ft->scale()); 1052 } 1053 delete f; 1054 f = g; 1055 } 1056 v_.fixed_ = f; 1057 break; 1058 } 1059 case IdlType::tk_enum: 1060 v_.enumerator_ = expr->evalAsEnumerator((Enum*)((DeclaredType*)t)->decl()); 1061 break; 1062 1063 default: 1064 IdlError(file, line, "Invalid type for constant: %s", t->kindAsString()); 1065 break; 1066 } 1067 delete expr; 1068 1069 Scope::current()->addDecl(identifier, 0, this, constType, file, line); 1070} 1071 1072Const:: 1073~Const() 1074{ 1075 if (constKind_ == IdlType::tk_string) delete [] v_.string_; 1076 if (constKind_ == IdlType::tk_wstring) delete [] v_.wstring_; 1077 if (constKind_ == IdlType::tk_fixed) delete v_.fixed_; 1078 if (delType_) delete constType_; 1079} 1080 1081#define CONST_AS(rt, op, tk, un) \ 1082rt Const::op() const { \ 1083 assert(constKind_ == IdlType::tk); \ 1084 return v_.un; \ 1085} 1086 1087CONST_AS(IDL_Short, constAsShort, tk_short, short_) 1088CONST_AS(IDL_Long, constAsLong, tk_long, long_) 1089CONST_AS(IDL_UShort, constAsUShort, tk_ushort, ushort_) 1090CONST_AS(IDL_ULong, constAsULong, tk_ulong, ulong_) 1091CONST_AS(IDL_Float, constAsFloat, tk_float, float_) 1092CONST_AS(IDL_Double, constAsDouble, tk_double, double_) 1093CONST_AS(IDL_Boolean, constAsBoolean, tk_boolean, boolean_) 1094CONST_AS(IDL_Char, constAsChar, tk_char, char_) 1095CONST_AS(IDL_Octet, constAsOctet, tk_octet, octet_) 1096CONST_AS(const char*, constAsString, tk_string, string_) 1097#ifdef HAS_LongLong 1098CONST_AS(IDL_LongLong, constAsLongLong, tk_longlong, longlong_) 1099CONST_AS(IDL_ULongLong, constAsULongLong, tk_ulonglong, ulonglong_) 1100#endif 1101#ifdef HAS_LongDouble 1102CONST_AS(IDL_LongDouble, constAsLongDouble, tk_longdouble, longdouble_) 1103#endif 1104CONST_AS(IDL_WChar, constAsWChar, tk_wchar, wchar_) 1105CONST_AS(const IDL_WChar*, constAsWString, tk_wstring, wstring_) 1106CONST_AS(Enumerator*, constAsEnumerator, tk_enum, enumerator_) 1107 1108IDL_Fixed* 1109Const::constAsFixed() const { 1110 assert(constKind_ == IdlType::tk_fixed); 1111 1112 // Have to copy the fixed object to get the memory management right 1113 return new IDL_Fixed(*v_.fixed_); 1114} 1115 1116 1117// Declarator 1118Declarator:: 1119Declarator(const char* file, int line, IDL_Boolean mainFile, 1120 const char* identifier, ArraySize* sizes) 1121 1122 : Decl(D_DECLARATOR, file, line, mainFile), 1123 DeclRepoId(identifier), 1124 sizes_(sizes), 1125 thisType_(0), 1126 alias_(0), 1127 attribute_(0) 1128{ 1129} 1130 1131Declarator:: 1132~Declarator() 1133{ 1134 if (sizes_) delete sizes_; 1135 if (thisType_) delete thisType_; 1136} 1137 1138const char* 1139Declarator:: 1140kindAsString() const 1141{ 1142 if (alias_) return "typedef declarator"; 1143 if (attribute_) return "attribute declarator"; 1144 return "declarator"; 1145} 1146 1147void 1148Declarator:: 1149setAlias(Typedef* td) 1150{ 1151 alias_ = td; 1152 thisType_ = new DeclaredType(IdlType::tk_alias, this, this); 1153 if (td->aliasType() && td->aliasType()->local()) thisType_->setLocal(); 1154 if (sizes_) checkValidType(file(), line(), td->aliasType()); 1155} 1156 1157void 1158Declarator:: 1159setAttribute(Attribute* at) 1160{ 1161 attribute_ = at; 1162} 1163 1164// Typedef 1165Typedef:: 1166Typedef(const char* file, int line, IDL_Boolean mainFile, 1167 IdlType* aliasType, IDL_Boolean constrType, 1168 Declarator* declarators) 1169 1170 : Decl(D_TYPEDEF, file, line, mainFile), 1171 aliasType_(aliasType), 1172 constrType_(constrType), 1173 declarators_(declarators) 1174{ 1175 if (aliasType) delType_ = aliasType->shouldDelete(); 1176 else delType_ = 0; 1177 1178 if (aliasType) checkNotForward(file, line, aliasType); 1179 1180 for (Declarator* d = declarators; d; d = (Declarator*)d->next()) { 1181 d->setAlias(this); 1182 Scope::current()->addDecl(d->eidentifier(), 0, d, d->thisType(), 1183 d->file(), d->line()); 1184 } 1185} 1186 1187Typedef:: 1188~Typedef() 1189{ 1190 if (delType_) delete aliasType_; 1191 if (declarators_) delete declarators_; 1192} 1193 1194 1195// Member 1196Member:: 1197Member(const char* file, int line, IDL_Boolean mainFile, 1198 IdlType* memberType, IDL_Boolean constrType, 1199 Declarator* declarators) 1200 1201 : Decl(D_MEMBER, file, line, mainFile), 1202 memberType_(memberType), 1203 constrType_(constrType), 1204 declarators_(declarators) 1205{ 1206 if (memberType) delType_ = memberType->shouldDelete(); 1207 else { 1208 delType_ = 0; 1209 return; 1210 } 1211 checkNotForward(file, line, memberType); 1212 1213 IdlType* bareType = memberType->unalias(); 1214 1215 if (bareType->kind() == IdlType::tk_struct) { 1216 Struct* s = (Struct*)((DeclaredType*)bareType)->decl(); 1217 if (!s->finished()) { 1218 IdlError(file, line, 1219 "Cannot create an instance of struct '%s' inside " 1220 "its own definition", s->identifier()); 1221 } 1222 } 1223 else if (bareType->kind() == IdlType::tk_union) { 1224 Union* u = (Union*)((DeclaredType*)bareType)->decl(); 1225 if (!u->finished()) { 1226 IdlError(file, line, 1227 "Cannot create an instance of union '%s' inside " 1228 "its own definition", u->identifier()); 1229 } 1230 } 1231 else if (bareType->kind() == IdlType::tk_sequence) { 1232 // Look for recursive sequence 1233 IdlType* t = bareType; 1234 while (t && t->kind() == IdlType::tk_sequence) 1235 t = ((SequenceType*)t)->seqType()->unalias(); 1236 1237 if (!t) return; // Sequence of undeclared type 1238 1239 if (t->kind() == IdlType::tk_struct) { 1240 Struct* s = (Struct*)((DeclaredType*)t)->decl(); 1241 if (!s->finished()) { 1242 s->setRecursive(); 1243 IdlWarning(file, line, 1244 "Anonymous sequences for recursive structures " 1245 "are deprecated. Use a forward declaration instead."); 1246 } 1247 } 1248 else if (t->kind() == IdlType::tk_union) { 1249 Union* u = (Union*)((DeclaredType*)t)->decl(); 1250 if (!u->finished()) { 1251 u->setRecursive(); 1252 IdlWarning(file, line, 1253 "Anonymous sequences for recursive unions " 1254 "are deprecated. Use a forward declaration instead."); 1255 } 1256 } 1257 else if (t->kind() == IdlType::ot_structforward) { 1258 StructForward* f = (StructForward*)((DeclaredType*)t)->decl(); 1259 Struct* s = f->definition(); 1260 if (s) { 1261 if (!s->finished()) 1262 s->setRecursive(); 1263 } 1264 else { 1265 char* ssn = f->scopedName()->toString(); 1266 IdlError(file, line, 1267 "Cannot use sequence of forward-declared struct '%s' " 1268 "before it is fully defined", ssn); 1269 IdlErrorCont(f->file(), f->line(), 1270 "('%s' forward-declared here)", f->identifier()); 1271 delete [] ssn; 1272 } 1273 } 1274 else if (t->kind() == IdlType::ot_unionforward) { 1275 UnionForward* f = (UnionForward*)((DeclaredType*)t)->decl(); 1276 Union* u = f->definition(); 1277 if (u) { 1278 if (!u->finished()) 1279 u->setRecursive(); 1280 } 1281 else { 1282 char* ssn = f->scopedName()->toString(); 1283 IdlError(file, line, 1284 "Cannot use sequence of forward-declared union '%s' " 1285 "before it is fully defined", ssn); 1286 IdlErrorCont(f->file(), f->line(), 1287 "('%s' forward-declared here)", f->identifier()); 1288 delete [] ssn; 1289 } 1290 } 1291 } 1292 for (Declarator* d = declarators; d; d = (Declarator*)d->next()) { 1293 Scope::current()->addInstance(d->eidentifier(), d, memberType, 1294 d->file(), d->line()); 1295 } 1296} 1297 1298Member:: 1299~Member() 1300{ 1301 if (declarators_) delete declarators_; 1302 if (delType_) delete memberType_; 1303} 1304 1305// Struct 1306Struct:: 1307Struct(const char* file, int line, IDL_Boolean mainFile, 1308 const char* identifier) 1309 1310 : Decl(D_STRUCT, file, line, mainFile), 1311 DeclRepoId(identifier), 1312 members_(0), 1313 recursive_(0), 1314 finished_(0) 1315{ 1316 // Look for forward struct 1317 Scope::Entry* se = Scope::current()->find(identifier); 1318 1319 if (se && 1320 se->kind() == Scope::Entry::E_DECL && 1321 se->decl()->kind() == Decl::D_STRUCTFORWARD) { 1322 1323 StructForward* f = (StructForward*)se->decl(); 1324 1325 if (strcmp(f->file(), file)) { 1326 IdlError(file, line, 1327 "Struct '%s' defined in different source file to " 1328 "its forward declaration", identifier); 1329 IdlErrorCont(f->file(), f->line(), 1330 "('%s' forward declared here)", identifier); 1331 } 1332 if (strcmp(f->prefix(), prefix())) { 1333 IdlError(file, line, 1334 "In declaration of struct '%s', repository id " 1335 "prefix '%s' differs from that of forward declaration", 1336 identifier, prefix()); 1337 1338 IdlErrorCont(f->file(), f->line(), 1339 "('%s' forward declared here with prefix '%s')", 1340 f->identifier(), f->prefix()); 1341 } 1342 if (f->repoIdSet()) setRepoId(f->repoId(), f->rifile(), f->riline()); 1343 f->setDefinition(this); 1344 Scope::current()->remEntry(se); 1345 } 1346 Scope* s = Scope::current()->newStructScope(identifier, file, line); 1347 thisType_ = new DeclaredType(IdlType::tk_struct, this, this); 1348 Scope::current()->addDecl(identifier, s, this, thisType_, file, line); 1349 Scope::startScope(s); 1350 Prefix::newScope(identifier); 1351} 1352 1353Struct:: 1354~Struct() 1355{ 1356 if (members_) delete members_; 1357 delete thisType_; 1358} 1359 1360void 1361Struct:: 1362finishConstruction(Member* members) 1363{ 1364 // Is this a local type? 1365 for (Member* m = members; m; m = (Member*)m->next()) { 1366 if (m->memberType() && m->memberType()->local()) { 1367 thisType()->setLocal(); 1368 break; 1369 } 1370 } 1371 members_ = members; 1372 Prefix::endScope(); 1373 Scope::endScope(); 1374 finished_ = 1; 1375 mostRecent_ = this; 1376} 1377 1378// StructForward 1379StructForward:: 1380StructForward(const char* file, int line, IDL_Boolean mainFile, 1381 const char* identifier) 1382 : Decl(D_STRUCTFORWARD, file, line, mainFile), 1383 DeclRepoId(identifier), 1384 definition_(0), 1385 firstForward_(0), 1386 thisType_(0) 1387{ 1388 Scope::Entry* se = Scope::current()->find(identifier); 1389 IDL_Boolean reg = 1; 1390 1391 if (se && se->kind() == Scope::Entry::E_DECL) { 1392 1393 if (se->decl()->kind() == D_STRUCT) { 1394 Struct* s = (Struct*)se->decl(); 1395 definition_ = s; 1396 1397 if (strcmp(s->file(), file)) { 1398 IdlError(file, line, 1399 "Struct '%s' forward declared in different source file to " 1400 "its definition", identifier); 1401 IdlErrorCont(s->file(), s->line(), 1402 "('%s' defined here)", identifier); 1403 } 1404 if (strcmp(s->prefix(), prefix())) { 1405 IdlError(file, line, 1406 "In forward declaration of struct '%s', repository " 1407 "id prefix '%s' differs from that of earlier declaration", 1408 identifier, prefix()); 1409 1410 IdlErrorCont(s->file(), s->line(), 1411 "('%s' fully declared here with prefix '%s')", 1412 s->identifier(), s->prefix()); 1413 } 1414 reg = 0; 1415 } 1416 else if (se->decl()->kind() == D_STRUCTFORWARD) { 1417 StructForward* s = (StructForward*)se->decl(); 1418 firstForward_ = s; 1419 1420 if (strcmp(s->file(), file)) { 1421 IdlError(file, line, 1422 "Struct '%s' forward declared in more than one " 1423 "source file", identifier); 1424 IdlErrorCont(s->file(), s->line(), 1425 "('%s' also forward declared here)", identifier); 1426 } 1427 if (strcmp(s->prefix(), prefix())) { 1428 IdlError(file, line, 1429 "In forward declaration of struct '%s', repository " 1430 "id prefix '%s' differs from that of earlier declaration", 1431 identifier, prefix()); 1432 1433 IdlErrorCont(s->file(), s->line(), 1434 "('%s' forward declared here with prefix '%s')", 1435 s->identifier(), s->prefix()); 1436 } 1437 reg = 0; 1438 } 1439 } 1440 if (reg) { 1441 thisType_ = new DeclaredType(IdlType::ot_structforward, this, this); 1442 Scope::current()->addDecl(identifier, 0, this, thisType_, file, line); 1443 } 1444} 1445 1446StructForward:: 1447~StructForward() 1448{