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