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