diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 23 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 81 | ||||
-rw-r--r-- | clang/lib/AST/MangleNumberingContext.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 37 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 2 |
5 files changed, 98 insertions, 59 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 7f02f59c683..933e5e057ee 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -7990,24 +7990,19 @@ 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())) - 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++)); +void ASTContext::setManglingNumber(const NamedDecl *ND, unsigned Number) { + if (Number > 1) + MangleNumbers[ND] = Number; } -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::getManglingNumber(const NamedDecl *ND) const { + llvm::DenseMap<const NamedDecl *, unsigned>::const_iterator I = + MangleNumbers.find(ND); + return I != MangleNumbers.end() ? I->second : 1; } -MangleNumberingContext &ASTContext::getManglingNumberContext(DeclContext *DC) { +MangleNumberingContext & +ASTContext::getManglingNumberContext(const DeclContext *DC) { return MangleNumberingContexts[DC]; } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 79219825aae..2dc44eb3555 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -99,7 +99,8 @@ static const unsigned UnknownArity = ~0U; class ItaniumMangleContext : public MangleContext { llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds; - unsigned Discriminator; + typedef std::pair<const DeclContext*, IdentifierInfo*> DiscriminatorKeyTy; + llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator; llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier; public: @@ -114,11 +115,6 @@ public: return Result.first->second; } - void startNewFunction() { - MangleContext::startNewFunction(); - mangleInitDiscriminator(); - } - /// @name Mangler Entry Points /// @{ @@ -153,21 +149,33 @@ public: void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &); void mangleItaniumThreadLocalWrapper(const VarDecl *D, raw_ostream &); - void mangleInitDiscriminator() { - Discriminator = 0; - } - bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) { - // Lambda closure types with external linkage (indicated by a - // non-zero lambda mangling number) have their own numbering scheme, so - // they do not need a discriminator. + // Lambda closure types are already numbered. if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND)) - if (RD->isLambda() && RD->getLambdaManglingNumber() > 0) + if (RD->isLambda()) return false; - + + // Anonymous tags are already numbered. + if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) { + if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl()) + return false; + } + + // Use the canonical number for externally visible decls. + if (ND->isExternallyVisible()) { + unsigned discriminator = getASTContext().getManglingNumber(ND); + if (discriminator == 1) + return false; + disc = discriminator - 2; + return true; + } + + // Make up a reasonable number for internal decls. unsigned &discriminator = Uniquifier[ND]; - if (!discriminator) - discriminator = ++Discriminator; + if (!discriminator) { + const DeclContext *DC = getEffectiveDeclContext(ND); + discriminator = ++Discriminator[std::make_pair(DC, ND->getIdentifier())]; + } if (discriminator == 1) return false; disc = discriminator-2; @@ -1141,11 +1149,11 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, } } - int UnnamedMangle = Context.getASTContext().getUnnamedTagManglingNumber(TD); - if (UnnamedMangle != -1) { + if (TD->isExternallyVisible()) { + unsigned UnnamedMangle = getASTContext().getManglingNumber(TD); Out << "Ut"; - if (UnnamedMangle != 0) - Out << llvm::utostr(UnnamedMangle - 1); + if (UnnamedMangle > 1) + Out << llvm::utostr(UnnamedMangle - 2); Out << '_'; break; } @@ -1300,7 +1308,6 @@ void CXXNameMangler::mangleLocalName(const Decl *D) { // <entity name> will of course contain a <closure-type-name>: Its // numbering will be local to the particular argument in which it appears // -- other default arguments do not affect its encoding. - bool SkipDiscriminator = false; const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD); if (CXXRD->isLambda()) { if (const ParmVarDecl *Parm @@ -1312,7 +1319,6 @@ void CXXNameMangler::mangleLocalName(const Decl *D) { if (Num > 1) mangleNumber(Num - 2); Out << '_'; - SkipDiscriminator = true; } } } @@ -1328,24 +1334,21 @@ void CXXNameMangler::mangleLocalName(const Decl *D) { const NamedDecl *ND = cast<NamedDecl>(D); mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/); } - - if (!SkipDiscriminator) { - unsigned disc; - if (Context.getNextDiscriminator(RD, disc)) { - if (disc < 10) - Out << '_' << disc; - else - Out << "__" << disc << '_'; - } + } else { + if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) + mangleUnqualifiedBlock(BD); + else + mangleUnqualifiedName(cast<NamedDecl>(D)); + } + if (const NamedDecl *ND = dyn_cast<NamedDecl>(RD ? RD : D)) { + unsigned disc; + if (Context.getNextDiscriminator(ND, disc)) { + if (disc < 10) + Out << '_' << disc; + else + Out << "__" << disc << '_'; } - - return; } - - if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) - mangleUnqualifiedBlock(BD); - else - mangleUnqualifiedName(cast<NamedDecl>(D)); } void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) { diff --git a/clang/lib/AST/MangleNumberingContext.cpp b/clang/lib/AST/MangleNumberingContext.cpp index a4c8a27da5c..4e9006ec24a 100644 --- a/clang/lib/AST/MangleNumberingContext.cpp +++ b/clang/lib/AST/MangleNumberingContext.cpp @@ -19,7 +19,7 @@ using namespace clang; unsigned -MangleNumberingContext::getManglingNumber(CXXMethodDecl *CallOperator) { +MangleNumberingContext::getManglingNumber(const CXXMethodDecl *CallOperator) { const FunctionProtoType *Proto = CallOperator->getType()->getAs<FunctionProtoType>(); ASTContext &Context = CallOperator->getASTContext(); @@ -31,8 +31,18 @@ MangleNumberingContext::getManglingNumber(CXXMethodDecl *CallOperator) { } unsigned -MangleNumberingContext::getManglingNumber(BlockDecl *BD) { +MangleNumberingContext::getManglingNumber(const BlockDecl *BD) { // FIXME: Compute a BlockPointerType? Not obvious how. const Type *Ty = 0; return ++ManglingNumbers[Ty]; } + +unsigned +MangleNumberingContext::getManglingNumber(const VarDecl *VD) { + return ++VarManglingNumbers[VD->getIdentifier()]; +} + +unsigned +MangleNumberingContext::getManglingNumber(const TagDecl *TD) { + return ++TagManglingNumbers[TD->getIdentifier()]; +} diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 3f85de5d2c1..5e535da19a1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3043,6 +3043,27 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg()); } +static void HandleTagNumbering(Sema &S, const TagDecl *Tag) { + if (isa<CXXRecordDecl>(Tag->getParent())) { + // If this tag is the direct child of a class, number it if + // it is anonymous. + if (!Tag->getName().empty() || Tag->getTypedefNameForAnonDecl()) + return; + MangleNumberingContext &MCtx = + S.Context.getManglingNumberContext(Tag->getParent()); + S.Context.setManglingNumber(Tag, MCtx.getManglingNumber(Tag)); + return; + } + + // If this tag isn't a direct child of a class, number it if it is local. + Decl *ManglingContextDecl; + if (MangleNumberingContext *MCtx = + S.getCurrentMangleNumberContext(Tag->getDeclContext(), + ManglingContextDecl)) { + S.Context.setManglingNumber(Tag, MCtx->getManglingNumber(Tag)); + } +} + /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with /// no declarator (e.g. "struct foo;") is parsed. It also accepts template /// parameters to cope with template friend declarations. @@ -3072,7 +3093,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, } if (Tag) { - getASTContext().addUnnamedTag(Tag); + HandleTagNumbering(*this, Tag); Tag->setFreeStanding(); if (Tag->isInvalidDecl()) return Tag; @@ -5120,6 +5141,15 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, isIncompleteDeclExternC(*this, NewVD)) RegisterLocallyScopedExternCDecl(NewVD, S); + if (NewVD->isStaticLocal()) { + Decl *ManglingContextDecl; + if (MangleNumberingContext *MCtx = + getCurrentMangleNumberContext(NewVD->getDeclContext(), + ManglingContextDecl)) { + Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD)); + } + } + return NewVD; } @@ -8374,9 +8404,10 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, if (Decl *D = Group[i]) Decls.push_back(D); - if (DeclSpec::isDeclRep(DS.getTypeSpecType())) + if (DeclSpec::isDeclRep(DS.getTypeSpecType())) { if (const TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) - getASTContext().addUnnamedTag(Tag); + HandleTagNumbering(*this, Tag); + } return BuildDeclaratorGroup(Decls, DS.containsPlaceholderType()); } diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 1e6ef9baf70..8351ff27869 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -53,7 +53,7 @@ static bool isInInlineFunction(const DeclContext *DC) { } MangleNumberingContext * -Sema::getCurrentMangleNumberContext(DeclContext *DC, +Sema::getCurrentMangleNumberContext(const DeclContext *DC, Decl *&ManglingContextDecl) { // Compute the context for allocating mangling numbers in the current // expression, if the ABI requires them. |