<div dir="ltr">Done in r227838.</div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 2, 2015 at 4:40 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Mon, Feb 2, 2015 at 5:22 AM, David Majnemer <<a href="mailto:david.majnemer@gmail.com">david.majnemer@gmail.com</a>> wrote:<br>
> Author: majnemer<br>
> Date: Mon Feb 2 04:22:20 2015<br>
> New Revision: 227796<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=227796&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=227796&view=rev</a><br>
> Log:<br>
> MS ABI: Implement support for 'novtable'<br>
><br>
> It is common for COM interface classes to be marked as 'novtable' to<br>
> tell the compiler that constructors and destructors should not reference<br>
> virtual function tables.<br>
><br>
> This commit implements this feature in clang.<br>
><br>
> Modified:<br>
> cfe/trunk/include/clang/Basic/Attr.td<br>
> cfe/trunk/lib/CodeGen/CGClass.cpp<br>
> cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp<br>
> cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
> cfe/trunk/test/Parser/MicrosoftExtensions.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/Attr.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=227796&r1=227795&r2=227796&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=227796&r1=227795&r2=227796&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/Attr.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/Attr.td Mon Feb 2 04:22:20 2015<br>
> @@ -1761,6 +1761,12 @@ def TypeTagForDatatype : InheritableAttr<br>
><br>
> // Microsoft-related attributes<br>
><br>
> +def MsNoVTable : InheritableAttr {<br>
> + let Spellings = [Declspec<"novtable">];<br>
> + let Subjects = SubjectList<[CXXRecord]>;<br>
> + let Documentation = [Undocumented];<br>
<br>
</div></div>No undocumented attributes, please.<br>
<div><div class="h5"><br>
> +}<br>
> +<br>
> def MsProperty : IgnoredAttr {<br>
> let Spellings = [Declspec<"property">];<br>
> }<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CGClass.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=227796&r1=227795&r2=227796&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=227796&r1=227795&r2=227796&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CGClass.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGClass.cpp Mon Feb 2 04:22:20 2015<br>
> @@ -1949,6 +1949,14 @@ CodeGenFunction::InitializeVTablePointer<br>
> const CXXRecordDecl *NearestVBase,<br>
> CharUnits OffsetFromNearestVBase,<br>
> const CXXRecordDecl *VTableClass) {<br>
> + const CXXRecordDecl *RD = Base.getBase();<br>
> +<br>
> + // Don't initialize the vtable pointer if the class is marked with the<br>
> + // 'novtable' attribute.<br>
> + if ((RD == VTableClass || RD == NearestVBase) &&<br>
> + VTableClass->hasAttr<MsNoVTableAttr>())<br>
> + return;<br>
> +<br>
> // Compute the address point.<br>
> bool NeedsVirtualOffset;<br>
> llvm::Value *VTableAddressPoint =<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=227796&r1=227795&r2=227796&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=227796&r1=227795&r2=227796&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Mon Feb 2 04:22:20 2015<br>
> @@ -1582,7 +1582,8 @@ void MicrosoftCXXABI::emitVirtualInherit<br>
> for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {<br>
> const VPtrInfo *VBT = (*VBGlobals.VBTables)[I];<br>
> llvm::GlobalVariable *GV = VBGlobals.Globals[I];<br>
> - emitVBTableDefinition(*VBT, RD, GV);<br>
> + if (GV->isDeclaration())<br>
> + emitVBTableDefinition(*VBT, RD, GV);<br>
> }<br>
> }<br>
><br>
> @@ -1609,6 +1610,9 @@ MicrosoftCXXABI::getAddrOfVBTable(const<br>
> else if (RD->hasAttr<DLLExportAttr>())<br>
> GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);<br>
><br>
> + if (!GV->hasExternalLinkage())<br>
> + emitVBTableDefinition(VBT, RD, GV);<br>
> +<br>
> return GV;<br>
> }<br>
><br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=227796&r1=227795&r2=227796&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=227796&r1=227795&r2=227796&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Feb 2 04:22:20 2015<br>
> @@ -4689,6 +4689,9 @@ static void ProcessDeclAttribute(Sema &S<br>
> break;<br>
><br>
> // Microsoft attributes:<br>
> + case AttributeList::AT_MsNoVTable:<br>
> + handleSimpleAttribute<MsNoVTableAttr>(S, D, Attr);<br>
> + break;<br>
> case AttributeList::AT_MsStruct:<br>
> handleSimpleAttribute<MsStructAttr>(S, D, Attr);<br>
> break;<br>
><br>
> Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=227796&r1=227795&r2=227796&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=227796&r1=227795&r2=227796&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original)<br>
> +++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Mon Feb 2 04:22:20 2015<br>
> @@ -339,7 +339,7 @@ void TestProperty() {<br>
> //expected-warning@+1 {{C++ operator 'and' (aka '&&') used as a macro name}}<br>
> #define and foo<br>
><br>
> -struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; // expected-warning{{__declspec attribute 'novtable' is not supported}}<br>
> +struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {};<br>
<br>
</div></div>I would like to see some tests that ensure it accepts no arguments,<br>
and cannot apply to something other than a CXXRecordDecl.<br>
<br>
Thank you for implementing this!<br>
<span class="HOEnZb"><font color="#888888"><br>
~Aaron<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
><br>
> typedef bool (__stdcall __stdcall *blarg)(int);<br>
><br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div>