DeclCXX.cpp revision 195341
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 : RecordDecl(K, TK, DC, L, Id), 29 UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false), 30 UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false), 31 Aggregate(true), PlainOldData(true), Polymorphic(false), Abstract(false), 32 HasTrivialConstructor(true), HasTrivialDestructor(true), 33 Bases(0), NumBases(0), Conversions(DC, DeclarationName()), 34 TemplateOrInstantiation() { } 35 36CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, 37 SourceLocation L, IdentifierInfo *Id, 38 CXXRecordDecl* PrevDecl, 39 bool DelayTypeCreation) { 40 CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id); 41 if (!DelayTypeCreation) 42 C.getTypeDeclType(R, PrevDecl); 43 return R; 44} 45 46CXXRecordDecl::~CXXRecordDecl() { 47} 48 49void CXXRecordDecl::Destroy(ASTContext &C) { 50 C.Deallocate(Bases); 51 this->RecordDecl::Destroy(C); 52} 53 54void 55CXXRecordDecl::setBases(ASTContext &C, 56 CXXBaseSpecifier const * const *Bases, 57 unsigned NumBases) { 58 // C++ [dcl.init.aggr]p1: 59 // An aggregate is an array or a class (clause 9) with [...] 60 // no base classes [...]. 61 Aggregate = false; 62 63 if (this->Bases) 64 C.Deallocate(this->Bases); 65 66 this->Bases = new(C) CXXBaseSpecifier [NumBases]; 67 this->NumBases = NumBases; 68 for (unsigned i = 0; i < NumBases; ++i) 69 this->Bases[i] = *Bases[i]; 70} 71 72bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const { 73 return getCopyConstructor(Context, QualType::Const) != 0; 74} 75 76CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context, 77 unsigned TypeQuals) const{ 78 QualType ClassType 79 = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this)); 80 DeclarationName ConstructorName 81 = Context.DeclarationNames.getCXXConstructorName( 82 Context.getCanonicalType(ClassType)); 83 unsigned FoundTQs; 84 DeclContext::lookup_const_iterator Con, ConEnd; 85 for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName); 86 Con != ConEnd; ++Con) { 87 if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, 88 FoundTQs)) { 89 if (((TypeQuals & QualType::Const) == (FoundTQs & QualType::Const)) || 90 (!(TypeQuals & QualType::Const) && (FoundTQs & QualType::Const))) 91 return cast<CXXConstructorDecl>(*Con); 92 93 } 94 } 95 return 0; 96} 97 98bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const { 99 QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType( 100 const_cast<CXXRecordDecl*>(this))); 101 DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal); 102 103 DeclContext::lookup_const_iterator Op, OpEnd; 104 for (llvm::tie(Op, OpEnd) = this->lookup(OpName); 105 Op != OpEnd; ++Op) { 106 // C++ [class.copy]p9: 107 // A user-declared copy assignment operator is a non-static non-template 108 // member function of class X with exactly one parameter of type X, X&, 109 // const X&, volatile X& or const volatile X&. 110 const CXXMethodDecl* Method = cast<CXXMethodDecl>(*Op); 111 if (Method->isStatic()) 112 continue; 113 // TODO: Skip templates? Or is this implicitly done due to parameter types? 114 const FunctionProtoType *FnType = 115 Method->getType()->getAsFunctionProtoType(); 116 assert(FnType && "Overloaded operator has no prototype."); 117 // Don't assert on this; an invalid decl might have been left in the AST. 118 if (FnType->getNumArgs() != 1 || FnType->isVariadic()) 119 continue; 120 bool AcceptsConst = true; 121 QualType ArgType = FnType->getArgType(0); 122 if (const LValueReferenceType *Ref = ArgType->getAsLValueReferenceType()) { 123 ArgType = Ref->getPointeeType(); 124 // Is it a non-const lvalue reference? 125 if (!ArgType.isConstQualified()) 126 AcceptsConst = false; 127 } 128 if (Context.getCanonicalType(ArgType).getUnqualifiedType() != ClassType) 129 continue; 130 131 // We have a single argument of type cv X or cv X&, i.e. we've found the 132 // copy assignment operator. Return whether it accepts const arguments. 133 return AcceptsConst; 134 } 135 assert(isInvalidDecl() && 136 "No copy assignment operator declared in valid code."); 137 return false; 138} 139 140void 141CXXRecordDecl::addedConstructor(ASTContext &Context, 142 CXXConstructorDecl *ConDecl) { 143 assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl"); 144 // Note that we have a user-declared constructor. 145 UserDeclaredConstructor = true; 146 147 // C++ [dcl.init.aggr]p1: 148 // An aggregate is an array or a class (clause 9) with no 149 // user-declared constructors (12.1) [...]. 150 Aggregate = false; 151 152 // C++ [class]p4: 153 // A POD-struct is an aggregate class [...] 154 PlainOldData = false; 155 156 // C++ [class.ctor]p5: 157 // A constructor is trivial if it is an implicitly-declared default 158 // constructor. 159 HasTrivialConstructor = false; 160 161 // Note when we have a user-declared copy constructor, which will 162 // suppress the implicit declaration of a copy constructor. 163 if (ConDecl->isCopyConstructor(Context)) 164 UserDeclaredCopyConstructor = true; 165} 166 167void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context, 168 CXXMethodDecl *OpDecl) { 169 // We're interested specifically in copy assignment operators. 170 const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType(); 171 assert(FnType && "Overloaded operator has no proto function type."); 172 assert(FnType->getNumArgs() == 1 && !FnType->isVariadic()); 173 QualType ArgType = FnType->getArgType(0); 174 if (const LValueReferenceType *Ref = ArgType->getAsLValueReferenceType()) 175 ArgType = Ref->getPointeeType(); 176 177 ArgType = ArgType.getUnqualifiedType(); 178 QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType( 179 const_cast<CXXRecordDecl*>(this))); 180 181 if (ClassType != Context.getCanonicalType(ArgType)) 182 return; 183 184 // This is a copy assignment operator. 185 // Suppress the implicit declaration of a copy constructor. 186 UserDeclaredCopyAssignment = true; 187 188 // C++ [class]p4: 189 // A POD-struct is an aggregate class that [...] has no user-defined copy 190 // assignment operator [...]. 191 PlainOldData = false; 192} 193 194void CXXRecordDecl::addConversionFunction(ASTContext &Context, 195 CXXConversionDecl *ConvDecl) { 196 Conversions.addOverload(ConvDecl); 197} 198 199 200CXXConstructorDecl * 201CXXRecordDecl::getDefaultConstructor(ASTContext &Context) { 202 QualType ClassType = Context.getTypeDeclType(this); 203 DeclarationName ConstructorName 204 = Context.DeclarationNames.getCXXConstructorName( 205 Context.getCanonicalType(ClassType.getUnqualifiedType())); 206 207 DeclContext::lookup_const_iterator Con, ConEnd; 208 for (llvm::tie(Con, ConEnd) = lookup(ConstructorName); 209 Con != ConEnd; ++Con) { 210 CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); 211 if (Constructor->isDefaultConstructor()) 212 return Constructor; 213 } 214 return 0; 215} 216 217const CXXDestructorDecl * 218CXXRecordDecl::getDestructor(ASTContext &Context) { 219 QualType ClassType = Context.getTypeDeclType(this); 220 221 DeclarationName Name 222 = Context.DeclarationNames.getCXXDestructorName(ClassType); 223 224 DeclContext::lookup_iterator I, E; 225 llvm::tie(I, E) = lookup(Name); 226 assert(I != E && "Did not find a destructor!"); 227 228 const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I); 229 assert(++I == E && "Found more than one destructor!"); 230 231 return Dtor; 232} 233 234CXXMethodDecl * 235CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, 236 SourceLocation L, DeclarationName N, 237 QualType T, bool isStatic, bool isInline) { 238 return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline); 239} 240 241 242typedef llvm::DenseMap<const CXXMethodDecl*, 243 std::vector<const CXXMethodDecl *> *> 244 OverriddenMethodsMapTy; 245 246static OverriddenMethodsMapTy *OverriddenMethods = 0; 247 248void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) { 249 // FIXME: The CXXMethodDecl dtor needs to remove and free the entry. 250 251 if (!OverriddenMethods) 252 OverriddenMethods = new OverriddenMethodsMapTy(); 253 254 std::vector<const CXXMethodDecl *> *&Methods = (*OverriddenMethods)[this]; 255 if (!Methods) 256 Methods = new std::vector<const CXXMethodDecl *>; 257 258 Methods->push_back(MD); 259} 260 261CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const { 262 if (!OverriddenMethods) 263 return 0; 264 265 OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this); 266 if (it == OverriddenMethods->end()) 267 return 0; 268 return &(*it->second)[0]; 269} 270 271CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const { 272 if (!OverriddenMethods) 273 return 0; 274 275 OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this); 276 if (it == OverriddenMethods->end()) 277 return 0; 278 279 return &(*it->second)[it->second->size()]; 280} 281 282QualType CXXMethodDecl::getThisType(ASTContext &C) const { 283 // C++ 9.3.2p1: The type of this in a member function of a class X is X*. 284 // If the member function is declared const, the type of this is const X*, 285 // if the member function is declared volatile, the type of this is 286 // volatile X*, and if the member function is declared const volatile, 287 // the type of this is const volatile X*. 288 289 assert(isInstance() && "No 'this' for static methods!"); 290 291 QualType ClassTy; 292 if (ClassTemplateDecl *TD = getParent()->getDescribedClassTemplate()) 293 ClassTy = TD->getInjectedClassNameType(C); 294 else 295 ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(getParent())); 296 ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers()); 297 return C.getPointerType(ClassTy).withConst(); 298} 299 300CXXBaseOrMemberInitializer:: 301CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs, 302 SourceLocation L) 303 : Args(0), NumArgs(0), IdLoc(L) { 304 BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr()); 305 assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer"); 306 BaseOrMember |= 0x01; 307 308 if (NumArgs > 0) { 309 this->NumArgs = NumArgs; 310 this->Args = new Expr*[NumArgs]; 311 for (unsigned Idx = 0; Idx < NumArgs; ++Idx) 312 this->Args[Idx] = Args[Idx]; 313 } 314} 315 316CXXBaseOrMemberInitializer:: 317CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs, 318 SourceLocation L) 319 : Args(0), NumArgs(0), IdLoc(L) { 320 BaseOrMember = reinterpret_cast<uintptr_t>(Member); 321 assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer"); 322 323 if (NumArgs > 0) { 324 this->NumArgs = NumArgs; 325 this->Args = new Expr*[NumArgs]; 326 for (unsigned Idx = 0; Idx < NumArgs; ++Idx) 327 this->Args[Idx] = Args[Idx]; 328 } 329} 330 331CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() { 332 delete [] Args; 333} 334 335CXXConstructorDecl * 336CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 337 SourceLocation L, DeclarationName N, 338 QualType T, bool isExplicit, 339 bool isInline, bool isImplicitlyDeclared) { 340 assert(N.getNameKind() == DeclarationName::CXXConstructorName && 341 "Name must refer to a constructor"); 342 return new (C) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline, 343 isImplicitlyDeclared); 344} 345 346bool CXXConstructorDecl::isDefaultConstructor() const { 347 // C++ [class.ctor]p5: 348 // A default constructor for a class X is a constructor of class 349 // X that can be called without an argument. 350 return (getNumParams() == 0) || 351 (getNumParams() > 0 && getParamDecl(0)->getDefaultArg() != 0); 352} 353 354bool 355CXXConstructorDecl::isCopyConstructor(ASTContext &Context, 356 unsigned &TypeQuals) const { 357 // C++ [class.copy]p2: 358 // A non-template constructor for class X is a copy constructor 359 // if its first parameter is of type X&, const X&, volatile X& or 360 // const volatile X&, and either there are no other parameters 361 // or else all other parameters have default arguments (8.3.6). 362 if ((getNumParams() < 1) || 363 (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg())) 364 return false; 365 366 const ParmVarDecl *Param = getParamDecl(0); 367 368 // Do we have a reference type? Rvalue references don't count. 369 const LValueReferenceType *ParamRefType = 370 Param->getType()->getAsLValueReferenceType(); 371 if (!ParamRefType) 372 return false; 373 374 // Is it a reference to our class type? 375 QualType PointeeType 376 = Context.getCanonicalType(ParamRefType->getPointeeType()); 377 QualType ClassTy 378 = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent())); 379 if (PointeeType.getUnqualifiedType() != ClassTy) 380 return false; 381 382 // We have a copy constructor. 383 TypeQuals = PointeeType.getCVRQualifiers(); 384 return true; 385} 386 387bool CXXConstructorDecl::isConvertingConstructor() const { 388 // C++ [class.conv.ctor]p1: 389 // A constructor declared without the function-specifier explicit 390 // that can be called with a single parameter specifies a 391 // conversion from the type of its first parameter to the type of 392 // its class. Such a constructor is called a converting 393 // constructor. 394 if (isExplicit()) 395 return false; 396 397 return (getNumParams() == 0 && 398 getType()->getAsFunctionProtoType()->isVariadic()) || 399 (getNumParams() == 1) || 400 (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg()); 401} 402 403CXXDestructorDecl * 404CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 405 SourceLocation L, DeclarationName N, 406 QualType T, bool isInline, 407 bool isImplicitlyDeclared) { 408 assert(N.getNameKind() == DeclarationName::CXXDestructorName && 409 "Name must refer to a destructor"); 410 return new (C) CXXDestructorDecl(RD, L, N, T, isInline, 411 isImplicitlyDeclared); 412} 413 414void 415CXXConstructorDecl::setBaseOrMemberInitializers( 416 ASTContext &C, 417 CXXBaseOrMemberInitializer **Initializers, 418 unsigned NumInitializers) { 419 if (NumInitializers > 0) { 420 NumBaseOrMemberInitializers = NumInitializers; 421 BaseOrMemberInitializers = 422 new (C, 8) CXXBaseOrMemberInitializer*[NumInitializers]; 423 for (unsigned Idx = 0; Idx < NumInitializers; ++Idx) 424 BaseOrMemberInitializers[Idx] = Initializers[Idx]; 425 } 426} 427 428void 429CXXConstructorDecl::Destroy(ASTContext& C) { 430 C.Deallocate(BaseOrMemberInitializers); 431 this->~CXXMethodDecl(); 432 C.Deallocate((void *)this); 433} 434 435CXXConversionDecl * 436CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, 437 SourceLocation L, DeclarationName N, 438 QualType T, bool isInline, bool isExplicit) { 439 assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName && 440 "Name must refer to a conversion function"); 441 return new (C) CXXConversionDecl(RD, L, N, T, isInline, isExplicit); 442} 443 444OverloadedFunctionDecl * 445OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC, 446 DeclarationName N) { 447 return new (C) OverloadedFunctionDecl(DC, N); 448} 449 450void OverloadedFunctionDecl::addOverload(AnyFunctionDecl F) { 451 Functions.push_back(F); 452 this->setLocation(F.get()->getLocation()); 453} 454 455LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, 456 DeclContext *DC, 457 SourceLocation L, 458 LanguageIDs Lang, bool Braces) { 459 return new (C) LinkageSpecDecl(DC, L, Lang, Braces); 460} 461 462UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, 463 SourceLocation L, 464 SourceLocation NamespaceLoc, 465 SourceRange QualifierRange, 466 NestedNameSpecifier *Qualifier, 467 SourceLocation IdentLoc, 468 NamespaceDecl *Used, 469 DeclContext *CommonAncestor) { 470 return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange, 471 Qualifier, IdentLoc, Used, CommonAncestor); 472} 473 474NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, 475 SourceLocation L, 476 SourceLocation AliasLoc, 477 IdentifierInfo *Alias, 478 SourceRange QualifierRange, 479 NestedNameSpecifier *Qualifier, 480 SourceLocation IdentLoc, 481 NamedDecl *Namespace) { 482 return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange, 483 Qualifier, IdentLoc, Namespace); 484} 485 486UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, 487 SourceLocation L, SourceRange NNR, SourceLocation TargetNL, 488 SourceLocation UL, NamedDecl* Target, 489 NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) { 490 return new (C) UsingDecl(DC, L, NNR, TargetNL, UL, Target, 491 TargetNNS, IsTypeNameArg); 492} 493 494StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, 495 SourceLocation L, Expr *AssertExpr, 496 StringLiteral *Message) { 497 return new (C) StaticAssertDecl(DC, L, AssertExpr, Message); 498} 499 500void StaticAssertDecl::Destroy(ASTContext& C) { 501 AssertExpr->Destroy(C); 502 Message->Destroy(C); 503 this->~StaticAssertDecl(); 504 C.Deallocate((void *)this); 505} 506 507StaticAssertDecl::~StaticAssertDecl() { 508} 509 510static const char *getAccessName(AccessSpecifier AS) { 511 switch (AS) { 512 default: 513 case AS_none: 514 assert("Invalid access specifier!"); 515 return 0; 516 case AS_public: 517 return "public"; 518 case AS_private: 519 return "private"; 520 case AS_protected: 521 return "protected"; 522 } 523} 524 525const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 526 AccessSpecifier AS) { 527 return DB << getAccessName(AS); 528} 529 530 531