[cfe-commits] r106937 - in /cfe/trunk: lib/CodeGen/MicrosoftCXXABI.cpp test/CodeGenCXX/mangle-ms.cpp
Charles Davis
cdavis at mines.edu
Fri Jun 25 20:50:05 PDT 2010
Author: cdavis
Date: Fri Jun 25 22:50:05 2010
New Revision: 106937
URL: http://llvm.org/viewvc/llvm-project?rev=106937&view=rev
Log:
Mangle pointer and (lvalue) reference types in the Microsoft C++ Mangler.
Also, fix mangling of throw specs. Turns out MSVC totally ignores throw
specs when mangling names.
Modified:
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=106937&r1=106936&r2=106937&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Fri Jun 25 22:50:05 2010
@@ -69,7 +69,7 @@
#include "clang/AST/TypeNodes.def"
void mangleType(const TagType*);
- void mangleType(const FunctionType *T, bool IsStructor);
+ void mangleType(const FunctionType *T, bool IsStructor, bool IsInstMethod);
void mangleFunctionClass(const FunctionDecl *FD);
void mangleCallingConvention(const FunctionType *T);
void mangleThrowSpecification(const FunctionProtoType *T);
@@ -202,11 +202,13 @@
// We should never ever see a FunctionNoProtoType at this point.
// We don't even know how to mangle their types anyway :).
- FunctionProtoType *OldType = cast<FunctionProtoType>(FD->getType());
+ const FunctionProtoType *FT = cast<FunctionProtoType>(FD->getType());
- bool InStructor = false;
+ bool InStructor = false, InInstMethod = false;
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
if (MD) {
+ if (MD->isInstance())
+ InInstMethod = true;
if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD))
InStructor = true;
}
@@ -214,29 +216,7 @@
// First, the function class.
mangleFunctionClass(FD);
- // If this is a C++ instance method, mangle the CVR qualifiers for the
- // this pointer.
- if (MD && MD->isInstance())
- mangleQualifiers(Qualifiers::fromCVRMask(OldType->getTypeQuals()), false);
-
- // Do the canonicalization out here because parameter types can
- // undergo additional canonicalization (e.g. array decay).
- const FunctionProtoType *FT = cast<FunctionProtoType>(getASTContext()
- .getCanonicalType(OldType));
- // If the function's type had a throw spec, canonicalization removed it.
- // Get it back.
- FT = cast<FunctionProtoType>(getASTContext().getFunctionType(
- FT->getResultType(),
- FT->arg_type_begin(),
- FT->getNumArgs(),
- FT->isVariadic(),
- FT->getTypeQuals(),
- OldType->hasExceptionSpec(),
- OldType->hasAnyExceptionSpec(),
- OldType->getNumExceptions(),
- OldType->exception_begin(),
- FT->getExtInfo()).getTypePtr());
- mangleType(FT, InStructor);
+ mangleType(FT, InStructor, InInstMethod);
}
void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
@@ -263,9 +243,17 @@
Out << '4';
// Now mangle the type.
// <variable-type> ::= <type> <cvr-qualifiers>
+ // ::= <type> A # pointers and references
+ // Pointers and references are odd. The type of 'int * const foo;' gets
+ // mangled as 'QAHA' instead of 'PAHB', for example.
QualType Ty = VD->getType();
- mangleType(Ty.getLocalUnqualifiedType());
- mangleQualifiers(Ty.getLocalQualifiers(), false);
+ if (Ty->isPointerType() || Ty->isReferenceType()) {
+ mangleType(Ty);
+ Out << 'A';
+ } else {
+ mangleType(Ty.getLocalUnqualifiedType());
+ mangleQualifiers(Ty.getLocalQualifiers(), false);
+ }
}
void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
@@ -642,6 +630,32 @@
// Only operate on the canonical type!
T = getASTContext().getCanonicalType(T);
+ Qualifiers Quals = T.getLocalQualifiers();
+ if (Quals) {
+ // We have to mangle these now, while we still have enough information.
+ // <pointer-cvr-qualifiers> ::= P # pointer
+ // ::= Q # const pointer
+ // ::= R # volatile pointer
+ // ::= S # const volatile pointer
+ if (T->isPointerType()) {
+ if (!Quals.hasVolatile()) {
+ Out << 'Q';
+ } else {
+ if (!Quals.hasConst())
+ Out << 'R';
+ else
+ Out << 'S';
+ }
+ } else
+ // Just emit qualifiers like normal.
+ // NB: When we mangle a pointer/reference type, and the pointee
+ // type has no qualifiers, the lack of qualifier gets mangled
+ // in there.
+ mangleQualifiers(Quals, false);
+ }
+ else if (T->isPointerType()) {
+ Out << 'P';
+ }
switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, PARENT)
#define NON_CANONICAL_TYPE(CLASS, PARENT) \
@@ -659,6 +673,12 @@
case Type::Record:
mangleType(static_cast<RecordType *>(T.getTypePtr()));
break;
+ case Type::Pointer:
+ mangleType(static_cast<PointerType *>(T.getTypePtr()));
+ break;
+ case Type::LValueReference:
+ mangleType(static_cast<LValueReferenceType *>(T.getTypePtr()));
+ break;
default:
assert(false && "Don't know how to mangle this type!");
break;
@@ -743,22 +763,29 @@
void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T) {
// Structors only appear in decls, so at this point we know it's not a
// structor type.
- mangleType(T, false);
+ // I'll probably have mangleType(MemberPointerType) call
+ mangleType(T, false, false);
}
void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T) {
llvm_unreachable("Can't mangle K&R function prototypes");
}
void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
- bool IsStructor) {
- // <function-type> ::= <calling-convention> <return-type> <argument-list>
- // <throw-spec>
- mangleCallingConvention(T);
-
+ bool IsStructor,
+ bool IsInstMethod) {
+ // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
+ // <return-type> <argument-list> <throw-spec>
const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
- // Structors always have a 'void' return type, but MSVC mangles them as an
- // '@' (because they have no declared return type).
+ // If this is a C++ instance method, mangle the CVR qualifiers for the
+ // this pointer.
+ if (IsInstMethod)
+ mangleQualifiers(Qualifiers::fromCVRMask(Proto->getTypeQuals()), false);
+
+ mangleCallingConvention(T);
+
+ // <return-type> ::= <type>
+ // ::= @ # structors (they have no declared return type)
if (IsStructor)
Out << '@';
else
@@ -871,15 +898,10 @@
// <throw-spec> ::= Z # throw(...) (default)
// ::= @ # throw() or __declspec/__attribute__((nothrow))
// ::= <type>+
- if (!FT->hasExceptionSpec() || FT->hasAnyExceptionSpec())
- Out << 'Z';
- else {
- for (unsigned Exception = 0, NumExceptions = FT->getNumExceptions();
- Exception < NumExceptions;
- ++Exception)
- mangleType(FT->getExceptionType(Exception).getLocalUnqualifiedType());
- Out << '@';
- }
+ // NOTE: Since the Microsoft compiler ignores throw specifications, they are
+ // all actually mangled as 'Z'. (They're ignored because their associated
+ // functionality isn't implemented, and probably never will be.)
+ Out << 'Z';
}
// <type> ::= <union-type> | <struct-type> | <class-type> | <enum-type>
@@ -913,6 +935,27 @@
mangleName(T->getDecl());
}
+// <type> ::= <pointer-type>
+// <pointer-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
+void MicrosoftCXXNameMangler::mangleType(const PointerType *T) {
+ QualType PointeeTy = T->getPointeeType();
+ if (!PointeeTy.hasLocalQualifiers())
+ // Lack of qualifiers is mangled as 'A'.
+ Out << 'A';
+ mangleType(PointeeTy);
+}
+
+// <type> ::= <reference-type>
+// <reference-type> ::= A <cvr-qualifiers> <type>
+void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T) {
+ Out << 'A';
+ QualType PointeeTy = T->getPointeeType();
+ if (!PointeeTy.hasLocalQualifiers())
+ // Lack of qualifiers is mangled as 'A'.
+ Out << 'A';
+ mangleType(PointeeTy);
+}
+
void MicrosoftMangleContext::mangleName(const NamedDecl *D,
llvm::SmallVectorImpl<char> &Name) {
assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=106937&r1=106936&r2=106937&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Fri Jun 25 22:50:05 2010
@@ -7,6 +7,7 @@
// CHECK: @"\01?e at foo@@1JC"
// CHECK: @"\01?f at foo@@2DD"
// CHECK: @"\01?g at bar@@2HA"
+// CHECK: @"\01?h@@3QAHA"
int a;
@@ -50,18 +51,23 @@
int bar::g;
+extern int * const h = &a;
+
// Static functions are mangled, too.
// Also make sure calling conventions, arglists, and throw specs work.
static void __stdcall alpha(float a, double b) throw() {}
bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) {
-// CHECK: @"\01?beta@@YI_N_J_W at CE@"
+// CHECK: @"\01?beta@@YI_N_J_W at Z"
alpha(0.f, 0.0);
return false;
}
-// CHECK: @"\01?alpha@@YGXMN@@"
+// CHECK: @"\01?alpha@@YGXMN at Z"
// Make sure tag-type mangling works.
void gamma(class foo, struct bar, union baz, enum quux) {}
// CHECK: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
+// Make sure pointer/reference-type mangling works.
+void delta(int * const a, const long &) {}
+// CHECK: @"\01?delta@@YAXQAHABJ at Z"
More information about the cfe-commits
mailing list