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