diff options
Diffstat (limited to 'lib/AST/DeclBase.cpp')
-rw-r--r-- | lib/AST/DeclBase.cpp | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 4fcec53..16394e8 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -45,10 +45,19 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const { getASTContext().getExternalSource()->updateOutOfDateIdentifier(II); } +#define DECL(DERIVED, BASE) \ + static_assert(Decl::DeclObjAlignment >= \ + llvm::AlignOf<DERIVED##Decl>::Alignment, \ + "Alignment sufficient after objects prepended to " #DERIVED); +#define ABSTRACT_DECL(DECL) +#include "clang/AST/DeclNodes.inc" + void *Decl::operator new(std::size_t Size, const ASTContext &Context, unsigned ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the - // resulting pointer will still be 8-byte aligned. + // resulting pointer will still be 8-byte aligned. + static_assert(sizeof(unsigned) * 2 >= DeclObjAlignment, + "Decl won't be misaligned"); void *Start = Context.Allocate(Size + Extra + 8); void *Result = (char*)Start + 8; @@ -69,7 +78,13 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx, // With local visibility enabled, we track the owning module even for local // declarations. if (Ctx.getLangOpts().ModulesLocalVisibility) { - void *Buffer = ::operator new(sizeof(Module *) + Size + Extra, Ctx); + // Ensure required alignment of the resulting object by adding extra + // padding at the start if required. + size_t ExtraAlign = + llvm::OffsetToAlignment(sizeof(Module *), DeclObjAlignment); + char *Buffer = reinterpret_cast<char *>( + ::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx)); + Buffer += ExtraAlign; return new (Buffer) Module*(nullptr) + 1; } return ::operator new(Size + Extra, Ctx); @@ -251,6 +266,18 @@ void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, } } +bool Decl::isLexicallyWithinFunctionOrMethod() const { + const DeclContext *LDC = getLexicalDeclContext(); + while (true) { + if (LDC->isFunctionOrMethod()) + return true; + if (!isa<TagDecl>(LDC)) + return false; + LDC = LDC->getLexicalParent(); + } + return false; +} + bool Decl::isInAnonymousNamespace() const { const DeclContext *DC = getDeclContext(); do { @@ -612,6 +639,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ExternCContext: case UsingDirective: + case BuiltinTemplate: case ClassTemplateSpecialization: case ClassTemplatePartialSpecialization: case ClassScopeFunctionSpecialization: @@ -1044,14 +1072,7 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const { // Load the external declarations, if any. SmallVector<Decl*, 64> Decls; ExternalLexicalStorage = false; - switch (Source->FindExternalLexicalDecls(this, Decls)) { - case ELR_Success: - break; - - case ELR_Failure: - case ELR_AlreadyLoaded: - return false; - } + Source->FindExternalLexicalDecls(this, Decls); if (Decls.empty()) return false; @@ -1189,13 +1210,16 @@ void DeclContext::removeDecl(Decl *D) { // Remove only decls that have a name if (!ND->getDeclName()) return; - StoredDeclsMap *Map = getPrimaryContext()->LookupPtr; - if (!Map) return; - - StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); - assert(Pos != Map->end() && "no lookup entry for decl"); - if (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND) - Pos->second.remove(ND); + auto *DC = this; + do { + StoredDeclsMap *Map = DC->getPrimaryContext()->LookupPtr; + if (Map) { + StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); + assert(Pos != Map->end() && "no lookup entry for decl"); + if (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND) + Pos->second.remove(ND); + } + } while (DC->isTransparentContext() && (DC = DC->getParent())); } } @@ -1213,7 +1237,7 @@ void DeclContext::addHiddenDecl(Decl *D) { } // Notify a C++ record declaration that we've added a member, so it can - // update it's class-specific state. + // update its class-specific state. if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this)) Record->addedMember(D); |