summaryrefslogtreecommitdiffstats
path: root/lib/AST/ItaniumMangle.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-06-12 15:46:16 +0000
committerdim <dim@FreeBSD.org>2011-06-12 15:46:16 +0000
commitc49018d9cce52d8c9f34b44865ec3ba8e89a1488 (patch)
treec5e9e10bc189de0058aa763c47b9920a8351b7df /lib/AST/ItaniumMangle.cpp
parent110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (diff)
downloadFreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.zip
FreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.tar.gz
Vendor import of clang trunk r132879:
http://llvm.org/svn/llvm-project/cfe/trunk@132879
Diffstat (limited to 'lib/AST/ItaniumMangle.cpp')
-rw-r--r--lib/AST/ItaniumMangle.cpp141
1 files changed, 123 insertions, 18 deletions
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index c460929..e81ec7e 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -255,7 +255,8 @@ private:
DeclarationName name,
unsigned KnownArity = UnknownArity);
- void mangleUnresolvedType(QualType type);
+ static bool isUnresolvedType(const Type *type);
+ void mangleUnresolvedType(const Type *type);
void mangleName(const TemplateDecl *TD,
const TemplateArgument *TemplateArgs,
@@ -277,6 +278,7 @@ private:
unsigned NumTemplateArgs);
void manglePrefix(NestedNameSpecifier *qualifier);
void manglePrefix(const DeclContext *DC, bool NoFunction=false);
+ void manglePrefix(QualType type);
void mangleTemplatePrefix(const TemplateDecl *ND);
void mangleTemplatePrefix(TemplateName Template);
void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
@@ -317,6 +319,8 @@ private:
void mangleTemplateArgs(const TemplateParameterList &PL,
const TemplateArgumentList &AL);
void mangleTemplateArg(const NamedDecl *P, const TemplateArgument &A);
+ void mangleUnresolvedTemplateArgs(const TemplateArgument *args,
+ unsigned numArgs);
void mangleTemplateParameter(unsigned Index);
@@ -667,7 +671,7 @@ void CXXNameMangler::mangleCallOffset(int64_t NonVirtual, int64_t Virtual) {
Out << '_';
}
-void CXXNameMangler::mangleUnresolvedType(QualType type) {
+void CXXNameMangler::manglePrefix(QualType type) {
if (const TemplateSpecializationType *TST =
type->getAs<TemplateSpecializationType>()) {
if (!mangleSubstitution(QualType(TST, 0))) {
@@ -698,6 +702,31 @@ void CXXNameMangler::mangleUnresolvedType(QualType type) {
}
}
+/// Returns true if the given type, appearing within an
+/// unresolved-name, should be mangled as an unresolved-type.
+bool CXXNameMangler::isUnresolvedType(const Type *type) {
+ // <unresolved-type> ::= <template-param>
+ // ::= <decltype>
+ // ::= <template-template-param> <template-args>
+ // (this last is not official yet)
+
+ if (isa<TemplateTypeParmType>(type)) return true;
+ if (isa<DecltypeType>(type)) return true;
+ // typeof?
+ if (const TemplateSpecializationType *tst =
+ dyn_cast<TemplateSpecializationType>(type)) {
+ TemplateDecl *temp = tst->getTemplateName().getAsTemplateDecl();
+ if (temp && isa<TemplateTemplateParmDecl>(temp))
+ return true;
+ }
+ return false;
+}
+
+void CXXNameMangler::mangleUnresolvedType(const Type *type) {
+ // This seems to be do everything we want.
+ mangleType(QualType(type, 0));
+}
+
/// Mangle everything prior to the base-unresolved-name in an unresolved-name.
///
/// \param firstQualifierLookup - the entity found by unqualified lookup
@@ -752,17 +781,60 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
- // Both cases want this.
- Out << "sr";
+ const Type *type = qualifier->getAsType();
- // We only get here recursively if we're followed by identifiers.
- if (recursive) Out << 'N';
+ // We only want to use an unresolved-type encoding if this is one of:
+ // - a decltype
+ // - a template type parameter
+ // - a template template parameter with arguments
+ // In all of these cases, we should have no prefix.
+ if (qualifier->getPrefix()) {
+ mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,
+ /*recursive*/ true);
+ } else {
+ // Otherwise, all the cases want this.
+ Out << "sr";
- mangleUnresolvedType(QualType(qualifier->getAsType(), 0));
+ if (isUnresolvedType(type)) {
+ // We only get here recursively if we're followed by identifiers.
+ if (recursive) Out << 'N';
+ mangleUnresolvedType(type);
- // We never want to print 'E' directly after an unresolved-type,
- // so we return directly.
- return;
+ // We never want to print 'E' directly after an unresolved-type,
+ // so we return directly.
+ return;
+ }
+ }
+
+ assert(!isUnresolvedType(type));
+
+ // Only certain other types are valid as prefixes; enumerate them.
+ // FIXME: can we get ElaboratedTypes here?
+ // FIXME: SubstTemplateTypeParmType?
+ if (const TagType *t = dyn_cast<TagType>(type)) {
+ mangleSourceName(t->getDecl()->getIdentifier());
+ } else if (const TypedefType *t = dyn_cast<TypedefType>(type)) {
+ mangleSourceName(t->getDecl()->getIdentifier());
+ } else if (const UnresolvedUsingType *t
+ = dyn_cast<UnresolvedUsingType>(type)) {
+ mangleSourceName(t->getDecl()->getIdentifier());
+ } else if (const DependentNameType *t
+ = dyn_cast<DependentNameType>(type)) {
+ mangleSourceName(t->getIdentifier());
+ } else if (const TemplateSpecializationType *tst
+ = dyn_cast<TemplateSpecializationType>(type)) {
+ TemplateDecl *temp = tst->getTemplateName().getAsTemplateDecl();
+ assert(temp && "no template for template specialization type");
+ mangleSourceName(temp->getIdentifier());
+ mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs());
+ } else if (const DependentTemplateSpecializationType *tst
+ = dyn_cast<DependentTemplateSpecializationType>(type)) {
+ mangleSourceName(tst->getIdentifier());
+ mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs());
+ } else {
+ llvm_unreachable("unexpected type in nested name specifier!");
+ }
+ break;
}
case NestedNameSpecifier::Identifier:
@@ -1050,6 +1122,12 @@ void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
// := Z <function encoding> E s [<discriminator>]
// <discriminator> := _ <non-negative number>
const DeclContext *DC = ND->getDeclContext();
+ if (isa<ObjCMethodDecl>(DC) && isa<FunctionDecl>(ND)) {
+ // Don't add objc method name mangling to locally declared function
+ mangleUnqualifiedName(ND);
+ return;
+ }
+
Out << 'Z';
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) {
@@ -1097,7 +1175,7 @@ void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
- mangleUnresolvedType(QualType(qualifier->getAsType(), 0));
+ manglePrefix(QualType(qualifier->getAsType(), 0));
return;
case NestedNameSpecifier::Identifier:
@@ -1867,6 +1945,22 @@ void CXXNameMangler::mangleType(const DecltypeType *T) {
Out << 'E';
}
+void CXXNameMangler::mangleType(const UnaryTransformType *T) {
+ // If this is dependent, we need to record that. If not, we simply
+ // mangle it as the underlying type since they are equivalent.
+ if (T->isDependentType()) {
+ Out << 'U';
+
+ switch (T->getUTTKind()) {
+ case UnaryTransformType::EnumUnderlyingType:
+ Out << "3eut";
+ break;
+ }
+ }
+
+ mangleType(T->getUnderlyingType());
+}
+
void CXXNameMangler::mangleType(const AutoType *T) {
QualType D = T->getDeducedType();
// <builtin-type> ::= Da # dependent auto
@@ -1951,6 +2045,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
// ::= <function-param>
// ::= sr <type> <unqualified-name> # dependent name
// ::= sr <type> <unqualified-name> <template-args> # dependent template-id
+ // ::= ds <expression> <expression> # expr.*expr
// ::= sZ <template-param> # size of a parameter pack
// ::= sZ <function-param> # size of a function parameter pack
// ::= <expr-primary>
@@ -2005,7 +2100,9 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
case Expr::VAArgExprClass:
case Expr::CXXUuidofExprClass:
case Expr::CXXNoexceptExprClass:
- case Expr::CUDAKernelCallExprClass: {
+ case Expr::CUDAKernelCallExprClass:
+ case Expr::AsTypeExprClass:
+ {
// As bad as this diagnostic is, it's better than crashing.
Diagnostic &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
@@ -2227,8 +2324,11 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
case Expr::CompoundAssignOperatorClass: // fallthrough
case Expr::BinaryOperatorClass: {
const BinaryOperator *BO = cast<BinaryOperator>(E);
- mangleOperatorName(BinaryOperator::getOverloadedOperator(BO->getOpcode()),
- /*Arity=*/2);
+ if (BO->getOpcode() == BO_PtrMemD)
+ Out << "ds";
+ else
+ mangleOperatorName(BinaryOperator::getOverloadedOperator(BO->getOpcode()),
+ /*Arity=*/2);
mangleExpression(BO->getLHS());
mangleExpression(BO->getRHS());
break;
@@ -2552,8 +2652,8 @@ void CXXNameMangler::mangleTemplateArgs(
const ExplicitTemplateArgumentList &TemplateArgs) {
// <template-args> ::= I <template-arg>+ E
Out << 'I';
- for (unsigned I = 0, E = TemplateArgs.NumTemplateArgs; I != E; ++I)
- mangleTemplateArg(0, TemplateArgs.getTemplateArgs()[I].getArgument());
+ for (unsigned i = 0, e = TemplateArgs.NumTemplateArgs; i != e; ++i)
+ mangleTemplateArg(0, TemplateArgs.getTemplateArgs()[i].getArgument());
Out << 'E';
}
@@ -2564,10 +2664,15 @@ void CXXNameMangler::mangleTemplateArgs(TemplateName Template,
return mangleTemplateArgs(*TD->getTemplateParameters(), TemplateArgs,
NumTemplateArgs);
+ mangleUnresolvedTemplateArgs(TemplateArgs, NumTemplateArgs);
+}
+
+void CXXNameMangler::mangleUnresolvedTemplateArgs(const TemplateArgument *args,
+ unsigned numArgs) {
// <template-args> ::= I <template-arg>+ E
Out << 'I';
- for (unsigned i = 0; i != NumTemplateArgs; ++i)
- mangleTemplateArg(0, TemplateArgs[i]);
+ for (unsigned i = 0; i != numArgs; ++i)
+ mangleTemplateArg(0, args[i]);
Out << 'E';
}
OpenPOWER on IntegriCloud