DeclCXX.cpp revision 194711
1193323Sed//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements the C++ related Decl classes. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "clang/AST/DeclCXX.h" 15193323Sed#include "clang/AST/DeclTemplate.h" 16193323Sed#include "clang/AST/ASTContext.h" 17193323Sed#include "clang/AST/Expr.h" 18193323Sed#include "clang/Basic/IdentifierTable.h" 19193323Sed#include "llvm/ADT/STLExtras.h" 20193323Sedusing namespace clang; 21193323Sed 22193323Sed//===----------------------------------------------------------------------===// 23198090Srdivacky// Decl Allocation/Deallocation Method Implementations 24202375Srdivacky//===----------------------------------------------------------------------===// 25193323Sed 26193323SedCXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, 27193323Sed SourceLocation L, IdentifierInfo *Id) 28193323Sed : RecordDecl(K, TK, DC, L, Id), 29193323Sed UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false), 30198090Srdivacky UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false), 31198090Srdivacky Aggregate(true), PlainOldData(true), Polymorphic(false), Abstract(false), 32198090Srdivacky HasTrivialConstructor(true), HasTrivialDestructor(true), 33198090Srdivacky Bases(0), NumBases(0), Conversions(DC, DeclarationName()), 34198090Srdivacky TemplateOrInstantiation() { } 35198090Srdivacky 36198090SrdivackyCXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, 37198090Srdivacky SourceLocation L, IdentifierInfo *Id, 38198090Srdivacky CXXRecordDecl* PrevDecl, 39198090Srdivacky bool DelayTypeCreation) { 40193323Sed CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id); 41193323Sed if (!DelayTypeCreation) 42193323Sed C.getTypeDeclType(R, PrevDecl); 43193323Sed return R; 44193323Sed} 45193323Sed 46193323SedCXXRecordDecl::~CXXRecordDecl() { 47193323Sed delete [] Bases; 48198090Srdivacky} 49198090Srdivacky 50198090Srdivackyvoid 51198090SrdivackyCXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, 52198090Srdivacky unsigned NumBases) { 53198090Srdivacky // C++ [dcl.init.aggr]p1: 54198090Srdivacky // An aggregate is an array or a class (clause 9) with [...] 55198090Srdivacky // no base classes [...]. 56198090Srdivacky Aggregate = false; 57198090Srdivacky 58198090Srdivacky if (this->Bases) 59198090Srdivacky delete [] this->Bases; 60201360Srdivacky 61198090Srdivacky // FIXME: allocate using the ASTContext 62198090Srdivacky this->Bases = new CXXBaseSpecifier[NumBases]; 63198090Srdivacky this->NumBases = NumBases; 64198090Srdivacky for (unsigned i = 0; i < NumBases; ++i) 65198090Srdivacky this->Bases[i] = *Bases[i]; 66198090Srdivacky} 67198090Srdivacky 68198090Srdivackybool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const { 69198090Srdivacky return getCopyConstructor(Context, QualType::Const) != 0; 70198090Srdivacky} 71198090Srdivacky 72198090SrdivackyCXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context, 73198090Srdivacky unsigned TypeQuals) const{ 74198090Srdivacky QualType ClassType 75198090Srdivacky = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this)); 76198090Srdivacky DeclarationName ConstructorName 77198090Srdivacky = Context.DeclarationNames.getCXXConstructorName( 78198090Srdivacky Context.getCanonicalType(ClassType)); 79198090Srdivacky unsigned FoundTQs; 80198090Srdivacky DeclContext::lookup_const_iterator Con, ConEnd; 81198090Srdivacky for (llvm::tie(Con, ConEnd) = this->lookup(Context, ConstructorName); 82198090Srdivacky Con != ConEnd; ++Con) { 83198090Srdivacky if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, 84198090Srdivacky FoundTQs)) { 85198090Srdivacky if (((TypeQuals & QualType::Const) == (FoundTQs & QualType::Const)) || 86198090Srdivacky (!(TypeQuals & QualType::Const) && (FoundTQs & QualType::Const))) 87198090Srdivacky return cast<CXXConstructorDecl>(*Con); 88198090Srdivacky 89198090Srdivacky } 90198090Srdivacky } 91198090Srdivacky return 0; 92198090Srdivacky} 93198090Srdivacky 94198090Srdivackybool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const { 95198090Srdivacky QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType( 96198090Srdivacky const_cast<CXXRecordDecl*>(this))); 97198090Srdivacky DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal); 98198090Srdivacky 99198090Srdivacky DeclContext::lookup_const_iterator Op, OpEnd; 100198090Srdivacky for (llvm::tie(Op, OpEnd) = this->lookup(Context, OpName); 101198090Srdivacky Op != OpEnd; ++Op) { 102198090Srdivacky // C++ [class.copy]p9: 103198090Srdivacky // A user-declared copy assignment operator is a non-static non-template 104198090Srdivacky // member function of class X with exactly one parameter of type X, X&, 105198090Srdivacky // const X&, volatile X& or const volatile X&. 106198090Srdivacky const CXXMethodDecl* Method = cast<CXXMethodDecl>(*Op); 107198090Srdivacky if (Method->isStatic()) 108198090Srdivacky continue; 109198090Srdivacky // TODO: Skip templates? Or is this implicitly done due to parameter types? 110198090Srdivacky const FunctionProtoType *FnType = 111198090Srdivacky Method->getType()->getAsFunctionProtoType(); 112198090Srdivacky assert(FnType && "Overloaded operator has no prototype."); 113198090Srdivacky // Don't assert on this; an invalid decl might have been left in the AST. 114198090Srdivacky if (FnType->getNumArgs() != 1 || FnType->isVariadic()) 115198090Srdivacky continue; 116198090Srdivacky bool AcceptsConst = true; 117198090Srdivacky QualType ArgType = FnType->getArgType(0); 118198090Srdivacky if (const LValueReferenceType *Ref = ArgType->getAsLValueReferenceType()) { 119198090Srdivacky ArgType = Ref->getPointeeType(); 120198090Srdivacky // Is it a non-const lvalue reference? 121198090Srdivacky if (!ArgType.isConstQualified()) 122198090Srdivacky AcceptsConst = false; 123198090Srdivacky } 124198090Srdivacky if (Context.getCanonicalType(ArgType).getUnqualifiedType() != ClassType) 125198090Srdivacky continue; 126198090Srdivacky 127198090Srdivacky // We have a single argument of type cv X or cv X&, i.e. we've found the 128198090Srdivacky // copy assignment operator. Return whether it accepts const arguments. 129198090Srdivacky return AcceptsConst; 130198090Srdivacky } 131198090Srdivacky assert(isInvalidDecl() && 132198090Srdivacky "No copy assignment operator declared in valid code."); 133198090Srdivacky return false; 134198090Srdivacky} 135198090Srdivacky 136198090Srdivackyvoid 137198090SrdivackyCXXRecordDecl::addedConstructor(ASTContext &Context, 138198090Srdivacky CXXConstructorDecl *ConDecl) { 139198090Srdivacky assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl"); 140198090Srdivacky // Note that we have a user-declared constructor. 141198090Srdivacky UserDeclaredConstructor = true; 142198090Srdivacky 143198090Srdivacky // C++ [dcl.init.aggr]p1: 144198090Srdivacky // An aggregate is an array or a class (clause 9) with no 145198090Srdivacky // user-declared constructors (12.1) [...]. 146198090Srdivacky Aggregate = false; 147198090Srdivacky 148198090Srdivacky // C++ [class]p4: 149198090Srdivacky // A POD-struct is an aggregate class [...] 150198090Srdivacky PlainOldData = false; 151198090Srdivacky 152198090Srdivacky // C++ [class.ctor]p5: 153198090Srdivacky // A constructor is trivial if it is an implicitly-declared default 154198090Srdivacky // constructor. 155198090Srdivacky HasTrivialConstructor = false; 156198090Srdivacky 157198090Srdivacky // Note when we have a user-declared copy constructor, which will 158198090Srdivacky // suppress the implicit declaration of a copy constructor. 159198090Srdivacky if (ConDecl->isCopyConstructor(Context)) 160198090Srdivacky UserDeclaredCopyConstructor = true; 161198090Srdivacky} 162198090Srdivacky 163198090Srdivackyvoid CXXRecordDecl::addedAssignmentOperator(ASTContext &Context, 164198090Srdivacky CXXMethodDecl *OpDecl) { 165198090Srdivacky // We're interested specifically in copy assignment operators. 166198090Srdivacky const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType(); 167198090Srdivacky assert(FnType && "Overloaded operator has no proto function type."); 168198090Srdivacky assert(FnType->getNumArgs() == 1 && !FnType->isVariadic()); 169198090Srdivacky QualType ArgType = FnType->getArgType(0); 170198090Srdivacky if (const LValueReferenceType *Ref = ArgType->getAsLValueReferenceType()) 171198090Srdivacky ArgType = Ref->getPointeeType(); 172198090Srdivacky 173198090Srdivacky ArgType = ArgType.getUnqualifiedType(); 174198090Srdivacky QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType( 175198090Srdivacky const_cast<CXXRecordDecl*>(this))); 176198090Srdivacky 177198090Srdivacky if (ClassType != Context.getCanonicalType(ArgType)) 178198090Srdivacky return; 179198090Srdivacky 180198090Srdivacky // This is a copy assignment operator. 181198090Srdivacky // Suppress the implicit declaration of a copy constructor. 182198090Srdivacky UserDeclaredCopyAssignment = true; 183198090Srdivacky 184198090Srdivacky // C++ [class]p4: 185198090Srdivacky // A POD-struct is an aggregate class that [...] has no user-defined copy 186198090Srdivacky // assignment operator [...]. 187198090Srdivacky PlainOldData = false; 188198090Srdivacky} 189198090Srdivacky 190198090Srdivackyvoid CXXRecordDecl::addConversionFunction(ASTContext &Context, 191198090Srdivacky CXXConversionDecl *ConvDecl) { 192198090Srdivacky Conversions.addOverload(ConvDecl); 193198090Srdivacky} 194198090Srdivacky 195198090Srdivacky 196198090SrdivackyCXXConstructorDecl * 197198090SrdivackyCXXRecordDecl::getDefaultConstructor(ASTContext &Context) { 198198090Srdivacky QualType ClassType = Context.getTypeDeclType(this); 199198090Srdivacky DeclarationName ConstructorName 200198090Srdivacky = Context.DeclarationNames.getCXXConstructorName( 201198090Srdivacky Context.getCanonicalType(ClassType.getUnqualifiedType())); 202198090Srdivacky 203198090Srdivacky DeclContext::lookup_const_iterator Con, ConEnd; 204198090Srdivacky for (llvm::tie(Con, ConEnd) = lookup(Context, ConstructorName); 205198090Srdivacky Con != ConEnd; ++Con) { 206198090Srdivacky CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); 207198090Srdivacky if (Constructor->isDefaultConstructor()) 208198090Srdivacky return Constructor; 209198090Srdivacky } 210198090Srdivacky return 0; 211198090Srdivacky} 212198090Srdivacky 213198090Srdivackyconst CXXDestructorDecl * 214198090SrdivackyCXXRecordDecl::getDestructor(ASTContext &Context) { 215198090Srdivacky QualType ClassType = Context.getTypeDeclType(this); 216198090Srdivacky 217198090Srdivacky DeclarationName Name 218198090Srdivacky = Context.DeclarationNames.getCXXDestructorName(ClassType); 219198090Srdivacky 220198090Srdivacky DeclContext::lookup_iterator I, E; 221198090Srdivacky llvm::tie(I, E) = lookup(Context, Name); 222198090Srdivacky assert(I != E && "Did not find a destructor!"); 223198090Srdivacky 224198090Srdivacky const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I); 225198090Srdivacky assert(++I == E && "Found more than one destructor!"); 226198090Srdivacky 227198090Srdivacky return Dtor; 228198090Srdivacky} 229198090Srdivacky 230198090SrdivackyCXXMethodDecl * 231198090SrdivackyCXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, 232198090Srdivacky SourceLocation L, DeclarationName N, 233198090Srdivacky QualType T, bool isStatic, bool isInline) { 234198090Srdivacky return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline); 235198090Srdivacky} 236198090Srdivacky 237198090Srdivacky 238198090Srdivackytypedef llvm::DenseMap<const CXXMethodDecl*, 239198090Srdivacky std::vector<const CXXMethodDecl *> *> 240198090Srdivacky OverriddenMethodsMapTy; 241198090Srdivacky 242198090Srdivackystatic OverriddenMethodsMapTy *OverriddenMethods = 0; 243198090Srdivacky 244198090Srdivackyvoid CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) { 245198090Srdivacky // FIXME: The CXXMethodDecl dtor needs to remove and free the entry. 246198090Srdivacky 247199989Srdivacky if (!OverriddenMethods) 248199989Srdivacky OverriddenMethods = new OverriddenMethodsMapTy(); 249199989Srdivacky 250199989Srdivacky std::vector<const CXXMethodDecl *> *&Methods = (*OverriddenMethods)[this]; 251199989Srdivacky if (!Methods) 252198090Srdivacky Methods = new std::vector<const CXXMethodDecl *>; 253198090Srdivacky 254198090Srdivacky Methods->push_back(MD); 255198090Srdivacky} 256198090Srdivacky 257198090SrdivackyCXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const { 258198090Srdivacky if (!OverriddenMethods) 259198090Srdivacky return 0; 260198090Srdivacky 261198090Srdivacky OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this); 262198090Srdivacky if (it == OverriddenMethods->end()) 263198090Srdivacky return 0; 264198090Srdivacky return &(*it->second)[0]; 265198090Srdivacky} 266205218Srdivacky 267198090SrdivackyCXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const { 268198090Srdivacky if (!OverriddenMethods) 269198090Srdivacky return 0; 270198090Srdivacky 271198090Srdivacky OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this); 272199481Srdivacky if (it == OverriddenMethods->end()) 273199481Srdivacky return 0; 274198090Srdivacky 275198090Srdivacky return &(*it->second)[it->second->size()]; 276198090Srdivacky} 277199481Srdivacky 278198090SrdivackyQualType CXXMethodDecl::getThisType(ASTContext &C) const { 279198090Srdivacky // C++ 9.3.2p1: The type of this in a member function of a class X is X*. 280204961Srdivacky // If the member function is declared const, the type of this is const X*, 281204961Srdivacky // if the member function is declared volatile, the type of this is 282204961Srdivacky // volatile X*, and if the member function is declared const volatile, 283204961Srdivacky // the type of this is const volatile X*. 284204961Srdivacky 285204961Srdivacky assert(isInstance() && "No 'this' for static methods!"); 286205218Srdivacky 287198090Srdivacky QualType ClassTy; 288198090Srdivacky if (ClassTemplateDecl *TD = getParent()->getDescribedClassTemplate()) 289198090Srdivacky ClassTy = TD->getInjectedClassNameType(C); 290198090Srdivacky else 291198090Srdivacky ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(getParent())); 292198090Srdivacky ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers()); 293198090Srdivacky return C.getPointerType(ClassTy).withConst(); 294198090Srdivacky} 295198090Srdivacky 296198090SrdivackyCXXBaseOrMemberInitializer:: 297198090SrdivackyCXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs) 298199481Srdivacky : Args(0), NumArgs(0) { 299199481Srdivacky BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr()); 300199481Srdivacky assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer"); 301199481Srdivacky BaseOrMember |= 0x01; 302199481Srdivacky 303199481Srdivacky if (NumArgs > 0) { 304199481Srdivacky this->NumArgs = NumArgs; 305199481Srdivacky this->Args = new Expr*[NumArgs]; 306198396Srdivacky for (unsigned Idx = 0; Idx < NumArgs; ++Idx) 307198396Srdivacky this->Args[Idx] = Args[Idx]; 308198396Srdivacky } 309198090Srdivacky} 310198090Srdivacky 311198090SrdivackyCXXBaseOrMemberInitializer:: 312198090SrdivackyCXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs) 313198090Srdivacky : Args(0), NumArgs(0) { 314198090Srdivacky BaseOrMember = reinterpret_cast<uintptr_t>(Member); 315198090Srdivacky assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer"); 316198396Srdivacky 317198090Srdivacky if (NumArgs > 0) { 318198090Srdivacky this->NumArgs = NumArgs; 319198090Srdivacky this->Args = new Expr*[NumArgs]; 320198090Srdivacky for (unsigned Idx = 0; Idx < NumArgs; ++Idx) 321198090Srdivacky this->Args[Idx] = Args[Idx]; 322198090Srdivacky } 323198090Srdivacky} 324200581Srdivacky 325198090SrdivackyCXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() { 326198090Srdivacky delete [] Args; 327198090Srdivacky} 328200581Srdivacky 329200581SrdivackyCXXConstructorDecl * 330198090SrdivackyCXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 331198090Srdivacky SourceLocation L, DeclarationName N, 332198090Srdivacky QualType T, bool isExplicit, 333198090Srdivacky bool isInline, bool isImplicitlyDeclared) { 334198090Srdivacky assert(N.getNameKind() == DeclarationName::CXXConstructorName && 335198090Srdivacky "Name must refer to a constructor"); 336198090Srdivacky return new (C) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline, 337198090Srdivacky isImplicitlyDeclared); 338198090Srdivacky} 339198090Srdivacky 340198090Srdivackybool CXXConstructorDecl::isDefaultConstructor() const { 341198090Srdivacky // C++ [class.ctor]p5: 342198090Srdivacky // A default constructor for a class X is a constructor of class 343198090Srdivacky // X that can be called without an argument. 344198090Srdivacky return (getNumParams() == 0) || 345198090Srdivacky (getNumParams() > 0 && getParamDecl(0)->getDefaultArg() != 0); 346198090Srdivacky} 347198090Srdivacky 348198090Srdivackybool 349198090SrdivackyCXXConstructorDecl::isCopyConstructor(ASTContext &Context, 350198090Srdivacky unsigned &TypeQuals) const { 351198090Srdivacky // C++ [class.copy]p2: 352198090Srdivacky // A non-template constructor for class X is a copy constructor 353198090Srdivacky // if its first parameter is of type X&, const X&, volatile X& or 354198090Srdivacky // const volatile X&, and either there are no other parameters 355198090Srdivacky // or else all other parameters have default arguments (8.3.6). 356198090Srdivacky if ((getNumParams() < 1) || 357198090Srdivacky (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg())) 358198090Srdivacky return false; 359198090Srdivacky 360198090Srdivacky const ParmVarDecl *Param = getParamDecl(0); 361198090Srdivacky 362198090Srdivacky // Do we have a reference type? Rvalue references don't count. 363198090Srdivacky const LValueReferenceType *ParamRefType = 364198090Srdivacky Param->getType()->getAsLValueReferenceType(); 365198090Srdivacky if (!ParamRefType) 366198090Srdivacky return false; 367198090Srdivacky 368198090Srdivacky // Is it a reference to our class type? 369198090Srdivacky QualType PointeeType 370198090Srdivacky = Context.getCanonicalType(ParamRefType->getPointeeType()); 371198090Srdivacky QualType ClassTy 372198090Srdivacky = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent())); 373198090Srdivacky if (PointeeType.getUnqualifiedType() != ClassTy) 374198090Srdivacky return false; 375198090Srdivacky 376198090Srdivacky // We have a copy constructor. 377198090Srdivacky TypeQuals = PointeeType.getCVRQualifiers(); 378198090Srdivacky return true; 379198090Srdivacky} 380198090Srdivacky 381198090Srdivackybool CXXConstructorDecl::isConvertingConstructor() const { 382198090Srdivacky // C++ [class.conv.ctor]p1: 383198090Srdivacky // A constructor declared without the function-specifier explicit 384198090Srdivacky // that can be called with a single parameter specifies a 385198090Srdivacky // conversion from the type of its first parameter to the type of 386198090Srdivacky // its class. Such a constructor is called a converting 387198090Srdivacky // constructor. 388198090Srdivacky if (isExplicit()) 389198090Srdivacky return false; 390198090Srdivacky 391198090Srdivacky return (getNumParams() == 0 && 392198090Srdivacky getType()->getAsFunctionProtoType()->isVariadic()) || 393202375Srdivacky (getNumParams() == 1) || 394202375Srdivacky (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg()); 395202375Srdivacky} 396202375Srdivacky 397193323SedCXXDestructorDecl * 398193323SedCXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 399193323Sed SourceLocation L, DeclarationName N, 400193323Sed QualType T, bool isInline, 401193323Sed bool isImplicitlyDeclared) { 402195340Sed assert(N.getNameKind() == DeclarationName::CXXDestructorName && 403193323Sed "Name must refer to a destructor"); 404193323Sed return new (C) CXXDestructorDecl(RD, L, N, T, isInline, 405193323Sed isImplicitlyDeclared); 406198090Srdivacky} 407198090Srdivacky 408198090SrdivackyCXXConversionDecl * 409198090SrdivackyCXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, 410198090Srdivacky SourceLocation L, DeclarationName N, 411198090Srdivacky QualType T, bool isInline, bool isExplicit) { 412198090Srdivacky assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName && 413198090Srdivacky "Name must refer to a conversion function"); 414198090Srdivacky return new (C) CXXConversionDecl(RD, L, N, T, isInline, isExplicit); 415198090Srdivacky} 416198090Srdivacky 417198090SrdivackyOverloadedFunctionDecl * 418198090SrdivackyOverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC, 419198090Srdivacky DeclarationName N) { 420198090Srdivacky return new (C) OverloadedFunctionDecl(DC, N); 421198090Srdivacky} 422198090Srdivacky 423193323SedLinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, 424193323Sed DeclContext *DC, 425193323Sed SourceLocation L, 426193323Sed LanguageIDs Lang, bool Braces) { 427198090Srdivacky return new (C) LinkageSpecDecl(DC, L, Lang, Braces); 428198090Srdivacky} 429198090Srdivacky 430198090SrdivackyUsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, 431198090Srdivacky 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