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<
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 {
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);
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:
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) {
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;
}
}
}
-
+
//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();
// 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
/// 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)
/// \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();
// 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;
}
}
/// 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.
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());
// 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:
if (D.isInvalidType())
*DInfo = 0;
else
- *DInfo = GetDeclaratorInfoForDeclarator(D, T, Skip);
+ *DInfo = GetDeclaratorInfoForDeclarator(D, T);
}
return T;
///
/// \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();
}
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;
(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}}