From 86447ec25fa34aa3c2f48ebc49ec09bc1f03f002 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 9 Mar 2009 16:13:40 +0000 Subject: [PATCH] Rename DiagnoseIncompleteType to RequireCompleteType, and update the documentation to reflect the fact that we can instantiate templates here git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66421 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/Sema.h | 2 +- lib/Sema/SemaDecl.cpp | 12 ++++++------ lib/Sema/SemaDeclCXX.cpp | 4 ++-- lib/Sema/SemaExpr.cpp | 12 ++++++------ lib/Sema/SemaExprCXX.cpp | 4 ++-- lib/Sema/SemaNamedCast.cpp | 4 ++-- lib/Sema/SemaType.cpp | 18 ++++++++---------- 7 files changed, 27 insertions(+), 29 deletions(-) diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 1ef579f687..10a3a9defd 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -283,7 +283,7 @@ public: virtual TypeResult ActOnTypeName(Scope *S, Declarator &D); - bool DiagnoseIncompleteType(SourceLocation Loc, QualType T, unsigned diag, + bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned diag, SourceRange Range1 = SourceRange(), SourceRange Range2 = SourceRange(), QualType PrintType = QualType()); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e902cbe135..fbdab591c3 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -893,7 +893,7 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) { // function declarator that is part of a function definition of // that function shall not have incomplete type. if (!Param->isInvalidDecl() && - DiagnoseIncompleteType(Param->getLocation(), Param->getType(), + RequireCompleteType(Param->getLocation(), Param->getType(), diag::err_typecheck_decl_incomplete_type)) { Param->setInvalidDecl(); HasInvalidParm = true; @@ -2255,7 +2255,7 @@ void Sema::ActOnUninitializedDecl(DeclTy *dcl) { Var->getStorageClass() != VarDecl::PrivateExtern && InitType->isRecordType()) { const CXXConstructorDecl *Constructor = 0; - if (!DiagnoseIncompleteType(Var->getLocation(), InitType, + if (!RequireCompleteType(Var->getLocation(), InitType, diag::err_invalid_incomplete_type_use)) Constructor = PerformInitializationByConstructor(InitType, 0, 0, @@ -2333,7 +2333,7 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) { if (IDecl->isBlockVarDecl() && IDecl->getStorageClass() != VarDecl::Extern) { if (!IDecl->isInvalidDecl() && - DiagnoseIncompleteType(IDecl->getLocation(), T, + RequireCompleteType(IDecl->getLocation(), T, diag::err_typecheck_decl_incomplete_type)) IDecl->setInvalidDecl(); } @@ -2347,7 +2347,7 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) { // C99 6.9.2 (p2, p5): Implicit initialization causes an incomplete // array to be completed. Don't issue a diagnostic. } else if (!IDecl->isInvalidDecl() && - DiagnoseIncompleteType(IDecl->getLocation(), T, + RequireCompleteType(IDecl->getLocation(), T, diag::err_typecheck_decl_incomplete_type)) // C99 6.9.2p3: If the declaration of an identifier for an object is // a tentative definition and has internal linkage (C99 6.2.2p3), the @@ -3488,7 +3488,7 @@ void Sema::ActOnFields(Scope* S, // C99 6.7.2.1p2 - A field may not be an incomplete type except... if (FDTy->isIncompleteType()) { if (!Record) { // Incomplete ivar type is always an error. - DiagnoseIncompleteType(FD->getLocation(), FD->getType(), + RequireCompleteType(FD->getLocation(), FD->getType(), diag::err_field_incomplete); FD->setInvalidDecl(); EnclosingDecl->setInvalidDecl(); @@ -3497,7 +3497,7 @@ void Sema::ActOnFields(Scope* S, if (i != NumFields-1 || // ... that the last member ... !Record->isStruct() || // ... of a structure ... !FDTy->isArrayType()) { //... may have incomplete array type. - DiagnoseIncompleteType(FD->getLocation(), FD->getType(), + RequireCompleteType(FD->getLocation(), FD->getType(), diag::err_field_incomplete); FD->setInvalidDecl(); EnclosingDecl->setInvalidDecl(); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index e2a8bb4347..7773b9e615 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -350,7 +350,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, // C++ [class.derived]p2: // The class-name in a base-specifier shall not be an incompletely // defined class. - if (DiagnoseIncompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class, + if (RequireCompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class, SpecifierRange)) return 0; @@ -2270,7 +2270,7 @@ Sema::DeclTy *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) DK = diag::err_catch_incomplete_ref; } if ((Mode == 0 || !BaseType->isVoidType()) && - DiagnoseIncompleteType(Begin, BaseType, DK)) + RequireCompleteType(Begin, BaseType, DK)) Invalid = true; // FIXME: Need to test for ability to copy-construct and destroy the diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 4ba35a593c..d96b5e56d4 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1189,7 +1189,7 @@ bool Sema::CheckSizeOfAlignOfOperand(QualType exprType, return false; } - return DiagnoseIncompleteType(OpLoc, exprType, + return RequireCompleteType(OpLoc, exprType, isSizeof ? diag::err_sizeof_incomplete_type : diag::err_alignof_incomplete_type, ExprRange); @@ -1703,7 +1703,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, // of the ObjC 'id' struct. if (const RecordType *RTy = BaseType->getAsRecordType()) { RecordDecl *RDecl = RTy->getDecl(); - if (DiagnoseIncompleteType(OpLoc, BaseType, + if (RequireCompleteType(OpLoc, BaseType, diag::err_typecheck_incomplete_tag, BaseExpr->getSourceRange())) return ExprError(); @@ -2257,7 +2257,7 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty, if (literalType->isVariableArrayType()) return ExprError(Diag(LParenLoc, diag::err_variable_object_no_init) << SourceRange(LParenLoc, literalExpr->getSourceRange().getEnd())); - } else if (DiagnoseIncompleteType(LParenLoc, literalType, + } else if (RequireCompleteType(LParenLoc, literalType, diag::err_typecheck_decl_incomplete_type, SourceRange(LParenLoc, literalExpr->getSourceRange().getEnd()))) return ExprError(); @@ -3017,7 +3017,7 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 Diag(Loc, diag::ext_gnu_ptr_func_arith) << lex->getType() << lex->getSourceRange(); } else { - DiagnoseIncompleteType(Loc, PTy->getPointeeType(), + RequireCompleteType(Loc, PTy->getPointeeType(), diag::err_typecheck_arithmetic_incomplete_type, lex->getSourceRange(), SourceRange(), lex->getType()); @@ -3436,7 +3436,7 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { break; case Expr::MLV_IncompleteType: case Expr::MLV_IncompleteVoidType: - return S.DiagnoseIncompleteType(Loc, E->getType(), + return S.RequireCompleteType(Loc, E->getType(), diag::err_typecheck_incomplete_type_not_modifiable_lvalue, E->getSourceRange()); case Expr::MLV_DuplicateVectorComponents: @@ -3577,7 +3577,7 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc, Diag(OpLoc, diag::ext_gnu_ptr_func_arith) << ResType << Op->getSourceRange(); } else { - DiagnoseIncompleteType(OpLoc, PT->getPointeeType(), + RequireCompleteType(OpLoc, PT->getPointeeType(), diag::err_typecheck_arithmetic_incomplete_type, Op->getSourceRange(), SourceRange(), ResType); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 37e4fdb24d..8453b4e88c 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -177,7 +177,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, if (Ty->isArrayType()) return Diag(TyBeginLoc, diag::err_value_init_for_array_type) << FullRange; if (!Ty->isDependentType() && !Ty->isVoidType() && - DiagnoseIncompleteType(TyBeginLoc, Ty, + RequireCompleteType(TyBeginLoc, Ty, diag::err_invalid_incomplete_type_use, FullRange)) return true; @@ -595,7 +595,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, QualType Pointee = Type->getAsPointerType()->getPointeeType(); if (!Pointee->isVoidType() && - DiagnoseIncompleteType(StartLoc, Pointee, diag::warn_delete_incomplete, + RequireCompleteType(StartLoc, Pointee, diag::warn_delete_incomplete, Ex->getSourceRange())) return true; else if (!Pointee->isObjectType()) { diff --git a/lib/Sema/SemaNamedCast.cpp b/lib/Sema/SemaNamedCast.cpp index 166ed24d92..fbde930f0b 100644 --- a/lib/Sema/SemaNamedCast.cpp +++ b/lib/Sema/SemaNamedCast.cpp @@ -776,7 +776,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, if (DestPointee->isVoidType()) { assert(DestPointer && "Reference to void is not possible"); } else if (DestRecord) { - if (Self.DiagnoseIncompleteType(OpRange.getBegin(), DestPointee, + if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee, diag::err_bad_dynamic_cast_incomplete, DestRange)) return; @@ -810,7 +810,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, const RecordType *SrcRecord = SrcPointee->getAsRecordType(); if (SrcRecord) { - if (Self.DiagnoseIncompleteType(OpRange.getBegin(), SrcPointee, + if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee, diag::err_bad_dynamic_cast_incomplete, SrcExpr->getSourceRange())) return; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 96d17be931..bfbc6c3708 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -395,7 +395,7 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, SourceLocation Loc, DeclarationName Entity) { // C99 6.7.5.2p1: If the element type is an incomplete or function type, // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]()) - if (DiagnoseIncompleteType(Loc, T, + if (RequireCompleteType(Loc, T, diag::err_illegal_decl_array_incomplete_type)) return QualType(); @@ -992,13 +992,15 @@ void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) { } } -/// @brief If the type T is incomplete and cannot be completed, -/// produce a suitable diagnostic. +/// @brief Ensure that the type T is a complete type. /// /// This routine checks whether the type @p T is complete in any /// context where a complete type is required. If @p T is a complete -/// type, returns false. If @p T is incomplete, issues the diagnostic -/// @p diag (giving it the type @p T) and returns true. +/// type, returns false. If @p T is a class template specialization, +/// this routine then attempts to perform class template +/// instantiation. If instantiation fails, or if @p T is incomplete +/// and cannot be completed, issues the diagnostic @p diag (giving it +/// the type @p T) and returns true. /// /// @param Loc The location in the source that the incomplete type /// diagnostic should refer to. @@ -1023,11 +1025,7 @@ void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) { /// /// @returns @c true if @p T is incomplete and a diagnostic was emitted, /// @c false otherwise. -/// -/// @todo When Clang gets proper support for C++ templates, this -/// routine will also be able perform template instantiation when @p T -/// is a class template specialization. -bool Sema::DiagnoseIncompleteType(SourceLocation Loc, QualType T, unsigned diag, +bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, unsigned diag, SourceRange Range1, SourceRange Range2, QualType PrintType) { // If we have a complete type, we're done. -- 2.40.0