summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/Attr.td6
-rw-r--r--clang/lib/CodeGen/CGClass.cpp8
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp6
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp3
-rw-r--r--clang/test/Parser/MicrosoftExtensions.cpp2
5 files changed, 23 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 40871021405..00fc5be3cc0 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -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">];
}
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index d72eda95d7c..459b7742a26 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -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 =
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 40f88f32a99..48adf3a23d7 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -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;
}
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 80f141ef8d0..63695e84703 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -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;
diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp
index 73a1bb57af3..42689d141f7 100644
--- a/clang/test/Parser/MicrosoftExtensions.cpp
+++ b/clang/test/Parser/MicrosoftExtensions.cpp
@@ -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);
OpenPOWER on IntegriCloud