aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-11-09 22:53:32 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-11-09 22:53:32 +0000
commit0f84a23cc542a76f97aee735cdf3ff948b149879 (patch)
treea76de5c3a878148917084f802bf006379f325637 /lib/Sema/SemaDecl.cpp
parent630c81b78a6a469707e2940a421da874f3b12643 (diff)
When a tag has nested-name ('struct foo::bar'), use not 'CurContext' but the context of the nested-name ('foo::').
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58945 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp34
1 files changed, 19 insertions, 15 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index d0cb986fb6..cae05a365c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2145,18 +2145,20 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
if (Kind != TagDecl::TK_enum)
return ActOnTagStruct(S, Kind, TK, KWLoc, SS, Name, NameLoc, Attr);
- ScopedDecl *PrevDecl;
+ DeclContext *DC = CurContext;
+ ScopedDecl *PrevDecl = 0;
if (Name && SS.isNotEmpty()) {
// We have a nested-name tag ('struct foo::bar').
// Check for invalid 'foo::'.
- DeclContext *DC = static_cast<DeclContext*>(SS.getScopeRep());
- if (DC == 0) {
+ if (SS.isInvalid()) {
Name = 0;
goto CreateNewDecl;
}
+ DC = static_cast<DeclContext*>(SS.getScopeRep());
+ // Look-up name inside 'foo::'.
PrevDecl = dyn_cast_or_null<TagDecl>(LookupDecl(Name, Decl::IDNS_Tag,S,DC));
// A tag 'foo::bar' must already exist.
@@ -2180,7 +2182,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
// 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 (TK == TK_Reference || isDeclInScope(PrevDecl, CurContext, S)) {
+ if (TK == TK_Reference || isDeclInScope(PrevDecl, DC, S)) {
// Make sure that this wasn't declared as an enum and now used as a
// struct or something similar.
if (PrevTagDecl->getTagKind() != Kind) {
@@ -2215,7 +2217,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
// type.
} else {
// PrevDecl is a namespace.
- if (isDeclInScope(PrevDecl, CurContext, S)) {
+ if (isDeclInScope(PrevDecl, DC, S)) {
// The tag name clashes with a namespace name, issue an error and
// recover by making this tag be anonymous.
Diag(NameLoc, diag::err_redefinition_different_kind, Name->getName());
@@ -2237,7 +2239,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
if (Kind == TagDecl::TK_enum) {
// FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
// enum X { A, B, C } D; D should chain to X.
- New = EnumDecl::Create(Context, CurContext, Loc, Name, 0);
+ New = EnumDecl::Create(Context, DC, Loc, Name, 0);
// If this is an undefined enum, warn.
if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum);
} else {
@@ -2247,9 +2249,9 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
// struct X { int A; } D; D should chain to X.
if (getLangOptions().CPlusPlus)
// FIXME: Look for a way to use RecordDecl for simple structs.
- New = CXXRecordDecl::Create(Context, Kind, CurContext, Loc, Name);
+ New = CXXRecordDecl::Create(Context, Kind, DC, Loc, Name);
else
- New = RecordDecl::Create(Context, Kind, CurContext, Loc, Name);
+ New = RecordDecl::Create(Context, Kind, DC, Loc, Name);
}
// If this has an identifier, add it to the scope stack.
@@ -2275,18 +2277,20 @@ Sema::DeclTy *Sema::ActOnTagStruct(Scope *S, TagDecl::TagKind Kind, TagKind TK,
SourceLocation KWLoc, const CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
AttributeList *Attr) {
- ScopedDecl *PrevDecl;
+ DeclContext *DC = CurContext;
+ ScopedDecl *PrevDecl = 0;
if (Name && SS.isNotEmpty()) {
// We have a nested-name tag ('struct foo::bar').
// Check for invalid 'foo::'.
- DeclContext *DC = static_cast<DeclContext*>(SS.getScopeRep());
- if (DC == 0) {
+ if (SS.isInvalid()) {
Name = 0;
goto CreateNewDecl;
}
+ DC = static_cast<DeclContext*>(SS.getScopeRep());
+ // Look-up name inside 'foo::'.
PrevDecl = dyn_cast_or_null<TagDecl>(LookupDecl(Name, Decl::IDNS_Tag,S,DC));
// A tag 'foo::bar' must already exist.
@@ -2311,7 +2315,7 @@ Sema::DeclTy *Sema::ActOnTagStruct(Scope *S, TagDecl::TagKind Kind, TagKind TK,
// 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 (TK == TK_Reference || isDeclInScope(PrevDecl, CurContext, S)) {
+ if (TK == TK_Reference || isDeclInScope(PrevDecl, DC, S)) {
// Make sure that this wasn't declared as an enum and now used as a
// struct or something similar.
if (PrevTagDecl->getTagKind() != Kind) {
@@ -2359,7 +2363,7 @@ Sema::DeclTy *Sema::ActOnTagStruct(Scope *S, TagDecl::TagKind Kind, TagKind TK,
}
} else {
// PrevDecl is a namespace.
- if (isDeclInScope(PrevDecl, CurContext, S)) {
+ if (isDeclInScope(PrevDecl, DC, S)) {
// The tag name clashes with a namespace name, issue an error and
// recover by making this tag be anonymous.
Diag(NameLoc, diag::err_redefinition_different_kind, Name->getName());
@@ -2383,10 +2387,10 @@ Sema::DeclTy *Sema::ActOnTagStruct(Scope *S, TagDecl::TagKind Kind, TagKind TK,
// struct X { int A; } D; D should chain to X.
if (getLangOptions().CPlusPlus)
// FIXME: Look for a way to use RecordDecl for simple structs.
- New = CXXRecordDecl::Create(Context, Kind, CurContext, Loc, Name,
+ New = CXXRecordDecl::Create(Context, Kind, DC, Loc, Name,
dyn_cast_or_null<CXXRecordDecl>(PrevDecl));
else
- New = RecordDecl::Create(Context, Kind, CurContext, Loc, Name,
+ New = RecordDecl::Create(Context, Kind, DC, Loc, Name,
dyn_cast_or_null<RecordDecl>(PrevDecl));
// If this has an identifier, add it to the scope stack.