summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2013-07-10 00:30:46 +0000
committerEli Friedman <eli.friedman@gmail.com>2013-07-10 00:30:46 +0000
commit3b7d46c3ae516c81d19e53fa9d9b105919f6dd97 (patch)
treecea38305a338cf8065c2eb8e2e832623cd01f2de /clang/lib/AST
parenta830ea7431afca36431825f028a3c7817d1a940d (diff)
downloadbcm5719-llvm-3b7d46c3ae516c81d19e53fa9d9b105919f6dd97.tar.gz
bcm5719-llvm-3b7d46c3ae516c81d19e53fa9d9b105919f6dd97.zip
More local mangling fixes.
Compute mangling numbers for externally visible local variables and tags. Change the mangler to consistently use discriminators where necessary. Tweak the scheme we use to number decls which are not externally visible to avoid unnecessary discriminators in common cases now that we request them more consistently. Fixes <rdar://problem/14204721>. llvm-svn: 185986
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp23
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp81
-rw-r--r--clang/lib/AST/MangleNumberingContext.cpp14
3 files changed, 63 insertions, 55 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()];
+}
OpenPOWER on IntegriCloud