mirror of
https://github.com/intel/llvm.git
synced 2026-02-02 10:08:59 +08:00
When parsing a struct/union tag, we need to know whether the tag is a use
or a definition/declaration of a tag. This is required to handle C99 6.7.2.3p11 properly. llvm-svn: 39274
This commit is contained in:
@@ -83,7 +83,7 @@ public:
|
||||
Decl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
|
||||
Scope *S);
|
||||
|
||||
virtual DeclTy *ParseStructUnionTag(Scope *S, bool isUnion,
|
||||
virtual DeclTy *ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
|
||||
SourceLocation KWLoc,IdentifierInfo *Name,
|
||||
SourceLocation NameLoc);
|
||||
|
||||
|
||||
@@ -141,7 +141,6 @@ Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
||||
const DeclaratorChunk::ParamInfo &PI = FTI.Fun.ArgInfo[ArgNo];
|
||||
|
||||
IdentifierInfo *II = PI.Ident;
|
||||
|
||||
if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
|
||||
|
||||
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
|
||||
@@ -265,14 +264,31 @@ Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
|
||||
/// ParseStructUnionTag - This is invoked when we see 'struct foo' or
|
||||
/// 'struct {'. In the former case, Name will be non-null. In the later case,
|
||||
/// Name will be null. isUnion indicates whether this is a union or struct tag.
|
||||
Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion,
|
||||
/// isUse indicates whether this is a use of a preexisting struct tag, or if it
|
||||
/// is a definition or declaration of a new one.
|
||||
Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
|
||||
SourceLocation KWLoc,
|
||||
IdentifierInfo *Name,
|
||||
SourceLocation NameLoc) {
|
||||
// If this is a use of an existing tag, it must have a name.
|
||||
assert((isUse || Name != 0) && "Nameless record must have a name!");
|
||||
|
||||
// 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)) {
|
||||
|
||||
// If this is a use of a previous tag, or if the tag is already declared in
|
||||
// the same scope (so that the definition/declaration completes or
|
||||
// rementions the tag), reuse the decl.
|
||||
if (isUse || S->isDeclScope(PrevDecl)) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
// TODO: verify it's struct/union, etc.
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// If there is an identifier, use the location of the identifier as the
|
||||
|
||||
@@ -454,9 +454,17 @@ void Parser::ParseStructUnionSpecifier(DeclSpec &DS) {
|
||||
|
||||
// There are three options here. If we have 'struct foo;', then this is a
|
||||
// forward declaration. If we have 'struct foo {...' then this is a
|
||||
// definition. Otherwise we have something like 'struct foo xyz', a use.
|
||||
DeclTy *TagDecl = Actions.ParseStructUnionTag(CurScope, isUnion, StartLoc,
|
||||
Name, NameLoc);
|
||||
// definition. Otherwise we have something like 'struct foo xyz', a use. Tell
|
||||
// the actions module whether this is a definition (forward or not) of the
|
||||
// type insted of a use.
|
||||
//
|
||||
// This is needed to handle stuff like this right (C99 6.7.2.3p11):
|
||||
// struct foo {..}; void bar() { struct foo; } <- new foo in bar.
|
||||
// struct foo {..}; void bar() { struct foo x; } <- use of old foo.
|
||||
//
|
||||
bool isUse = Tok.getKind() != tok::l_brace && Tok.getKind() != tok::semi;
|
||||
DeclTy *TagDecl = Actions.ParseStructUnionTag(CurScope, isUnion, isUse,
|
||||
StartLoc, Name, NameLoc);
|
||||
// TODO: more with the tag decl.
|
||||
if (Tok.getKind() == tok::l_brace) {
|
||||
SourceLocation LBraceLoc = ConsumeBrace();
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
Decl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
|
||||
Scope *S);
|
||||
|
||||
virtual DeclTy *ParseStructUnionTag(Scope *S, bool isUnion,
|
||||
virtual DeclTy *ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
|
||||
SourceLocation KWLoc,IdentifierInfo *Name,
|
||||
SourceLocation NameLoc);
|
||||
|
||||
|
||||
@@ -141,7 +141,6 @@ Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
||||
const DeclaratorChunk::ParamInfo &PI = FTI.Fun.ArgInfo[ArgNo];
|
||||
|
||||
IdentifierInfo *II = PI.Ident;
|
||||
|
||||
if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
|
||||
|
||||
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
|
||||
@@ -265,14 +264,31 @@ Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
|
||||
/// ParseStructUnionTag - This is invoked when we see 'struct foo' or
|
||||
/// 'struct {'. In the former case, Name will be non-null. In the later case,
|
||||
/// Name will be null. isUnion indicates whether this is a union or struct tag.
|
||||
Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion,
|
||||
/// isUse indicates whether this is a use of a preexisting struct tag, or if it
|
||||
/// is a definition or declaration of a new one.
|
||||
Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
|
||||
SourceLocation KWLoc,
|
||||
IdentifierInfo *Name,
|
||||
SourceLocation NameLoc) {
|
||||
// If this is a use of an existing tag, it must have a name.
|
||||
assert((isUse || Name != 0) && "Nameless record must have a name!");
|
||||
|
||||
// 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)) {
|
||||
|
||||
// If this is a use of a previous tag, or if the tag is already declared in
|
||||
// the same scope (so that the definition/declaration completes or
|
||||
// rementions the tag), reuse the decl.
|
||||
if (isUse || S->isDeclScope(PrevDecl)) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
// TODO: verify it's struct/union, etc.
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// If there is an identifier, use the location of the identifier as the
|
||||
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual DeclTy *ParseStructUnionTag(Scope *S, bool isUnion,
|
||||
virtual DeclTy *ParseStructUnionTag(Scope *S, bool isUnion, bool isUse,
|
||||
SourceLocation KWLoc,IdentifierInfo *Name,
|
||||
SourceLocation NameLoc) {
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user