diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 17 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 6 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 12 |
3 files changed, 31 insertions, 4 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 577dd0adaf..80ce66a017 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -7508,6 +7508,23 @@ size_t ASTContext::getSideTableAllocatedMemory() const { + llvm::capacity_in_bytes(ClassScopeSpecializationPattern); } +void ASTContext::addUnnamedTag(const TagDecl *Tag) { + // FIXME: This mangling should be applied to function local classes too + if (!Tag->getName().empty() || Tag->getTypedefNameForAnonDecl() || + !isa<CXXRecordDecl>(Tag->getParent()) || Tag->getLinkage() != ExternalLinkage) + return; + + std::pair<llvm::DenseMap<const DeclContext *, unsigned>::iterator, bool> P = + UnnamedMangleContexts.insert(std::make_pair(Tag->getParent(), 0)); + UnnamedMangleNumbers.insert(std::make_pair(Tag, P.first->second++)); +} + +int ASTContext::getUnnamedTagManglingNumber(const TagDecl *Tag) const { + llvm::DenseMap<const TagDecl *, unsigned>::const_iterator I = + UnnamedMangleNumbers.find(Tag); + return I != UnnamedMangleNumbers.end() ? I->second : -1; +} + unsigned ASTContext::getLambdaManglingNumber(CXXMethodDecl *CallOperator) { CXXRecordDecl *Lambda = CallOperator->getParent(); return LambdaMangleContexts[Lambda->getDeclContext()] diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 74abbaa492..9569841a56 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -480,8 +480,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, bool OnlyTemplate) { if (!(isa<CXXMethodDecl>(D) || isa<VarDecl>(D) || isa<FieldDecl>(D) || - (isa<TagDecl>(D) && - (D->getDeclName() || cast<TagDecl>(D)->getTypedefNameForAnonDecl())))) + isa<TagDecl>(D))) return LinkageInfo::none(); LinkageInfo LV; @@ -2561,8 +2560,7 @@ void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { void TagDecl::startDefinition() { IsBeingDefined = true; - if (isa<CXXRecordDecl>(this)) { - CXXRecordDecl *D = cast<CXXRecordDecl>(this); + if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(this)) { struct CXXRecordDecl::DefinitionData *Data = new (getASTContext()) struct CXXRecordDecl::DefinitionData(D); for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 851944a42b..fc61d88bd9 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -1117,6 +1117,18 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, break; } } + + int UnnamedMangle = Context.getASTContext().getUnnamedTagManglingNumber(TD); + if (UnnamedMangle != -1) { + Out << "Ut"; + if (UnnamedMangle != 0) + Out << llvm::utostr(UnnamedMangle - 1); + Out << '_'; + break; + } + + //assert(cast<RecordDecl>(RD)->isAnonymousStructOrUnion() && "Don't mangle unnamed things as " + // "anonymous things"); // Get a unique id for the anonymous struct. uint64_t AnonStructId = Context.getAnonymousStructId(TD); |