[cfe-commits] r91805 - in /cfe/trunk: lib/CodeGen/CGRTTI.cpp test/CodeGenCXX/rtti-linkage.cpp

Anders Carlsson andersca at mac.com
Sun Dec 20 16:41:43 PST 2009


Author: andersca
Date: Sun Dec 20 18:41:42 2009
New Revision: 91805

URL: http://llvm.org/viewvc/llvm-project?rev=91805&view=rev
Log:
Incomplete structs should also have internal linkage.

Modified:
    cfe/trunk/lib/CodeGen/CGRTTI.cpp
    cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp

Modified: cfe/trunk/lib/CodeGen/CGRTTI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRTTI.cpp?rev=91805&r1=91804&r2=91805&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGRTTI.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRTTI.cpp Sun Dec 20 18:41:42 2009
@@ -314,10 +314,6 @@
     const clang::Type &Type
       = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
 
-    if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
-      if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
-        return BuildClassTypeInfo(RD);
-
     switch (Type.getTypeClass()) {
     default: {
       assert(0 && "typeid expression");
@@ -329,10 +325,20 @@
       return GetAddrOfExternalRTTIDescriptor(Ty);
     }
 
+    case Type::Record: {
+      const RecordType *RT = cast<RecordType>(&Type);
+      
+      const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+      if (RD->getNumBases())
+        return BuildClassTypeInfo(RD);
+
+      // Fall through.
+    }
+
     case Type::Pointer:
     case Type::MemberPointer:
-        
       return BuildTypeInfo(Ty);
+
     case Type::FunctionProto:
     case Type::FunctionNoProto:
       return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
@@ -496,8 +502,17 @@
     return TypeInfoIsInStandardLibrary(PointerTy);
 
   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
-    (void)RecordTy;
-    assert(false && "FIXME");
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+    if (!RD->isDynamicClass())
+      return false;
+
+    // Get the key function.
+    const CXXMethodDecl *KeyFunction = RD->getASTContext().getKeyFunction(RD);
+    if (KeyFunction && !KeyFunction->getBody()) {
+      // The class has a key function, but it is not defined in this translation
+      // unit, so we should use the external descriptor for it.
+      return true;
+    }
   }
   
   return false;
@@ -555,8 +570,40 @@
   //   making it a local static object.
   if (ContainsIncompleteClassType(Ty))
     return llvm::GlobalValue::InternalLinkage;
-   
-  // FIXME: Check linkage and anonymous namespace.
+  
+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty)) {
+    // If the pointee type has internal linkage, then the pointer type needs to
+    // have it as well.
+    if (getTypeInfoLinkage(PointerTy->getPointeeType()) == 
+        llvm::GlobalVariable::InternalLinkage)
+      return llvm::GlobalVariable::InternalLinkage;
+    
+    return llvm::GlobalVariable::WeakODRLinkage;
+  }
+    
+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+
+    // If we're in an anonymous namespace, then we always want internal linkage.
+    if (RD->isInAnonymousNamespace() || !RD->hasLinkage())
+      return llvm::GlobalVariable::InternalLinkage;
+    
+    if (!RD->isDynamicClass())
+      return llvm::GlobalValue::WeakODRLinkage;
+    
+    // Get the key function.
+    const CXXMethodDecl *KeyFunction = RD->getASTContext().getKeyFunction(RD);
+    if (!KeyFunction) {
+      // There is no key function, the RTTI descriptor is emitted with weak_odr
+      // linkage.
+      return llvm::GlobalValue::WeakODRLinkage;
+    }
+
+    // Otherwise, the RTTI descriptor is emitted with external linkage.
+    return llvm::GlobalValue::ExternalLinkage;
+  }
+
+  assert(false && "Unhandled type!");
   return llvm::GlobalValue::WeakODRLinkage;
 }
 
@@ -565,6 +612,17 @@
 
   switch (Ty->getTypeClass()) {
   default: assert(0 && "Unhandled type!");
+  
+  case Type::Record: {
+    const CXXRecordDecl *RD = 
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+    if (!RD->getNumBases()) {
+      // abi::__class_type_info
+      VtableName = "_ZTVN10__cxxabiv117__class_type_infoE";
+      break;
+    }
+  }
+
   case Type::Pointer:
     // abi::__pointer_type_info
     VtableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
@@ -620,6 +678,15 @@
     assert(false && "Builtin type info must be in the standard library!");
     break;
 
+  case Type::Record: {
+    const CXXRecordDecl *RD = 
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+    if (!RD->getNumBases()) {
+      // We don't need to emit any fields.
+      break;
+    }
+  }
+      
   case Type::Pointer:
     BuildPointerTypeInfo(cast<PointerType>(Ty));
     break;

Modified: cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp?rev=91805&r1=91804&r2=91805&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp Sun Dec 20 18:41:42 2009
@@ -6,6 +6,8 @@
 // CHECK: _ZTI1A = weak_odr constant
 // CHECK: _ZTI1B = constant
 // CHECK: _ZTSP1C = internal constant
+// CHECK: _ZTS1C = internal constant
+// CHECK: _ZTI1C = internal constant
 // CHECK: _ZTIP1C = internal constant
 // CHECK: _ZTSPP1C = internal constant
 // CHECK: _ZTIPP1C = internal constant





More information about the cfe-commits mailing list