Diagnose mixing of tags. For example, for:

struct blah * P;
union blah *P2;

we now emit:

t.c:2:1: error: redefinition of 'blah' with tag that does not match previous use
union blah *P2;
^
t.c:1:8: error: previous use is here
struct blah * P;
       ^

llvm-svn: 39275
This commit is contained in:
Chris Lattner 2007-01-23 02:05:42 +00:00
parent 8799cf202c
commit 7e783a1a08
3 changed files with 37 additions and 16 deletions

View File

@ -273,6 +273,14 @@ Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
// If this is a use of an existing tag, it must have a name.
assert((isUse || Name != 0) && "Nameless record must have a name!");
Decl::Kind Kind = isUnion ? Decl::Union : Decl::Struct;
// If there is an identifier, use the location of the identifier as the
// location of the decl, otherwise use the location of the struct/union
// keyword.
SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
// If this is a named struct, check to see if there was a previous forward
// declaration or definition.
if (Decl *PrevDecl = LookupScopedDecl(Name, Decl::IDNS_Tag)) {
@ -281,7 +289,12 @@ Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
// the same scope (so that the definition/declaration completes or
// rementions the tag), reuse the decl.
if (isUse || S->isDeclScope(PrevDecl)) {
// Make sure that this wasn't declared as an enum and now used as a struct
// or something similar.
if (PrevDecl->getKind() != Kind) {
Diag(KWLoc, diag::err_redefinition_with_wrong_tag, Name->getName());
Diag(PrevDecl->getLocation(), diag::err_previous_use);
}
}
@ -291,13 +304,8 @@ Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
}
// If there is an identifier, use the location of the identifier as the
// location of the decl, otherwise use the location of the struct/union
// keyword.
SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
// Otherwise, if this is the first time we've seen this tag, create the decl.
Decl *New = new RecordDecl(isUnion ? Decl::Union : Decl::Struct, Loc, Name);
Decl *New = new RecordDecl(Kind, Loc, Name);
// If this has an identifier, add it to the scope stack.
if (Name) {

View File

@ -273,6 +273,14 @@ Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
// If this is a use of an existing tag, it must have a name.
assert((isUse || Name != 0) && "Nameless record must have a name!");
Decl::Kind Kind = isUnion ? Decl::Union : Decl::Struct;
// If there is an identifier, use the location of the identifier as the
// location of the decl, otherwise use the location of the struct/union
// keyword.
SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
// If this is a named struct, check to see if there was a previous forward
// declaration or definition.
if (Decl *PrevDecl = LookupScopedDecl(Name, Decl::IDNS_Tag)) {
@ -281,7 +289,12 @@ Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
// the same scope (so that the definition/declaration completes or
// rementions the tag), reuse the decl.
if (isUse || S->isDeclScope(PrevDecl)) {
// Make sure that this wasn't declared as an enum and now used as a struct
// or something similar.
if (PrevDecl->getKind() != Kind) {
Diag(KWLoc, diag::err_redefinition_with_wrong_tag, Name->getName());
Diag(PrevDecl->getLocation(), diag::err_previous_use);
}
}
@ -291,13 +304,8 @@ Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
}
// If there is an identifier, use the location of the identifier as the
// location of the decl, otherwise use the location of the struct/union
// keyword.
SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
// Otherwise, if this is the first time we've seen this tag, create the decl.
Decl *New = new RecordDecl(isUnion ? Decl::Union : Decl::Struct, Loc, Name);
Decl *New = new RecordDecl(Kind, Loc, Name);
// If this has an identifier, add it to the scope stack.
if (Name) {

View File

@ -415,14 +415,19 @@ DIAG(err_no_matching_param, ERROR,
DIAG(err_param_not_declared, ERROR,
"parameter '%s' was not declared")
DIAG(err_previous_definition, ERROR,
"previous definition is here")
DIAG(err_previous_use, ERROR,
"previous use is here")
DIAG(err_unexpected_typedef, ERROR,
"unexpected type name '%s': expected expression")
DIAG(err_undeclared_var_use, ERROR,
"use of undeclared identifier '%s'")
DIAG(err_redefinition, ERROR,
"redefinition of '%s'")
DIAG(err_previous_definition, ERROR,
"previous definition is here")
DIAG(err_redefinition_with_wrong_tag, ERROR,
"redefinition of '%s' with tag that does not match previous use")
DIAG(warn_implicit_function_decl, WARNING,
"implicit declaration of function '%s'")