[cfe-commits] r97523 - in /cfe/trunk: include/clang/AST/TypeNodes.def lib/AST/ASTContext.cpp lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/Mangle.cpp lib/Sema/SemaTemplateDeduction.cpp test/CodeGenCXX/mangle.cpp

John McCall rjmccall at apple.com
Mon Mar 1 15:49:17 PST 2010


Author: rjmccall
Date: Mon Mar  1 17:49:17 2010
New Revision: 97523

URL: http://llvm.org/viewvc/llvm-project?rev=97523&view=rev
Log:
Split out types that are non-canonical unless dependent as their own
category.  Use this in a few places to eliminate unnecessary TST cases and
do some future-proofing.  Provide terrible manglings for typeof.  Mangle
decltype with some hope of accuracy.

Our manglings for some of the cases covered in the testcase are different
from gcc's, which I've raised as an issue with the ABI list.


Modified:
    cfe/trunk/include/clang/AST/TypeNodes.def
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/CodeGenCXX/mangle.cpp

Modified: cfe/trunk/include/clang/AST/TypeNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=97523&r1=97522&r2=97523&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)
+++ cfe/trunk/include/clang/AST/TypeNodes.def Mon Mar  1 17:49:17 2010
@@ -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(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 @@
 #undef LEAF_TYPE
 #endif
 
+#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
 #undef DEPENDENT_TYPE
 #undef NON_CANONICAL_TYPE
 #undef ABSTRACT_TYPE

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=97523&r1=97522&r2=97523&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Mar  1 17:49:17 2010
@@ -4522,6 +4522,7 @@
   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 @@
 
     return QualType();
   }
-  case Type::TemplateSpecialization:
-    assert(false && "Dependent types have no size");
-    break;
   }
 
   return QualType();

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=97523&r1=97522&r2=97523&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Mon Mar  1 17:49:17 2010
@@ -190,6 +190,7 @@
 #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 @@
                                    NULL);
     return PtrDiffTy;
   }
-
-  case Type::TemplateSpecialization:
-    assert(false && "Dependent types can't get here");
   }
 
   // FIXME: implement.

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=97523&r1=97522&r2=97523&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Mon Mar  1 17:49:17 2010
@@ -455,7 +455,9 @@
     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 @@
   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

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=97523&r1=97522&r2=97523&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Mar  1 17:49:17 2010
@@ -2419,6 +2419,27 @@
                                  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:

Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=97523&r1=97522&r2=97523&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle.cpp Mon Mar  1 17:49:17 2010
@@ -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 @@
 // 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);
+  }
+}





More information about the cfe-commits mailing list