From 5912a3544e438a92832b8c52c13f48d4f54795dc Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Tue, 28 Aug 2007 20:14:24 +0000 Subject: [PATCH] Finish converting decls over to the new invalid decl API. Also removed an old FIXME (FIXME: "auto func();" passes through...). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41555 91177308-0d34-0410-b5e6-96231b3b80d8 --- Sema/SemaDecl.cpp | 38 ++++++++++++++++++++++++-------------- Sema/SemaExpr.cpp | 2 +- Sema/SemaType.cpp | 18 ++++++++++-------- include/clang/AST/Decl.h | 2 +- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index d91420d16f..4510f00d0c 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -304,6 +304,8 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *init, PrevDecl = 0; // If in outer scope, it isn't the same thing. Decl *New; + bool InvalidDecl = false; + if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) { assert(Init == 0 && "Can't have initializer for a typedef!"); TypedefDecl *NewTD = ParseTypedefDecl(S, D, LastDeclarator); @@ -323,13 +325,14 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *init, // then it shall have block scope. if (ArrayType *ary = dyn_cast(NewTD->getUnderlyingType())) { if (VerifyConstantArrayType(ary, D.getIdentifierLoc())) - return 0; + InvalidDecl = true; } } } else if (D.isFunctionDeclarator()) { assert(Init == 0 && "Can't have an initializer for a functiondecl!"); + QualType R = GetTypeForDeclarator(D, S); - if (R.isNull()) return 0; // FIXME: "auto func();" passes through... + assert(!R.isNull() && "GetTypeForDeclarator() returned null type"); FunctionDecl::StorageClass SC; switch (D.getDeclSpec().getStorageClassSpec()) { @@ -338,7 +341,8 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *init, case DeclSpec::SCS_register: Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_func, R.getAsString()); - return 0; + InvalidDecl = true; + break; case DeclSpec::SCS_unspecified: SC = FunctionDecl::None; break; case DeclSpec::SCS_extern: SC = FunctionDecl::Extern; break; case DeclSpec::SCS_static: SC = FunctionDecl::Static; break; @@ -356,9 +360,7 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *init, New = NewFD; } else { QualType R = GetTypeForDeclarator(D, S); - assert(!R.isNull() && "GetTypeForDeclarator() returned null type"); - bool InvalidDecl = false; VarDecl *NewVD; VarDecl::StorageClass SC; @@ -420,9 +422,6 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *init, } NewVD = new BlockVarDecl(D.getIdentifierLoc(), II, R, SC, LastDeclarator); } - if (InvalidDecl) - NewVD->setInvalidDecl(); - // Handle attributes prior to checking for duplicates in MergeVarDecl HandleDeclAttributes(NewVD, D.getDeclSpec().getAttributes(), D.getAttributes()); @@ -450,6 +449,10 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *init, if (S->getParent() == 0) AddTopLevelDecl(New, LastDeclarator); + + // If any semantic error occurred, mark the decl as invalid. + if (D.getInvalidType() || InvalidDecl) + New->setInvalidDecl(); return New; } @@ -649,11 +652,14 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, assert(D.getIdentifier() && "Wrong callback for declspec without declarator"); QualType T = GetTypeForDeclarator(D, S); - if (T.isNull()) return 0; + assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); // Scope manipulation handled by caller. - return new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), T, - LastDeclarator); + TypedefDecl *NewTD = new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), + T, LastDeclarator); + if (D.getInvalidType()) + NewTD->setInvalidDecl(); + return NewTD; } @@ -789,17 +795,21 @@ Sema::DeclTy *Sema::ParseField(Scope *S, DeclTy *TagDecl, } QualType T = GetTypeForDeclarator(D, S); - if (T.isNull()) return 0; + assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); + bool InvalidDecl = false; // C99 6.7.2.1p8: A member of a structure or union may have any type other // than a variably modified type. if (const ArrayType *ary = T->getAsArrayType()) { if (VerifyConstantArrayType(ary, Loc)) - return 0; + InvalidDecl = true; } // FIXME: Chain fielddecls together. - return new FieldDecl(Loc, II, T, 0); + FieldDecl *NewFD = new FieldDecl(Loc, II, T, 0); + if (D.getInvalidType() || InvalidDecl) + NewFD->setInvalidDecl(); + return NewFD; } void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl, diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index bea6e99912..eb7daf18c7 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -76,7 +76,7 @@ Sema::ExprResult Sema::ParseIdentifierExpr(Scope *S, SourceLocation Loc, } if (ValueDecl *VD = dyn_cast(D)) { // Only create DeclRefExpr's for valid Decl's. - if (VD->getInvalidDecl()) + if (VD->isInvalidDecl()) return true; return new DeclRefExpr(VD, VD->getType(), Loc); } diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp index 04264a3e51..3bc0e760ba 100644 --- a/Sema/SemaType.cpp +++ b/Sema/SemaType.cpp @@ -278,11 +278,12 @@ Sema::TypeResult Sema::ParseTypeName(Scope *S, Declarator &D) { assert(D.getIdentifier() == 0 && "Type name should have no identifier!"); QualType T = GetTypeForDeclarator(D, S); + + assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); - // If the type of the declarator was invalid, this is an invalid typename. - if (T.isNull()) - return true; - + // In this context, we *do not* check D.getInvalidType(). If the declarator + // type was invalid, GetTypeForDeclarator() still returns a "valid" type, + // though it will not reflect the user specified type. return T.getAsOpaquePtr(); } @@ -292,9 +293,10 @@ Sema::TypeResult Sema::ParseParamDeclaratorType(Scope *S, Declarator &D) { // just want the type converted. QualType T = GetTypeForDeclarator(D, S); - // If the type of the declarator was invalid, this is an invalid typename. - if (T.isNull()) - return true; - + assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); + + // In this context, we *do not* check D.getInvalidType(). If the declarator + // type was invalid, GetTypeForDeclarator() still returns a "valid" type, + // though it will not reflect the user specified type. return T.getAsOpaquePtr(); } diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 563921c572..1dbe4c1125 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -92,7 +92,7 @@ public: /// setInvalidDecl - Indicates the Decl had a semantic error. This /// allows for graceful error recovery. void setInvalidDecl() { InvalidDecl = 1; } - int getInvalidDecl() const { return InvalidDecl; } + int isInvalidDecl() const { return InvalidDecl; } /// getNextDeclarator - If this decl was part of a multi-declarator /// declaration, such as "int X, Y, *Z;" this returns the decl for the next -- 2.40.0