[cfe-commits] r173514 - in /cfe/trunk: include/clang/Basic/TargetCXXABI.h include/clang/Basic/TargetInfo.h lib/AST/ASTContext.cpp lib/AST/RecordLayout.cpp lib/AST/RecordLayoutBuilder.cpp lib/AST/VTableBuilder.cpp lib/Basic/TargetInfo.cpp lib/Basic/Targets.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGRecordLayoutBuilder.cpp lib/CodeGen/CodeGenModule.cpp lib/Sema/SemaType.cpp

John McCall rjmccall at apple.com
Fri Jan 25 14:30:50 PST 2013


Author: rjmccall
Date: Fri Jan 25 16:30:49 2013
New Revision: 173514

URL: http://llvm.org/viewvc/llvm-project?rev=173514&view=rev
Log:
First pass at abstracting out a class for the target C++ ABI.

Added:
    cfe/trunk/include/clang/Basic/TargetCXXABI.h
Modified:
    cfe/trunk/include/clang/Basic/TargetInfo.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/RecordLayout.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/AST/VTableBuilder.cpp
    cfe/trunk/lib/Basic/TargetInfo.cpp
    cfe/trunk/lib/Basic/Targets.cpp
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Added: cfe/trunk/include/clang/Basic/TargetCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetCXXABI.h?rev=173514&view=auto
==============================================================================
--- cfe/trunk/include/clang/Basic/TargetCXXABI.h (added)
+++ cfe/trunk/include/clang/Basic/TargetCXXABI.h Fri Jan 25 16:30:49 2013
@@ -0,0 +1,159 @@
+//===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the TargetCXXABI class, which abstracts details of the
+/// C++ ABI that we're targeting.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TARGETCXXABI_H
+#define LLVM_CLANG_TARGETCXXABI_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+
+/// \brief The basic abstraction for the target C++ ABI.
+class TargetCXXABI {
+public:
+  /// \brief The basic C++ ABI kind.
+  enum Kind {
+    /// The generic Itanium ABI is the standard ABI of most open-source
+    /// and Unix-like platforms.  It is the primary ABI targeted by
+    /// many compilers, including Clang and GCC.
+    ///
+    /// It is documented here:
+    ///   http://www.codesourcery.com/public/cxx-abi/
+    GenericItanium,
+
+    /// The generic ARM ABI is a modified version of the Itanium ABI
+    /// proposed by ARM for use on ARM-based platforms.
+    ///
+    /// These changes include:
+    ///   - the representation of member function pointers is adjusted
+    ///     to not conflict with the 'thumb' bit of ARM function pointers;
+    ///   - constructors and destructors return 'this';
+    ///   - guard variables are smaller;
+    ///   - inline functions are never key functions;
+    ///   - array cookies have a slightly different layout;
+    ///   - additional convenience functions are specified;
+    ///   - and more!
+    ///
+    /// It is documented here:
+    ///    http://infocenter.arm.com
+    ///                    /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
+    GenericARM,
+
+    /// The iOS ABI is a partial implementation of the ARM ABI.
+    /// Several of the features of the ARM ABI were not fully implemented
+    /// in the compilers that iOS was launched with.
+    ///
+    /// Essentially, the iOS ABI includes the ARM changes to:
+    ///   - member function pointers,
+    ///   - guard variables,
+    ///   - array cookies, and
+    ///   - constructor/destructor signatures.
+    iOS,
+
+    /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
+    /// compatible compilers).
+    ///
+    /// FIXME: should this be split into Win32 and Win64 variants?
+    ///
+    /// Only scattered and incomplete official documentation exists.
+    Microsoft
+  };
+
+private:
+  // Right now, this class is passed around as a cheap value type.
+  // If you add more members, especially non-POD members, please
+  // audit the users to pass it by reference instead.
+  Kind TheKind;
+
+public:
+  /// A bogus initialization of the platform ABI.
+  TargetCXXABI() : TheKind(GenericItanium) {}
+
+  TargetCXXABI(Kind kind) : TheKind(kind) {}
+
+  void set(Kind kind) {
+    TheKind = kind;
+  }
+
+  Kind getKind() const { return TheKind; }
+
+  /// \brief Does this ABI generally fall into the Itanium family of ABIs?
+  bool isItaniumFamily() const {
+    switch (getKind()) {
+    case GenericItanium:
+    case GenericARM:
+    case iOS:
+      return true;
+
+    case Microsoft:
+      return false;
+    }
+    llvm_unreachable("bad ABI kind");
+  }
+
+  /// \brief Is this ABI an MSVC-compatible ABI?
+  bool isMicrosoft() const {
+    switch (getKind()) {
+    case GenericItanium:
+    case GenericARM:
+    case iOS:
+      return false;
+
+    case Microsoft:
+      return true;
+    }
+    llvm_unreachable("bad ABI kind");
+  }
+
+  /// \brief Is the default C++ member function calling convention
+  /// the same as the default calling convention?
+  bool isMemberFunctionCCDefault() const {
+    // Right now, this is always true for Microsoft.
+    return !isMicrosoft();
+  }
+
+  /// \brief Does this ABI have different entrypoints for complete-object
+  /// and base-subobject constructors?
+  bool hasConstructorVariants() const {
+    return isItaniumFamily();
+  }
+
+  /// \brief Does this ABI have different entrypoints for complete-object
+  /// and base-subobject destructors?
+  bool hasDestructorVariants() const {
+    return isItaniumFamily();
+  }
+
+  /// \brief Does this ABI allow virtual bases to be primary base classes?
+  bool hasPrimaryVBases() const {
+    return isItaniumFamily();
+  }
+
+  /// Try to parse an ABI name, returning false on error.
+  bool tryParse(llvm::StringRef name);
+
+  friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
+    return left.getKind() == right.getKind();
+  }
+
+  friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
+    return !(left == right);
+  }
+};
+
+}  // end namespace clang
+
+#endif

Modified: cfe/trunk/include/clang/Basic/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TargetInfo.h (original)
+++ cfe/trunk/include/clang/Basic/TargetInfo.h Fri Jan 25 16:30:49 2013
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_BASIC_TARGETINFO_H
 
 #include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/TargetCXXABI.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TargetOptions.h"
@@ -43,22 +44,6 @@ class SourceManager;
 
 namespace Builtin { struct Info; }
 
-/// \brief The types of C++ ABIs for which we can generate code.
-enum TargetCXXABI {
-  /// The generic ("Itanium") C++ ABI, documented at:
-  ///   http://www.codesourcery.com/public/cxx-abi/
-  CXXABI_Itanium,
-
-  /// The ARM C++ ABI, based largely on the Itanium ABI but with
-  /// significant differences.
-  ///    http://infocenter.arm.com
-  ///                    /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
-  CXXABI_ARM,
-
-  /// The Visual Studio ABI.  Only scattered official documentation exists.
-  CXXABI_Microsoft
-};
-
 /// \brief Exposes information about the current target.
 ///
 class TargetInfo : public RefCountedBase<TargetInfo> {
@@ -89,7 +74,7 @@ protected:
   const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
     *LongDoubleFormat;
   unsigned char RegParmMax, SSERegParmMax;
-  TargetCXXABI CXXABI;
+  TargetCXXABI TheCXXABI;
   const LangAS::Map *AddrSpaceMap;
 
   mutable StringRef PlatformName;
@@ -634,8 +619,8 @@ public:
   }
 
   /// \brief Get the C++ ABI currently in use.
-  virtual TargetCXXABI getCXXABI() const {
-    return CXXABI;
+  TargetCXXABI getCXXABI() const {
+    return TheCXXABI;
   }
 
   /// \brief Target the specified CPU.
@@ -655,14 +640,9 @@ public:
   /// \brief Use this specified C++ ABI.
   ///
   /// \return False on error (invalid C++ ABI name).
-  bool setCXXABI(const std::string &Name) {
-    static const TargetCXXABI Unknown = static_cast<TargetCXXABI>(-1);
-    TargetCXXABI ABI = llvm::StringSwitch<TargetCXXABI>(Name)
-      .Case("arm", CXXABI_ARM)
-      .Case("itanium", CXXABI_Itanium)
-      .Case("microsoft", CXXABI_Microsoft)
-      .Default(Unknown);
-    if (ABI == Unknown) return false;
+  bool setCXXABI(llvm::StringRef name) {
+    TargetCXXABI ABI;
+    if (!ABI.tryParse(name)) return false;
     return setCXXABI(ABI);
   }
 
@@ -670,7 +650,7 @@ public:
   ///
   /// \return False on error (ABI not valid on this target)
   virtual bool setCXXABI(TargetCXXABI ABI) {
-    CXXABI = ABI;
+    TheCXXABI = ABI;
     return true;
   }
 

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Jan 25 16:30:49 2013
@@ -583,12 +583,13 @@ ASTContext::getCanonicalTemplateTemplate
 CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {
   if (!LangOpts.CPlusPlus) return 0;
 
-  switch (T.getCXXABI()) {
-  case CXXABI_ARM:
+  switch (T.getCXXABI().getKind()) {
+  case TargetCXXABI::GenericARM:
+  case TargetCXXABI::iOS:
     return CreateARMCXXABI(*this);
-  case CXXABI_Itanium:
+  case TargetCXXABI::GenericItanium:
     return CreateItaniumCXXABI(*this);
-  case CXXABI_Microsoft:
+  case TargetCXXABI::Microsoft:
     return CreateMicrosoftCXXABI(*this);
   }
   llvm_unreachable("Invalid CXXABI type!");
@@ -7607,7 +7608,8 @@ CallingConv ASTContext::getDefaultCXXMet
 }
 
 CallingConv ASTContext::getCanonicalCallConv(CallingConv CC) const {
-  if (CC == CC_C && !LangOpts.MRTD && getTargetInfo().getCXXABI() != CXXABI_Microsoft)
+  if (CC == CC_C && !LangOpts.MRTD &&
+      getTargetInfo().getCXXABI().isMemberFunctionCCDefault())
     return CC_Default;
   return CC;
 }
@@ -7618,11 +7620,12 @@ bool ASTContext::isNearlyEmpty(const CXX
 }
 
 MangleContext *ASTContext::createMangleContext() {
-  switch (Target->getCXXABI()) {
-  case CXXABI_ARM:
-  case CXXABI_Itanium:
+  switch (Target->getCXXABI().getKind()) {
+  case TargetCXXABI::GenericItanium:
+  case TargetCXXABI::GenericARM:
+  case TargetCXXABI::iOS:
     return createItaniumMangleContext(*this, getDiagnostics());
-  case CXXABI_Microsoft:
+  case TargetCXXABI::Microsoft:
     return createMicrosoftMangleContext(*this, getDiagnostics());
   }
   llvm_unreachable("Unsupported ABI");

Modified: cfe/trunk/lib/AST/RecordLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayout.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayout.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayout.cpp Fri Jan 25 16:30:49 2013
@@ -75,10 +75,9 @@ ASTRecordLayout::ASTRecordLayout(const A
 #ifndef NDEBUG
     if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
       if (isPrimaryBaseVirtual()) {
-        // Microsoft ABI doesn't have primary virtual base
-        if (Ctx.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
-        assert(getVBaseClassOffset(PrimaryBase).isZero() &&
-               "Primary virtual base must be at offset 0!");
+        if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
+          assert(getVBaseClassOffset(PrimaryBase).isZero() &&
+                 "Primary virtual base must be at offset 0!");
         }
       } else {
         assert(getBaseClassOffset(PrimaryBase).isZero() &&

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Fri Jan 25 16:30:49 2013
@@ -676,8 +676,12 @@ protected:
                           bool FieldPacked, const FieldDecl *D);
   void LayoutBitField(const FieldDecl *D);
 
+  TargetCXXABI getCXXABI() const {
+    return Context.getTargetInfo().getCXXABI();
+  }
+
   bool isMicrosoftCXXABI() const {
-    return Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft;
+    return getCXXABI().isMicrosoft();
   }
 
   void MSLayoutVirtualBases(const CXXRecordDecl *RD);
@@ -2606,7 +2610,7 @@ static void DumpCXXRecordLayout(raw_ostr
 
   // Vtable pointer.
   if (RD->isDynamicClass() && !PrimaryBase &&
-      C.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
+      !C.getTargetInfo().getCXXABI().isMicrosoft()) {
     PrintOffset(OS, Offset, IndentLevel);
     OS << '(' << *RD << " vtable pointer)\n";
   }

Modified: cfe/trunk/lib/AST/VTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/VTableBuilder.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/AST/VTableBuilder.cpp (original)
+++ cfe/trunk/lib/AST/VTableBuilder.cpp Fri Jan 25 16:30:49 2013
@@ -2197,7 +2197,8 @@ VTableLayout::~VTableLayout() { }
 
 VTableContext::VTableContext(ASTContext &Context)
   : Context(Context),
-  IsMicrosoftABI(Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft) { }
+    IsMicrosoftABI(Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+}
 
 VTableContext::~VTableContext() {
   llvm::DeleteContainerSeconds(VTableLayouts);

Modified: cfe/trunk/lib/Basic/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/TargetInfo.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/TargetInfo.cpp (original)
+++ cfe/trunk/lib/Basic/TargetInfo.cpp Fri Jan 25 16:30:49 2013
@@ -84,7 +84,7 @@ TargetInfo::TargetInfo(const std::string
   ComplexLongDoubleUsesFP2Ret = false;
 
   // Default to using the Itanium ABI.
-  CXXABI = CXXABI_Itanium;
+  TheCXXABI.set(TargetCXXABI::GenericItanium);
 
   // Default to an empty address space map.
   AddrSpaceMap = &DefaultAddrSpaceMap;
@@ -496,3 +496,17 @@ bool TargetInfo::validateInputConstraint
 
   return true;
 }
+
+bool TargetCXXABI::tryParse(llvm::StringRef name) {
+  const Kind unknown = static_cast<Kind>(-1);
+  Kind kind = llvm::StringSwitch<Kind>(name)
+    .Case("arm", GenericARM)
+    .Case("ios", iOS)
+    .Case("itanium", GenericItanium)
+    .Case("microsoft", Microsoft)
+    .Default(unknown);
+  if (kind == unknown) return false;
+
+  set(kind);
+  return true;
+}

Modified: cfe/trunk/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Targets.cpp (original)
+++ cfe/trunk/lib/Basic/Targets.cpp Fri Jan 25 16:30:49 2013
@@ -3081,7 +3081,7 @@ public:
     }
 
     // ARM targets default to using the ARM C++ ABI.
-    CXXABI = CXXABI_ARM;
+    TheCXXABI.set(TargetCXXABI::GenericARM);
 
     // ARM has atomics up to 8 bytes
     // FIXME: Set MaxAtomicInlineWidth if we have the feature v6e
@@ -3491,6 +3491,9 @@ public:
     // iOS always has 64-bit atomic instructions.
     // FIXME: This should be based off of the target features in ARMTargetInfo.
     MaxAtomicInlineWidth = 64;
+
+    // Darwin on iOS uses a variant of the ARM C++ ABI.
+    TheCXXABI.set(TargetCXXABI::iOS);
   }
 };
 } // end anonymous namespace.

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Fri Jan 25 16:30:49 2013
@@ -721,7 +721,7 @@ void CodeGenFunction::EmitConstructorBod
   // Before we go any further, try the complete->base constructor
   // delegation optimization.
   if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) &&
-      CGM.getContext().getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
+      CGM.getContext().getTargetInfo().getCXXABI().hasConstructorVariants()) {
     if (CGDebugInfo *DI = getDebugInfo()) 
       DI->EmitLocation(Builder, Ctor->getLocEnd());
     EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args);
@@ -920,7 +920,8 @@ void CodeGenFunction::EmitDestructorBody
     // Enter the cleanup scopes for virtual bases.
     EnterDtorCleanups(Dtor, Dtor_Complete);
 
-    if (!isTryBody && CGM.getContext().getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
+    if (!isTryBody &&
+        CGM.getContext().getTargetInfo().getCXXABI().hasDestructorVariants()) {
       EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false,
                             LoadCXXThis());
       break;

Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Fri Jan 25 16:30:49 2013
@@ -814,7 +814,7 @@ bool CGRecordLayoutBuilder::LayoutFields
 
     // Lay out the virtual bases.  The MS ABI uses a different
     // algorithm here due to the lack of primary virtual bases.
-    if (Types.getContext().getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
+    if (Types.getContext().getTargetInfo().getCXXABI().hasPrimaryVBases()) {
       RD->getIndirectPrimaryBases(IndirectPrimaryBases);
       if (Layout.isPrimaryBaseVirtual())
         IndirectPrimaryBases.insert(Layout.getPrimaryBase());

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Jan 25 16:30:49 2013
@@ -52,10 +52,13 @@ using namespace CodeGen;
 static const char AnnotationSection[] = "llvm.metadata";
 
 static CGCXXABI &createCXXABI(CodeGenModule &CGM) {
-  switch (CGM.getContext().getTargetInfo().getCXXABI()) {
-  case CXXABI_ARM: return *CreateARMCXXABI(CGM);
-  case CXXABI_Itanium: return *CreateItaniumCXXABI(CGM);
-  case CXXABI_Microsoft: return *CreateMicrosoftCXXABI(CGM);
+  switch (CGM.getContext().getTargetInfo().getCXXABI().getKind()) {
+  // For IR-generation purposes, there's no significant difference
+  // between the ARM and iOS ABIs.
+  case TargetCXXABI::GenericARM: return *CreateARMCXXABI(CGM);
+  case TargetCXXABI::iOS: return *CreateARMCXXABI(CGM);
+  case TargetCXXABI::GenericItanium: return *CreateItaniumCXXABI(CGM);
+  case TargetCXXABI::Microsoft: return *CreateMicrosoftCXXABI(CGM);
   }
 
   llvm_unreachable("invalid C++ ABI kind");

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=173514&r1=173513&r2=173514&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Jan 25 16:30:49 2013
@@ -1667,11 +1667,16 @@ QualType Sema::BuildMemberPointerType(Qu
     return QualType();
   }
 
-  // In the Microsoft ABI, the class is allowed to be an incomplete
-  // type. In such cases, the compiler makes a worst-case assumption.
-  // We make no such assumption right now, so emit an error if the
-  // class isn't a complete type.
-  if (Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft &&
+  // C++ allows the class type in a member pointer to be an incomplete type.
+  // In the Microsoft ABI, the size of the member pointer can vary
+  // according to the class type, which means that we really need a
+  // complete type if possible, which means we need to instantiate templates.
+  //
+  // For now, just require a complete type, which will instantiate
+  // templates.  This will also error if the type is just forward-declared,
+  // which is a bug, but it's a bug that saves us from dealing with some
+  // complexities at the moment.
+  if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
       RequireCompleteType(Loc, Class, diag::err_incomplete_type))
     return QualType();
 





More information about the cfe-commits mailing list