Decl.cpp revision 9f9bf258f8ebae30bfb70feb9d797d6eb67b0460
1//===--- Decl.cpp - Declaration AST Node Implementation -------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the Decl subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/Decl.h" 15#include "clang/AST/DeclCXX.h" 16#include "clang/AST/DeclObjC.h" 17#include "clang/AST/ASTContext.h" 18#include "clang/AST/Stmt.h" 19#include "clang/AST/Expr.h" 20#include "clang/Basic/IdentifierTable.h" 21#include <vector> 22 23using namespace clang; 24 25void Attr::Destroy(ASTContext &C) { 26 if (Next) { 27 Next->Destroy(C); 28 Next = 0; 29 } 30 this->~Attr(); 31 C.Deallocate((void*)this); 32} 33 34 35//===----------------------------------------------------------------------===// 36// Decl Allocation/Deallocation Method Implementations 37//===----------------------------------------------------------------------===// 38 39 40TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { 41 return new (C) TranslationUnitDecl(); 42} 43 44NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, 45 SourceLocation L, IdentifierInfo *Id) { 46 return new (C) NamespaceDecl(DC, L, Id); 47} 48 49void NamespaceDecl::Destroy(ASTContext& C) { 50 // NamespaceDecl uses "NextDeclarator" to chain namespace declarations 51 // together. They are all top-level Decls. 52 53 this->~NamespaceDecl(); 54 C.Deallocate((void *)this); 55} 56 57 58ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, 59 SourceLocation L, IdentifierInfo *Id, QualType T) { 60 return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T); 61} 62 63const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) { 64 switch (SC) { 65 case VarDecl::None: break; 66 case VarDecl::Auto: return "auto"; break; 67 case VarDecl::Extern: return "extern"; break; 68 case VarDecl::PrivateExtern: return "__private_extern__"; break; 69 case VarDecl::Register: return "register"; break; 70 case VarDecl::Static: return "static"; break; 71 } 72 73 assert(0 && "Invalid storage class"); 74 return 0; 75} 76 77ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, 78 SourceLocation L, IdentifierInfo *Id, 79 QualType T, StorageClass S, 80 Expr *DefArg) { 81 return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, S, DefArg); 82} 83 84QualType ParmVarDecl::getOriginalType() const { 85 if (const OriginalParmVarDecl *PVD = 86 dyn_cast<OriginalParmVarDecl>(this)) 87 return PVD->OriginalType; 88 return getType(); 89} 90 91bool VarDecl::isExternC(ASTContext &Context) const { 92 if (!Context.getLangOptions().CPlusPlus) 93 return (getDeclContext()->isTranslationUnit() && 94 getStorageClass() != Static) || 95 (getDeclContext()->isFunctionOrMethod() && hasExternalStorage()); 96 97 for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); 98 DC = DC->getParent()) { 99 if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) { 100 if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) 101 return getStorageClass() != Static; 102 103 break; 104 } 105 106 if (DC->isFunctionOrMethod()) 107 return false; 108 } 109 110 return false; 111} 112 113OriginalParmVarDecl *OriginalParmVarDecl::Create( 114 ASTContext &C, DeclContext *DC, 115 SourceLocation L, IdentifierInfo *Id, 116 QualType T, QualType OT, StorageClass S, 117 Expr *DefArg) { 118 return new (C) OriginalParmVarDecl(DC, L, Id, T, OT, S, DefArg); 119} 120 121FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, 122 SourceLocation L, 123 DeclarationName N, QualType T, 124 StorageClass S, bool isInline, 125 bool hasPrototype, 126 SourceLocation TypeSpecStartLoc) { 127 FunctionDecl *New 128 = new (C) FunctionDecl(Function, DC, L, N, T, S, isInline, 129 TypeSpecStartLoc); 130 New->HasPrototype = hasPrototype; 131 return New; 132} 133 134BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { 135 return new (C) BlockDecl(DC, L); 136} 137 138FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 139 IdentifierInfo *Id, QualType T, Expr *BW, 140 bool Mutable) { 141 return new (C) FieldDecl(Decl::Field, DC, L, Id, T, BW, Mutable); 142} 143 144bool FieldDecl::isAnonymousStructOrUnion() const { 145 if (!isImplicit() || getDeclName()) 146 return false; 147 148 if (const RecordType *Record = getType()->getAsRecordType()) 149 return Record->getDecl()->isAnonymousStructOrUnion(); 150 151 return false; 152} 153 154EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, 155 SourceLocation L, 156 IdentifierInfo *Id, QualType T, 157 Expr *E, const llvm::APSInt &V) { 158 return new (C) EnumConstantDecl(CD, L, Id, T, E, V); 159} 160 161void EnumConstantDecl::Destroy(ASTContext& C) { 162 if (Init) Init->Destroy(C); 163 Decl::Destroy(C); 164} 165 166TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, 167 SourceLocation L, 168 IdentifierInfo *Id, QualType T) { 169 return new (C) TypedefDecl(DC, L, Id, T); 170} 171 172EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 173 IdentifierInfo *Id, 174 EnumDecl *PrevDecl) { 175 EnumDecl *Enum = new (C) EnumDecl(DC, L, Id); 176 C.getTypeDeclType(Enum, PrevDecl); 177 return Enum; 178} 179 180void EnumDecl::Destroy(ASTContext& C) { 181 Decl::Destroy(C); 182} 183 184void EnumDecl::completeDefinition(ASTContext &C, QualType NewType) { 185 assert(!isDefinition() && "Cannot redefine enums!"); 186 IntegerType = NewType; 187 TagDecl::completeDefinition(); 188} 189 190FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, 191 SourceLocation L, 192 StringLiteral *Str) { 193 return new (C) FileScopeAsmDecl(DC, L, Str); 194} 195 196//===----------------------------------------------------------------------===// 197// NamedDecl Implementation 198//===----------------------------------------------------------------------===// 199 200std::string NamedDecl::getQualifiedNameAsString() const { 201 std::vector<std::string> Names; 202 std::string QualName; 203 const DeclContext *Ctx = getDeclContext(); 204 205 if (Ctx->isFunctionOrMethod()) 206 return getNameAsString(); 207 208 while (Ctx) { 209 if (Ctx->isFunctionOrMethod()) 210 // FIXME: That probably will happen, when D was member of local 211 // scope class/struct/union. How do we handle this case? 212 break; 213 214 if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx)) 215 Names.push_back(ND->getNameAsString()); 216 else 217 break; 218 219 Ctx = Ctx->getParent(); 220 } 221 222 std::vector<std::string>::reverse_iterator 223 I = Names.rbegin(), 224 End = Names.rend(); 225 226 for (; I!=End; ++I) 227 QualName += *I + "::"; 228 229 QualName += getNameAsString(); 230 231 return QualName; 232} 233 234 235bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { 236 assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch"); 237 238 // UsingDirectiveDecl's are not really NamedDecl's, and all have same name. 239 // We want to keep it, unless it nominates same namespace. 240 if (getKind() == Decl::UsingDirective) { 241 return cast<UsingDirectiveDecl>(this)->getNominatedNamespace() == 242 cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace(); 243 } 244 245 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) 246 // For function declarations, we keep track of redeclarations. 247 return FD->getPreviousDeclaration() == OldD; 248 249 // For method declarations, we keep track of redeclarations. 250 if (isa<ObjCMethodDecl>(this)) 251 return false; 252 253 // For non-function declarations, if the declarations are of the 254 // same kind then this must be a redeclaration, or semantic analysis 255 // would not have given us the new declaration. 256 return this->getKind() == OldD->getKind(); 257} 258 259bool NamedDecl::hasLinkage() const { 260 if (const VarDecl *VD = dyn_cast<VarDecl>(this)) 261 return VD->hasExternalStorage() || VD->isFileVarDecl(); 262 263 if (isa<FunctionDecl>(this) && !isa<CXXMethodDecl>(this)) 264 return true; 265 266 return false; 267} 268 269//===----------------------------------------------------------------------===// 270// VarDecl Implementation 271//===----------------------------------------------------------------------===// 272 273VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 274 IdentifierInfo *Id, QualType T, StorageClass S, 275 SourceLocation TypeSpecStartLoc) { 276 return new (C) VarDecl(Var, DC, L, Id, T, S, TypeSpecStartLoc); 277} 278 279void VarDecl::Destroy(ASTContext& C) { 280 Expr *Init = getInit(); 281 if (Init) 282 Init->Destroy(C); 283 this->~VarDecl(); 284 C.Deallocate((void *)this); 285} 286 287VarDecl::~VarDecl() { 288} 289 290bool VarDecl::isTentativeDefinition(ASTContext &Context) const { 291 if (!isFileVarDecl() || Context.getLangOptions().CPlusPlus) 292 return false; 293 294 const VarDecl *Def = 0; 295 return (!getDefinition(Def) && 296 (getStorageClass() == None || getStorageClass() == Static)); 297} 298 299const Expr *VarDecl::getDefinition(const VarDecl *&Def) const { 300 Def = this; 301 while (Def && !Def->getInit()) 302 Def = Def->getPreviousDeclaration(); 303 304 return Def? Def->getInit() : 0; 305} 306 307//===----------------------------------------------------------------------===// 308// FunctionDecl Implementation 309//===----------------------------------------------------------------------===// 310 311void FunctionDecl::Destroy(ASTContext& C) { 312 if (Body && Body.isOffset()) 313 Body.get(C.getExternalSource())->Destroy(C); 314 315 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 316 (*I)->Destroy(C); 317 318 C.Deallocate(ParamInfo); 319 320 Decl::Destroy(C); 321} 322 323 324Stmt *FunctionDecl::getBody(ASTContext &Context, 325 const FunctionDecl *&Definition) const { 326 for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) { 327 if (FD->Body) { 328 Definition = FD; 329 return FD->Body.get(Context.getExternalSource()); 330 } 331 } 332 333 return 0; 334} 335 336Stmt *FunctionDecl::getBodyIfAvailable() const { 337 for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) { 338 if (FD->Body && !FD->Body.isOffset()) { 339 return FD->Body.get(0); 340 } 341 } 342 343 return 0; 344} 345 346bool FunctionDecl::isMain() const { 347 return getDeclContext()->getLookupContext()->isTranslationUnit() && 348 getIdentifier() && getIdentifier()->isStr("main"); 349} 350 351bool FunctionDecl::isExternC(ASTContext &Context) const { 352 // In C, any non-static, non-overloadable function has external 353 // linkage. 354 if (!Context.getLangOptions().CPlusPlus) 355 return getStorageClass() != Static && !getAttr<OverloadableAttr>(); 356 357 for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); 358 DC = DC->getParent()) { 359 if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) { 360 if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) 361 return getStorageClass() != Static && !getAttr<OverloadableAttr>(); 362 363 break; 364 } 365 } 366 367 return false; 368} 369 370bool FunctionDecl::isGlobal() const { 371 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this)) 372 return Method->isStatic(); 373 374 if (getStorageClass() == Static) 375 return false; 376 377 for (const DeclContext *DC = getDeclContext(); 378 DC->isNamespace(); 379 DC = DC->getParent()) { 380 if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) { 381 if (!Namespace->getDeclName()) 382 return false; 383 break; 384 } 385 } 386 387 return true; 388} 389 390/// \brief Returns a value indicating whether this function 391/// corresponds to a builtin function. 392/// 393/// The function corresponds to a built-in function if it is 394/// declared at translation scope or within an extern "C" block and 395/// its name matches with the name of a builtin. The returned value 396/// will be 0 for functions that do not correspond to a builtin, a 397/// value of type \c Builtin::ID if in the target-independent range 398/// \c [1,Builtin::First), or a target-specific builtin value. 399unsigned FunctionDecl::getBuiltinID(ASTContext &Context) const { 400 if (!getIdentifier() || !getIdentifier()->getBuiltinID()) 401 return 0; 402 403 unsigned BuiltinID = getIdentifier()->getBuiltinID(); 404 if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 405 return BuiltinID; 406 407 // This function has the name of a known C library 408 // function. Determine whether it actually refers to the C library 409 // function or whether it just has the same name. 410 411 // If this is a static function, it's not a builtin. 412 if (getStorageClass() == Static) 413 return 0; 414 415 // If this function is at translation-unit scope and we're not in 416 // C++, it refers to the C library function. 417 if (!Context.getLangOptions().CPlusPlus && 418 getDeclContext()->isTranslationUnit()) 419 return BuiltinID; 420 421 // If the function is in an extern "C" linkage specification and is 422 // not marked "overloadable", it's the real function. 423 if (isa<LinkageSpecDecl>(getDeclContext()) && 424 cast<LinkageSpecDecl>(getDeclContext())->getLanguage() 425 == LinkageSpecDecl::lang_c && 426 !getAttr<OverloadableAttr>()) 427 return BuiltinID; 428 429 // Not a builtin 430 return 0; 431} 432 433 434/// getNumParams - Return the number of parameters this function must have 435/// based on its FunctionType. This is the length of the PararmInfo array 436/// after it has been created. 437unsigned FunctionDecl::getNumParams() const { 438 const FunctionType *FT = getType()->getAsFunctionType(); 439 if (isa<FunctionNoProtoType>(FT)) 440 return 0; 441 return cast<FunctionProtoType>(FT)->getNumArgs(); 442 443} 444 445void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, 446 unsigned NumParams) { 447 assert(ParamInfo == 0 && "Already has param info!"); 448 assert(NumParams == getNumParams() && "Parameter count mismatch!"); 449 450 // Zero params -> null pointer. 451 if (NumParams) { 452 void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); 453 ParamInfo = new (Mem) ParmVarDecl*[NumParams]; 454 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); 455 } 456} 457 458/// getMinRequiredArguments - Returns the minimum number of arguments 459/// needed to call this function. This may be fewer than the number of 460/// function parameters, if some of the parameters have default 461/// arguments (in C++). 462unsigned FunctionDecl::getMinRequiredArguments() const { 463 unsigned NumRequiredArgs = getNumParams(); 464 while (NumRequiredArgs > 0 465 && getParamDecl(NumRequiredArgs-1)->getDefaultArg()) 466 --NumRequiredArgs; 467 468 return NumRequiredArgs; 469} 470 471bool FunctionDecl::hasActiveGNUInlineAttribute() const { 472 if (!isInline() || !hasAttr<GNUInlineAttr>()) 473 return false; 474 475 for (const FunctionDecl *FD = getPreviousDeclaration(); FD; 476 FD = FD->getPreviousDeclaration()) { 477 if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>()) 478 return false; 479 } 480 481 return true; 482} 483 484bool FunctionDecl::isExternGNUInline() const { 485 if (!hasActiveGNUInlineAttribute()) 486 return false; 487 488 for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDeclaration()) 489 if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>()) 490 return true; 491 492 return false; 493} 494 495/// getOverloadedOperator - Which C++ overloaded operator this 496/// function represents, if any. 497OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { 498 if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName) 499 return getDeclName().getCXXOverloadedOperator(); 500 else 501 return OO_None; 502} 503 504//===----------------------------------------------------------------------===// 505// TagDecl Implementation 506//===----------------------------------------------------------------------===// 507 508void TagDecl::startDefinition() { 509 TagType *TagT = const_cast<TagType *>(TypeForDecl->getAsTagType()); 510 TagT->decl.setPointer(this); 511 TagT->getAsTagType()->decl.setInt(1); 512} 513 514void TagDecl::completeDefinition() { 515 assert((!TypeForDecl || 516 TypeForDecl->getAsTagType()->decl.getPointer() == this) && 517 "Attempt to redefine a tag definition?"); 518 IsDefinition = true; 519 TagType *TagT = const_cast<TagType *>(TypeForDecl->getAsTagType()); 520 TagT->decl.setPointer(this); 521 TagT->decl.setInt(0); 522} 523 524TagDecl* TagDecl::getDefinition(ASTContext& C) const { 525 QualType T = C.getTypeDeclType(const_cast<TagDecl*>(this)); 526 TagDecl* D = cast<TagDecl>(T->getAsTagType()->getDecl()); 527 return D->isDefinition() ? D : 0; 528} 529 530//===----------------------------------------------------------------------===// 531// RecordDecl Implementation 532//===----------------------------------------------------------------------===// 533 534RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, 535 IdentifierInfo *Id) 536 : TagDecl(DK, TK, DC, L, Id) { 537 HasFlexibleArrayMember = false; 538 AnonymousStructOrUnion = false; 539 assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); 540} 541 542RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, 543 SourceLocation L, IdentifierInfo *Id, 544 RecordDecl* PrevDecl) { 545 546 RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id); 547 C.getTypeDeclType(R, PrevDecl); 548 return R; 549} 550 551RecordDecl::~RecordDecl() { 552} 553 554void RecordDecl::Destroy(ASTContext& C) { 555 TagDecl::Destroy(C); 556} 557 558bool RecordDecl::isInjectedClassName() const { 559 return isImplicit() && getDeclName() && getDeclContext()->isRecord() && 560 cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName(); 561} 562 563/// completeDefinition - Notes that the definition of this type is now 564/// complete. 565void RecordDecl::completeDefinition(ASTContext& C) { 566 assert(!isDefinition() && "Cannot redefine record!"); 567 TagDecl::completeDefinition(); 568} 569 570//===----------------------------------------------------------------------===// 571// BlockDecl Implementation 572//===----------------------------------------------------------------------===// 573 574BlockDecl::~BlockDecl() { 575} 576 577void BlockDecl::Destroy(ASTContext& C) { 578 if (Body) 579 Body->Destroy(C); 580 581 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 582 (*I)->Destroy(C); 583 584 C.Deallocate(ParamInfo); 585 Decl::Destroy(C); 586} 587 588void BlockDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, 589 unsigned NParms) { 590 assert(ParamInfo == 0 && "Already has param info!"); 591 592 // Zero params -> null pointer. 593 if (NParms) { 594 NumParams = NParms; 595 void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); 596 ParamInfo = new (Mem) ParmVarDecl*[NumParams]; 597 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); 598 } 599} 600 601unsigned BlockDecl::getNumParams() const { 602 return NumParams; 603} 604