diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
commit | 9092c3e0fa01f3139b016d05d267a89e3b07747a (patch) | |
tree | 137ebebcae16fb0ce7ab4af456992bbd8d22fced /lib/AST/DeclBase.cpp | |
parent | 4981926bf654fe5a2c3893f24ca44106b217e71e (diff) | |
download | FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.zip FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.tar.gz |
Update clang to r84119.
Diffstat (limited to 'lib/AST/DeclBase.cpp')
-rw-r--r-- | lib/AST/DeclBase.cpp | 164 |
1 files changed, 108 insertions, 56 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 96ba19b..224bf87 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -62,12 +62,12 @@ bool Decl::CollectingStats(bool Enable) { void Decl::PrintStats() { fprintf(stderr, "*** Decl Stats:\n"); - + int totalDecls = 0; #define DECL(Derived, Base) totalDecls += n##Derived##s; #include "clang/AST/DeclNodes.def" fprintf(stderr, " %d decls total.\n", totalDecls); - + int totalBytes = 0; #define DECL(Derived, Base) \ if (n##Derived##s > 0) { \ @@ -77,7 +77,7 @@ void Decl::PrintStats() { (int)(n##Derived##s * sizeof(Derived##Decl))); \ } #include "clang/AST/DeclNodes.def" - + fprintf(stderr, "Total bytes = %d\n", totalBytes); } @@ -92,26 +92,26 @@ void Decl::addDeclKind(Kind k) { bool Decl::isTemplateParameterPack() const { if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this)) return TTP->isParameterPack(); - + return false; } bool Decl::isFunctionOrFunctionTemplate() const { if (const UsingDecl *UD = dyn_cast<UsingDecl>(this)) return UD->getTargetDecl()->isFunctionOrFunctionTemplate(); - + return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this); } //===----------------------------------------------------------------------===// // PrettyStackTraceDecl Implementation //===----------------------------------------------------------------------===// - + void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const { SourceLocation TheLoc = Loc; if (TheLoc.isInvalid() && TheDecl) TheLoc = TheDecl->getLocation(); - + if (TheLoc.isValid()) { TheLoc.print(OS, SM); OS << ": "; @@ -123,7 +123,7 @@ void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const { OS << " '" << DN->getQualifiedNameAsString() << '\''; OS << '\n'; } - + //===----------------------------------------------------------------------===// // Decl Implementation //===----------------------------------------------------------------------===// @@ -132,14 +132,14 @@ void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const { Decl::~Decl() { if (isOutOfSemaDC()) delete getMultipleDC(); - + assert(!HasAttrs && "attributes should have been freed by Destroy"); } void Decl::setDeclContext(DeclContext *DC) { if (isOutOfSemaDC()) delete getMultipleDC(); - + DeclCtx = DC; } @@ -157,28 +157,39 @@ void Decl::setLexicalDeclContext(DeclContext *DC) { } } +bool Decl::isInAnonymousNamespace() const { + const DeclContext *DC = getDeclContext(); + do { + if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC)) + if (ND->isAnonymousNamespace()) + return true; + } while ((DC = DC->getParent())); + + return false; +} + TranslationUnitDecl *Decl::getTranslationUnitDecl() { if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this)) return TUD; DeclContext *DC = getDeclContext(); assert(DC && "This decl is not contained in a translation unit!"); - + while (!DC->isTranslationUnit()) { DC = DC->getParent(); assert(DC && "This decl is not contained in a translation unit!"); } - + return cast<TranslationUnitDecl>(DC); } ASTContext &Decl::getASTContext() const { - return getTranslationUnitDecl()->getASTContext(); + return getTranslationUnitDecl()->getASTContext(); } unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { switch (DeclKind) { - default: + default: if (DeclKind >= FunctionFirst && DeclKind <= FunctionLast) return IDNS_Ordinary; assert(0 && "Unknown decl kind!"); @@ -191,6 +202,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case OriginalParmVar: case NonTypeTemplateParm: case Using: + case UnresolvedUsing: case ObjCMethod: case ObjCContainer: case ObjCCategory: @@ -198,10 +210,10 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCProperty: case ObjCCompatibleAlias: return IDNS_Ordinary; - + case ObjCProtocol: return IDNS_ObjCProtocol; - + case ObjCImplementation: return IDNS_ObjCImplementation; @@ -212,13 +224,13 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCAtDefsField: case ObjCIvar: return IDNS_Member; - + case Record: case CXXRecord: case Enum: case TemplateTypeParm: return IDNS_Tag; - + case Namespace: case Template: case FunctionTemplate: @@ -226,8 +238,10 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case TemplateTemplateParm: case NamespaceAlias: return IDNS_Tag | IDNS_Ordinary; - + // Never have names. + case Friend: + case FriendTemplate: case LinkageSpec: case FileScopeAsm: case StaticAssert: @@ -250,41 +264,41 @@ void Decl::addAttr(Attr *NewAttr) { NewAttr->setNext(ExistingAttr); ExistingAttr = NewAttr; - + HasAttrs = true; } void Decl::invalidateAttrs() { if (!HasAttrs) return; - + HasAttrs = false; getASTContext().eraseDeclAttrs(this); } const Attr *Decl::getAttrsImpl() const { - assert(HasAttrs && "getAttrs() should verify this!"); + assert(HasAttrs && "getAttrs() should verify this!"); return getASTContext().getDeclAttrs(this); } void Decl::swapAttrs(Decl *RHS) { bool HasLHSAttr = this->HasAttrs; bool HasRHSAttr = RHS->HasAttrs; - + // Usually, neither decl has attrs, nothing to do. if (!HasLHSAttr && !HasRHSAttr) return; - + // If 'this' has no attrs, swap the other way. if (!HasLHSAttr) return RHS->swapAttrs(this); - + ASTContext &Context = getASTContext(); - + // Handle the case when both decls have attrs. if (HasRHSAttr) { std::swap(Context.getDeclAttrs(this), Context.getDeclAttrs(RHS)); return; } - + // Otherwise, LHS has an attr and RHS doesn't. Context.getDeclAttrs(RHS) = Context.getDeclAttrs(this); Context.eraseDeclAttrs(this); @@ -300,7 +314,7 @@ void Decl::Destroy(ASTContext &C) { invalidateAttrs(); HasAttrs = false; } - + #if 0 // FIXME: Once ownership is fully understood, we can enable this code if (DeclContext *DC = dyn_cast<DeclContext>(this)) @@ -309,15 +323,15 @@ void Decl::Destroy(ASTContext &C) { // Observe the unrolled recursion. By setting N->NextDeclInContext = 0x0 // within the loop, only the Destroy method for the first Decl // will deallocate all of the Decls in a chain. - + Decl* N = getNextDeclInContext(); - + while (N) { Decl* Tmp = N->getNextDeclInContext(); N->NextDeclInContext = 0; N->Destroy(C); N = Tmp; - } + } this->~Decl(); C.Deallocate((void *)this); @@ -377,8 +391,13 @@ SourceLocation Decl::getBodyRBrace() const { #ifndef NDEBUG void Decl::CheckAccessDeclContext() const { - assert((Access != AS_none || isa<TranslationUnitDecl>(this) || - !isa<CXXRecordDecl>(getDeclContext())) && + // If the decl is the toplevel translation unit or if we're not in a + // record decl context, we don't need to check anything. + if (isa<TranslationUnitDecl>(this) || + !isa<CXXRecordDecl>(getDeclContext())) + return; + + assert(Access != AS_none && "Access specifier is AS_none inside a record decl"); } @@ -413,6 +432,22 @@ void DeclContext::DestroyDecls(ASTContext &C) { (*D++)->Destroy(C); } +/// \brief Find the parent context of this context that will be +/// used for unqualified name lookup. +/// +/// Generally, the parent lookup context is the semantic context. However, for +/// a friend function the parent lookup context is the lexical context, which +/// is the class in which the friend is declared. +DeclContext *DeclContext::getLookupParent() { + // FIXME: Find a better way to identify friends + if (isa<FunctionDecl>(this)) + if (getParent()->getLookupContext()->isFileContext() && + getLexicalParent()->getLookupContext()->isRecord()) + return getLexicalParent(); + + return getParent(); +} + bool DeclContext::isDependentContext() const { if (isFileContext()) return false; @@ -427,7 +462,7 @@ bool DeclContext::isDependentContext() const { if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) if (Function->getDescribedFunctionTemplate()) return true; - + return getParent() && getParent()->isDependentContext(); } @@ -444,11 +479,21 @@ bool DeclContext::isTransparentContext() const { return false; } +bool DeclContext::Encloses(DeclContext *DC) { + if (getPrimaryContext() != this) + return getPrimaryContext()->Encloses(DC); + + for (; DC; DC = DC->getParent()) + if (DC->getPrimaryContext() == this) + return true; + return false; +} + DeclContext *DeclContext::getPrimaryContext() { switch (DeclKind) { case Decl::TranslationUnit: case Decl::LinkageSpec: - case Decl::Block: + case Decl::Block: // There is only one DeclContext for these entities. return this; @@ -473,8 +518,8 @@ DeclContext *DeclContext::getPrimaryContext() { if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) { // If this is a tag type that has a definition or is currently // being defined, that definition is our primary context. - if (const TagType *TagT =cast<TagDecl>(this)->TypeForDecl->getAsTagType()) - if (TagT->isBeingDefined() || + if (const TagType *TagT =cast<TagDecl>(this)->TypeForDecl->getAs<TagType>()) + if (TagT->isBeingDefined() || (TagT->getDecl() && TagT->getDecl()->isDefinition())) return TagT->getDecl(); return this; @@ -499,13 +544,13 @@ DeclContext *DeclContext::getNextContext() { /// \brief Load the declarations within this lexical storage from an /// external source. -void +void DeclContext::LoadLexicalDeclsFromExternalStorage() const { ExternalASTSource *Source = getParentASTContext().getExternalSource(); assert(hasExternalLexicalStorage() && Source && "No external storage?"); llvm::SmallVector<uint32_t, 64> Decls; - if (Source->ReadDeclsLexicallyInContext(const_cast<DeclContext *>(this), + if (Source->ReadDeclsLexicallyInContext(const_cast<DeclContext *>(this), Decls)) return; @@ -537,7 +582,7 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const { LastDecl = PrevDecl; } -void +void DeclContext::LoadVisibleDeclsFromExternalStorage() const { DeclContext *This = const_cast<DeclContext *>(this); ExternalASTSource *Source = getParentASTContext().getExternalSource(); @@ -566,14 +611,14 @@ DeclContext::decl_iterator DeclContext::decls_begin() const { // FIXME: Check whether we need to load some declarations from // external storage. - return decl_iterator(FirstDecl); + return decl_iterator(FirstDecl); } DeclContext::decl_iterator DeclContext::decls_end() const { if (hasExternalLexicalStorage()) LoadLexicalDeclsFromExternalStorage(); - return decl_iterator(); + return decl_iterator(); } bool DeclContext::decls_empty() const { @@ -583,10 +628,10 @@ bool DeclContext::decls_empty() const { return !FirstDecl; } -void DeclContext::addDecl(Decl *D) { +void DeclContext::addHiddenDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "Decl inserted into wrong lexical context"); - assert(!D->getNextDeclInContext() && D != LastDecl && + assert(!D->getNextDeclInContext() && D != LastDecl && "Decl already inserted into a DeclContext"); if (FirstDecl) { @@ -595,6 +640,10 @@ void DeclContext::addDecl(Decl *D) { } else { FirstDecl = LastDecl = D; } +} + +void DeclContext::addDecl(Decl *D) { + addHiddenDecl(D); if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) ND->getDeclContext()->makeDeclVisibleInContext(ND); @@ -605,12 +654,15 @@ void DeclContext::addDecl(Decl *D) { /// transparent contexts nested within it). void DeclContext::buildLookup(DeclContext *DCtx) { for (; DCtx; DCtx = DCtx->getNextContext()) { - for (decl_iterator D = DCtx->decls_begin(), - DEnd = DCtx->decls_end(); + for (decl_iterator D = DCtx->decls_begin(), + DEnd = DCtx->decls_end(); D != DEnd; ++D) { - // Insert this declaration into the lookup structure + // Insert this declaration into the lookup structure, but only + // if it's semantically in its decl context. During non-lazy + // lookup building, this is implicitly enforced by addDecl. if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) - makeDeclVisibleInContextImpl(ND); + if (D->getDeclContext() == DCtx) + makeDeclVisibleInContextImpl(ND); // If this declaration is itself a transparent declaration context, // add its members (recursively). @@ -621,7 +673,7 @@ void DeclContext::buildLookup(DeclContext *DCtx) { } } -DeclContext::lookup_result +DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) { DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) @@ -647,7 +699,7 @@ DeclContext::lookup(DeclarationName Name) { return Pos->second.getLookupResult(getParentASTContext()); } -DeclContext::lookup_const_result +DeclContext::lookup_const_result DeclContext::lookup(DeclarationName Name) const { return const_cast<DeclContext*>(this)->lookup(Name); } @@ -668,7 +720,7 @@ DeclContext *DeclContext::getEnclosingNamespaceContext() { return Ctx->getPrimaryContext(); } -void DeclContext::makeDeclVisibleInContext(NamedDecl *D) { +void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) { // FIXME: This feels like a hack. Should DeclarationName support // template-ids, or is there a better way to keep specializations // from being visible? @@ -677,20 +729,20 @@ void DeclContext::makeDeclVisibleInContext(NamedDecl *D) { DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) { - PrimaryContext->makeDeclVisibleInContext(D); + PrimaryContext->makeDeclVisibleInContext(D, Recoverable); return; } // If we already have a lookup data structure, perform the insertion // into it. Otherwise, be lazy and don't build that structure until // someone asks for it. - if (LookupPtr) + if (LookupPtr || !Recoverable) makeDeclVisibleInContextImpl(D); // If we are a transparent context, insert into our parent context, // too. This operation is recursive. if (isTransparentContext()) - getParent()->makeDeclVisibleInContext(D); + getParent()->makeDeclVisibleInContext(D, Recoverable); } void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) { @@ -720,14 +772,14 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) { // one, just replace it and return. if (DeclNameEntries.HandleRedeclaration(getParentASTContext(), D)) return; - + // Put this declaration into the appropriate slot. DeclNameEntries.AddSubsequentDecl(D); } /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within /// this context. -DeclContext::udir_iterator_range +DeclContext::udir_iterator_range DeclContext::getUsingDirectives() const { lookup_const_result Result = lookup(UsingDirectiveDecl::getName()); return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first), |