aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/TypeNodes.def19
-rw-r--r--lib/AST/ASTContext.cpp4
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp4
-rw-r--r--lib/CodeGen/Mangle.cpp40
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp21
-rw-r--r--test/CodeGenCXX/mangle.cpp40
6 files changed, 115 insertions, 13 deletions
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 9cf2cb7bd7..8187caddc6 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -31,7 +31,11 @@
// type that is always dependent. Clients that do not need to deal
// with uninstantiated C++ templates can ignore these types.
//
-// There is a fifth macro, independent of the others. Most clients
+// NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
+// is non-canonical unless it is dependent. Defaults to TYPE because
+// it is neither reliably dependent nor reliably non-canonical.
+//
+// There is a sixth macro, independent of the others. Most clients
// will not need to use it.
//
// LEAF_TYPE(Class) - A type that never has inner types. Clients
@@ -51,6 +55,10 @@
# define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
#endif
+#ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
+# define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
TYPE(Builtin, Type)
TYPE(Complex, Type)
TYPE(Pointer, Type)
@@ -72,16 +80,16 @@ TYPE(FunctionProto, FunctionType)
TYPE(FunctionNoProto, FunctionType)
DEPENDENT_TYPE(UnresolvedUsing, Type)
NON_CANONICAL_TYPE(Typedef, Type)
-NON_CANONICAL_TYPE(TypeOfExpr, Type)
-NON_CANONICAL_TYPE(TypeOf, Type)
-NON_CANONICAL_TYPE(Decltype, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
ABSTRACT_TYPE(Tag, Type)
TYPE(Record, TagType)
TYPE(Enum, TagType)
NON_CANONICAL_TYPE(Elaborated, Type)
DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
-TYPE(TemplateSpecialization, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
@@ -101,6 +109,7 @@ LEAF_TYPE(TemplateTypeParm)
#undef LEAF_TYPE
#endif
+#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
#undef DEPENDENT_TYPE
#undef NON_CANONICAL_TYPE
#undef ABSTRACT_TYPE
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 22871a4a68..5cd52396a8 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4522,6 +4522,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
switch (LHSClass) {
#define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
#define DEPENDENT_TYPE(Class, Base) case Type::Class:
#include "clang/AST/TypeNodes.def"
@@ -4644,9 +4645,6 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
return QualType();
}
- case Type::TemplateSpecialization:
- assert(false && "Dependent types have no size");
- break;
}
return QualType();
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index f30e03c8c9..4feca4dd7d 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -190,6 +190,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
#define ABSTRACT_TYPE(Class, Base)
#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
#include "clang/AST/TypeNodes.def"
assert(false && "Non-canonical or dependent types aren't possible.");
break;
@@ -390,9 +391,6 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
NULL);
return PtrDiffTy;
}
-
- case Type::TemplateSpecialization:
- assert(false && "Dependent types can't get here");
}
// FIXME: implement.
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index d9a7991f78..64743c7696 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -455,7 +455,9 @@ void CXXNameMangler::mangleUnresolvedScope(NestedNameSpecifier *Qualifier) {
mangleType(QualType(Qualifier->getAsType(), 0));
break;
case NestedNameSpecifier::Identifier:
- mangleUnresolvedScope(Qualifier->getPrefix());
+ // Member expressions can have these without prefixes.
+ if (Qualifier->getPrefix())
+ mangleUnresolvedScope(Qualifier->getPrefix());
mangleSourceName(Qualifier->getAsIdentifier());
break;
}
@@ -1123,6 +1125,42 @@ void CXXNameMangler::mangleType(const TypenameType *T) {
Out << 'E';
}
+void CXXNameMangler::mangleType(const TypeOfType *T) {
+ // FIXME: this is pretty unsatisfactory, but there isn't an obvious
+ // "extension with parameters" mangling.
+ Out << "u6typeof";
+}
+
+void CXXNameMangler::mangleType(const TypeOfExprType *T) {
+ // FIXME: this is pretty unsatisfactory, but there isn't an obvious
+ // "extension with parameters" mangling.
+ Out << "u6typeof";
+}
+
+void CXXNameMangler::mangleType(const DecltypeType *T) {
+ Expr *E = T->getUnderlyingExpr();
+
+ // type ::= Dt <expression> E # decltype of an id-expression
+ // # or class member access
+ // ::= DT <expression> E # decltype of an expression
+
+ // This purports to be an exhaustive list of id-expressions and
+ // class member accesses. Note that we do not ignore parentheses;
+ // parentheses change the semantics of decltype for these
+ // expressions (and cause the mangler to use the other form).
+ if (isa<DeclRefExpr>(E) ||
+ isa<MemberExpr>(E) ||
+ isa<UnresolvedLookupExpr>(E) ||
+ isa<DependentScopeDeclRefExpr>(E) ||
+ isa<CXXDependentScopeMemberExpr>(E) ||
+ isa<UnresolvedMemberExpr>(E))
+ Out << "Dt";
+ else
+ Out << "DT";
+ mangleExpression(E);
+ Out << 'E';
+}
+
void CXXNameMangler::mangleIntegerLiteral(QualType T,
const llvm::APSInt &Value) {
// <expr-primary> ::= L <type> <value number> E # integer literal
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index df4d4a828d..7f16400aea 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -2419,6 +2419,27 @@ MarkUsedTemplateParameters(Sema &SemaRef, QualType T,
OnlyDeduced, Depth, Used);
break;
+ case Type::TypeOf:
+ if (!OnlyDeduced)
+ MarkUsedTemplateParameters(SemaRef,
+ cast<TypeOfType>(T)->getUnderlyingType(),
+ OnlyDeduced, Depth, Used);
+ break;
+
+ case Type::TypeOfExpr:
+ if (!OnlyDeduced)
+ MarkUsedTemplateParameters(SemaRef,
+ cast<TypeOfExprType>(T)->getUnderlyingExpr(),
+ OnlyDeduced, Depth, Used);
+ break;
+
+ case Type::Decltype:
+ if (!OnlyDeduced)
+ MarkUsedTemplateParameters(SemaRef,
+ cast<DecltypeType>(T)->getUnderlyingExpr(),
+ OnlyDeduced, Depth, Used);
+ break;
+
// None of these types have any template parameters in them.
case Type::Builtin:
case Type::VariableArray:
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index d00579155c..e18ca03d1b 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++0x | FileCheck %s
struct X { };
struct Y { };
@@ -376,3 +376,41 @@ namespace test1 {
// CHECK: define internal void @_Z27functionWithInternalLinkagev()
static void functionWithInternalLinkage() { }
void g() { functionWithInternalLinkage(); }
+
+namespace test2 {
+ template <class T> decltype(((T*) 0)->member) read_member(T& obj) {
+ return obj.member;
+ }
+
+ struct A { int member; } obj;
+ int test() {
+ return read_member(obj);
+ }
+
+ // CHECK: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_(
+}
+
+namespace test3 {
+ struct AmbiguousBase { int ab; };
+ struct Path1 : AmbiguousBase { float p; };
+ struct Path2 : AmbiguousBase { double p; };
+ struct Derived : Path1, Path2 { };
+
+ //template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; }
+ //template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; }
+
+ // define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path11pERS2_(
+ template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; }
+
+ // define linkonce_odr double @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path21pERS2_(
+ template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; }
+
+ Derived obj;
+ void test() {
+ // FIXME: uncomment these when we support diamonds competently
+ //get_ab_1(obj);
+ //get_ab_2(obj);
+ get_p_1(obj);
+ get_p_2(obj);
+ }
+}