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