Extract code dealing with variable declarator into a separate function.

No functionality change.

llvm-svn: 62300
This commit is contained in:
Zhongxing Xu 2009-01-16 02:36:34 +00:00
parent d243c0e3d9
commit 9b7714d909
2 changed files with 113 additions and 100 deletions

View File

@ -277,9 +277,12 @@ public:
}
DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup,
bool IsFunctionDefinition);
ScopedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, ScopedDecl* LastDeclarator,
Decl* PrevDecl, bool& InvalidDecl);
ScopedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, ScopedDecl *LastDeclarator,
Decl* PreDecl, bool IsFunctionDefinition,
Decl* PrevDecl, bool IsFunctionDefinition,
bool& InvalidDecl);
virtual DeclTy *ActOnParamDeclarator(Scope *S, Declarator &D);
virtual void ActOnParamDefaultArgument(DeclTy *param,

View File

@ -1328,105 +1328,8 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
New = ActOnFunctionDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
IsFunctionDefinition, InvalidDecl);
} else {
// Check that there are no default arguments (C++ only).
if (getLangOptions().CPlusPlus)
CheckExtraCXXDefaultArguments(D);
if (R.getTypePtr()->isObjCInterfaceType()) {
Diag(D.getIdentifierLoc(), diag::err_statically_allocated_object)
<< D.getIdentifier();
InvalidDecl = true;
}
VarDecl *NewVD;
VarDecl::StorageClass SC;
switch (D.getDeclSpec().getStorageClassSpec()) {
default: assert(0 && "Unknown storage class!");
case DeclSpec::SCS_unspecified: SC = VarDecl::None; break;
case DeclSpec::SCS_extern: SC = VarDecl::Extern; break;
case DeclSpec::SCS_static: SC = VarDecl::Static; break;
case DeclSpec::SCS_auto: SC = VarDecl::Auto; break;
case DeclSpec::SCS_register: SC = VarDecl::Register; break;
case DeclSpec::SCS_private_extern: SC = VarDecl::PrivateExtern; break;
case DeclSpec::SCS_mutable:
// mutable can only appear on non-static class members, so it's always
// an error here
Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember);
InvalidDecl = true;
SC = VarDecl::None;
break;
}
IdentifierInfo *II = Name.getAsIdentifierInfo();
if (!II) {
Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
<< Name.getAsString();
return 0;
}
if (DC->isRecord()) {
// This is a static data member for a C++ class.
NewVD = CXXClassVarDecl::Create(Context, cast<CXXRecordDecl>(DC),
D.getIdentifierLoc(), II,
R, LastDeclarator);
} else {
bool ThreadSpecified = D.getDeclSpec().isThreadSpecified();
if (S->getFnParent() == 0) {
// C99 6.9p2: The storage-class specifiers auto and register shall not
// appear in the declaration specifiers in an external declaration.
if (SC == VarDecl::Auto || SC == VarDecl::Register) {
Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
InvalidDecl = true;
}
}
NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(),
II, R, SC, LastDeclarator,
// FIXME: Move to DeclGroup...
D.getDeclSpec().getSourceRange().getBegin());
NewVD->setThreadSpecified(ThreadSpecified);
}
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(NewVD, D);
// Handle GNU asm-label extension (encoded as an attribute).
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
NewVD->addAttr(new AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
// Emit an error if an address space was applied to decl with local storage.
// This includes arrays of objects with address space qualifiers, but not
// automatic variables that point to other address spaces.
// ISO/IEC TR 18037 S5.1.2
if (NewVD->hasLocalStorage() && (NewVD->getType().getAddressSpace() != 0)) {
Diag(D.getIdentifierLoc(), diag::err_as_qualified_auto_decl);
InvalidDecl = true;
}
// Merge the decl with the existing one if appropriate. If the decl is
// in an outer scope, it isn't the same thing.
if (PrevDecl && isDeclInScope(PrevDecl, DC, S)) {
if (isa<FieldDecl>(PrevDecl) && D.getCXXScopeSpec().isSet()) {
// The user tried to define a non-static data member
// out-of-line (C++ [dcl.meaning]p1).
Diag(NewVD->getLocation(), diag::err_nonstatic_member_out_of_line)
<< D.getCXXScopeSpec().getRange();
NewVD->Destroy(Context);
return 0;
}
NewVD = MergeVarDecl(NewVD, PrevDecl);
if (NewVD == 0) return 0;
if (D.getCXXScopeSpec().isSet()) {
// No previous declaration in the qualifying scope.
Diag(D.getIdentifierLoc(), diag::err_typecheck_no_member)
<< Name << D.getCXXScopeSpec().getRange();
InvalidDecl = true;
}
}
New = NewVD;
New = ActOnVariableDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
InvalidDecl);
}
if (New == 0)
@ -1446,6 +1349,113 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
return New;
}
ScopedDecl*
Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, ScopedDecl* LastDeclarator,
Decl* PrevDecl, bool& InvalidDecl) {
DeclarationName Name = GetNameForDeclarator(D);
// Check that there are no default arguments (C++ only).
if (getLangOptions().CPlusPlus)
CheckExtraCXXDefaultArguments(D);
if (R.getTypePtr()->isObjCInterfaceType()) {
Diag(D.getIdentifierLoc(), diag::err_statically_allocated_object)
<< D.getIdentifier();
InvalidDecl = true;
}
VarDecl *NewVD;
VarDecl::StorageClass SC;
switch (D.getDeclSpec().getStorageClassSpec()) {
default: assert(0 && "Unknown storage class!");
case DeclSpec::SCS_unspecified: SC = VarDecl::None; break;
case DeclSpec::SCS_extern: SC = VarDecl::Extern; break;
case DeclSpec::SCS_static: SC = VarDecl::Static; break;
case DeclSpec::SCS_auto: SC = VarDecl::Auto; break;
case DeclSpec::SCS_register: SC = VarDecl::Register; break;
case DeclSpec::SCS_private_extern: SC = VarDecl::PrivateExtern; break;
case DeclSpec::SCS_mutable:
// mutable can only appear on non-static class members, so it's always
// an error here
Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember);
InvalidDecl = true;
SC = VarDecl::None;
break;
}
IdentifierInfo *II = Name.getAsIdentifierInfo();
if (!II) {
Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
<< Name.getAsString();
return 0;
}
if (DC->isRecord()) {
// This is a static data member for a C++ class.
NewVD = CXXClassVarDecl::Create(Context, cast<CXXRecordDecl>(DC),
D.getIdentifierLoc(), II,
R, LastDeclarator);
} else {
bool ThreadSpecified = D.getDeclSpec().isThreadSpecified();
if (S->getFnParent() == 0) {
// C99 6.9p2: The storage-class specifiers auto and register shall not
// appear in the declaration specifiers in an external declaration.
if (SC == VarDecl::Auto || SC == VarDecl::Register) {
Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
InvalidDecl = true;
}
}
NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(),
II, R, SC, LastDeclarator,
// FIXME: Move to DeclGroup...
D.getDeclSpec().getSourceRange().getBegin());
NewVD->setThreadSpecified(ThreadSpecified);
}
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(NewVD, D);
// Handle GNU asm-label extension (encoded as an attribute).
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
NewVD->addAttr(new AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
// Emit an error if an address space was applied to decl with local storage.
// This includes arrays of objects with address space qualifiers, but not
// automatic variables that point to other address spaces.
// ISO/IEC TR 18037 S5.1.2
if (NewVD->hasLocalStorage() && (NewVD->getType().getAddressSpace() != 0)) {
Diag(D.getIdentifierLoc(), diag::err_as_qualified_auto_decl);
InvalidDecl = true;
}
// Merge the decl with the existing one if appropriate. If the decl is
// in an outer scope, it isn't the same thing.
if (PrevDecl && isDeclInScope(PrevDecl, DC, S)) {
if (isa<FieldDecl>(PrevDecl) && D.getCXXScopeSpec().isSet()) {
// The user tried to define a non-static data member
// out-of-line (C++ [dcl.meaning]p1).
Diag(NewVD->getLocation(), diag::err_nonstatic_member_out_of_line)
<< D.getCXXScopeSpec().getRange();
NewVD->Destroy(Context);
return 0;
}
NewVD = MergeVarDecl(NewVD, PrevDecl);
if (NewVD == 0) return 0;
if (D.getCXXScopeSpec().isSet()) {
// No previous declaration in the qualifying scope.
Diag(D.getIdentifierLoc(), diag::err_typecheck_no_member)
<< Name << D.getCXXScopeSpec().getRange();
InvalidDecl = true;
}
}
return NewVD;
}
ScopedDecl*
Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, ScopedDecl *LastDeclarator,