DeclCXX.cpp revision 08c6357918c8c4bf00ede6936c7b64c7d89e7c41
1//===--- DeclCXX.cpp - C++ 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 C++ related Decl classes. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/DeclCXX.h" 15#include "clang/AST/DeclTemplate.h" 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/Expr.h" 18#include "clang/Basic/IdentifierTable.h" 19#include "llvm/ADT/STLExtras.h" 20using namespace clang; 21 22//===----------------------------------------------------------------------===// 23// Decl Allocation/Deallocation Method Implementations 24//===----------------------------------------------------------------------===// 25 26CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, 27 SourceLocation L, IdentifierInfo *Id, 28 SourceLocation TKL) 29 : RecordDecl(K, TK, DC, L, Id, TKL), 30 UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false), 31 UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false), 32 Aggregate(true), PlainOldData(true), Polymorphic(false), Abstract(false), 33 HasTrivialConstructor(true), HasTrivialCopyConstructor(true), 34 HasTrivialCopyAssignment(true), HasTrivialDestructor(true), 35 Bases(0), NumBases(0), VBases(0), NumVBases(0), 36 Conversions(DC, DeclarationName()), 37 TemplateOrInstantiation() { } 38 39CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, 40 SourceLocation L, IdentifierInfo *Id, 41 SourceLocation TKL, 42 CXXRecordDecl* PrevDecl, 43 bool DelayTypeCreation) { 44 CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id, TKL); 45 if (!DelayTypeCreation) 46 C.getTypeDeclType(R, PrevDecl); 47 return R; 48} 49 50CXXRecordDecl::~CXXRecordDecl() { 51} 52 53void CXXRecordDecl::Destroy(ASTContext &C) { 54 C.Deallocate(Bases); 55 C.Deallocate(VBases); 56 this->RecordDecl::Destroy(C); 57} 58 59void 60CXXRecordDecl::setBases(ASTContext &C, 61 CXXBaseSpecifier const * const *Bases, 62 unsigned NumBases) { 63 // C++ [dcl.init.aggr]p1: 64 // An aggregate is an array or a class (clause 9) with [...] 65 // no base classes [...]. 66 Aggregate = false; 67 68 if (this->Bases) 69 C.Deallocate(this->Bases); 70 71 int vbaseCount = 0; 72 llvm::SmallVector<const CXXBaseSpecifier*, 8> UniqueVbases; 73 bool hasDirectVirtualBase = false; 74 75 this->Bases = new(C) CXXBaseSpecifier [NumBases]; 76 this->NumBases = NumBases; 77 for (unsigned i = 0; i < NumBases; ++i) { 78 this->Bases[i] = *Bases[i]; 79 // Keep track of inherited vbases for this base class. 80 const CXXBaseSpecifier *Base = Bases[i]; 81 QualType BaseType = Base->getType(); 82 // Skip template types. 83 // FIXME. This means that this list must be rebuilt during template 84 // instantiation. 85 if (BaseType->isDependentType()) 86 continue; 87 CXXRecordDecl *BaseClassDecl 88 = cast<CXXRecordDecl>(BaseType->getAsRecordType()->getDecl()); 89 if (Base->isVirtual()) 90 hasDirectVirtualBase = true; 91 for (CXXRecordDecl::base_class_iterator VBase = 92 BaseClassDecl->vbases_begin(), 93 E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) { 94 // Add this vbase to the array of vbases for current class if it is 95 // not already in the list. 96 // FIXME. Note that we do a linear search as number of such classes are 97 // very few. 98 int i; 99 for (i = 0; i < vbaseCount; ++i) 100 if (UniqueVbases[i]->getType() == VBase->getType()) 101 break; 102 if (i == vbaseCount) { 103 UniqueVbases.push_back(VBase); 104 ++vbaseCount; 105 } 106 } 107 } 108 if (hasDirectVirtualBase) { 109 // Iterate one more time through the direct bases and add the virtual 110 // base to the list of vritual bases for current class. 111 for (unsigned i = 0; i < NumBases; ++i) { 112 const CXXBaseSpecifier *VBase = Bases[i]; 113 if (!VBase->isVirtual()) 114 continue; 115 int j; 116 for (j = 0; j < vbaseCount; ++j) 117 if (UniqueVbases[j]->getType() == VBase->getType()) 118 break; 119 if (j == vbaseCount) { 120 UniqueVbases.push_back(VBase); 121 ++vbaseCount; 122 } 123 } 124 } 125 if (vbaseCount > 0) { 126 // build AST for inhireted, direct or indirect, virtual bases. 127 this->VBases = new (C) CXXBaseSpecifier [vbaseCount]; 128 this->NumVBases = vbaseCount; 129 for (int i = 0; i < vbaseCount; i++) { 130 QualType QT = UniqueVbases[i]->getType(); 131 CXXRecordDecl *VBaseClassDecl 132 = cast<CXXRecordDecl>(QT->getAsRecordType()->getDecl()); 133 this->VBases[i] = 134 CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true, 135 VBaseClassDecl->getTagKind() == RecordDecl::TK_class, 136 UniqueVbases[i]->getAccessSpecifier(), QT); 137 } 138 } 139} 140 141bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const { 142 return getCopyConstructor(Context, QualType::Const) != 0; 143} 144 145CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context, 146 unsigned TypeQuals) const{ 147 QualType ClassType 148 = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this)); 149 DeclarationName ConstructorName 150 = Context.DeclarationNames.getCXXConstructorName( 151 Context.getCanonicalType(ClassType)); 152 unsigned FoundTQs; 153 DeclContext::lookup_const_iterator Con, ConEnd; 154 for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName); 155 Con != ConEnd; ++Con) { 156 if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, 157 FoundTQs)) { 158 if (((TypeQuals & QualType::Const) == (FoundTQs & QualType::Const)) || 159 (!(TypeQuals & QualType::Const) && (FoundTQs & QualType::Const))) 160 return cast<CXXConstructorDecl>(*Con); 161 162 } 163 } 164 return 0; 165} 166 167bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const { 168 QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType( 169 const_cast<CXXRecordDecl*>(this))); 170 DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal); 171 172 DeclContext::lookup_const_iterator Op, OpEnd; 173 for (llvm::tie(Op, OpEnd) = this->lookup(OpName); 174 Op != OpEnd; ++Op) { 175 // C++ [class.copy]p9: 176 // A user-declared copy assignment operator is a non-static non-template 177 // member function of class X with exactly one parameter of type X, X&, 178 // const X&, volatile X& or const volatile X&. 179 const CXXMethodDecl* Method = cast<CXXMethodDecl>(*Op); 180 if (Method->isStatic()) 181 continue; 182 // TODO: Skip templates? Or is this implicitly done due to parameter types? 183 const FunctionProtoType *FnType = 184 Method->getType()->getAsFunctionProtoType(); 185 assert(FnType && "Overloaded operator has no prototype."); 186 // Don't assert on this; an invalid decl might have been left in the AST. 187 if (FnType->getNumArgs() != 1 || FnType->isVariadic()) 188 continue; 189 bool AcceptsConst = true; 190 QualType ArgType = FnType->getArgType(0); 191 if (const LValueReferenceType *Ref = ArgType->getAsLValueReferenceType()) { 192 ArgType = Ref->getPointeeType(); 193 // Is it a non-const lvalue reference? 194 if (!ArgType.isConstQualified()) 195 AcceptsConst = false; 196 } 197 if (Context.getCanonicalType(ArgType).getUnqualifiedType() != ClassType) 198 continue; 199 200 // We have a single argument of type cv X or cv X&, i.e. we've found the 201 // copy assignment operator. Return whether it accepts const arguments. 202 return AcceptsConst; 203 } 204 assert(isInvalidDecl() && 205 "No copy assignment operator declared in valid code."); 206 return false; 207} 208 209void 210CXXRecordDecl::addedConstructor(ASTContext &Context, 211 CXXConstructorDecl *ConDecl) { 212 assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl"); 213 // Note that we have a user-declared constructor. 214 UserDeclaredConstructor = true; 215 216 // C++ [dcl.init.aggr]p1: 217 // An aggregate is an array or a class (clause 9) with no 218 // user-declared constructors (12.1) [...]. 219 Aggregate = false; 220 221 // C++ [class]p4: 222 // A POD-struct is an aggregate class [...] 223 PlainOldData = false; 224 225 // C++ [class.ctor]p5: 226 // A constructor is trivial if it is an implicitly-declared default 227 // constructor. 228 // FIXME: C++0x: don't do this for "= default" default constructors. 229 HasTrivialConstructor = false; 230 231 // Note when we have a user-declared copy constructor, which will 232 // suppress the implicit declaration of a copy constructor. 233 if (ConDecl->isCopyConstructor(Context)) { 234 UserDeclaredCopyConstructor = true; 235 236 // C++ [class.copy]p6: 237 // A copy constructor is trivial if it is implicitly declared. 238 // FIXME: C++0x: don't do this for "= default" copy constructors. 239 HasTrivialCopyConstructor = false; 240 } 241} 242 243void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context, 244 CXXMethodDecl *OpDecl) { 245 // We're interested specifically in copy assignment operators. 246 const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType(); 247 assert(FnType && "Overloaded operator has no proto function type."); 248 assert(FnType->getNumArgs() == 1 && !FnType->isVariadic()); 249 QualType ArgType = FnType->getArgType(0); 250 if (const LValueReferenceType *Ref = ArgType->getAsLValueReferenceType()) 251 ArgType = Ref->getPointeeType(); 252 253 ArgType = ArgType.getUnqualifiedType(); 254 QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType( 255 const_cast<CXXRecordDecl*>(this))); 256 257 if (ClassType != Context.getCanonicalType(ArgType)) 258 return; 259 260 // This is a copy assignment operator. 261 // Suppress the implicit declaration of a copy constructor. 262 UserDeclaredCopyAssignment = true; 263 264 // C++ [class.copy]p11: 265 // A copy assignment operator is trivial if it is implicitly declared. 266 // FIXME: C++0x: don't do this for "= default" copy operators. 267 HasTrivialCopyAssignment = false; 268 269 // C++ [class]p4: 270 // A POD-struct is an aggregate class that [...] has no user-defined copy 271 // assignment operator [...]. 272 PlainOldData = false; 273} 274 275void CXXRecordDecl::addConversionFunction(ASTContext &Context, 276 CXXConversionDecl *ConvDecl) { 277 Conversions.addOverload(ConvDecl); 278} 279 280 281CXXConstructorDecl * 282CXXRecordDecl::getDefaultConstructor(ASTContext &Context) { 283 QualType ClassType = Context.getTypeDeclType(this); 284 DeclarationName ConstructorName 285 = Context.DeclarationNames.getCXXConstructorName( 286 Context.getCanonicalType(ClassType.getUnqualifiedType())); 287 288 DeclContext::lookup_const_iterator Con, ConEnd; 289 for (llvm::tie(Con, ConEnd) = lookup(ConstructorName); 290 Con != ConEnd; ++Con) { 291 CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); 292 if (Constructor->isDefaultConstructor()) 293 return Constructor; 294 } 295 return 0; 296} 297 298const CXXDestructorDecl * 299CXXRecordDecl::getDestructor(ASTContext &Context) { 300 QualType ClassType = Context.getTypeDeclType(this); 301 302 DeclarationName Name 303 = Context.DeclarationNames.getCXXDestructorName(ClassType); 304 305 DeclContext::lookup_iterator I, E; 306 llvm::tie(I, E) = lookup(Name); 307 assert(I != E && "Did not find a destructor!"); 308 309 const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I); 310 assert(++I == E && "Found more than one destructor!"); 311 312 return Dtor; 313} 314 315CXXMethodDecl * 316CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, 317 SourceLocation L, DeclarationName N, 318 QualType T, bool isStatic, bool isInline) { 319 return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline); 320} 321 322 323typedef llvm::DenseMap<const CXXMethodDecl*, 324 std::vector<const CXXMethodDecl *> *> 325 OverriddenMethodsMapTy; 326 327static OverriddenMethodsMapTy *OverriddenMethods = 0; 328 329void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) { 330 // FIXME: The CXXMethodDecl dtor needs to remove and free the entry. 331 332 if (!OverriddenMethods) 333 OverriddenMethods = new OverriddenMethodsMapTy(); 334 335 std::vector<const CXXMethodDecl *> *&Methods = (*OverriddenMethods)[this]; 336 if (!Methods) 337 Methods = new std::vector<const CXXMethodDecl *>; 338 339 Methods->push_back(MD); 340} 341 342CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const { 343 if (!OverriddenMethods) 344 return 0; 345 346 OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this); 347 if (it == OverriddenMethods->end()) 348 return 0; 349 return &(*it->second)[0]; 350} 351 352CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const { 353 if (!OverriddenMethods) 354 return 0; 355 356 OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this); 357 if (it == OverriddenMethods->end()) 358 return 0; 359 360 return &(*it->second)[it->second->size()]; 361} 362 363QualType CXXMethodDecl::getThisType(ASTContext &C) const { 364 // C++ 9.3.2p1: The type of this in a member function of a class X is X*. 365 // If the member function is declared const, the type of this is const X*, 366 // if the member function is declared volatile, the type of this is 367 // volatile X*, and if the member function is declared const volatile, 368 // the type of this is const volatile X*. 369 370 assert(isInstance() && "No 'this' for static methods!"); 371 372 QualType ClassTy; 373 if (ClassTemplateDecl *TD = getParent()->getDescribedClassTemplate()) 374 ClassTy = TD->getInjectedClassNameType(C); 375 else 376 ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(getParent())); 377 ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers()); 378 return C.getPointerType(ClassTy); 379} 380 381CXXBaseOrMemberInitializer:: 382CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs, 383 CXXConstructorDecl *C, 384 SourceLocation L) 385 : Args(0), NumArgs(0), IdLoc(L) { 386 BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr()); 387 assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer"); 388 BaseOrMember |= 0x01; 389 390 if (NumArgs > 0) { 391 this->NumArgs = NumArgs; 392 // FIXME. Allocation via Context 393 this->Args = new Stmt*[NumArgs]; 394 for (unsigned Idx = 0; Idx < NumArgs; ++Idx) 395 this->Args[Idx] = Args[Idx]; 396 } 397 CtorToCall = C; 398} 399 400CXXBaseOrMemberInitializer:: 401CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs, 402 CXXConstructorDecl *C, 403 SourceLocation L) 404 : Args(0), NumArgs(0), IdLoc(L) { 405 BaseOrMember = reinterpret_cast<uintptr_t>(Member); 406 assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer"); 407 408 if (NumArgs > 0) { 409 this->NumArgs = NumArgs; 410 this->Args = new Stmt*[NumArgs]; 411 for (unsigned Idx = 0; Idx < NumArgs; ++Idx) 412 this->Args[Idx] = Args[Idx]; 413 } 414 CtorToCall = C; 415} 416 417CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() { 418 delete [] Args; 419} 420 421CXXConstructorDecl * 422CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 423 SourceLocation L, DeclarationName N, 424 QualType T, bool isExplicit, 425 bool isInline, bool isImplicitlyDeclared) { 426 assert(N.getNameKind() == DeclarationName::CXXConstructorName && 427 "Name must refer to a constructor"); 428 return new (C) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline, 429 isImplicitlyDeclared); 430} 431 432bool CXXConstructorDecl::isDefaultConstructor() const { 433 // C++ [class.ctor]p5: 434 // A default constructor for a class X is a constructor of class 435 // X that can be called without an argument. 436 return (getNumParams() == 0) || 437 (getNumParams() > 0 && getParamDecl(0)->getDefaultArg() != 0); 438} 439 440bool 441CXXConstructorDecl::isCopyConstructor(ASTContext &Context, 442 unsigned &TypeQuals) const { 443 // C++ [class.copy]p2: 444 // A non-template constructor for class X is a copy constructor 445 // if its first parameter is of type X&, const X&, volatile X& or 446 // const volatile X&, and either there are no other parameters 447 // or else all other parameters have default arguments (8.3.6). 448 if ((getNumParams() < 1) || 449 (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg())) 450 return false; 451 452 const ParmVarDecl *Param = getParamDecl(0); 453 454 // Do we have a reference type? Rvalue references don't count. 455 const LValueReferenceType *ParamRefType = 456 Param->getType()->getAsLValueReferenceType(); 457 if (!ParamRefType) 458 return false; 459 460 // Is it a reference to our class type? 461 QualType PointeeType 462 = Context.getCanonicalType(ParamRefType->getPointeeType()); 463 QualType ClassTy 464 = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent())); 465 if (PointeeType.getUnqualifiedType() != ClassTy) 466 return false; 467 468 // We have a copy constructor. 469 TypeQuals = PointeeType.getCVRQualifiers(); 470 return true; 471} 472 473bool CXXConstructorDecl::isConvertingConstructor() const { 474 // C++ [class.conv.ctor]p1: 475 // A constructor declared without the function-specifier explicit 476 // that can be called with a single parameter specifies a 477 // conversion from the type of its first parameter to the type of 478 // its class. Such a constructor is called a converting 479 // constructor. 480 if (isExplicit()) 481 return false; 482 483 return (getNumParams() == 0 && 484 getType()->getAsFunctionProtoType()->isVariadic()) || 485 (getNumParams() == 1) || 486 (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg()); 487} 488 489CXXDestructorDecl * 490CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 491 SourceLocation L, DeclarationName N, 492 QualType T, bool isInline, 493 bool isImplicitlyDeclared) { 494 assert(N.getNameKind() == DeclarationName::CXXDestructorName && 495 "Name must refer to a destructor"); 496 return new (C) CXXDestructorDecl(RD, L, N, T, isInline, 497 isImplicitlyDeclared); 498} 499 500void 501CXXDestructorDecl::Destroy(ASTContext& C) { 502 C.Deallocate(BaseOrMemberDestructions); 503 CXXMethodDecl::Destroy(C); 504} 505 506void 507CXXDestructorDecl::computeBaseOrMembersToDestroy(ASTContext &C) { 508 CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext()); 509 llvm::SmallVector<uintptr_t, 32> AllToDestruct; 510 511 for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), 512 E = ClassDecl->vbases_end(); VBase != E; ++VBase) { 513 // Skip over virtual bases which have trivial destructors. 514 CXXRecordDecl *BaseClassDecl 515 = cast<CXXRecordDecl>(VBase->getType()->getAsRecordType()->getDecl()); 516 if (BaseClassDecl->hasTrivialDestructor()) 517 continue; 518 uintptr_t Member = 519 reinterpret_cast<uintptr_t>(VBase->getType().getTypePtr()) | VBASE; 520 AllToDestruct.push_back(Member); 521 } 522 for (CXXRecordDecl::base_class_iterator Base = 523 ClassDecl->bases_begin(), 524 E = ClassDecl->bases_end(); Base != E; ++Base) { 525 if (Base->isVirtual()) 526 continue; 527 // Skip over virtual bases which have trivial destructors. 528 CXXRecordDecl *BaseClassDecl 529 = cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl()); 530 if (BaseClassDecl->hasTrivialDestructor()) 531 continue; 532 533 uintptr_t Member = 534 reinterpret_cast<uintptr_t>(Base->getType().getTypePtr()) | DRCTNONVBASE; 535 AllToDestruct.push_back(Member); 536 } 537 538 // non-static data members. 539 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), 540 E = ClassDecl->field_end(); Field != E; ++Field) { 541 QualType FieldType = C.getBaseElementType((*Field)->getType()); 542 543 if (const RecordType* RT = FieldType->getAsRecordType()) { 544 // Skip over virtual bases which have trivial destructors. 545 CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 546 if (BaseClassDecl->hasTrivialDestructor()) 547 continue; 548 uintptr_t Member = reinterpret_cast<uintptr_t>(*Field); 549 AllToDestruct.push_back(Member); 550 } 551 } 552 553 unsigned NumDestructions = AllToDestruct.size(); 554 if (NumDestructions > 0) { 555 NumBaseOrMemberDestructions = NumDestructions; 556 BaseOrMemberDestructions = new (C) uintptr_t [NumDestructions]; 557 // Insert in reverse order. 558 for (int Idx = NumDestructions-1, i=0 ; Idx >= 0; --Idx) 559 BaseOrMemberDestructions[i++] = AllToDestruct[Idx]; 560 } 561} 562 563void 564CXXConstructorDecl::setBaseOrMemberInitializers( 565 ASTContext &C, 566 CXXBaseOrMemberInitializer **Initializers, 567 unsigned NumInitializers, 568 llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases, 569 llvm::SmallVectorImpl<FieldDecl *>&Fields) { 570 // We need to build the initializer AST according to order of construction 571 // and not what user specified in the Initializers list. 572 CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext()); 573 llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit; 574 llvm::DenseMap<const void *, CXXBaseOrMemberInitializer*> AllBaseFields; 575 576 for (unsigned i = 0; i < NumInitializers; i++) { 577 CXXBaseOrMemberInitializer *Member = Initializers[i]; 578 if (Member->isBaseInitializer()) 579 AllBaseFields[Member->getBaseClass()->getAsRecordType()] = Member; 580 else 581 AllBaseFields[Member->getMember()] = Member; 582 } 583 584 // Push virtual bases before others. 585 for (CXXRecordDecl::base_class_iterator VBase = 586 ClassDecl->vbases_begin(), 587 E = ClassDecl->vbases_end(); VBase != E; ++VBase) { 588 if (CXXBaseOrMemberInitializer *Value = 589 AllBaseFields.lookup(VBase->getType()->getAsRecordType())) 590 AllToInit.push_back(Value); 591 else { 592 CXXRecordDecl *VBaseDecl = 593 cast<CXXRecordDecl>(VBase->getType()->getAsRecordType()->getDecl()); 594 assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null"); 595 if (!VBaseDecl->getDefaultConstructor(C) && 596 !VBase->getType()->isDependentType()) 597 Bases.push_back(VBase); 598 CXXBaseOrMemberInitializer *Member = 599 new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0, 600 VBaseDecl->getDefaultConstructor(C), 601 SourceLocation()); 602 AllToInit.push_back(Member); 603 } 604 } 605 606 for (CXXRecordDecl::base_class_iterator Base = 607 ClassDecl->bases_begin(), 608 E = ClassDecl->bases_end(); Base != E; ++Base) { 609 // Virtuals are in the virtual base list and already constructed. 610 if (Base->isVirtual()) 611 continue; 612 if (CXXBaseOrMemberInitializer *Value = 613 AllBaseFields.lookup(Base->getType()->getAsRecordType())) 614 AllToInit.push_back(Value); 615 else { 616 CXXRecordDecl *BaseDecl = 617 cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl()); 618 assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null"); 619 if (!BaseDecl->getDefaultConstructor(C) && 620 !Base->getType()->isDependentType()) 621 Bases.push_back(Base); 622 CXXBaseOrMemberInitializer *Member = 623 new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0, 624 BaseDecl->getDefaultConstructor(C), 625 SourceLocation()); 626 AllToInit.push_back(Member); 627 } 628 } 629 630 // non-static data members. 631 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), 632 E = ClassDecl->field_end(); Field != E; ++Field) { 633 if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*Field)) { 634 AllToInit.push_back(Value); 635 continue; 636 } 637 638 QualType FT = C.getBaseElementType((*Field)->getType()); 639 if (const RecordType* RT = FT->getAsRecordType()) { 640 CXXConstructorDecl *Ctor = 641 cast<CXXRecordDecl>(RT->getDecl())->getDefaultConstructor(C); 642 if (!Ctor && !FT->isDependentType()) 643 Fields.push_back(*Field); 644 CXXBaseOrMemberInitializer *Member = 645 new (C) CXXBaseOrMemberInitializer((*Field), 0, 0, 646 Ctor, 647 SourceLocation()); 648 AllToInit.push_back(Member); 649 } 650 } 651 652 NumInitializers = AllToInit.size(); 653 if (NumInitializers > 0) { 654 NumBaseOrMemberInitializers = NumInitializers; 655 BaseOrMemberInitializers = 656 new (C) CXXBaseOrMemberInitializer*[NumInitializers]; 657 for (unsigned Idx = 0; Idx < NumInitializers; ++Idx) 658 BaseOrMemberInitializers[Idx] = AllToInit[Idx]; 659 } 660} 661 662void 663CXXConstructorDecl::Destroy(ASTContext& C) { 664 C.Deallocate(BaseOrMemberInitializers); 665 CXXMethodDecl::Destroy(C); 666} 667 668CXXConversionDecl * 669CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, 670 SourceLocation L, DeclarationName N, 671 QualType T, bool isInline, bool isExplicit) { 672 assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName && 673 "Name must refer to a conversion function"); 674 return new (C) CXXConversionDecl(RD, L, N, T, isInline, isExplicit); 675} 676 677OverloadedFunctionDecl * 678OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC, 679 DeclarationName N) { 680 return new (C) OverloadedFunctionDecl(DC, N); 681} 682 683void OverloadedFunctionDecl::addOverload(AnyFunctionDecl F) { 684 Functions.push_back(F); 685 this->setLocation(F.get()->getLocation()); 686} 687 688OverloadIterator::reference OverloadIterator::operator*() const { 689 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 690 return FD; 691 692 if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) 693 return FTD; 694 695 assert(isa<OverloadedFunctionDecl>(D)); 696 return *Iter; 697} 698 699OverloadIterator &OverloadIterator::operator++() { 700 if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) { 701 D = 0; 702 return *this; 703 } 704 705 if (++Iter == cast<OverloadedFunctionDecl>(D)->function_end()) 706 D = 0; 707 708 return *this; 709} 710 711bool OverloadIterator::Equals(const OverloadIterator &Other) const { 712 if (!D || !Other.D) 713 return D == Other.D; 714 715 if (D != Other.D) 716 return false; 717 718 return !isa<OverloadedFunctionDecl>(D) || Iter == Other.Iter; 719} 720 721LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, 722 DeclContext *DC, 723 SourceLocation L, 724 LanguageIDs Lang, bool Braces) { 725 return new (C) LinkageSpecDecl(DC, L, Lang, Braces); 726} 727 728UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, 729 SourceLocation L, 730 SourceLocation NamespaceLoc, 731 SourceRange QualifierRange, 732 NestedNameSpecifier *Qualifier, 733 SourceLocation IdentLoc, 734 NamespaceDecl *Used, 735 DeclContext *CommonAncestor) { 736 return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange, 737 Qualifier, IdentLoc, Used, CommonAncestor); 738} 739 740NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, 741 SourceLocation L, 742 SourceLocation AliasLoc, 743 IdentifierInfo *Alias, 744 SourceRange QualifierRange, 745 NestedNameSpecifier *Qualifier, 746 SourceLocation IdentLoc, 747 NamedDecl *Namespace) { 748 return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange, 749 Qualifier, IdentLoc, Namespace); 750} 751 752UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, 753 SourceLocation L, SourceRange NNR, SourceLocation TargetNL, 754 SourceLocation UL, NamedDecl* Target, 755 NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) { 756 return new (C) UsingDecl(DC, L, NNR, TargetNL, UL, Target, 757 TargetNNS, IsTypeNameArg); 758} 759 760StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, 761 SourceLocation L, Expr *AssertExpr, 762 StringLiteral *Message) { 763 return new (C) StaticAssertDecl(DC, L, AssertExpr, Message); 764} 765 766void StaticAssertDecl::Destroy(ASTContext& C) { 767 AssertExpr->Destroy(C); 768 Message->Destroy(C); 769 this->~StaticAssertDecl(); 770 C.Deallocate((void *)this); 771} 772 773StaticAssertDecl::~StaticAssertDecl() { 774} 775 776static const char *getAccessName(AccessSpecifier AS) { 777 switch (AS) { 778 default: 779 case AS_none: 780 assert("Invalid access specifier!"); 781 return 0; 782 case AS_public: 783 return "public"; 784 case AS_private: 785 return "private"; 786 case AS_protected: 787 return "protected"; 788 } 789} 790 791const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 792 AccessSpecifier AS) { 793 return DB << getAccessName(AS); 794} 795 796 797