<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 8, 2016 at 4:08 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Thu, Jan 7, 2016 at 6:00 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Fri, Dec 18, 2015 at 2:40 PM, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: rsmith<br>
Date: Fri Dec 18 16:40:25 2015<br>
New Revision: 256049<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=256049&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=256049&view=rev</a><br>
Log:<br>
Split RequireCompleteType into a function that actually requires that the type<br>
is complete (with an error produced if not) and a function that merely queries<br>
whether the type is complete. Either way we'll trigger instantiation if<br>
necessary, but only the former will diagnose and recover from missing module<br>
imports.<br>
<br>
The intent of this change is to prevent a class of bugs where code would call<br>
RequireCompleteType(..., 0) and then ignore the result. With modules, we must<br>
check the return value and use it to determine whether the definition of the<br>
type is visible.<br>
<br>
This also fixes a debug info quality issue: calls to isCompleteType do not<br>
trigger the emission of debug information for a type in limited-debug-info<br>
mode. This allows us to avoid emitting debug information for type definitions<br>
in more cases where we believe it is safe to do so.<br></blockquote><div><br></div></span><div>Thanks for mentioning - I was wondering if that was the case.<br><br>Do you have a canonical example where we previously required the type to be complete, but we now only query it?</div></div></div></div></blockquote><div><br></div></span><div>The example in <span style="font-size:12.8px">test/CodeGenCXX/</span><span style="font-size:12.8px">debug-info-limited.cpp is probably as good as any. I regressed that one a while back while fixing an ADL bug and it's now doing the right thing again.</span></div></div></div></div></blockquote><div><br></div><div>Oh, I remember that one now. Awesome - thanks! </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Modified:<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/Sema/SemaCast.cpp<br>
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaExprObjC.cpp<br>
    cfe/trunk/lib/Sema/SemaInit.cpp<br>
    cfe/trunk/lib/Sema/SemaLookup.cpp<br>
    cfe/trunk/lib/Sema/SemaOverload.cpp<br>
    cfe/trunk/lib/Sema/SemaStmt.cpp<br>
    cfe/trunk/lib/Sema/SemaStmtAsm.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp<br>
    cfe/trunk/lib/Sema/SemaType.cpp<br>
    cfe/trunk/test/CodeGenCXX/debug-info-limited.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Dec 18 16:40:25 2015<br>
@@ -1316,9 +1316,7 @@ public:<br>
<br>
   /// \brief Abstract class used to diagnose incomplete types.<br>
   struct TypeDiagnoser {<br>
-    bool Suppressed;<br>
-<br>
-    TypeDiagnoser(bool Suppressed = false) : Suppressed(Suppressed) { }<br>
+    TypeDiagnoser() {}<br>
<br>
     virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0;<br>
     virtual ~TypeDiagnoser() {}<br>
@@ -1354,11 +1352,11 @@ public:<br>
<br>
   public:<br>
     BoundTypeDiagnoser(unsigned DiagID, const Ts &...Args)<br>
-        : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Args(Args...) {}<br>
+        : TypeDiagnoser(), DiagID(DiagID), Args(Args...) {<br>
+      assert(DiagID != 0 && "no diagnostic for type diagnoser");<br>
+    }<br>
<br>
     void diagnose(Sema &S, SourceLocation Loc, QualType T) override {<br>
-      if (Suppressed)<br>
-        return;<br>
       const SemaDiagnosticBuilder &DB = S.Diag(Loc, DiagID);<br>
       emit(DB, llvm::index_sequence_for<Ts...>());<br>
       DB << T;<br>
@@ -1367,7 +1365,7 @@ public:<br>
<br>
 private:<br>
   bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,<br>
-                           TypeDiagnoser &Diagnoser);<br>
+                               TypeDiagnoser *Diagnoser);<br>
<br>
   VisibleModuleSet VisibleModules;<br>
   llvm::SmallVector<VisibleModuleSet, 16> VisibleModulesStack;<br>
@@ -1413,6 +1411,9 @@ public:<br>
       SourceLocation Loc, const NamedDecl *D,<br>
       ArrayRef<const NamedDecl *> Equiv);<br>
<br>
+  bool isCompleteType(SourceLocation Loc, QualType T) {<br>
+    return !RequireCompleteTypeImpl(Loc, T, nullptr);<br>
+  }<br>
   bool RequireCompleteType(SourceLocation Loc, QualType T,<br>
                            TypeDiagnoser &Diagnoser);<br>
   bool RequireCompleteType(SourceLocation Loc, QualType T,<br>
@@ -5502,6 +5503,7 @@ public:<br>
     AbstractArrayType<br>
   };<br>
<br>
+  bool isAbstractType(SourceLocation Loc, QualType T);<br>
   bool RequireNonAbstractType(SourceLocation Loc, QualType T,<br>
                               TypeDiagnoser &Diagnoser);<br>
   template <typename... Ts><br>
@@ -5513,9 +5515,6 @@ public:<br>
<br>
   void DiagnoseAbstractType(const CXXRecordDecl *RD);<br>
<br>
-  bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID,<br>
-                              AbstractDiagSelID SelID = AbstractNone);<br>
-<br>
   //===--------------------------------------------------------------------===//<br>
   // C++ Overloaded Operators [C++ 13.5]<br>
   //<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaCast.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaCast.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaCast.cpp Fri Dec 18 16:40:25 2015<br>
@@ -1262,8 +1262,8 @@ TryStaticDowncast(Sema &Self, CanQualTyp<br>
                   QualType OrigDestType, unsigned &msg,<br>
                   CastKind &Kind, CXXCastPath &BasePath) {<br>
   // We can only work with complete types. But don't complain if it doesn't work<br>
-  if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, 0) ||<br>
-      Self.RequireCompleteType(OpRange.getBegin(), DestType, 0))<br>
+  if (!Self.isCompleteType(OpRange.getBegin(), SrcType) ||<br>
+      !Self.isCompleteType(OpRange.getBegin(), DestType))<br>
     return TC_NotApplicable;<br>
<br>
   // Downcast can only happen in class hierarchies, so we need classes.<br>
@@ -1399,8 +1399,11 @@ TryStaticMemberPointerUpcast(Sema &Self,<br>
     msg = diag::err_bad_static_cast_member_pointer_nonmp;<br>
     return TC_NotApplicable;<br>
   }<br>
+<br>
+  // Lock down the inheritance model right now in MS ABI, whether or not the<br>
+  // pointee types are the same.<br>
   if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft())<br>
-    Self.RequireCompleteType(OpRange.getBegin(), SrcType, 0);<br>
+    (void)Self.isCompleteType(OpRange.getBegin(), SrcType);<br>
<br>
   // T == T, modulo cv<br>
   if (!Self.Context.hasSameUnqualifiedType(SrcMemPtr->getPointeeType(),<br>
@@ -1844,8 +1847,8 @@ static TryCastResult TryReinterpretCast(<br>
     if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {<br>
       // We need to determine the inheritance model that the class will use if<br>
       // haven't yet.<br>
-      Self.RequireCompleteType(OpRange.getBegin(), SrcType, 0);<br>
-      Self.RequireCompleteType(OpRange.getBegin(), DestType, 0);<br>
+      (void)Self.isCompleteType(OpRange.getBegin(), SrcType);<br>
+      (void)Self.isCompleteType(OpRange.getBegin(), DestType);<br>
     }<br>
<br>
     // Don't allow casting between member pointers of different sizes.<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Fri Dec 18 16:40:25 2015<br>
@@ -4052,7 +4052,7 @@ void Sema::CodeCompleteCall(Scope *S, Ex<br>
       // If expression's type is CXXRecordDecl, it may overload the function<br>
       // call operator, so we check if it does and add them as candidates.<br>
       // A complete type is needed to lookup for member function call operators.<br>
-      if (!RequireCompleteType(Loc, NakedFn->getType(), 0)) {<br>
+      if (isCompleteType(Loc, NakedFn->getType())) {<br>
         DeclarationName OpName = Context.DeclarationNames<br>
                                  .getCXXOperatorName(OO_Call);<br>
         LookupResult R(*this, OpName, Loc, LookupOrdinaryName);<br>
@@ -4094,7 +4094,7 @@ void Sema::CodeCompleteConstructor(Scope<br>
     return;<br>
<br>
   // A complete type is needed to lookup for constructors.<br>
-  if (RequireCompleteType(Loc, Type, 0))<br>
+  if (!isCompleteType(Loc, Type))<br>
     return;<br>
<br>
   CXXRecordDecl *RD = Type->getAsCXXRecordDecl();<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Dec 18 16:40:25 2015<br>
@@ -1673,11 +1673,6 @@ bool Sema::IsDerivedFrom(SourceLocation<br>
   if (!DerivedRD)<br>
     return false;<br>
<br>
-  // FIXME: In a modules build, do we need the entire path to be visible for us<br>
-  // to be able to use the inheritance relationship?<br>
-  if (RequireCompleteType(Loc, Derived, 0) && !DerivedRD->isBeingDefined())<br>
-    return false;<br>
-<br>
   CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl();<br>
   if (!BaseRD)<br>
     return false;<br>
@@ -1687,6 +1682,11 @@ bool Sema::IsDerivedFrom(SourceLocation<br>
   if (BaseRD->isInvalidDecl() || DerivedRD->isInvalidDecl())<br>
     return false;<br>
<br>
+  // FIXME: In a modules build, do we need the entire path to be visible for us<br>
+  // to be able to use the inheritance relationship?<br>
+  if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined())<br>
+    return false;<br>
+<br>
   return DerivedRD->isDerivedFrom(BaseRD);<br>
 }<br>
<br>
@@ -1701,13 +1701,13 @@ bool Sema::IsDerivedFrom(SourceLocation<br>
   if (!DerivedRD)<br>
     return false;<br>
<br>
-  if (RequireCompleteType(Loc, Derived, 0) && !DerivedRD->isBeingDefined())<br>
-    return false;<br>
-<br>
   CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl();<br>
   if (!BaseRD)<br>
     return false;<br>
<br>
+  if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined())<br>
+    return false;<br>
+<br>
   return DerivedRD->isDerivedFrom(BaseRD, Paths);<br>
 }<br>
<br>
@@ -4420,64 +4420,35 @@ void Sema::ActOnDefaultCtorInitializers(<br>
   }<br>
 }<br>
<br>
-bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,<br>
-                                  unsigned DiagID, AbstractDiagSelID SelID) {<br>
-  class NonAbstractTypeDiagnoser : public TypeDiagnoser {<br>
-    unsigned DiagID;<br>
-    AbstractDiagSelID SelID;<br>
-<br>
-  public:<br>
-    NonAbstractTypeDiagnoser(unsigned DiagID, AbstractDiagSelID SelID)<br>
-      : TypeDiagnoser(DiagID == 0), DiagID(DiagID), SelID(SelID) { }<br>
-<br>
-    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {<br>
-      if (Suppressed) return;<br>
-      if (SelID == -1)<br>
-        S.Diag(Loc, DiagID) << T;<br>
-      else<br>
-        S.Diag(Loc, DiagID) << SelID << T;<br>
-    }<br>
-  } Diagnoser(DiagID, SelID);<br>
-<br>
-  return RequireNonAbstractType(Loc, T, Diagnoser);<br>
-}<br>
-<br>
-bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,<br>
-                                  TypeDiagnoser &Diagnoser) {<br>
+bool Sema::isAbstractType(SourceLocation Loc, QualType T) {<br>
   if (!getLangOpts().CPlusPlus)<br>
     return false;<br>
<br>
-  if (const ArrayType *AT = Context.getAsArrayType(T))<br>
-    return RequireNonAbstractType(Loc, AT->getElementType(), Diagnoser);<br>
-<br>
-  if (const PointerType *PT = T->getAs<PointerType>()) {<br>
-    // Find the innermost pointer type.<br>
-    while (const PointerType *T = PT->getPointeeType()->getAs<PointerType>())<br>
-      PT = T;<br>
-<br>
-    if (const ArrayType *AT = Context.getAsArrayType(PT->getPointeeType()))<br>
-      return RequireNonAbstractType(Loc, AT->getElementType(), Diagnoser);<br>
-  }<br>
-<br>
-  const RecordType *RT = T->getAs<RecordType>();<br>
-  if (!RT)<br>
+  const auto *RD = Context.getBaseElementType(T)->getAsCXXRecordDecl();<br>
+  if (!RD)<br>
     return false;<br>
<br>
-  const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());<br>
+  // FIXME: Per [temp.inst]p1, we are supposed to trigger instantiation of a<br>
+  // class template specialization here, but doing so breaks a lot of code.<br>
<br>
   // We can't answer whether something is abstract until it has a<br>
-  // definition.  If it's currently being defined, we'll walk back<br>
+  // definition. If it's currently being defined, we'll walk back<br>
   // over all the declarations when we have a full definition.<br>
   const CXXRecordDecl *Def = RD->getDefinition();<br>
   if (!Def || Def->isBeingDefined())<br>
     return false;<br>
<br>
-  if (!RD->isAbstract())<br>
+  return RD->isAbstract();<br>
+}<br>
+<br>
+bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,<br>
+                                  TypeDiagnoser &Diagnoser) {<br>
+  if (!isAbstractType(Loc, T))<br>
     return false;<br>
<br>
+  T = Context.getBaseElementType(T);<br>
   Diagnoser.diagnose(*this, Loc, T);<br>
-  DiagnoseAbstractType(RD);<br>
-<br>
+  DiagnoseAbstractType(T->getAsCXXRecordDecl());<br>
   return true;<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri Dec 18 16:40:25 2015<br>
@@ -1867,6 +1867,8 @@ Decl *Sema::ActOnStartClassImplementatio<br>
     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;<br>
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);<br>
   } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {<br>
+    // FIXME: This will produce an error if the definition of the interface has<br>
+    // been imported from a module but is not visible.<br>
     RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),<br>
                         diag::warn_undef_interface);<br>
   } else {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Dec 18 16:40:25 2015<br>
@@ -686,9 +686,10 @@ ExprResult Sema::DefaultLvalueConversion<br>
   if (T.hasQualifiers())<br>
     T = T.getUnqualifiedType();<br>
<br>
+  // Under the MS ABI, lock down the inheritance model now.<br>
   if (T->isMemberPointerType() &&<br>
       Context.getTargetInfo().getCXXABI().isMicrosoft())<br>
-    RequireCompleteType(E->getExprLoc(), T, 0);<br>
+    (void)isCompleteType(E->getExprLoc(), T);<br>
<br>
   UpdateMarkingForLValueToRValue(E);<br>
<br>
@@ -9947,8 +9948,9 @@ QualType Sema::CheckAddressOfOperand(Exp<br>
<br>
     QualType MPTy = Context.getMemberPointerType(<br>
         op->getType(), Context.getTypeDeclType(MD->getParent()).getTypePtr());<br>
+    // Under the MS ABI, lock down the inheritance model now.<br>
     if (Context.getTargetInfo().getCXXABI().isMicrosoft())<br>
-      RequireCompleteType(OpLoc, MPTy, 0);<br>
+      (void)isCompleteType(OpLoc, MPTy);<br>
     return MPTy;<br>
   } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {<br>
     // C99 6.5.3.2p1<br>
@@ -10003,8 +10005,9 @@ QualType Sema::CheckAddressOfOperand(Exp<br>
           QualType MPTy = Context.getMemberPointerType(<br>
               op->getType(),<br>
               Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr());<br>
+          // Under the MS ABI, lock down the inheritance model now.<br>
           if (Context.getTargetInfo().getCXXABI().isMicrosoft())<br>
-            RequireCompleteType(OpLoc, MPTy, 0);<br>
+            (void)isCompleteType(OpLoc, MPTy);<br>
           return MPTy;<br>
         }<br>
       }<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Dec 18 16:40:25 2015<br>
@@ -2717,6 +2717,8 @@ Sema::ActOnCXXDelete(SourceLocation Star<br>
       return ExprError(Diag(StartLoc, diag::err_delete_operand)<br>
         << Type << Ex.get()->getSourceRange());<br>
     } else if (!Pointee->isDependentType()) {<br>
+      // FIXME: This can result in errors if the definition was imported from a<br>
+      // module but is hidden.<br>
       if (!RequireCompleteType(StartLoc, Pointee,<br>
                                diag::warn_delete_incomplete, Ex.get())) {<br>
         if (const RecordType *RT = PointeeElem->getAs<RecordType>())<br>
@@ -2792,7 +2794,7 @@ Sema::ActOnCXXDelete(SourceLocation Star<br>
     if (!OperatorDelete)<br>
       // Look for a global declaration.<br>
       OperatorDelete = FindUsualDeallocationFunction(<br>
-          StartLoc, !RequireCompleteType(StartLoc, Pointee, 0) &&<br>
+          StartLoc, isCompleteType(StartLoc, Pointee) &&<br>
                     (!ArrayForm || UsualArrayDeleteWantsSize ||<br>
                      Pointee.isDestructedType()),<br>
           DeleteName);<br>
@@ -3309,8 +3311,8 @@ Sema::PerformImplicitConversion(Expr *Fr<br>
     // We may not have been able to figure out what this member pointer resolved<br>
     // to up until this exact point.  Attempt to lock-in it's inheritance model.<br>
     if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {<br>
-      RequireCompleteType(From->getExprLoc(), From->getType(), 0);<br>
-      RequireCompleteType(From->getExprLoc(), ToType, 0);<br>
+      (void)isCompleteType(From->getExprLoc(), From->getType());<br>
+      (void)isCompleteType(From->getExprLoc(), ToType);<br>
     }<br>
<br>
     From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)<br>
@@ -4291,8 +4293,7 @@ static bool EvaluateBinaryTypeTrait(Sema<br>
       return LhsT->isVoidType();<br>
<br>
     // A function definition requires a complete, non-abstract return type.<br>
-    if (Self.RequireCompleteType(KeyLoc, RhsT, 0) ||<br>
-        Self.RequireNonAbstractType(KeyLoc, RhsT, 0))<br>
+    if (!Self.isCompleteType(KeyLoc, RhsT) || Self.isAbstractType(KeyLoc, RhsT))<br>
       return false;<br>
<br>
     // Compute the result of add_rvalue_reference.<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Dec 18 16:40:25 2015<br>
@@ -2726,6 +2726,8 @@ ExprResult Sema::BuildInstanceMessage(Ex<br>
<br>
         // Try to complete the type. Under ARC, this is a hard error from which<br>
         // we don't try to recover.<br>
+        // FIXME: In the non-ARC case, this will still be a hard error if the<br>
+        // definition is found in a module that's not visible.<br>
         const ObjCInterfaceDecl *forwardClass = nullptr;<br>
         if (RequireCompleteType(Loc, OCIType->getPointeeType(),<br>
               getLangOpts().ObjCAutoRefCount<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Dec 18 16:40:25 2015<br>
@@ -3328,7 +3328,7 @@ static bool TryInitializerListConstructi<br>
   if (!S.isStdInitializerList(DestType, &E))<br>
     return false;<br>
<br>
-  if (S.RequireCompleteType(List->getExprLoc(), E, 0)) {<br>
+  if (!S.isCompleteType(List->getExprLoc(), E)) {<br>
     Sequence.setIncompleteTypeFailure(E);<br>
     return true;<br>
   }<br>
@@ -3438,7 +3438,7 @@ static void TryConstructorInitialization<br>
          "IsListInit must come with a single initializer list argument.");<br>
<br>
   // The type we're constructing needs to be complete.<br>
-  if (S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {<br>
+  if (!S.isCompleteType(Kind.getLocation(), DestType)) {<br>
     Sequence.setIncompleteTypeFailure(DestType);<br>
     return;<br>
   }<br>
@@ -3679,7 +3679,7 @@ static void TryListInitialization(Sema &<br>
   }<br>
<br>
   if (DestType->isRecordType() &&<br>
-      S.RequireCompleteType(InitList->getLocStart(), DestType, 0)) {<br>
+      !S.isCompleteType(InitList->getLocStart(), DestType)) {<br>
     Sequence.setIncompleteTypeFailure(DestType);<br>
     return;<br>
   }<br>
@@ -3841,7 +3841,7 @@ static OverloadingResult TryRefInitWithC<br>
<br>
   const RecordType *T1RecordType = nullptr;<br>
   if (AllowRValues && (T1RecordType = T1->getAs<RecordType>()) &&<br>
-      !S.RequireCompleteType(Kind.getLocation(), T1, 0)) {<br>
+      S.isCompleteType(Kind.getLocation(), T1)) {<br>
     // The type we're converting to is a class type. Enumerate its constructors<br>
     // to see if there is a suitable conversion.<br>
     CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl());<br>
@@ -3877,7 +3877,7 @@ static OverloadingResult TryRefInitWithC<br>
<br>
   const RecordType *T2RecordType = nullptr;<br>
   if ((T2RecordType = T2->getAs<RecordType>()) &&<br>
-      !S.RequireCompleteType(Kind.getLocation(), T2, 0)) {<br>
+      S.isCompleteType(Kind.getLocation(), T2)) {<br>
     // The type we're converting from is a class type, enumerate its conversion<br>
     // functions.<br>
     CXXRecordDecl *T2RecordDecl = cast<CXXRecordDecl>(T2RecordType->getDecl());<br>
@@ -4462,7 +4462,7 @@ static void TryUserDefinedConversion(Sem<br>
       = cast<CXXRecordDecl>(DestRecordType->getDecl());<br>
<br>
     // Try to complete the type we're converting to.<br>
-    if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {<br>
+    if (S.isCompleteType(Kind.getLocation(), DestType)) {<br>
       DeclContext::lookup_result R = S.LookupConstructors(DestRecordDecl);<br>
       // The container holding the constructors can under certain conditions<br>
       // be changed while iterating. To be safe we copy the lookup results<br>
@@ -4508,7 +4508,7 @@ static void TryUserDefinedConversion(Sem<br>
<br>
     // We can only enumerate the conversion functions for a complete type; if<br>
     // the type isn't complete, simply skip this step.<br>
-    if (!S.RequireCompleteType(DeclLoc, SourceType, 0)) {<br>
+    if (S.isCompleteType(DeclLoc, SourceType)) {<br>
       CXXRecordDecl *SourceRecordDecl<br>
         = cast<CXXRecordDecl>(SourceRecordType->getDecl());<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Dec 18 16:40:25 2015<br>
@@ -2428,8 +2428,8 @@ addAssociatedClassesAndNamespaces(Associ<br>
   }<br>
<br>
   // Only recurse into base classes for complete types.<br>
-  if (Result.S.RequireCompleteType(Result.InstantiationLoc,<br>
-                                   Result.S.Context.getRecordType(Class), 0))<br>
+  if (!Result.S.isCompleteType(Result.InstantiationLoc,<br>
+                               Result.S.Context.getRecordType(Class)))<br>
     return;<br>
<br>
   // Add direct and indirect base classes along with their associated<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Dec 18 16:40:25 2015<br>
@@ -1822,7 +1822,7 @@ bool Sema::IsIntegralPromotion(Expr *Fro<br>
<br>
     // We have already pre-calculated the promotion type, so this is trivial.<br>
     if (ToType->isIntegerType() &&<br>
-        !RequireCompleteType(From->getLocStart(), FromType, 0))<br>
+        isCompleteType(From->getLocStart(), FromType))<br>
       return Context.hasSameUnqualifiedType(<br>
           ToType, FromEnumType->getDecl()->getPromotionType());<br>
   }<br>
@@ -3085,7 +3085,7 @@ IsUserDefinedConversion(Sema &S, Expr *F<br>
          S.IsDerivedFrom(From->getLocStart(), From->getType(), ToType)))<br>
       ConstructorsOnly = true;<br>
<br>
-    if (S.RequireCompleteType(From->getExprLoc(), ToType, 0)) {<br>
+    if (!S.isCompleteType(From->getExprLoc(), ToType)) {<br>
       // We're not going to find any constructors.<br>
     } else if (CXXRecordDecl *ToRecordDecl<br>
                  = dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {<br>
@@ -3159,7 +3159,7 @@ IsUserDefinedConversion(Sema &S, Expr *F<br>
<br>
   // Enumerate conversion functions, if we're allowed to.<br>
   if (ConstructorsOnly || isa<InitListExpr>(From)) {<br>
-  } else if (S.RequireCompleteType(From->getLocStart(), From->getType(), 0)) {<br>
+  } else if (!S.isCompleteType(From->getLocStart(), From->getType())) {<br>
     // No conversion functions from incomplete types.<br>
   } else if (const RecordType *FromRecordType<br>
                                    = From->getType()->getAs<RecordType>()) {<br>
@@ -4047,7 +4047,7 @@ Sema::CompareReferenceRelationship(Sourc<br>
   ObjCLifetimeConversion = false;<br>
   if (UnqualT1 == UnqualT2) {<br>
     // Nothing to do.<br>
-  } else if (!RequireCompleteType(Loc, OrigT2, 0) &&<br>
+  } else if (isCompleteType(Loc, OrigT2) &&<br>
              isTypeValid(UnqualT1) && isTypeValid(UnqualT2) &&<br>
              IsDerivedFrom(Loc, UnqualT2, UnqualT1))<br>
     DerivedToBase = true;<br>
@@ -4314,7 +4314,7 @@ TryReferenceInit(Sema &S, Expr *Init, Qu<br>
     //          conversion functions (13.3.1.6) and choosing the best<br>
     //          one through overload resolution (13.3)),<br>
     if (!SuppressUserConversions && T2->isRecordType() &&<br>
-        !S.RequireCompleteType(DeclLoc, T2, 0) &&<br>
+        S.isCompleteType(DeclLoc, T2) &&<br>
         RefRelationship == Sema::Ref_Incompatible) {<br>
       if (FindConversionForRefInit(S, ICS, DeclType, DeclLoc,<br>
                                    Init, T2, /*AllowRvalues=*/false,<br>
@@ -4377,7 +4377,7 @@ TryReferenceInit(Sema &S, Expr *Init, Qu<br>
   //          in the second case (or, in either case, to an appropriate base<br>
   //          class subobject).<br>
   if (!SuppressUserConversions && RefRelationship == Sema::Ref_Incompatible &&<br>
-      T2->isRecordType() && !S.RequireCompleteType(DeclLoc, T2, 0) &&<br>
+      T2->isRecordType() && S.isCompleteType(DeclLoc, T2) &&<br>
       FindConversionForRefInit(S, ICS, DeclType, DeclLoc,<br>
                                Init, T2, /*AllowRvalues=*/true,<br>
                                AllowExplicit)) {<br>
@@ -4515,7 +4515,7 @@ TryListConversion(Sema &S, InitListExpr<br>
<br>
   // We need a complete type for what follows. Incomplete types can never be<br>
   // initialized from init lists.<br>
-  if (S.RequireCompleteType(From->getLocStart(), ToType, 0))<br>
+  if (!S.isCompleteType(From->getLocStart(), ToType))<br>
     return Result;<br>
<br>
   // Per DR1467:<br>
@@ -5449,14 +5449,15 @@ ExprResult Sema::PerformContextualImplic<br>
     Expr *From;<br>
<br>
     TypeDiagnoserPartialDiag(ContextualImplicitConverter &Converter, Expr *From)<br>
-        : TypeDiagnoser(Converter.Suppress), Converter(Converter), From(From) {}<br>
+        : Converter(Converter), From(From) {}<br>
<br>
     void diagnose(Sema &S, SourceLocation Loc, QualType T) override {<br>
       Converter.diagnoseIncomplete(S, Loc, T) << From->getSourceRange();<br>
     }<br>
   } IncompleteDiagnoser(Converter, From);<br>
<br>
-  if (RequireCompleteType(Loc, T, IncompleteDiagnoser))<br>
+  if (Converter.Suppress ? !isCompleteType(Loc, T)<br>
+                         : RequireCompleteType(Loc, T, IncompleteDiagnoser))<br>
     return From;<br>
<br>
   // Look for a conversion to an integral or enumeration type.<br>
@@ -6432,7 +6433,7 @@ Sema::AddConversionCandidate(CXXConversi<br>
                                 &ConversionRef, VK_RValue);<br>
<br>
   QualType ConversionType = Conversion->getConversionType();<br>
-  if (RequireCompleteType(From->getLocStart(), ConversionType, 0)) {<br>
+  if (!isCompleteType(From->getLocStart(), ConversionType)) {<br>
     Candidate.Viable = false;<br>
     Candidate.FailureKind = ovl_fail_bad_final_conversion;<br>
     return;<br>
@@ -6681,7 +6682,7 @@ void Sema::AddMemberOperatorCandidates(O<br>
   //        the set of member candidates is empty.<br>
   if (const RecordType *T1Rec = T1->getAs<RecordType>()) {<br>
     // Complete the type if it can be completed.<br>
-    if (RequireCompleteType(OpLoc, T1, 0) && !T1Rec->isBeingDefined())<br>
+    if (!isCompleteType(OpLoc, T1) && !T1Rec->isBeingDefined())<br>
       return;<br>
     // If the type is neither complete nor being defined, bail out now.<br>
     if (!T1Rec->getDecl()->getDefinition())<br>
@@ -7031,7 +7032,7 @@ BuiltinCandidateTypeSet::AddTypesConvert<br>
     HasNullPtrType = true;<br>
   } else if (AllowUserConversions && TyRec) {<br>
     // No conversion functions in incomplete types.<br>
-    if (SemaRef.RequireCompleteType(Loc, Ty, 0))<br>
+    if (!SemaRef.isCompleteType(Loc, Ty))<br>
       return;<br>
<br>
     CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri Dec 18 16:40:25 2015<br>
@@ -1706,11 +1706,10 @@ Sema::CheckObjCForCollectionOperand(Sour<br>
   // If we have a forward-declared type, we can't do this check.<br>
   // Under ARC, it is an error not to have a forward-declared class.<br>
   if (iface &&<br>
-      RequireCompleteType(forLoc, QualType(objectType, 0),<br>
-                          getLangOpts().ObjCAutoRefCount<br>
-                            ? diag::err_arc_collection_forward<br>
-                            : 0,<br>
-                          collection)) {<br>
+      (getLangOpts().ObjCAutoRefCount<br>
+           ? RequireCompleteType(forLoc, QualType(objectType, 0),<br>
+                                 diag::err_arc_collection_forward, collection)<br>
+           : !isCompleteType(forLoc, QualType(objectType, 0)))) {<br>
     // Otherwise, if we have any useful type information, check that<br>
     // the type declares the appropriate method.<br>
   } else if (iface || !objectType->qual_empty()) {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaStmtAsm.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAsm.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAsm.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmtAsm.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmtAsm.cpp Fri Dec 18 16:40:25 2015<br>
@@ -647,7 +647,8 @@ bool Sema::LookupInlineAsmField(StringRe<br>
     if (!RT)<br>
       return true;<br>
<br>
-    if (RequireCompleteType(AsmLoc, QualType(RT, 0), 0))<br>
+    if (RequireCompleteType(AsmLoc, QualType(RT, 0),<br>
+                            diag::err_asm_incomplete_type))<br>
       return true;<br>
<br>
     LookupResult FieldResult(*this, &Context.Idents.get(NextMember),<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Dec 18 16:40:25 2015<br>
@@ -4282,7 +4282,7 @@ isNullPointerValueTemplateArgument(Sema<br>
   if (Arg->isValueDependent() || Arg->isTypeDependent())<br>
     return NPV_NotNullPointer;<br>
<br>
-  if (S.RequireCompleteType(Arg->getExprLoc(), ParamType, 0))<br>
+  if (!S.isCompleteType(Arg->getExprLoc(), ParamType))<br>
     llvm_unreachable(<br>
         "Incomplete parameter type in isNullPointerValueTemplateArgument!");<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Fri Dec 18 16:40:25 2015<br>
@@ -1440,7 +1440,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema<br>
           // We cannot inspect base classes as part of deduction when the type<br>
           // is incomplete, so either instantiate any templates necessary to<br>
           // complete the type, or skip over it if it cannot be completed.<br>
-          if (S.RequireCompleteType(Info.getLocation(), Arg, 0))<br>
+          if (!S.isCompleteType(Info.getLocation(), Arg))<br>
             return Result;<br>
<br>
           // Use data recursion to crawl through the list of base classes.<br>
@@ -3132,8 +3132,10 @@ static bool AdjustFunctionParmAndArgType<br>
<br>
   if (ParamRefType) {<br>
     // If the argument has incomplete array type, try to complete its type.<br>
-    if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0))<br>
+    if (ArgType->isIncompleteArrayType()) {<br>
+      S.completeExprArrayBound(Arg);<br>
       ArgType = Arg->getType();<br>
+    }<br>
<br>
     // C++0x [temp.deduct.call]p3:<br>
     //   If P is an rvalue reference to a cv-unqualified template<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaType.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaType.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Dec 18 16:40:25 2015<br>
@@ -1998,7 +1998,7 @@ QualType Sema::BuildArrayType(QualType T<br>
     if (Context.getTargetInfo().getCXXABI().isMicrosoft())<br>
       if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())<br>
         if (!MPTy->getClass()->isDependentType())<br>
-          RequireCompleteType(Loc, T, 0);<br>
+          (void)isCompleteType(Loc, T);<br>
<br>
   } else {<br>
     // C99 6.7.5.2p1: If the element type is an incomplete or function type,<br>
@@ -2126,12 +2126,9 @@ QualType Sema::BuildArrayType(QualType T<br>
     if (T->isVariableArrayType()) {<br>
       // Prohibit the use of non-POD types in VLAs.<br>
       QualType BaseT = Context.getBaseElementType(T);<br>
-      if (!T->isDependentType() &&<br>
-          !RequireCompleteType(Loc, BaseT, 0) &&<br>
-          !BaseT.isPODType(Context) &&<br>
-          !BaseT->isObjCLifetimeType()) {<br>
-        Diag(Loc, diag::err_vla_non_pod)<br>
-          << BaseT;<br>
+      if (!T->isDependentType() && isCompleteType(Loc, BaseT) &&<br>
+          !BaseT.isPODType(Context) && !BaseT->isObjCLifetimeType()) {<br>
+        Diag(Loc, diag::err_vla_non_pod) << BaseT;<br>
         return QualType();<br>
       }<br>
       // Prohibit the use of VLAs during template argument deduction.<br>
@@ -6466,7 +6463,7 @@ bool Sema::RequireCompleteExprType(Expr<br>
 /// @c false otherwise.<br>
 bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,<br>
                                TypeDiagnoser &Diagnoser) {<br>
-  if (RequireCompleteTypeImpl(Loc, T, Diagnoser))<br>
+  if (RequireCompleteTypeImpl(Loc, T, &Diagnoser))<br>
     return true;<br>
   if (const TagType *Tag = T->getAs<TagType>()) {<br>
     if (!Tag->getDecl()->isCompleteDefinitionRequired()) {<br>
@@ -6570,7 +6567,7 @@ static void assignInheritanceModel(Sema<br>
<br>
 /// \brief The implementation of RequireCompleteType<br>
 bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,<br>
-                                   TypeDiagnoser &Diagnoser) {<br>
+                                   TypeDiagnoser *Diagnoser) {<br>
   // FIXME: Add this assertion to make sure we always get instantiation points.<br>
   //  assert(!Loc.isInvalid() && "Invalid location in RequireCompleteType");<br>
   // FIXME: Add this assertion to help us flush out problems with<br>
@@ -6584,7 +6581,7 @@ bool Sema::RequireCompleteTypeImpl(Sourc<br>
   if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {<br>
     if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {<br>
       if (!MPTy->getClass()->isDependentType()) {<br>
-        RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0);<br>
+        (void)isCompleteType(Loc, QualType(MPTy->getClass(), 0));<br>
         assignInheritanceModel(*this, MPTy->getMostRecentCXXRecordDecl());<br>
       }<br>
     }<br>
@@ -6599,8 +6596,8 @@ bool Sema::RequireCompleteTypeImpl(Sourc<br>
         !hasVisibleDefinition(Def, &SuggestedDef, /*OnlyNeedComplete*/true)) {<br>
       // If the user is going to see an error here, recover by making the<br>
       // definition visible.<br>
-      bool TreatAsComplete = !Diagnoser.Suppressed && !isSFINAEContext();<br>
-      if (!Diagnoser.Suppressed)<br>
+      bool TreatAsComplete = Diagnoser && !isSFINAEContext();<br>
+      if (Diagnoser)<br>
         diagnoseMissingImport(Loc, SuggestedDef, /*NeedDefinition*/true,<br>
                               /*Recover*/TreatAsComplete);<br>
       return !TreatAsComplete;<br>
@@ -6660,7 +6657,7 @@ bool Sema::RequireCompleteTypeImpl(Sourc<br>
       if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared) {<br>
         Diagnosed = InstantiateClassTemplateSpecialization(<br>
             Loc, ClassTemplateSpec, TSK_ImplicitInstantiation,<br>
-            /*Complain=*/!Diagnoser.Suppressed);<br>
+            /*Complain=*/Diagnoser);<br>
         Instantiated = true;<br>
       }<br>
     } else if (CXXRecordDecl *Rec<br>
@@ -6675,7 +6672,7 @@ bool Sema::RequireCompleteTypeImpl(Sourc<br>
           Diagnosed = InstantiateClass(Loc, Rec, Pattern,<br>
                                        getTemplateInstantiationArgs(Rec),<br>
                                        TSK_ImplicitInstantiation,<br>
-                                       /*Complain=*/!Diagnoser.Suppressed);<br>
+                                       /*Complain=*/Diagnoser);<br>
           Instantiated = true;<br>
         }<br>
       }<br>
@@ -6684,7 +6681,7 @@ bool Sema::RequireCompleteTypeImpl(Sourc<br>
     if (Instantiated) {<br>
       // Instantiate* might have already complained that the template is not<br>
       // defined, if we asked it to.<br>
-      if (!Diagnoser.Suppressed && Diagnosed)<br>
+      if (Diagnoser && Diagnosed)<br>
         return true;<br>
       // If we instantiated a definition, check that it's usable, even if<br>
       // instantiation produced an error, so that repeated calls to this<br>
@@ -6694,7 +6691,7 @@ bool Sema::RequireCompleteTypeImpl(Sourc<br>
     }<br>
   }<br>
<br>
-  if (Diagnoser.Suppressed)<br>
+  if (!Diagnoser)<br>
     return true;<br>
<br>
   // We have an incomplete type. Produce a diagnostic.<br>
@@ -6704,7 +6701,7 @@ bool Sema::RequireCompleteTypeImpl(Sourc<br>
     return true;<br>
   }<br>
<br>
-  Diagnoser.diagnose(*this, Loc, T);<br>
+  Diagnoser->diagnose(*this, Loc, T);<br>
<br>
   // If the type was a forward declaration of a class/struct/union<br>
   // type, produce a note.<br>
@@ -6769,7 +6766,7 @@ bool Sema::RequireLiteralType(SourceLoca<br>
   assert(!T->isDependentType() && "type should not be dependent");<br>
<br>
   QualType ElemType = Context.getBaseElementType(T);<br>
-  if ((!RequireCompleteType(Loc, ElemType, 0) || ElemType->isVoidType()) &&<br>
+  if ((isCompleteType(Loc, ElemType) || ElemType->isVoidType()) &&<br>
       T->isLiteralType(Context))<br>
     return false;<br>
<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/debug-info-limited.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-limited.cpp?rev=256049&r1=256048&r2=256049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-limited.cpp?rev=256049&r1=256048&r2=256049&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/debug-info-limited.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/debug-info-limited.cpp Fri Dec 18 16:40:25 2015<br>
@@ -14,8 +14,7 @@ A *foo (A* x) {<br>
 }<br>
<br>
 // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B"<br>
-// CHECK-NOT:              DIFlagFwdDecl<br>
-// CHECK-SAME:             ){{$}}<br>
+// CHECK-SAME:             flags: DIFlagFwdDecl<br>
<br>
 class B {<br>
 public:<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>