Decl.h revision d664ff7beb054a2f2f56ec438ff3ce65be96eddc
1//===--- Decl.h - Classes for representing declarations ---------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the Decl interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_DECL_H 15#define LLVM_CLANG_AST_DECL_H 16 17#include "clang/Basic/SourceLocation.h" 18#include "clang/AST/Type.h" 19#include "llvm/ADT/APSInt.h" 20#include "clang/Lex/IdentifierTable.h" // FIXME: should be in Basic, not Lex. 21 22namespace clang { 23class Expr; 24class Stmt; 25class FunctionDecl; 26class AttributeList; 27class ObjcIvarDecl; 28class ObjcMethodDecl; 29class ObjcProtocolDecl; 30class ObjcCategoryDecl; 31 32/// Decl - This represents one declaration (or definition), e.g. a variable, 33/// typedef, function, struct, etc. 34/// 35class Decl { 36public: 37 enum Kind { 38 // Concrete sub-classes of ValueDecl 39 Function, BlockVariable, FileVariable, ParmVariable, EnumConstant, 40 // Concrete sub-classes of TypeDecl 41 Typedef, Struct, Union, Class, Enum, ObjcInterface, ObjcClass, ObjcMethod, 42 ObjcProtocol, ObjcForwardProtocol, ObjcCategory, 43 ObjcImplementation, 44 // Concrete sub-class of Decl 45 Field, ObjcIvar 46 }; 47 48 /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces, 49 /// labels, tags, members and ordinary identifiers. 50 /// Objective-c protocols have their own namespace, so a protocol can have 51 /// the same name as category, class, struct, typedef, etc. 52 enum IdentifierNamespace { 53 IDNS_Label, 54 IDNS_Tag, 55 IDNS_Member, 56 IDNS_Protocol, 57 IDNS_Ordinary 58 }; 59 60 enum ImplementationControl { None, Required, Optional }; 61 62private: 63 /// DeclKind - This indicates which class this is. 64 Kind DeclKind : 8; 65 66 /// InvalidDecl - This indicates a semantic error occurred. 67 unsigned int InvalidDecl : 1; 68 69 /// instance (true) or class (false) method. 70 bool IsInstance : 1; 71 /// @required/@optional 72 ImplementationControl DeclImplementation : 2; 73 74protected: 75 Decl(Kind DK) : DeclKind(DK), InvalidDecl(0), 76 IsInstance(false), DeclImplementation(None) { 77 if (Decl::CollectingStats()) addDeclKind(DK); 78 } 79 80 Decl(Kind DK, bool isInstance, ImplementationControl implControl) 81 : DeclKind(DK), InvalidDecl(0), 82 IsInstance(isInstance), DeclImplementation(implControl) { 83 if (Decl::CollectingStats()) addDeclKind(DK); 84 } 85 virtual ~Decl(); 86 87public: 88 89 Kind getKind() const { return DeclKind; } 90 const char *getDeclKindName() const; 91 92 /// setInvalidDecl - Indicates the Decl had a semantic error. This 93 /// allows for graceful error recovery. 94 void setInvalidDecl() { InvalidDecl = 1; } 95 int isInvalidDecl() const { return InvalidDecl; } 96 bool isInstance() const { return IsInstance; } 97 ImplementationControl getImplementationControl() const 98 { return DeclImplementation; } 99 100 IdentifierNamespace getIdentifierNamespace() const { 101 switch (DeclKind) { 102 default: assert(0 && "Unknown decl kind!"); 103 case Typedef: 104 case Function: 105 case BlockVariable: 106 case FileVariable: 107 case ParmVariable: 108 case EnumConstant: 109 case ObjcInterface: 110 return IDNS_Ordinary; 111 case Struct: 112 case Union: 113 case Class: 114 case Enum: 115 return IDNS_Tag; 116 case ObjcProtocol: 117 return IDNS_Protocol; 118 } 119 } 120 // global temp stats (until we have a per-module visitor) 121 static void addDeclKind(const Kind k); 122 static bool CollectingStats(bool enable=false); 123 static void PrintStats(); 124 125 // Implement isa/cast/dyncast/etc. 126 static bool classof(const Decl *) { return true; } 127}; 128 129/// ScopedDecl - Represent lexically scoped names, used for all ValueDecl's 130/// and TypeDecl's. 131class ScopedDecl : public Decl { 132 /// Identifier - The identifier for this declaration (e.g. the name for the 133 /// variable, the tag for a struct). 134 IdentifierInfo *Identifier; 135 136 /// Loc - The location that this decl. 137 SourceLocation Loc; 138 139 /// NextDeclarator - If this decl was part of a multi-declarator declaration, 140 /// such as "int X, Y, *Z;" this indicates Decl for the next declarator. 141 ScopedDecl *NextDeclarator; 142 143 /// When this decl is in scope while parsing, the Next field contains a 144 /// pointer to the shadowed decl of the same name. When the scope is popped, 145 /// Decls are relinked onto a containing decl object. 146 /// 147 ScopedDecl *Next; 148protected: 149 ScopedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) 150 : Decl(DK), Identifier(Id), Loc(L), NextDeclarator(PrevDecl), Next(0) {} 151public: 152 IdentifierInfo *getIdentifier() const { return Identifier; } 153 SourceLocation getLocation() const { return Loc; } 154 void setLocation(SourceLocation L) { Loc = L; } 155 const char *getName() const; 156 157 ScopedDecl *getNext() const { return Next; } 158 void setNext(ScopedDecl *N) { Next = N; } 159 160 /// getNextDeclarator - If this decl was part of a multi-declarator 161 /// declaration, such as "int X, Y, *Z;" this returns the decl for the next 162 /// declarator. Otherwise it returns null. 163 ScopedDecl *getNextDeclarator() { return NextDeclarator; } 164 const ScopedDecl *getNextDeclarator() const { return NextDeclarator; } 165 void setNextDeclarator(ScopedDecl *N) { NextDeclarator = N; } 166 167 // Implement isa/cast/dyncast/etc. - true for all ValueDecl's and TypeDecl's. 168 static bool classof(const Decl *D) { 169 return (D->getKind() >= Function && D->getKind() <= EnumConstant) || 170 (D->getKind() >= Typedef && D->getKind() <= Enum); 171 } 172 static bool classof(const ScopedDecl *D) { return true; } 173}; 174 175/// ValueDecl - Represent the declaration of a variable (in which case it is 176/// an lvalue) a function (in which case it is a function designator) or 177/// an enum constant. 178class ValueDecl : public ScopedDecl { 179 QualType DeclType; 180protected: 181 ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, 182 ScopedDecl *PrevDecl) : ScopedDecl(DK, L, Id, PrevDecl), DeclType(T) {} 183public: 184 QualType getType() const { return DeclType; } 185 void setType(QualType newType) { DeclType = newType; } 186 QualType getCanonicalType() const { return DeclType.getCanonicalType(); } 187 188 // Implement isa/cast/dyncast/etc. 189 static bool classof(const Decl *D) { 190 return D->getKind() >= Function && D->getKind() <= EnumConstant; 191 } 192 static bool classof(const ValueDecl *D) { return true; } 193}; 194 195/// VarDecl - An instance of this class is created to represent a variable 196/// declaration or definition. 197class VarDecl : public ValueDecl { 198public: 199 enum StorageClass { 200 None, Extern, Static, Auto, Register 201 }; 202 StorageClass getStorageClass() const { return SClass; } 203 204 const Expr *getInit() const { return Init; } 205 Expr *getInit() { return Init; } 206 void setInit(Expr *I) { Init = I; } 207 208 // hasAutoStorage - Returns true if either the implicit or explicit 209 // storage class of a variable is "auto." In particular, variables 210 // declared within a function that lack a storage keyword are 211 // implicitly "auto", but are represented internally with a storage 212 // class of None. 213 bool hasAutoStorage() { 214 return (SClass == Auto || (SClass == None && getKind() != FileVariable)); 215 } 216 217 // hasStaticStorage - Returns true if either the implicit or 218 // explicit storage class of a variable is "static." In 219 // particular, variables declared within a file (outside of a 220 // function) that lack a storage keyword are implicitly "static," 221 // but are represented internally with a storage class of "None". 222 bool hasStaticStorage() { 223 return (SClass == Static || (SClass == None && getKind() == FileVariable)); 224 } 225 226 // hasLocalStorage - Returns true if a variable with function scope 227 // is a non-static local variable. 228 bool hasLocalStorage() { return (hasAutoStorage() || SClass == Register); } 229 230 // hasGlobalStorage - Returns true for all variables that do not 231 // have local storage. This includs all global variables as well 232 // as static variables declared within a function. 233 bool hasGlobalStorage() { return !hasAutoStorage(); } 234 235 // Implement isa/cast/dyncast/etc. 236 static bool classof(const Decl *D) { 237 return D->getKind() >= BlockVariable && D->getKind() <= ParmVariable; 238 } 239 static bool classof(const VarDecl *D) { return true; } 240protected: 241 VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, 242 StorageClass SC, ScopedDecl *PrevDecl) 243 : ValueDecl(DK, L, Id, T, PrevDecl), Init(0) { SClass = SC; } 244private: 245 StorageClass SClass; 246 Expr *Init; 247}; 248 249/// BlockVarDecl - Represent a local variable declaration. 250class BlockVarDecl : public VarDecl { 251public: 252 BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, 253 ScopedDecl *PrevDecl) 254 : VarDecl(BlockVariable, L, Id, T, S, PrevDecl) {} 255 256 // Implement isa/cast/dyncast/etc. 257 static bool classof(const Decl *D) { return D->getKind() == BlockVariable; } 258 static bool classof(const BlockVarDecl *D) { return true; } 259}; 260 261/// FileVarDecl - Represent a file scoped variable declaration. This 262/// will allow us to reason about external variable declarations and tentative 263/// definitions (C99 6.9.2p2) using our type system (without storing a 264/// pointer to the decl's scope, which is transient). 265class FileVarDecl : public VarDecl { 266public: 267 FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, 268 ScopedDecl *PrevDecl) 269 : VarDecl(FileVariable, L, Id, T, S, PrevDecl) {} 270 271 // Implement isa/cast/dyncast/etc. 272 static bool classof(const Decl *D) { return D->getKind() == FileVariable; } 273 static bool classof(const FileVarDecl *D) { return true; } 274}; 275 276/// ParmVarDecl - Represent a parameter to a function. 277class ParmVarDecl : public VarDecl { 278public: 279 ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, 280 ScopedDecl *PrevDecl) 281 : VarDecl(ParmVariable, L, Id, T, S, PrevDecl) {} 282 283 // Implement isa/cast/dyncast/etc. 284 static bool classof(const Decl *D) { return D->getKind() == ParmVariable; } 285 static bool classof(const ParmVarDecl *D) { return true; } 286}; 287 288/// FunctionDecl - An instance of this class is created to represent a function 289/// declaration or definition. 290class FunctionDecl : public ValueDecl { 291public: 292 enum StorageClass { 293 None, Extern, Static 294 }; 295 FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T, 296 StorageClass S = None, bool isInline = false, 297 ScopedDecl *PrevDecl = 0) 298 : ValueDecl(Function, L, Id, T, PrevDecl), 299 ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {} 300 virtual ~FunctionDecl(); 301 302 Stmt *getBody() const { return Body; } 303 void setBody(Stmt *B) { Body = B; } 304 305 ScopedDecl *getDeclChain() const { return DeclChain; } 306 void setDeclChain(ScopedDecl *D) { DeclChain = D; } 307 308 unsigned getNumParams() const; 309 const ParmVarDecl *getParamDecl(unsigned i) const { 310 assert(i < getNumParams() && "Illegal param #"); 311 return ParamInfo[i]; 312 } 313 ParmVarDecl *getParamDecl(unsigned i) { 314 assert(i < getNumParams() && "Illegal param #"); 315 return ParamInfo[i]; 316 } 317 void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams); 318 319 QualType getResultType() const { 320 return cast<FunctionType>(getType())->getResultType(); 321 } 322 StorageClass getStorageClass() const { return SClass; } 323 bool isInline() const { return IsInline; } 324 325 // Implement isa/cast/dyncast/etc. 326 static bool classof(const Decl *D) { return D->getKind() == Function; } 327 static bool classof(const FunctionDecl *D) { return true; } 328private: 329 /// ParamInfo - new[]'d array of pointers to VarDecls for the formal 330 /// parameters of this function. This is null if a prototype or if there are 331 /// no formals. TODO: we could allocate this space immediately after the 332 /// FunctionDecl object to save an allocation like FunctionType does. 333 ParmVarDecl **ParamInfo; 334 335 Stmt *Body; // Null if a prototype. 336 337 /// DeclChain - Linked list of declarations that are defined inside this 338 /// function. 339 ScopedDecl *DeclChain; 340 341 StorageClass SClass : 2; 342 bool IsInline : 1; 343}; 344 345 346/// FieldDecl - An instance of this class is created by Sema::ActOnField to 347/// represent a member of a struct/union/class. 348class FieldDecl : public Decl { 349 /// Identifier - The identifier for this declaration (e.g. the name for the 350 /// variable, the tag for a struct). 351 IdentifierInfo *Identifier; 352 353 /// Loc - The location that this decl. 354 SourceLocation Loc; 355 356 QualType DeclType; 357public: 358 FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T) 359 : Decl(Field), Identifier(Id), Loc(L), DeclType(T) {} 360 FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T) 361 : Decl(DK), Identifier(Id), Loc(L), DeclType(T) {} 362 363 IdentifierInfo *getIdentifier() const { return Identifier; } 364 SourceLocation getLocation() const { return Loc; } 365 void setLocation(SourceLocation L) { Loc = L; } 366 const char *getName() const; 367 368 QualType getType() const { return DeclType; } 369 QualType getCanonicalType() const { return DeclType.getCanonicalType(); } 370 371 // Implement isa/cast/dyncast/etc. 372 static bool classof(const Decl *D) { 373 return D->getKind() == Field || D->getKind() == ObjcIvar; 374 } 375 static bool classof(const FieldDecl *D) { return true; } 376}; 377 378/// EnumConstantDecl - An instance of this object exists for each enum constant 379/// that is defined. For example, in "enum X {a,b}", each of a/b are 380/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a 381/// TagType for the X EnumDecl. 382class EnumConstantDecl : public ValueDecl { 383 Expr *Init; // an integer constant expression 384 llvm::APSInt Val; // The value. 385public: 386 EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, 387 const llvm::APSInt &V, ScopedDecl *PrevDecl) 388 : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {} 389 390 const Expr *getInitExpr() const { return Init; } 391 Expr *getInitExpr() { return Init; } 392 const llvm::APSInt &getInitVal() const { return Val; } 393 394 void setInitExpr(Expr *E) { Init = E; } 395 void setInitVal(llvm::APSInt &V) { Val = V; } 396 397 // Implement isa/cast/dyncast/etc. 398 static bool classof(const Decl *D) { 399 return D->getKind() == EnumConstant; 400 } 401 static bool classof(const EnumConstantDecl *D) { return true; } 402}; 403 404 405/// TypeDecl - Represents a declaration of a type. 406/// 407class TypeDecl : public ScopedDecl { 408 /// TypeForDecl - This indicates the Type object that represents this 409 /// TypeDecl. It is a cache maintained by ASTContext::getTypedefType and 410 /// ASTContext::getTagDeclType. 411 Type *TypeForDecl; 412 friend class ASTContext; 413protected: 414 TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) 415 : ScopedDecl(DK, L, Id, PrevDecl), TypeForDecl(0) {} 416public: 417 // Implement isa/cast/dyncast/etc. 418 static bool classof(const Decl *D) { 419 return D->getKind() >= Typedef && D->getKind() <= Enum; 420 } 421 static bool classof(const TypeDecl *D) { return true; } 422}; 423 424 425class TypedefDecl : public TypeDecl { 426 /// UnderlyingType - This is the type the typedef is set to. 427 QualType UnderlyingType; 428public: 429 TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PD) 430 : TypeDecl(Typedef, L, Id, PD), UnderlyingType(T) {} 431 432 QualType getUnderlyingType() const { return UnderlyingType; } 433 void setUnderlyingType(QualType newType) { UnderlyingType = newType; } 434 435 // Implement isa/cast/dyncast/etc. 436 static bool classof(const Decl *D) { return D->getKind() == Typedef; } 437 static bool classof(const TypedefDecl *D) { return true; } 438}; 439 440 441/// TagDecl - Represents the declaration of a struct/union/class/enum. 442class TagDecl : public TypeDecl { 443 /// IsDefinition - True if this is a definition ("struct foo {};"), false if 444 /// it is a declaration ("struct foo;"). 445 bool IsDefinition : 1; 446protected: 447 TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) 448 : TypeDecl(DK, L, Id, PrevDecl) { 449 IsDefinition = false; 450 } 451public: 452 453 /// isDefinition - Return true if this decl has its body specified. 454 bool isDefinition() const { 455 return IsDefinition; 456 } 457 458 const char *getKindName() const { 459 switch (getKind()) { 460 default: assert(0 && "Unknown TagDecl!"); 461 case Struct: return "struct"; 462 case Union: return "union"; 463 case Class: return "class"; 464 case Enum: return "enum"; 465 } 466 } 467 468 // Implement isa/cast/dyncast/etc. 469 static bool classof(const Decl *D) { 470 return D->getKind() == Struct || D->getKind() == Union || 471 D->getKind() == Class || D->getKind() == Enum; 472 } 473 static bool classof(const TagDecl *D) { return true; } 474protected: 475 void setDefinition(bool V) { IsDefinition = V; } 476}; 477 478/// EnumDecl - Represents an enum. As an extension, we allow forward-declared 479/// enums. 480class EnumDecl : public TagDecl { 481 /// ElementList - this is a linked list of EnumConstantDecl's which are linked 482 /// together through their getNextDeclarator pointers. 483 EnumConstantDecl *ElementList; 484 485 /// IntegerType - This represent the integer type that the enum corresponds 486 /// to for code generation purposes. Note that the enumerator constants may 487 /// have a different type than this does. 488 QualType IntegerType; 489public: 490 EnumDecl(SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) 491 : TagDecl(Enum, L, Id, PrevDecl) { 492 ElementList = 0; 493 } 494 495 /// defineElements - When created, EnumDecl correspond to a forward declared 496 /// enum. This method is used to mark the decl as being defined, with the 497 /// specified list of enums. 498 void defineElements(EnumConstantDecl *ListHead, QualType NewType) { 499 assert(!isDefinition() && "Cannot redefine enums!"); 500 ElementList = ListHead; 501 setDefinition(true); 502 503 IntegerType = NewType; 504 } 505 506 /// getIntegerType - Return the integer type this enum decl corresponds to. 507 /// This returns a null qualtype for an enum forward definition. 508 QualType getIntegerType() const { return IntegerType; } 509 510 /// getEnumConstantList - Return the first EnumConstantDecl in the enum. 511 /// 512 EnumConstantDecl *getEnumConstantList() { return ElementList; } 513 const EnumConstantDecl *getEnumConstantList() const { return ElementList; } 514 515 static bool classof(const Decl *D) { 516 return D->getKind() == Enum; 517 } 518 static bool classof(const EnumDecl *D) { return true; } 519}; 520 521 522/// RecordDecl - Represents a struct/union/class. For example: 523/// struct X; // Forward declaration, no "body". 524/// union Y { int A, B; }; // Has body with members A and B (FieldDecls). 525/// 526class RecordDecl : public TagDecl { 527 /// HasFlexibleArrayMember - This is true if this struct ends with a flexible 528 /// array member (e.g. int X[]) or if this union contains a struct that does. 529 /// If so, this cannot be contained in arrays or other structs as a member. 530 bool HasFlexibleArrayMember : 1; 531 532 /// Members/NumMembers - This is a new[]'d array of pointers to Decls. 533 FieldDecl **Members; // Null if not defined. 534 int NumMembers; // -1 if not defined. 535public: 536 RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl*PrevDecl) 537 : TagDecl(DK, L, Id, PrevDecl) { 538 HasFlexibleArrayMember = false; 539 assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); 540 Members = 0; 541 NumMembers = -1; 542 } 543 544 bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } 545 void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; } 546 547 /// getNumMembers - Return the number of members, or -1 if this is a forward 548 /// definition. 549 int getNumMembers() const { return NumMembers; } 550 const FieldDecl *getMember(unsigned i) const { return Members[i]; } 551 FieldDecl *getMember(unsigned i) { return Members[i]; } 552 553 /// defineBody - When created, RecordDecl's correspond to a forward declared 554 /// record. This method is used to mark the decl as being defined, with the 555 /// specified contents. 556 void defineBody(FieldDecl **Members, unsigned numMembers); 557 558 /// getMember - If the member doesn't exist, or there are no members, this 559 /// function will return 0; 560 FieldDecl *getMember(IdentifierInfo *name); 561 562 static bool classof(const Decl *D) { 563 return D->getKind() == Struct || D->getKind() == Union || 564 D->getKind() == Class; 565 } 566 static bool classof(const RecordDecl *D) { return true; } 567}; 568 569class ObjcInterfaceDecl : public TypeDecl { 570 571 /// Class's super class. 572 ObjcInterfaceDecl *SuperClass; 573 574 /// Protocols referenced in interface header declaration 575 ObjcProtocolDecl **IntfRefProtocols; // Null if no referenced protocols 576 int NumIntfRefProtocols; // -1 if no referenced protocols 577 578 /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls. 579 ObjcIvarDecl **Ivars; // Null if class has no ivars 580 int NumIvars; // -1 if class has no ivars 581 582 /// instance methods 583 ObjcMethodDecl **InsMethods; // Null if class has no instance methods 584 int NumInsMethods; // -1 if class has no instance methods 585 586 /// class methods 587 ObjcMethodDecl **ClsMethods; // Null if class has no class methods 588 int NumClsMethods; // -1 if class has no class methods 589 590 /// List of categories defined for this class. 591 ObjcCategoryDecl *ListCategories; 592 593 bool isForwardDecl; // declared with @class. 594public: 595 ObjcInterfaceDecl(SourceLocation L, unsigned numRefProtos, 596 IdentifierInfo *Id, bool FD = false) 597 : TypeDecl(ObjcInterface, L, Id, 0), 598 SuperClass(0), 599 IntfRefProtocols(0), NumIntfRefProtocols(-1), 600 Ivars(0), NumIvars(-1), 601 InsMethods(0), NumInsMethods(-1), ClsMethods(0), NumClsMethods(-1), 602 ListCategories(0), 603 isForwardDecl(FD) { 604 AllocIntfRefProtocols(numRefProtos); 605 } 606 607 void AllocIntfRefProtocols(unsigned numRefProtos) { 608 if (numRefProtos) { 609 IntfRefProtocols = new ObjcProtocolDecl*[numRefProtos]; 610 memset(IntfRefProtocols, '\0', 611 numRefProtos*sizeof(ObjcProtocolDecl*)); 612 NumIntfRefProtocols = numRefProtos; 613 } 614 } 615 616 ObjcProtocolDecl **getIntfRefProtocols() const { return IntfRefProtocols; } 617 int getNumIntfRefProtocols() const { return NumIntfRefProtocols; } 618 619 ObjcIvarDecl **getIntfDeclIvars() const { return Ivars; } 620 int getIntfDeclNumIvars() const { return NumIvars; } 621 622 ObjcMethodDecl** getInsMethods() const { return InsMethods; } 623 int getNumInsMethods() const { return NumInsMethods; } 624 625 ObjcMethodDecl** getClsMethods() const { return ClsMethods; } 626 int getNumClsMethods() const { return NumClsMethods; } 627 628 void ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars, 629 unsigned numIvars); 630 631 void ObjcAddMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, 632 ObjcMethodDecl **clsMethods, unsigned numClsMembers); 633 634 bool getIsForwardDecl() const { return isForwardDecl; } 635 void setIsForwardDecl(bool val) { isForwardDecl = val; } 636 637 void setIntfRefProtocols(int idx, ObjcProtocolDecl *OID) { 638 assert((idx < NumIntfRefProtocols) && "index out of range"); 639 IntfRefProtocols[idx] = OID; 640 } 641 642 ObjcInterfaceDecl *getSuperClass() const { return SuperClass; } 643 void setSuperClass(ObjcInterfaceDecl * superCls) { SuperClass = superCls; } 644 645 ObjcCategoryDecl* getListCategories() const { return ListCategories; } 646 void setListCategories(ObjcCategoryDecl *category) { 647 ListCategories = category; 648 } 649 650 static bool classof(const Decl *D) { 651 return D->getKind() == ObjcInterface; 652 } 653 static bool classof(const ObjcInterfaceDecl *D) { return true; } 654}; 655 656class ObjcIvarDecl : public FieldDecl { 657public: 658 ObjcIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T) 659 : FieldDecl(ObjcIvar, L, Id, T) {} 660 661 enum AccessControl { 662 None, Private, Protected, Public, Package 663 }; 664 void setAccessControl(AccessControl ac) { DeclAccess = ac; } 665 AccessControl getAccessControl() const { return DeclAccess; } 666 667 // Implement isa/cast/dyncast/etc. 668 static bool classof(const Decl *D) { return D->getKind() == ObjcIvar; } 669 static bool classof(const ObjcIvarDecl *D) { return true; } 670private: 671 AccessControl DeclAccess : 3; 672}; 673 674class ObjcClassDecl : public TypeDecl { 675 ObjcInterfaceDecl **ForwardDecls; // Null if not defined. 676 int NumForwardDecls; // -1 if not defined. 677public: 678 ObjcClassDecl(SourceLocation L, unsigned nElts) 679 : TypeDecl(ObjcClass, L, 0, 0) { 680 if (nElts) { 681 ForwardDecls = new ObjcInterfaceDecl*[nElts]; 682 memset(ForwardDecls, '\0', nElts*sizeof(ObjcInterfaceDecl*)); 683 } 684 NumForwardDecls = nElts; 685 } 686 void setInterfaceDecl(int idx, ObjcInterfaceDecl *OID) { 687 assert((idx < NumForwardDecls) && "index out of range"); 688 ForwardDecls[idx] = OID; 689 } 690 static bool classof(const Decl *D) { 691 return D->getKind() == ObjcClass; 692 } 693 static bool classof(const ObjcClassDecl *D) { return true; } 694}; 695 696/// ObjcMethodDecl - An instance of this class is created to represent an instance 697/// or class method declaration. 698class ObjcMethodDecl : public Decl { 699private: 700 // A unigue name for this method. 701 Selector SelName; 702 703 // Type of this method. 704 QualType MethodDeclType; 705 /// ParamInfo - new[]'d array of pointers to VarDecls for the formal 706 /// parameters of this Method. This is null if there are no formals. 707 ParmVarDecl **ParamInfo; 708 int NumMethodParams; // -1 if no parameters 709 710 /// List of attributes for this method declaration. 711 AttributeList *MethodAttrs; 712 713 /// Loc - location of this declaration. 714 SourceLocation Loc; 715 716public: 717 ObjcMethodDecl(SourceLocation L, Selector SelInfo, QualType T, 718 ParmVarDecl **paramInfo = 0, int numParams=-1, 719 AttributeList *M = 0, bool isInstance = true, 720 ImplementationControl impControl = None, 721 Decl *PrevDecl = 0) 722 : Decl(ObjcMethod, isInstance, impControl), 723 SelName(SelInfo), MethodDeclType(T), 724 ParamInfo(paramInfo), NumMethodParams(numParams), 725 MethodAttrs(M), Loc(L) {} 726#if 0 727 ObjcMethodDecl(Kind DK, SourceLocation L, IdentifierInfo &SelId, QualType T, 728 ParmVarDecl **paramInfo = 0, int numParams=-1, 729 AttributeList *M = 0, bool isInstance = true, 730 Decl *PrevDecl = 0) 731 : Decl(DK), Selector(SelId), MethodDeclType(T), 732 ParamInfo(paramInfo), NumMethodParams(numParams), 733 MethodAttrs(M), IsInstance(isInstance) {} 734#endif 735 virtual ~ObjcMethodDecl(); 736 Selector getSelector() const { return SelName; } 737 QualType getMethodType() const { return MethodDeclType; } 738 unsigned getNumMethodParams() const { return NumMethodParams; } 739 ParmVarDecl *getMethodParamDecl(unsigned i) { 740 assert(i < getNumMethodParams() && "Illegal param #"); 741 return ParamInfo[i]; 742 } 743 void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams); 744 745 AttributeList *getMethodAttrs() const {return MethodAttrs;} 746 SourceLocation getLocation() const { return Loc; } 747 748 // Implement isa/cast/dyncast/etc. 749 static bool classof(const Decl *D) { 750 return D->getKind() == ObjcMethod; 751 } 752 static bool classof(const ObjcMethodDecl *D) { return true; } 753}; 754 755class ObjcProtocolDecl : public TypeDecl { 756 /// referenced protocols 757 ObjcProtocolDecl **ReferencedProtocols; // Null if none 758 int NumReferencedProtocols; // -1 if none 759 760 /// protocol instance methods 761 ObjcMethodDecl **ProtoInsMethods; // Null if not defined 762 int NumProtoInsMethods; // -1 if not defined 763 764 /// protocol class methods 765 ObjcMethodDecl **ProtoClsMethods; // Null if not defined 766 int NumProtoClsMethods; // -1 if not defined 767 768 bool isForwardProtoDecl; // declared with @protocol. 769public: 770 ObjcProtocolDecl(SourceLocation L, unsigned numRefProtos, 771 IdentifierInfo *Id, bool FD = false) 772 : TypeDecl(ObjcProtocol, L, Id, 0), 773 ReferencedProtocols(0), NumReferencedProtocols(-1), 774 ProtoInsMethods(0), NumProtoInsMethods(-1), 775 ProtoClsMethods(0), NumProtoClsMethods(-1), 776 isForwardProtoDecl(FD) { 777 AllocReferencedProtocols(numRefProtos); 778 } 779 void AllocReferencedProtocols(unsigned numRefProtos) { 780 if (numRefProtos) { 781 ReferencedProtocols = new ObjcProtocolDecl*[numRefProtos]; 782 memset(ReferencedProtocols, '\0', 783 numRefProtos*sizeof(ObjcProtocolDecl*)); 784 NumReferencedProtocols = numRefProtos; 785 } 786 } 787 void ObjcAddProtoMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, 788 ObjcMethodDecl **clsMethods, unsigned numClsMembers); 789 790 void setReferencedProtocols(int idx, ObjcProtocolDecl *OID) { 791 assert((idx < NumReferencedProtocols) && "index out of range"); 792 ReferencedProtocols[idx] = OID; 793 } 794 795 ObjcProtocolDecl** getReferencedProtocols() const { 796 return ReferencedProtocols; 797 } 798 int getNumReferencedProtocols() const { return NumReferencedProtocols; } 799 800 ObjcMethodDecl** getInsMethods() const { return ProtoInsMethods; } 801 int getNumInsMethods() const { return NumProtoInsMethods; } 802 803 ObjcMethodDecl** getClsMethods() const { return ProtoClsMethods; } 804 int getNumClsMethods() const { return NumProtoClsMethods; } 805 806 bool getIsForwardProtoDecl() const { return isForwardProtoDecl; } 807 void setIsForwardProtoDecl(bool val) { isForwardProtoDecl = val; } 808 809 static bool classof(const Decl *D) { 810 return D->getKind() == ObjcProtocol; 811 } 812 static bool classof(const ObjcProtocolDecl *D) { return true; } 813}; 814 815class ObjcForwardProtocolDecl : public TypeDecl { 816 ObjcProtocolDecl **ForwardProtocolDecls; // Null if not defined. 817 int NumForwardProtocolDecls; // -1 if not defined. 818 public: 819 ObjcForwardProtocolDecl(SourceLocation L, unsigned nElts) 820 : TypeDecl(ObjcForwardProtocol, L, 0, 0) { 821 if (nElts) { 822 ForwardProtocolDecls = new ObjcProtocolDecl*[nElts]; 823 memset(ForwardProtocolDecls, '\0', nElts*sizeof(ObjcProtocolDecl*)); 824 NumForwardProtocolDecls = nElts; 825 } 826 } 827 void setForwardProtocolDecl(int idx, ObjcProtocolDecl *OID) { 828 assert((idx < NumForwardProtocolDecls) && "index out of range"); 829 ForwardProtocolDecls[idx] = OID; 830 } 831 static bool classof(const Decl *D) { 832 return D->getKind() == ObjcForwardProtocol; 833 } 834 static bool classof(const ObjcForwardProtocolDecl *D) { return true; } 835}; 836 837class ObjcCategoryDecl : public ScopedDecl { 838 /// Interface belonging to this category 839 ObjcInterfaceDecl *ClassInterface; 840 841 /// Category name 842 IdentifierInfo *ObjcCatName; 843 844 /// referenced protocols in this category 845 ObjcProtocolDecl **CatReferencedProtocols; // Null if none 846 int NumCatReferencedProtocols; // -1 if none 847 848 /// category instance methods 849 ObjcMethodDecl **CatInsMethods; // Null if not defined 850 int NumCatInsMethods; // -1 if not defined 851 852 /// category class methods 853 ObjcMethodDecl **CatClsMethods; // Null if not defined 854 int NumCatClsMethods; // -1 if not defined 855 856 /// Next category belonging to this class 857 ObjcCategoryDecl *NextClassCategory; 858 859public: 860 ObjcCategoryDecl(SourceLocation L, unsigned numRefProtocol, 861 IdentifierInfo *Id) 862 : ScopedDecl(ObjcCategory, L, Id, 0), 863 ClassInterface(0), ObjcCatName(0), 864 CatReferencedProtocols(0), NumCatReferencedProtocols(-1), 865 CatInsMethods(0), NumCatInsMethods(-1), 866 CatClsMethods(0), NumCatClsMethods(-1), 867 NextClassCategory(0) { 868 if (numRefProtocol) { 869 CatReferencedProtocols = new ObjcProtocolDecl*[numRefProtocol]; 870 memset(CatReferencedProtocols, '\0', 871 numRefProtocol*sizeof(ObjcProtocolDecl*)); 872 NumCatReferencedProtocols = numRefProtocol; 873 } 874 } 875 876 ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; } 877 void setClassInterface(ObjcInterfaceDecl *IDecl) { ClassInterface = IDecl; } 878 879 void setCatReferencedProtocols(int idx, ObjcProtocolDecl *OID) { 880 assert((idx < NumCatReferencedProtocols) && "index out of range"); 881 CatReferencedProtocols[idx] = OID; 882 } 883 884 void ObjcAddCatMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, 885 ObjcMethodDecl **clsMethods, unsigned numClsMembers); 886 887 IdentifierInfo *getCatName() const { return ObjcCatName; } 888 void setCatName(IdentifierInfo *catName) { ObjcCatName = catName; } 889 890 ObjcCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 891 void insertNextClassCategory() { 892 NextClassCategory = ClassInterface->getListCategories(); 893 ClassInterface->setListCategories(this); 894 } 895 896 static bool classof(const Decl *D) { 897 return D->getKind() == ObjcCategory; 898 } 899 static bool classof(const ObjcCategoryDecl *D) { return true; } 900}; 901 902class ObjcImplementationDecl : public TypeDecl { 903 904 /// Implementation Class's super class. 905 ObjcInterfaceDecl *SuperClass; 906 907 /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls. 908 ObjcIvarDecl **Ivars; // Null if not specified 909 int NumIvars; // -1 if not defined. 910 911 /// implemented instance methods 912 ObjcMethodDecl **InsMethods; // Null if not defined 913 int NumInsMethods; // -1 if not defined 914 915 /// implemented class methods 916 ObjcMethodDecl **ClsMethods; // Null if not defined 917 int NumClsMethods; // -1 if not defined 918 919 public: 920 ObjcImplementationDecl(SourceLocation L, IdentifierInfo *Id, 921 ObjcInterfaceDecl* superDecl) 922 : TypeDecl(ObjcImplementation, L, Id, 0), 923 SuperClass(superDecl), 924 Ivars(0), NumIvars(-1), 925 InsMethods(0), NumInsMethods(-1), ClsMethods(0), NumClsMethods(-1) {} 926 927 void ObjcAddInstanceVariablesToClassImpl(ObjcIvarDecl **ivars, 928 unsigned numIvars); 929 930 void ObjcAddImplMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, 931 ObjcMethodDecl **clsMethods, unsigned numClsMembers); 932 933 ObjcInterfaceDecl *getImplSuperClass() const { return SuperClass; } 934 935 void setImplSuperClass(ObjcInterfaceDecl * superCls) 936 { SuperClass = superCls; } 937 938 ObjcMethodDecl **getInsMethods() const { return InsMethods; } 939 int getNumInsMethods() const { return NumInsMethods; } 940 941 ObjcMethodDecl **getClsMethods() const { return ClsMethods; } 942 int getNumClsMethods() const { return NumClsMethods; } 943 944 static bool classof(const Decl *D) { 945 return D->getKind() == ObjcImplementation; 946 } 947 static bool classof(const ObjcImplementationDecl *D) { return true; } 948}; 949 950 951} // end namespace clang 952#endif 953