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