Decl.h revision 05672a0ce85f6a203a960a856d30c4606ab136a7
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 21namespace clang { 22class Expr; 23class Stmt; 24class FunctionDecl; 25class AttributeList; 26class IdentifierInfo; 27 28/// Decl - This represents one declaration (or definition), e.g. a variable, 29/// typedef, function, struct, etc. 30/// 31class Decl { 32public: 33 enum Kind { 34 // This lists the concrete classes of Decl in order of the inheritance 35 // hierarchy. This allows us to do efficient classof tests based on the 36 // enums below. The commented out names are abstract class names. 37 38 // Decl 39 // NamedDecl 40 Field, 41 ObjcIvar, 42 ObjcCategory, 43 ObjcCategoryImpl, 44 ObjcImplementation, 45 // ScopedDecl 46 ObjcProtocol, 47 // TypeDecl 48 ObjcInterface, 49 Typedef, 50 // TagDecl 51 Enum, 52 // RecordDecl, 53 Struct, 54 Union, 55 Class, 56 // ValueDecl 57 EnumConstant, 58 Function, 59 // VarDecl 60 BlockVar, 61 FileVar, 62 ParmVar, 63 ObjcMethod, 64 ObjcClass, 65 ObjcForwardProtocol, 66 67 // For each non-leaf class, we now define a mapping to the first/last member 68 // of the class, to allow efficient classof. 69 NamedFirst = Field, NamedLast = ParmVar, 70 FieldFirst = Field, FieldLast = ObjcIvar, 71 ScopedFirst = ObjcProtocol, ScopedLast = ParmVar, 72 TypeFirst = ObjcInterface, TypeLast = Class, 73 TagFirst = Enum , TagLast = Class, 74 RecordFirst = Struct , RecordLast = Class, 75 ValueFirst = EnumConstant , ValueLast = ParmVar, 76 VarFirst = BlockVar , VarLast = ParmVar 77 }; 78 79 /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces, 80 /// labels, tags, members and ordinary identifiers. 81 /// Objective-c protocols have their own namespace, so a protocol can have 82 /// the same name as category, class, struct, typedef, etc. 83 enum IdentifierNamespace { 84 IDNS_Label, 85 IDNS_Tag, 86 IDNS_Member, 87 IDNS_Ordinary 88 }; 89 90private: 91 /// Loc - The location that this decl. 92 SourceLocation Loc; 93 94 /// DeclKind - This indicates which class this is. 95 Kind DeclKind : 8; 96 97 /// InvalidDecl - This indicates a semantic error occurred. 98 unsigned int InvalidDecl : 1; 99 100protected: 101 Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0) { 102 if (Decl::CollectingStats()) addDeclKind(DK); 103 } 104 105 virtual ~Decl(); 106 107public: 108 SourceLocation getLocation() const { return Loc; } 109 void setLocation(SourceLocation L) { Loc = L; } 110 111 Kind getKind() const { return DeclKind; } 112 const char *getDeclKindName() const; 113 114 /// setInvalidDecl - Indicates the Decl had a semantic error. This 115 /// allows for graceful error recovery. 116 void setInvalidDecl() { InvalidDecl = 1; } 117 int isInvalidDecl() const { return InvalidDecl; } 118 119 IdentifierNamespace getIdentifierNamespace() const { 120 switch (DeclKind) { 121 default: assert(0 && "Unknown decl kind!"); 122 case Typedef: 123 case Function: 124 case BlockVar: 125 case FileVar: 126 case ParmVar: 127 case EnumConstant: 128 case ObjcInterface: 129 return IDNS_Ordinary; 130 case Struct: 131 case Union: 132 case Class: 133 case Enum: 134 return IDNS_Tag; 135 } 136 } 137 // global temp stats (until we have a per-module visitor) 138 static void addDeclKind(const Kind k); 139 static bool CollectingStats(bool enable=false); 140 static void PrintStats(); 141 142 // Implement isa/cast/dyncast/etc. 143 static bool classof(const Decl *) { return true; } 144}; 145 146/// NamedDecl - This represents a decl with an identifier for a name. Many 147/// decls have names, but not ObjcMethodDecl, @class, etc. 148class NamedDecl : public Decl { 149 /// Identifier - The identifier for this declaration (e.g. the name for the 150 /// variable, the tag for a struct). 151 IdentifierInfo *Identifier; 152public: 153 NamedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id) 154 : Decl(DK, L), Identifier(Id) {} 155 156 IdentifierInfo *getIdentifier() const { return Identifier; } 157 const char *getName() const; 158 159 160 static bool classof(const Decl *D) { 161 return D->getKind() >= NamedFirst && D->getKind() <= NamedLast; 162 } 163 static bool classof(const NamedDecl *D) { return true; } 164}; 165 166/// ScopedDecl - Represent lexically scoped names, used for all ValueDecl's 167/// and TypeDecl's. 168class ScopedDecl : public NamedDecl { 169 170 /// NextDeclarator - If this decl was part of a multi-declarator declaration, 171 /// such as "int X, Y, *Z;" this indicates Decl for the next declarator. 172 ScopedDecl *NextDeclarator; 173 174 /// When this decl is in scope while parsing, the Next field contains a 175 /// pointer to the shadowed decl of the same name. When the scope is popped, 176 /// Decls are relinked onto a containing decl object. 177 /// 178 ScopedDecl *Next; 179protected: 180 ScopedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id,ScopedDecl *PrevDecl) 181 : NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0) {} 182public: 183 ScopedDecl *getNext() const { return Next; } 184 void setNext(ScopedDecl *N) { Next = N; } 185 186 /// getNextDeclarator - If this decl was part of a multi-declarator 187 /// declaration, such as "int X, Y, *Z;" this returns the decl for the next 188 /// declarator. Otherwise it returns null. 189 ScopedDecl *getNextDeclarator() { return NextDeclarator; } 190 const ScopedDecl *getNextDeclarator() const { return NextDeclarator; } 191 void setNextDeclarator(ScopedDecl *N) { NextDeclarator = N; } 192 193 // Implement isa/cast/dyncast/etc. 194 static bool classof(const Decl *D) { 195 return D->getKind() >= ScopedFirst && D->getKind() <= ScopedLast; 196 } 197 static bool classof(const ScopedDecl *D) { return true; } 198}; 199 200/// ValueDecl - Represent the declaration of a variable (in which case it is 201/// an lvalue) a function (in which case it is a function designator) or 202/// an enum constant. 203class ValueDecl : public ScopedDecl { 204 QualType DeclType; 205protected: 206 ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, 207 ScopedDecl *PrevDecl) : ScopedDecl(DK, L, Id, PrevDecl), DeclType(T) {} 208public: 209 QualType getType() const { return DeclType; } 210 void setType(QualType newType) { DeclType = newType; } 211 QualType getCanonicalType() const { return DeclType.getCanonicalType(); } 212 213 // Implement isa/cast/dyncast/etc. 214 static bool classof(const Decl *D) { 215 return D->getKind() >= ValueFirst && D->getKind() <= ValueLast; 216 } 217 static bool classof(const ValueDecl *D) { return true; } 218}; 219 220/// VarDecl - An instance of this class is created to represent a variable 221/// declaration or definition. 222class VarDecl : public ValueDecl { 223public: 224 enum StorageClass { 225 None, Extern, Static, Auto, Register 226 }; 227 StorageClass getStorageClass() const { return SClass; } 228 229 const Expr *getInit() const { return Init; } 230 Expr *getInit() { return Init; } 231 void setInit(Expr *I) { Init = I; } 232 233 // hasAutoStorage - Returns true if either the implicit or explicit 234 // storage class of a variable is "auto." In particular, variables 235 // declared within a function that lack a storage keyword are 236 // implicitly "auto", but are represented internally with a storage 237 // class of None. 238 bool hasAutoStorage() const { 239 return SClass == Auto || (SClass == None && getKind() != FileVar); 240 } 241 242 // hasStaticStorage - Returns true if either the implicit or 243 // explicit storage class of a variable is "static." In 244 // particular, variables declared within a file (outside of a 245 // function) that lack a storage keyword are implicitly "static," 246 // but are represented internally with a storage class of "None". 247 bool hasStaticStorage() const { 248 return SClass == Static || (SClass == None && getKind() == FileVar); 249 } 250 251 // hasLocalStorage - Returns true if a variable with function scope 252 // is a non-static local variable. 253 bool hasLocalStorage() const { return hasAutoStorage() || SClass == Register;} 254 255 // hasGlobalStorage - Returns true for all variables that do not 256 // have local storage. This includs all global variables as well 257 // as static variables declared within a function. 258 bool hasGlobalStorage() const { return !hasAutoStorage(); } 259 260 // Implement isa/cast/dyncast/etc. 261 static bool classof(const Decl *D) { 262 return D->getKind() >= VarFirst && D->getKind() <= VarLast; 263 } 264 static bool classof(const VarDecl *D) { return true; } 265protected: 266 VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, 267 StorageClass SC, ScopedDecl *PrevDecl) 268 : ValueDecl(DK, L, Id, T, PrevDecl), Init(0) { SClass = SC; } 269private: 270 StorageClass SClass; 271 Expr *Init; 272}; 273 274/// BlockVarDecl - Represent a local variable declaration. 275class BlockVarDecl : public VarDecl { 276public: 277 BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, 278 ScopedDecl *PrevDecl) 279 : VarDecl(BlockVar, L, Id, T, S, PrevDecl) {} 280 281 // Implement isa/cast/dyncast/etc. 282 static bool classof(const Decl *D) { return D->getKind() == BlockVar; } 283 static bool classof(const BlockVarDecl *D) { return true; } 284}; 285 286/// FileVarDecl - Represent a file scoped variable declaration. This 287/// will allow us to reason about external variable declarations and tentative 288/// definitions (C99 6.9.2p2) using our type system (without storing a 289/// pointer to the decl's scope, which is transient). 290class FileVarDecl : public VarDecl { 291public: 292 FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, 293 ScopedDecl *PrevDecl) 294 : VarDecl(FileVar, L, Id, T, S, PrevDecl) {} 295 296 // Implement isa/cast/dyncast/etc. 297 static bool classof(const Decl *D) { return D->getKind() == FileVar; } 298 static bool classof(const FileVarDecl *D) { return true; } 299}; 300 301/// ParmVarDecl - Represent a parameter to a function. 302class ParmVarDecl : public VarDecl { 303public: 304 ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, 305 ScopedDecl *PrevDecl) 306 : VarDecl(ParmVar, L, Id, T, S, PrevDecl) {} 307 308 // Implement isa/cast/dyncast/etc. 309 static bool classof(const Decl *D) { return D->getKind() == ParmVar; } 310 static bool classof(const ParmVarDecl *D) { return true; } 311}; 312 313/// FunctionDecl - An instance of this class is created to represent a function 314/// declaration or definition. 315class FunctionDecl : public ValueDecl { 316public: 317 enum StorageClass { 318 None, Extern, Static 319 }; 320 FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T, 321 StorageClass S = None, bool isInline = false, 322 ScopedDecl *PrevDecl = 0) 323 : ValueDecl(Function, L, Id, T, PrevDecl), 324 ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {} 325 virtual ~FunctionDecl(); 326 327 Stmt *getBody() const { return Body; } 328 void setBody(Stmt *B) { Body = B; } 329 330 ScopedDecl *getDeclChain() const { return DeclChain; } 331 void setDeclChain(ScopedDecl *D) { DeclChain = D; } 332 333 unsigned getNumParams() const; 334 const ParmVarDecl *getParamDecl(unsigned i) const { 335 assert(i < getNumParams() && "Illegal param #"); 336 return ParamInfo[i]; 337 } 338 ParmVarDecl *getParamDecl(unsigned i) { 339 assert(i < getNumParams() && "Illegal param #"); 340 return ParamInfo[i]; 341 } 342 void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams); 343 344 QualType getResultType() const { 345 return cast<FunctionType>(getType())->getResultType(); 346 } 347 StorageClass getStorageClass() const { return SClass; } 348 bool isInline() const { return IsInline; } 349 350 // Implement isa/cast/dyncast/etc. 351 static bool classof(const Decl *D) { return D->getKind() == Function; } 352 static bool classof(const FunctionDecl *D) { return true; } 353private: 354 /// ParamInfo - new[]'d array of pointers to VarDecls for the formal 355 /// parameters of this function. This is null if a prototype or if there are 356 /// no formals. TODO: we could allocate this space immediately after the 357 /// FunctionDecl object to save an allocation like FunctionType does. 358 ParmVarDecl **ParamInfo; 359 360 Stmt *Body; // Null if a prototype. 361 362 /// DeclChain - Linked list of declarations that are defined inside this 363 /// function. 364 ScopedDecl *DeclChain; 365 366 StorageClass SClass : 2; 367 bool IsInline : 1; 368}; 369 370 371/// FieldDecl - An instance of this class is created by Sema::ActOnField to 372/// represent a member of a struct/union/class. 373class FieldDecl : public NamedDecl { 374 QualType DeclType; 375public: 376 FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T) 377 : NamedDecl(Field, L, Id), DeclType(T) {} 378 FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T) 379 : NamedDecl(DK, L, Id), DeclType(T) {} 380 381 QualType getType() const { return DeclType; } 382 QualType getCanonicalType() const { return DeclType.getCanonicalType(); } 383 384 // Implement isa/cast/dyncast/etc. 385 static bool classof(const Decl *D) { 386 return D->getKind() >= FieldFirst && D->getKind() <= FieldLast; 387 } 388 static bool classof(const FieldDecl *D) { return true; } 389}; 390 391/// EnumConstantDecl - An instance of this object exists for each enum constant 392/// that is defined. For example, in "enum X {a,b}", each of a/b are 393/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a 394/// TagType for the X EnumDecl. 395class EnumConstantDecl : public ValueDecl { 396 Expr *Init; // an integer constant expression 397 llvm::APSInt Val; // The value. 398public: 399 EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, 400 const llvm::APSInt &V, ScopedDecl *PrevDecl) 401 : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {} 402 403 const Expr *getInitExpr() const { return Init; } 404 Expr *getInitExpr() { return Init; } 405 const llvm::APSInt &getInitVal() const { return Val; } 406 407 void setInitExpr(Expr *E) { Init = E; } 408 void setInitVal(llvm::APSInt &V) { Val = V; } 409 410 // Implement isa/cast/dyncast/etc. 411 static bool classof(const Decl *D) { return D->getKind() == EnumConstant; } 412 static bool classof(const EnumConstantDecl *D) { return true; } 413}; 414 415 416/// TypeDecl - Represents a declaration of a type. 417/// 418class TypeDecl : public ScopedDecl { 419 /// TypeForDecl - This indicates the Type object that represents this 420 /// TypeDecl. It is a cache maintained by ASTContext::getTypedefType and 421 /// ASTContext::getTagDeclType. 422 Type *TypeForDecl; 423 friend class ASTContext; 424protected: 425 TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) 426 : ScopedDecl(DK, L, Id, PrevDecl), TypeForDecl(0) {} 427public: 428 // Implement isa/cast/dyncast/etc. 429 static bool classof(const Decl *D) { 430 return D->getKind() >= TypeFirst && D->getKind() <= TypeLast; 431 } 432 static bool classof(const TypeDecl *D) { return true; } 433}; 434 435 436class TypedefDecl : public TypeDecl { 437 /// UnderlyingType - This is the type the typedef is set to. 438 QualType UnderlyingType; 439public: 440 TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PD) 441 : TypeDecl(Typedef, L, Id, PD), UnderlyingType(T) {} 442 443 QualType getUnderlyingType() const { return UnderlyingType; } 444 void setUnderlyingType(QualType newType) { UnderlyingType = newType; } 445 446 // Implement isa/cast/dyncast/etc. 447 static bool classof(const Decl *D) { return D->getKind() == Typedef; } 448 static bool classof(const TypedefDecl *D) { return true; } 449}; 450 451 452/// TagDecl - Represents the declaration of a struct/union/class/enum. 453class TagDecl : public TypeDecl { 454 /// IsDefinition - True if this is a definition ("struct foo {};"), false if 455 /// it is a declaration ("struct foo;"). 456 bool IsDefinition : 1; 457protected: 458 TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) 459 : TypeDecl(DK, L, Id, PrevDecl) { 460 IsDefinition = false; 461 } 462public: 463 464 /// isDefinition - Return true if this decl has its body specified. 465 bool isDefinition() const { 466 return IsDefinition; 467 } 468 469 const char *getKindName() const { 470 switch (getKind()) { 471 default: assert(0 && "Unknown TagDecl!"); 472 case Struct: return "struct"; 473 case Union: return "union"; 474 case Class: return "class"; 475 case Enum: return "enum"; 476 } 477 } 478 479 // Implement isa/cast/dyncast/etc. 480 static bool classof(const Decl *D) { 481 return D->getKind() >= TagFirst && D->getKind() <= TagLast; 482 } 483 static bool classof(const TagDecl *D) { return true; } 484protected: 485 void setDefinition(bool V) { IsDefinition = V; } 486}; 487 488/// EnumDecl - Represents an enum. As an extension, we allow forward-declared 489/// enums. 490class EnumDecl : public TagDecl { 491 /// ElementList - this is a linked list of EnumConstantDecl's which are linked 492 /// together through their getNextDeclarator pointers. 493 EnumConstantDecl *ElementList; 494 495 /// IntegerType - This represent the integer type that the enum corresponds 496 /// to for code generation purposes. Note that the enumerator constants may 497 /// have a different type than this does. 498 QualType IntegerType; 499public: 500 EnumDecl(SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) 501 : TagDecl(Enum, L, Id, PrevDecl) { 502 ElementList = 0; 503 } 504 505 /// defineElements - When created, EnumDecl correspond to a forward declared 506 /// enum. This method is used to mark the decl as being defined, with the 507 /// specified list of enums. 508 void defineElements(EnumConstantDecl *ListHead, QualType NewType) { 509 assert(!isDefinition() && "Cannot redefine enums!"); 510 ElementList = ListHead; 511 setDefinition(true); 512 513 IntegerType = NewType; 514 } 515 516 /// getIntegerType - Return the integer type this enum decl corresponds to. 517 /// This returns a null qualtype for an enum forward definition. 518 QualType getIntegerType() const { return IntegerType; } 519 520 /// getEnumConstantList - Return the first EnumConstantDecl in the enum. 521 /// 522 EnumConstantDecl *getEnumConstantList() { return ElementList; } 523 const EnumConstantDecl *getEnumConstantList() const { return ElementList; } 524 525 static bool classof(const Decl *D) { return D->getKind() == Enum; } 526 static bool classof(const EnumDecl *D) { return true; } 527}; 528 529 530/// RecordDecl - Represents a struct/union/class. For example: 531/// struct X; // Forward declaration, no "body". 532/// union Y { int A, B; }; // Has body with members A and B (FieldDecls). 533/// 534class RecordDecl : public TagDecl { 535 /// HasFlexibleArrayMember - This is true if this struct ends with a flexible 536 /// array member (e.g. int X[]) or if this union contains a struct that does. 537 /// If so, this cannot be contained in arrays or other structs as a member. 538 bool HasFlexibleArrayMember : 1; 539 540 /// Members/NumMembers - This is a new[]'d array of pointers to Decls. 541 FieldDecl **Members; // Null if not defined. 542 int NumMembers; // -1 if not defined. 543public: 544 RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl*PrevDecl) 545 : TagDecl(DK, L, Id, PrevDecl) { 546 HasFlexibleArrayMember = false; 547 assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); 548 Members = 0; 549 NumMembers = -1; 550 } 551 552 bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } 553 void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; } 554 555 /// getNumMembers - Return the number of members, or -1 if this is a forward 556 /// definition. 557 int getNumMembers() const { return NumMembers; } 558 const FieldDecl *getMember(unsigned i) const { return Members[i]; } 559 FieldDecl *getMember(unsigned i) { return Members[i]; } 560 561 /// defineBody - When created, RecordDecl's correspond to a forward declared 562 /// record. This method is used to mark the decl as being defined, with the 563 /// specified contents. 564 void defineBody(FieldDecl **Members, unsigned numMembers); 565 566 /// getMember - If the member doesn't exist, or there are no members, this 567 /// function will return 0; 568 FieldDecl *getMember(IdentifierInfo *name); 569 570 static bool classof(const Decl *D) { 571 return D->getKind() >= RecordFirst && D->getKind() <= RecordLast; 572 } 573 static bool classof(const RecordDecl *D) { return true; } 574}; 575 576} // end namespace clang 577#endif 578