]> granicus.if.org Git - clang/commitdiff
MS ABI: Implement support for 'novtable'
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 2 Feb 2015 10:22:20 +0000 (10:22 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 2 Feb 2015 10:22:20 +0000 (10:22 +0000)
It is common for COM interface classes to be marked as 'novtable' to
tell the compiler that constructors and destructors should not reference
virtual function tables.

This commit implements this feature in clang.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@227796 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
lib/CodeGen/CGClass.cpp
lib/CodeGen/MicrosoftCXXABI.cpp
lib/Sema/SemaDeclAttr.cpp
test/Parser/MicrosoftExtensions.cpp

index 40871021405952739f4c8520d7f1586ae093f665..00fc5be3cc05354aa5f832ab045052581bbff03e 100644 (file)
@@ -1761,6 +1761,12 @@ def TypeTagForDatatype : InheritableAttr {
 
 // Microsoft-related attributes
 
+def MsNoVTable : InheritableAttr {
+  let Spellings = [Declspec<"novtable">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let Documentation = [Undocumented];
+}
+
 def MsProperty : IgnoredAttr {
   let Spellings = [Declspec<"property">];
 }
index d72eda95d7cf4c3299b4475f5484bdcef695c8f2..459b7742a26ae09556a985e3f6b05d6711fee2ea 100644 (file)
@@ -1949,6 +1949,14 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,
                                          const CXXRecordDecl *NearestVBase,
                                          CharUnits OffsetFromNearestVBase,
                                          const CXXRecordDecl *VTableClass) {
+  const CXXRecordDecl *RD = Base.getBase();
+
+  // Don't initialize the vtable pointer if the class is marked with the
+  // 'novtable' attribute.
+  if ((RD == VTableClass || RD == NearestVBase) &&
+      VTableClass->hasAttr<MsNoVTableAttr>())
+    return;
+
   // Compute the address point.
   bool NeedsVirtualOffset;
   llvm::Value *VTableAddressPoint =
index 40f88f32a9970f9714cbb4b94810b09067a0f1cc..48adf3a23d7449d59e5ca7f8c5dd0b7baddbcee2 100644 (file)
@@ -1582,7 +1582,8 @@ void MicrosoftCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {
   for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
     const VPtrInfo *VBT = (*VBGlobals.VBTables)[I];
     llvm::GlobalVariable *GV = VBGlobals.Globals[I];
-    emitVBTableDefinition(*VBT, RD, GV);
+    if (GV->isDeclaration())
+      emitVBTableDefinition(*VBT, RD, GV);
   }
 }
 
@@ -1609,6 +1610,9 @@ MicrosoftCXXABI::getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
   else if (RD->hasAttr<DLLExportAttr>())
     GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
 
+  if (!GV->hasExternalLinkage())
+    emitVBTableDefinition(VBT, RD, GV);
+
   return GV;
 }
 
index 80f141ef8d0b2e78142a6b1d4bdf2d163c99de1d..63695e847034afbc55691da593da4d2b3803262f 100644 (file)
@@ -4689,6 +4689,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
     break;
 
   // Microsoft attributes:
+  case AttributeList::AT_MsNoVTable:
+    handleSimpleAttribute<MsNoVTableAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_MsStruct:
     handleSimpleAttribute<MsStructAttr>(S, D, Attr);
     break;
index 73a1bb57af36ca499a021b23b29e6a525e20ad53..42689d141f7a2ce9e8b883378cb0126ee9c3821e 100644 (file)
@@ -339,7 +339,7 @@ void TestProperty() {
 //expected-warning@+1 {{C++ operator 'and' (aka '&&') used as a macro name}}
 #define and foo
 
-struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; // expected-warning{{__declspec attribute 'novtable' is not supported}}
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {};
 
 typedef bool (__stdcall __stdcall *blarg)(int);