diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-10-25 21:45:37 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-10-25 21:45:37 +0000 |
commit | d7b3d7dd79eb4fc0983068c3cd6d0f4ea21a9fc3 (patch) | |
tree | ec4cd19c7ed276c56724724068f171c8c6166aba | |
parent | 588f19acc1b490ba10b8cd11db0f122a94b3bcd4 (diff) | |
download | bcm5719-llvm-d7b3d7dd79eb4fc0983068c3cd6d0f4ea21a9fc3.tar.gz bcm5719-llvm-d7b3d7dd79eb4fc0983068c3cd6d0f4ea21a9fc3.zip |
Remove the Skip parameter from GetTypeForDeclarator and dependents. Take the opportunity to improve an error message and fix PR4498.
llvm-svn: 85068
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | clang/include/clang/Parse/DeclSpec.h | 7 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 26 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 28 | ||||
-rw-r--r-- | clang/test/SemaCXX/new-delete.cpp | 1 |
7 files changed, 45 insertions, 29 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7a87e244f77..c5539981460 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1661,7 +1661,9 @@ def err_bad_new_type : Error< def err_new_incomplete_type : Error< "allocation of incomplete type %0">; def err_new_array_nonconst : Error< - "only the first dimension of an allocated array may be non-const">; + "only the first dimension of an allocated array may have dynamic size">; +def err_new_paren_array_nonconst : Error< + "when type is in parentheses, array cannot have dynamic size">; def err_array_size_not_integral : Error< "array size expression must have integral or enumerated type, not %0">; def err_new_uninitialized_const : Error< diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index 51970f1867d..11507944a60 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -1069,6 +1069,13 @@ public: return DeclTypeInfo[i]; } + void DropFirstTypeObject() + { + assert(!DeclTypeInfo.empty() && "No type chunks to drop."); + DeclTypeInfo.front().destroy(); + DeclTypeInfo.erase(DeclTypeInfo.begin()); + } + /// isFunctionDeclarator - Once this declarator is fully parsed and formed, /// this method returns true if the identifier is a function declarator. bool isFunctionDeclarator() const { diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 453d388da36..cb840efe15f 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -468,9 +468,8 @@ public: SourceLocation Loc, DeclarationName Entity); QualType GetTypeForDeclarator(Declarator &D, Scope *S, DeclaratorInfo **DInfo = 0, - unsigned Skip = 0, TagDecl **OwnedDecl = 0); - DeclaratorInfo *GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, - unsigned Skip); + TagDecl **OwnedDecl = 0); + DeclaratorInfo *GetDeclaratorInfoForDeclarator(Declarator &D, QualType T); /// \brief Create a LocInfoType to hold the given QualType and DeclaratorInfo. QualType CreateLocInfoType(QualType T, DeclaratorInfo *DInfo); DeclarationName GetNameForDeclarator(Declarator &D); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d9da2545880..d18ac61b712 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3619,8 +3619,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { DeclaratorInfo *DInfo = 0; TagDecl *OwnedDecl = 0; - QualType parmDeclType = GetTypeForDeclarator(D, S, &DInfo, /*Skip=*/0, - &OwnedDecl); + QualType parmDeclType = GetTypeForDeclarator(D, S, &DInfo, &OwnedDecl); if (getLangOptions().CPlusPlus && OwnedDecl && OwnedDecl->isDefinition()) { // C++ [dcl.fct]p6: diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 3aac415c04c..942c6bc4fec 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -312,7 +312,6 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, MultiExprArg ConstructorArgs, SourceLocation ConstructorRParen) { Expr *ArraySize = 0; - unsigned Skip = 0; // If the specified type is an array, unwrap it and save the expression. if (D.getNumTypeObjects() > 0 && D.getTypeObject(0).Kind == DeclaratorChunk::Array) { @@ -323,14 +322,25 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, if (!Chunk.Arr.NumElts) return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size) << D.getSourceRange()); + + if (ParenTypeId) { + // Can't have dynamic array size when the type-id is in parentheses. + Expr *NumElts = (Expr *)Chunk.Arr.NumElts; + if (!NumElts->isTypeDependent() && !NumElts->isValueDependent() && + !NumElts->isIntegerConstantExpr(Context)) { + Diag(D.getTypeObject(0).Loc, diag::err_new_paren_array_nonconst) + << NumElts->getSourceRange(); + return ExprError(); + } + } + ArraySize = static_cast<Expr*>(Chunk.Arr.NumElts); - Skip = 1; + D.DropFirstTypeObject(); } // Every dimension shall be of constant size. - if (D.getNumTypeObjects() > 0 && - D.getTypeObject(0).Kind == DeclaratorChunk::Array) { - for (unsigned I = 1, N = D.getNumTypeObjects(); I < N; ++I) { + if (ArraySize) { + for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) { if (D.getTypeObject(I).Kind != DeclaratorChunk::Array) break; @@ -345,10 +355,10 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, } } } - + //FIXME: Store DeclaratorInfo in CXXNew expression. DeclaratorInfo *DInfo = 0; - QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo, Skip); + QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo); if (D.isInvalidType()) return ExprError(); @@ -935,7 +945,7 @@ Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc, // FIXME: Store DeclaratorInfo in the expression. DeclaratorInfo *DInfo = 0; TagDecl *OwnedTag = 0; - QualType Ty = GetTypeForDeclarator(D, S, &DInfo, /*Skip=*/0, &OwnedTag); + QualType Ty = GetTypeForDeclarator(D, S, &DInfo, &OwnedTag); if (Ty->isFunctionType()) { // The declarator shall not specify a function... // We exit without creating a CXXConditionDeclExpr because a FunctionDecl diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 71c352396df..50f1be2800e 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -52,9 +52,9 @@ QualType Sema::adjustParameterType(QualType T) { /// isOmittedBlockReturnType - Return true if this declarator is missing a /// return type because this is a omitted return type on a block literal. -static bool isOmittedBlockReturnType(const Declarator &D, unsigned Skip) { +static bool isOmittedBlockReturnType(const Declarator &D) { if (D.getContext() != Declarator::BlockLiteralContext || - Skip != 0 || D.getDeclSpec().hasTypeSpecifier()) + D.getDeclSpec().hasTypeSpecifier()) return false; if (D.getNumTypeObjects() == 0) @@ -72,8 +72,7 @@ static bool isOmittedBlockReturnType(const Declarator &D, unsigned Skip) { /// \param D the declarator containing the declaration specifier. /// \returns The type described by the declaration specifiers. This function /// never returns null. -static QualType ConvertDeclSpecToType(Declarator &TheDeclarator, unsigned Skip, - Sema &TheSema) { +static QualType ConvertDeclSpecToType(Declarator &TheDeclarator, Sema &TheSema){ // FIXME: Should move the logic from DeclSpec::Finish to here for validity // checking. const DeclSpec &DS = TheDeclarator.getDeclSpec(); @@ -135,7 +134,7 @@ static QualType ConvertDeclSpecToType(Declarator &TheDeclarator, unsigned Skip, // If this is a missing declspec in a block literal return context, then it // is inferred from the return statements inside the block. - if (isOmittedBlockReturnType(TheDeclarator, Skip)) { + if (isOmittedBlockReturnType(TheDeclarator)) { Result = Context.DependentTy; break; } @@ -852,14 +851,13 @@ QualType Sema::GetTypeFromParser(TypeTy *Ty, DeclaratorInfo **DInfo) { } /// GetTypeForDeclarator - Convert the type for the specified -/// declarator to Type instances. Skip the outermost Skip type -/// objects. +/// declarator to Type instances. /// /// If OwnedDecl is non-NULL, and this declarator's decl-specifier-seq /// owns the declaration of a type (e.g., the definition of a struct /// type), then *OwnedDecl will receive the owned declaration. QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, - DeclaratorInfo **DInfo, unsigned Skip, + DeclaratorInfo **DInfo, TagDecl **OwnedDecl) { // Determine the type of the declarator. Not all forms of declarator // have a type. @@ -870,7 +868,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, case Declarator::DK_Normal: case Declarator::DK_Operator: case Declarator::DK_TemplateId: - T = ConvertDeclSpecToType(D, Skip, *this); + T = ConvertDeclSpecToType(D, *this); if (!D.isInvalidType() && OwnedDecl && D.getDeclSpec().isTypeSpecOwned()) *OwnedDecl = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep()); @@ -937,8 +935,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, // Walk the DeclTypeInfo, building the recursive type as we go. // DeclTypeInfos are ordered from the identifier out, which is // opposite of what we want :). - for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) { - DeclaratorChunk &DeclType = D.getTypeObject(e-i-1+Skip); + for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { + DeclaratorChunk &DeclType = D.getTypeObject(e-i-1); switch (DeclType.Kind) { default: assert(0 && "Unknown decltype!"); case DeclaratorChunk::BlockPointer: @@ -1235,7 +1233,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, if (D.isInvalidType()) *DInfo = 0; else - *DInfo = GetDeclaratorInfoForDeclarator(D, T, Skip); + *DInfo = GetDeclaratorInfoForDeclarator(D, T); } return T; @@ -1377,11 +1375,11 @@ namespace { /// /// \param T QualType referring to the type as written in source code. DeclaratorInfo * -Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) { +Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T) { DeclaratorInfo *DInfo = Context.CreateDeclaratorInfo(T); UnqualTypeLoc CurrTL = DInfo->getTypeLoc().getUnqualifiedLoc(); - for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) { + for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { DeclaratorLocFiller(D.getTypeObject(i)).Visit(CurrTL); CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc(); } @@ -1474,7 +1472,7 @@ Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) { DeclaratorInfo *DInfo = 0; TagDecl *OwnedTag = 0; - QualType T = GetTypeForDeclarator(D, S, &DInfo, /*Skip=*/0, &OwnedTag); + QualType T = GetTypeForDeclarator(D, S, &DInfo, &OwnedTag); if (D.isInvalidType()) return true; diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp index c67a3f65390..6f3e9effe53 100644 --- a/clang/test/SemaCXX/new-delete.cpp +++ b/clang/test/SemaCXX/new-delete.cpp @@ -58,6 +58,7 @@ void bad_news(int *ip) (void)new int[1.1]; // expected-error {{array size expression must have integral or enumerated type, not 'double'}} (void)new int[1][i]; // expected-error {{only the first dimension}} (void)new (int[1][i]); // expected-error {{only the first dimension}} + (void)new (int[i]); // expected-error {{when type is in parentheses}} (void)new int(*(S*)0); // expected-error {{incompatible type initializing}} (void)new int(1, 2); // expected-error {{initializer of a builtin type can only take one argument}} (void)new S(1); // expected-error {{no matching constructor}} |