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