Decl.cpp revision af3280fadbdab6305581955c973e1229970958eb
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/TypeLoc.h" 20#include "clang/AST/Stmt.h" 21#include "clang/AST/Expr.h" 22#include "clang/AST/PrettyPrinter.h" 23#include "clang/Basic/Builtins.h" 24#include "clang/Basic/IdentifierTable.h" 25#include "clang/Parse/DeclSpec.h" 26#include "llvm/Support/ErrorHandling.h" 27#include <vector> 28 29using namespace clang; 30 31void Attr::Destroy(ASTContext &C) { 32 if (Next) { 33 Next->Destroy(C); 34 Next = 0; 35 } 36 this->~Attr(); 37 C.Deallocate((void*)this); 38} 39 40/// \brief Return the TypeLoc wrapper for the type source info. 41TypeLoc DeclaratorInfo::getTypeLoc() const { 42 return TypeLoc::Create(Ty, (void*)(this + 1)); 43} 44 45//===----------------------------------------------------------------------===// 46// Decl Allocation/Deallocation Method Implementations 47//===----------------------------------------------------------------------===// 48 49 50TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { 51 return new (C) TranslationUnitDecl(C); 52} 53 54NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, 55 SourceLocation L, IdentifierInfo *Id) { 56 return new (C) NamespaceDecl(DC, L, Id); 57} 58 59void NamespaceDecl::Destroy(ASTContext& C) { 60 // NamespaceDecl uses "NextDeclarator" to chain namespace declarations 61 // together. They are all top-level Decls. 62 63 this->~NamespaceDecl(); 64 C.Deallocate((void *)this); 65} 66 67 68ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, 69 SourceLocation L, IdentifierInfo *Id, QualType T) { 70 return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T); 71} 72 73const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) { 74 switch (SC) { 75 case VarDecl::None: break; 76 case VarDecl::Auto: return "auto"; break; 77 case VarDecl::Extern: return "extern"; break; 78 case VarDecl::PrivateExtern: return "__private_extern__"; break; 79 case VarDecl::Register: return "register"; break; 80 case VarDecl::Static: return "static"; break; 81 } 82 83 assert(0 && "Invalid storage class"); 84 return 0; 85} 86 87ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, 88 SourceLocation L, IdentifierInfo *Id, 89 QualType T, DeclaratorInfo *DInfo, 90 StorageClass S, Expr *DefArg) { 91 return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, DInfo, S, DefArg); 92} 93 94QualType ParmVarDecl::getOriginalType() const { 95 if (const OriginalParmVarDecl *PVD = 96 dyn_cast<OriginalParmVarDecl>(this)) 97 return PVD->OriginalType; 98 return getType(); 99} 100 101SourceRange ParmVarDecl::getDefaultArgRange() const { 102 if (const Expr *E = getInit()) 103 return E->getSourceRange(); 104 105 if (const Expr *E = getUninstantiatedDefaultArg()) 106 return E->getSourceRange(); 107 108 return SourceRange(); 109} 110 111void VarDecl::setInit(ASTContext &C, Expr *I) { 112 if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) { 113 Eval->~EvaluatedStmt(); 114 C.Deallocate(Eval); 115 } 116 117 Init = I; 118} 119 120bool VarDecl::isExternC(ASTContext &Context) const { 121 if (!Context.getLangOptions().CPlusPlus) 122 return (getDeclContext()->isTranslationUnit() && 123 getStorageClass() != Static) || 124 (getDeclContext()->isFunctionOrMethod() && hasExternalStorage()); 125 126 for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); 127 DC = DC->getParent()) { 128 if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) { 129 if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) 130 return getStorageClass() != Static; 131 132 break; 133 } 134 135 if (DC->isFunctionOrMethod()) 136 return false; 137 } 138 139 return false; 140} 141 142OriginalParmVarDecl *OriginalParmVarDecl::Create( 143 ASTContext &C, DeclContext *DC, 144 SourceLocation L, IdentifierInfo *Id, 145 QualType T, DeclaratorInfo *DInfo, 146 QualType OT, StorageClass S, Expr *DefArg) { 147 return new (C) OriginalParmVarDecl(DC, L, Id, T, DInfo, OT, S, DefArg); 148} 149 150FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, 151 SourceLocation L, 152 DeclarationName N, QualType T, 153 DeclaratorInfo *DInfo, 154 StorageClass S, bool isInline, 155 bool hasWrittenPrototype) { 156 FunctionDecl *New 157 = new (C) FunctionDecl(Function, DC, L, N, T, DInfo, S, isInline); 158 New->HasWrittenPrototype = hasWrittenPrototype; 159 return New; 160} 161 162BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { 163 return new (C) BlockDecl(DC, L); 164} 165 166FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 167 IdentifierInfo *Id, QualType T, 168 DeclaratorInfo *DInfo, Expr *BW, bool Mutable) { 169 return new (C) FieldDecl(Decl::Field, DC, L, Id, T, DInfo, BW, Mutable); 170} 171 172bool FieldDecl::isAnonymousStructOrUnion() const { 173 if (!isImplicit() || getDeclName()) 174 return false; 175 176 if (const RecordType *Record = getType()->getAs<RecordType>()) 177 return Record->getDecl()->isAnonymousStructOrUnion(); 178 179 return false; 180} 181 182EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, 183 SourceLocation L, 184 IdentifierInfo *Id, QualType T, 185 Expr *E, const llvm::APSInt &V) { 186 return new (C) EnumConstantDecl(CD, L, Id, T, E, V); 187} 188 189void EnumConstantDecl::Destroy(ASTContext& C) { 190 if (Init) Init->Destroy(C); 191 Decl::Destroy(C); 192} 193 194TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, 195 SourceLocation L, 196 IdentifierInfo *Id, QualType T) { 197 return new (C) TypedefDecl(DC, L, Id, T); 198} 199 200EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 201 IdentifierInfo *Id, SourceLocation TKL, 202 EnumDecl *PrevDecl) { 203 EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, PrevDecl, TKL); 204 C.getTypeDeclType(Enum, PrevDecl); 205 return Enum; 206} 207 208void EnumDecl::Destroy(ASTContext& C) { 209 Decl::Destroy(C); 210} 211 212void EnumDecl::completeDefinition(ASTContext &C, QualType NewType) { 213 assert(!isDefinition() && "Cannot redefine enums!"); 214 IntegerType = NewType; 215 TagDecl::completeDefinition(); 216} 217 218FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, 219 SourceLocation L, 220 StringLiteral *Str) { 221 return new (C) FileScopeAsmDecl(DC, L, Str); 222} 223 224//===----------------------------------------------------------------------===// 225// NamedDecl Implementation 226//===----------------------------------------------------------------------===// 227 228std::string NamedDecl::getQualifiedNameAsString() const { 229 return getQualifiedNameAsString(getASTContext().getLangOptions()); 230} 231 232std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const { 233 std::vector<std::string> Names; 234 std::string QualName; 235 const DeclContext *Ctx = getDeclContext(); 236 237 if (Ctx->isFunctionOrMethod()) 238 return getNameAsString(); 239 240 while (Ctx) { 241 if (Ctx->isFunctionOrMethod()) 242 // FIXME: That probably will happen, when D was member of local 243 // scope class/struct/union. How do we handle this case? 244 break; 245 246 if (const ClassTemplateSpecializationDecl *Spec 247 = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) { 248 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 249 std::string TemplateArgsStr 250 = TemplateSpecializationType::PrintTemplateArgumentList( 251 TemplateArgs.getFlatArgumentList(), 252 TemplateArgs.flat_size(), 253 P); 254 Names.push_back(Spec->getIdentifier()->getName() + TemplateArgsStr); 255 } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx)) 256 Names.push_back(ND->getNameAsString()); 257 else 258 break; 259 260 Ctx = Ctx->getParent(); 261 } 262 263 std::vector<std::string>::reverse_iterator 264 I = Names.rbegin(), 265 End = Names.rend(); 266 267 for (; I!=End; ++I) 268 QualName += *I + "::"; 269 270 QualName += getNameAsString(); 271 272 return QualName; 273} 274 275bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { 276 assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch"); 277 278 // UsingDirectiveDecl's are not really NamedDecl's, and all have same name. 279 // We want to keep it, unless it nominates same namespace. 280 if (getKind() == Decl::UsingDirective) { 281 return cast<UsingDirectiveDecl>(this)->getNominatedNamespace() == 282 cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace(); 283 } 284 285 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) 286 // For function declarations, we keep track of redeclarations. 287 return FD->getPreviousDeclaration() == OldD; 288 289 // For function templates, the underlying function declarations are linked. 290 if (const FunctionTemplateDecl *FunctionTemplate 291 = dyn_cast<FunctionTemplateDecl>(this)) 292 if (const FunctionTemplateDecl *OldFunctionTemplate 293 = dyn_cast<FunctionTemplateDecl>(OldD)) 294 return FunctionTemplate->getTemplatedDecl() 295 ->declarationReplaces(OldFunctionTemplate->getTemplatedDecl()); 296 297 // For method declarations, we keep track of redeclarations. 298 if (isa<ObjCMethodDecl>(this)) 299 return false; 300 301 // For non-function declarations, if the declarations are of the 302 // same kind then this must be a redeclaration, or semantic analysis 303 // would not have given us the new declaration. 304 return this->getKind() == OldD->getKind(); 305} 306 307bool NamedDecl::hasLinkage() const { 308 if (const VarDecl *VD = dyn_cast<VarDecl>(this)) 309 return VD->hasExternalStorage() || VD->isFileVarDecl(); 310 311 if (isa<FunctionDecl>(this) && !isa<CXXMethodDecl>(this)) 312 return true; 313 314 return false; 315} 316 317NamedDecl *NamedDecl::getUnderlyingDecl() { 318 NamedDecl *ND = this; 319 while (true) { 320 if (UsingDecl *UD = dyn_cast<UsingDecl>(ND)) 321 ND = UD->getTargetDecl(); 322 else if (ObjCCompatibleAliasDecl *AD 323 = dyn_cast<ObjCCompatibleAliasDecl>(ND)) 324 return AD->getClassInterface(); 325 else 326 return ND; 327 } 328} 329 330//===----------------------------------------------------------------------===// 331// DeclaratorDecl Implementation 332//===----------------------------------------------------------------------===// 333 334SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const { 335 if (DeclInfo) 336 return DeclInfo->getTypeLoc().getTypeSpecRange().getBegin(); 337 return SourceLocation(); 338} 339 340//===----------------------------------------------------------------------===// 341// VarDecl Implementation 342//===----------------------------------------------------------------------===// 343 344VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 345 IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo, 346 StorageClass S) { 347 return new (C) VarDecl(Var, DC, L, Id, T, DInfo, S); 348} 349 350void VarDecl::Destroy(ASTContext& C) { 351 Expr *Init = getInit(); 352 if (Init) { 353 Init->Destroy(C); 354 if (EvaluatedStmt *Eval = this->Init.dyn_cast<EvaluatedStmt *>()) { 355 Eval->~EvaluatedStmt(); 356 C.Deallocate(Eval); 357 } 358 } 359 this->~VarDecl(); 360 C.Deallocate((void *)this); 361} 362 363VarDecl::~VarDecl() { 364} 365 366SourceRange VarDecl::getSourceRange() const { 367 if (getInit()) 368 return SourceRange(getLocation(), getInit()->getLocEnd()); 369 return SourceRange(getLocation(), getLocation()); 370} 371 372VarDecl *VarDecl::getInstantiatedFromStaticDataMember() { 373 return getASTContext().getInstantiatedFromStaticDataMember(this); 374} 375 376bool VarDecl::isTentativeDefinition(ASTContext &Context) const { 377 if (!isFileVarDecl() || Context.getLangOptions().CPlusPlus) 378 return false; 379 380 const VarDecl *Def = 0; 381 return (!getDefinition(Def) && 382 (getStorageClass() == None || getStorageClass() == Static)); 383} 384 385const Expr *VarDecl::getDefinition(const VarDecl *&Def) const { 386 redecl_iterator I = redecls_begin(), E = redecls_end(); 387 while (I != E && !I->getInit()) 388 ++I; 389 390 if (I != E) { 391 Def = *I; 392 return I->getInit(); 393 } 394 return 0; 395} 396 397VarDecl *VarDecl::getCanonicalDecl() { 398 return getFirstDeclaration(); 399} 400 401//===----------------------------------------------------------------------===// 402// FunctionDecl Implementation 403//===----------------------------------------------------------------------===// 404 405void FunctionDecl::Destroy(ASTContext& C) { 406 if (Body && Body.isOffset()) 407 Body.get(C.getExternalSource())->Destroy(C); 408 409 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 410 (*I)->Destroy(C); 411 412 C.Deallocate(ParamInfo); 413 414 Decl::Destroy(C); 415} 416 417void FunctionDecl::getNameForDiagnostic(std::string &S, 418 const PrintingPolicy &Policy, 419 bool Qualified) const { 420 NamedDecl::getNameForDiagnostic(S, Policy, Qualified); 421 const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs(); 422 if (TemplateArgs) 423 S += TemplateSpecializationType::PrintTemplateArgumentList( 424 TemplateArgs->getFlatArgumentList(), 425 TemplateArgs->flat_size(), 426 Policy); 427 428} 429 430Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { 431 for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { 432 if (I->Body) { 433 Definition = *I; 434 return I->Body.get(getASTContext().getExternalSource()); 435 } 436 } 437 438 return 0; 439} 440 441void FunctionDecl::setBody(Stmt *B) { 442 Body = B; 443 if (B) 444 EndRangeLoc = B->getLocEnd(); 445} 446 447bool FunctionDecl::isMain(ASTContext &Context) const { 448 return !Context.getLangOptions().Freestanding && 449 getDeclContext()->getLookupContext()->isTranslationUnit() && 450 getIdentifier() && getIdentifier()->isStr("main"); 451} 452 453bool FunctionDecl::isExternC(ASTContext &Context) const { 454 // In C, any non-static, non-overloadable function has external 455 // linkage. 456 if (!Context.getLangOptions().CPlusPlus) 457 return getStorageClass() != Static && !getAttr<OverloadableAttr>(); 458 459 for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); 460 DC = DC->getParent()) { 461 if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) { 462 if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) 463 return getStorageClass() != Static && 464 !getAttr<OverloadableAttr>(); 465 466 break; 467 } 468 } 469 470 return false; 471} 472 473bool FunctionDecl::isGlobal() const { 474 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this)) 475 return Method->isStatic(); 476 477 if (getStorageClass() == Static) 478 return false; 479 480 for (const DeclContext *DC = getDeclContext(); 481 DC->isNamespace(); 482 DC = DC->getParent()) { 483 if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) { 484 if (!Namespace->getDeclName()) 485 return false; 486 break; 487 } 488 } 489 490 return true; 491} 492 493/// \brief Returns a value indicating whether this function 494/// corresponds to a builtin function. 495/// 496/// The function corresponds to a built-in function if it is 497/// declared at translation scope or within an extern "C" block and 498/// its name matches with the name of a builtin. The returned value 499/// will be 0 for functions that do not correspond to a builtin, a 500/// value of type \c Builtin::ID if in the target-independent range 501/// \c [1,Builtin::First), or a target-specific builtin value. 502unsigned FunctionDecl::getBuiltinID(ASTContext &Context) const { 503 if (!getIdentifier() || !getIdentifier()->getBuiltinID()) 504 return 0; 505 506 unsigned BuiltinID = getIdentifier()->getBuiltinID(); 507 if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 508 return BuiltinID; 509 510 // This function has the name of a known C library 511 // function. Determine whether it actually refers to the C library 512 // function or whether it just has the same name. 513 514 // If this is a static function, it's not a builtin. 515 if (getStorageClass() == Static) 516 return 0; 517 518 // If this function is at translation-unit scope and we're not in 519 // C++, it refers to the C library function. 520 if (!Context.getLangOptions().CPlusPlus && 521 getDeclContext()->isTranslationUnit()) 522 return BuiltinID; 523 524 // If the function is in an extern "C" linkage specification and is 525 // not marked "overloadable", it's the real function. 526 if (isa<LinkageSpecDecl>(getDeclContext()) && 527 cast<LinkageSpecDecl>(getDeclContext())->getLanguage() 528 == LinkageSpecDecl::lang_c && 529 !getAttr<OverloadableAttr>()) 530 return BuiltinID; 531 532 // Not a builtin 533 return 0; 534} 535 536 537/// getNumParams - Return the number of parameters this function must have 538/// based on its FunctionType. This is the length of the PararmInfo array 539/// after it has been created. 540unsigned FunctionDecl::getNumParams() const { 541 const FunctionType *FT = getType()->getAsFunctionType(); 542 if (isa<FunctionNoProtoType>(FT)) 543 return 0; 544 return cast<FunctionProtoType>(FT)->getNumArgs(); 545 546} 547 548void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, 549 unsigned NumParams) { 550 assert(ParamInfo == 0 && "Already has param info!"); 551 assert(NumParams == getNumParams() && "Parameter count mismatch!"); 552 553 // Zero params -> null pointer. 554 if (NumParams) { 555 void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); 556 ParamInfo = new (Mem) ParmVarDecl*[NumParams]; 557 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); 558 559 // Update source range. The check below allows us to set EndRangeLoc before 560 // setting the parameters. 561 if (EndRangeLoc.isInvalid() || EndRangeLoc == getLocation()) 562 EndRangeLoc = NewParamInfo[NumParams-1]->getLocEnd(); 563 } 564} 565 566/// getMinRequiredArguments - Returns the minimum number of arguments 567/// needed to call this function. This may be fewer than the number of 568/// function parameters, if some of the parameters have default 569/// arguments (in C++). 570unsigned FunctionDecl::getMinRequiredArguments() const { 571 unsigned NumRequiredArgs = getNumParams(); 572 while (NumRequiredArgs > 0 573 && getParamDecl(NumRequiredArgs-1)->hasDefaultArg()) 574 --NumRequiredArgs; 575 576 return NumRequiredArgs; 577} 578 579bool FunctionDecl::hasActiveGNUInlineAttribute(ASTContext &Context) const { 580 if (!isInline() || !hasAttr<GNUInlineAttr>()) 581 return false; 582 583 for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) 584 if (I->isInline() && !I->hasAttr<GNUInlineAttr>()) 585 return false; 586 587 return true; 588} 589 590bool FunctionDecl::isExternGNUInline(ASTContext &Context) const { 591 if (!hasActiveGNUInlineAttribute(Context)) 592 return false; 593 594 for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) 595 if (I->getStorageClass() == Extern && I->hasAttr<GNUInlineAttr>()) 596 return true; 597 598 return false; 599} 600 601void 602FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { 603 redeclarable_base::setPreviousDeclaration(PrevDecl); 604 605 if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) { 606 FunctionTemplateDecl *PrevFunTmpl 607 = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0; 608 assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch"); 609 FunTmpl->setPreviousDeclaration(PrevFunTmpl); 610 } 611} 612 613FunctionDecl *FunctionDecl::getCanonicalDecl() { 614 return getFirstDeclaration(); 615} 616 617/// getOverloadedOperator - Which C++ overloaded operator this 618/// function represents, if any. 619OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { 620 if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName) 621 return getDeclName().getCXXOverloadedOperator(); 622 else 623 return OO_None; 624} 625 626FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { 627 if (FunctionTemplateSpecializationInfo *Info 628 = TemplateOrSpecialization 629 .dyn_cast<FunctionTemplateSpecializationInfo*>()) { 630 return Info->Template.getPointer(); 631 } 632 return 0; 633} 634 635const TemplateArgumentList * 636FunctionDecl::getTemplateSpecializationArgs() const { 637 if (FunctionTemplateSpecializationInfo *Info 638 = TemplateOrSpecialization 639 .dyn_cast<FunctionTemplateSpecializationInfo*>()) { 640 return Info->TemplateArguments; 641 } 642 return 0; 643} 644 645void 646FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context, 647 FunctionTemplateDecl *Template, 648 const TemplateArgumentList *TemplateArgs, 649 void *InsertPos) { 650 FunctionTemplateSpecializationInfo *Info 651 = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); 652 if (!Info) 653 Info = new (Context) FunctionTemplateSpecializationInfo; 654 655 Info->Function = this; 656 Info->Template.setPointer(Template); 657 Info->Template.setInt(TSK_ImplicitInstantiation - 1); 658 Info->TemplateArguments = TemplateArgs; 659 TemplateOrSpecialization = Info; 660 661 // Insert this function template specialization into the set of known 662 // function template specialiations. 663 Template->getSpecializations().InsertNode(Info, InsertPos); 664} 665 666TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const { 667 // For a function template specialization, query the specialization 668 // information object. 669 FunctionTemplateSpecializationInfo *Info 670 = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); 671 if (Info) 672 return Info->getTemplateSpecializationKind(); 673 674 if (!getInstantiatedFromMemberFunction()) 675 return TSK_Undeclared; 676 677 // Find the class template specialization corresponding to this instantiation 678 // of a member function. 679 const DeclContext *Parent = getDeclContext(); 680 while (Parent && !isa<ClassTemplateSpecializationDecl>(Parent)) 681 Parent = Parent->getParent(); 682 683 if (!Parent) 684 return TSK_Undeclared; 685 686 return cast<ClassTemplateSpecializationDecl>(Parent)->getSpecializationKind(); 687} 688 689void 690FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { 691 FunctionTemplateSpecializationInfo *Info 692 = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); 693 assert(Info && "Not a function template specialization"); 694 Info->setTemplateSpecializationKind(TSK); 695} 696 697bool FunctionDecl::isOutOfLine() const { 698 // FIXME: Should we restrict this to member functions? 699 if (Decl::isOutOfLine()) 700 return true; 701 702 // If this function was instantiated from a member function of a 703 // class template, check whether that member function was defined out-of-line. 704 if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) { 705 const FunctionDecl *Definition; 706 if (FD->getBody(Definition)) 707 return Definition->isOutOfLine(); 708 } 709 710 // If this function was instantiated from a function template, 711 // check whether that function template was defined out-of-line. 712 if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) { 713 const FunctionDecl *Definition; 714 if (FunTmpl->getTemplatedDecl()->getBody(Definition)) 715 return Definition->isOutOfLine(); 716 } 717 718 return false; 719} 720 721//===----------------------------------------------------------------------===// 722// TagDecl Implementation 723//===----------------------------------------------------------------------===// 724 725SourceRange TagDecl::getSourceRange() const { 726 SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation(); 727 return SourceRange(TagKeywordLoc, E); 728} 729 730TagDecl* TagDecl::getCanonicalDecl() { 731 return getFirstDeclaration(); 732} 733 734void TagDecl::startDefinition() { 735 if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) { 736 TagT->decl.setPointer(this); 737 TagT->decl.setInt(1); 738 } 739} 740 741void TagDecl::completeDefinition() { 742 IsDefinition = true; 743 if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) { 744 assert(TagT->decl.getPointer() == this && 745 "Attempt to redefine a tag definition?"); 746 TagT->decl.setInt(0); 747 } 748} 749 750TagDecl* TagDecl::getDefinition(ASTContext& C) const { 751 if (isDefinition()) 752 return const_cast<TagDecl *>(this); 753 754 for (redecl_iterator R = redecls_begin(), REnd = redecls_end(); 755 R != REnd; ++R) 756 if (R->isDefinition()) 757 return *R; 758 759 return 0; 760} 761 762TagDecl::TagKind TagDecl::getTagKindForTypeSpec(unsigned TypeSpec) { 763 switch (TypeSpec) { 764 default: llvm::llvm_unreachable("unexpected type specifier"); 765 case DeclSpec::TST_struct: return TK_struct; 766 case DeclSpec::TST_class: return TK_class; 767 case DeclSpec::TST_union: return TK_union; 768 case DeclSpec::TST_enum: return TK_enum; 769 } 770} 771 772//===----------------------------------------------------------------------===// 773// RecordDecl Implementation 774//===----------------------------------------------------------------------===// 775 776RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, 777 IdentifierInfo *Id, RecordDecl *PrevDecl, 778 SourceLocation TKL) 779 : TagDecl(DK, TK, DC, L, Id, PrevDecl, TKL) { 780 HasFlexibleArrayMember = false; 781 AnonymousStructOrUnion = false; 782 HasObjectMember = false; 783 assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); 784} 785 786RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, 787 SourceLocation L, IdentifierInfo *Id, 788 SourceLocation TKL, RecordDecl* PrevDecl) { 789 790 RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id, PrevDecl, TKL); 791 C.getTypeDeclType(R, PrevDecl); 792 return R; 793} 794 795RecordDecl::~RecordDecl() { 796} 797 798void RecordDecl::Destroy(ASTContext& C) { 799 TagDecl::Destroy(C); 800} 801 802bool RecordDecl::isInjectedClassName() const { 803 return isImplicit() && getDeclName() && getDeclContext()->isRecord() && 804 cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName(); 805} 806 807/// completeDefinition - Notes that the definition of this type is now 808/// complete. 809void RecordDecl::completeDefinition(ASTContext& C) { 810 assert(!isDefinition() && "Cannot redefine record!"); 811 TagDecl::completeDefinition(); 812} 813 814//===----------------------------------------------------------------------===// 815// BlockDecl Implementation 816//===----------------------------------------------------------------------===// 817 818BlockDecl::~BlockDecl() { 819} 820 821void BlockDecl::Destroy(ASTContext& C) { 822 if (Body) 823 Body->Destroy(C); 824 825 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 826 (*I)->Destroy(C); 827 828 C.Deallocate(ParamInfo); 829 Decl::Destroy(C); 830} 831 832void BlockDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, 833 unsigned NParms) { 834 assert(ParamInfo == 0 && "Already has param info!"); 835 836 // Zero params -> null pointer. 837 if (NParms) { 838 NumParams = NParms; 839 void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); 840 ParamInfo = new (Mem) ParmVarDecl*[NumParams]; 841 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); 842 } 843} 844 845unsigned BlockDecl::getNumParams() const { 846 return NumParams; 847} 848