On Fri, Jan 8, 2016 at 4:08 PM, Richard Smith <rich...@metafoo.co.uk> wrote:
> On Thu, Jan 7, 2016 at 6:00 PM, David Blaikie <dblai...@gmail.com> wrote: > >> On Fri, Dec 18, 2015 at 2:40 PM, Richard Smith via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> 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. >>> >> >> Thanks for mentioning - I was wondering if that was the case. >> >> Do you have a canonical example where we previously required the type to >> be complete, but we now only query it? >> > > The example in test/CodeGenCXX/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. > Oh, I remember that one now. Awesome - thanks! > > >> 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 >>> >> >> >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits