forked from OSchip/llvm-project
Remove the Skip parameter from GetTypeForDeclarator and dependents. Take the opportunity to improve an error message and fix PR4498.
llvm-svn: 85068
This commit is contained in:
parent
588f19acc1
commit
d7b3d7dd79
|
@ -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<
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue