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:
parent
8799cf202c
commit
7e783a1a08
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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'")
|
||||
|
|
Loading…
Reference in New Issue