diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 19 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCast.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 73 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 25 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmtAsm.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 33 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/debug-info-limited.cpp | 3 |
17 files changed, 106 insertions, 126 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index acb30f2de5d..94fd00bf02c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -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] // diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 1cc97fcd9d2..07b058911c2 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -1262,8 +1262,8 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, 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, ExprResult &SrcExpr, QualType SrcType, 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(Sema &Self, ExprResult &SrcExpr, 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. diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 20a1eb1a6bc..52151f67599 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -4052,7 +4052,7 @@ void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args) { // 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 *S, QualType Type, SourceLocation Loc, return; // A complete type is needed to lookup for constructors. - if (RequireCompleteType(Loc, Type, 0)) + if (!isCompleteType(Loc, Type)) return; CXXRecordDecl *RD = Type->getAsCXXRecordDecl(); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 2cc0d071a96..f67e573c748 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1673,11 +1673,6 @@ bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) { 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 Loc, QualType Derived, QualType Base) { 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 Loc, QualType Derived, QualType Base, 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(Decl *CDtorDecl) { } } -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; } diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 6f0206f0884..a2f41a7cc30 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1867,6 +1867,8 @@ Decl *Sema::ActOnStartClassImplementation( 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 { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d31a816b80d..ac7e98c5835 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -686,9 +686,10 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { 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(ExprResult &OrigOp, SourceLocation OpLoc) { 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(ExprResult &OrigOp, SourceLocation OpLoc) { 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; } } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 1604a70d525..47d15c363c9 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2717,6 +2717,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, 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 StartLoc, bool UseGlobal, 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 *From, QualType ToType, // 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 &Self, TypeTrait BTT, QualType LhsT, 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. diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index a179957e981..c1ac621b57a 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -2726,6 +2726,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // 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 diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 1f0504fd38f..c3a89463dc6 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3328,7 +3328,7 @@ static bool TryInitializerListConstruction(Sema &S, 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(Sema &S, "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 &S, } if (DestType->isRecordType() && - S.RequireCompleteType(InitList->getLocStart(), DestType, 0)) { + !S.isCompleteType(InitList->getLocStart(), DestType)) { Sequence.setIncompleteTypeFailure(DestType); return; } @@ -3841,7 +3841,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, 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 TryRefInitWithConversionFunction(Sema &S, 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(Sema &S, = 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(Sema &S, // 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()); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 434fc7540cd..f56b722bcae 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -2428,8 +2428,8 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, } // 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 diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 58949bfd440..62f4f18bd3a 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1822,7 +1822,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { // 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 *From, QualType ToType, 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 *From, QualType ToType, // 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(SourceLocation Loc, 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, QualType DeclType, // 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, QualType DeclType, // 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 *From, QualType ToType, // 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::PerformContextualImplicitConversion( 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(CXXConversionDecl *Conversion, &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(OverloadedOperatorKind Op, // 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::AddTypesConvertedFrom(QualType Ty, 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()); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index ac6813e5fe7..e1b1a47e182 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1706,11 +1706,10 @@ Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) { // 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()) { diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 6991fd999b1..2917c5a3603 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -647,7 +647,8 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member, 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), diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index bd868139df2..9ef927f1c1c 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4282,7 +4282,7 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, 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!"); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 66b9abc3000..18ad12a63ca 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1440,7 +1440,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // 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 AdjustFunctionParmAndArgTypesForDeduction(Sema &S, 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 diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index f44b01f8ac3..c70568c23b5 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1998,7 +1998,7 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, 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, ArrayType::ArraySizeModifier ASM, 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 *E, unsigned DiagID) { /// @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 &S, CXXRecordDecl *RD) { /// \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(SourceLocation Loc, QualType T, 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(SourceLocation Loc, QualType T, !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(SourceLocation Loc, QualType T, 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(SourceLocation Loc, QualType T, Diagnosed = InstantiateClass(Loc, Rec, Pattern, getTemplateInstantiationArgs(Rec), TSK_ImplicitInstantiation, - /*Complain=*/!Diagnoser.Suppressed); + /*Complain=*/Diagnoser); Instantiated = true; } } @@ -6684,7 +6681,7 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T, 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(SourceLocation Loc, QualType T, } } - if (Diagnoser.Suppressed) + if (!Diagnoser) return true; // We have an incomplete type. Produce a diagnostic. @@ -6704,7 +6701,7 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T, 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(SourceLocation Loc, QualType T, 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; diff --git a/clang/test/CodeGenCXX/debug-info-limited.cpp b/clang/test/CodeGenCXX/debug-info-limited.cpp index d56e5b670a1..b209e3a850d 100644 --- a/clang/test/CodeGenCXX/debug-info-limited.cpp +++ b/clang/test/CodeGenCXX/debug-info-limited.cpp @@ -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: |