summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-04-27 13:50:30 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-04-27 13:50:30 +0000
commit081148986a60a761ac7528a9a132cab2ec70273b (patch)
tree94d2519348f1902edfbc32e6039e8c50b6d5c100 /clang/lib/Sema/SemaDecl.cpp
parented1eec4812bee974d9e7aafff96950184371b9af (diff)
downloadbcm5719-llvm-081148986a60a761ac7528a9a132cab2ec70273b.tar.gz
bcm5719-llvm-081148986a60a761ac7528a9a132cab2ec70273b.zip
Parsing of namespaces:
-NamespaceDecl for the AST -Checks for name clashes between namespaces and tag/normal declarations. This commit doesn't implement proper name lookup for namespaces. llvm-svn: 50321
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp81
1 files changed, 46 insertions, 35 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 373aaceb87f..61cfa798c27 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -43,7 +43,7 @@ Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) {
}
void Sema::PushDeclContext(DeclContext *DC) {
- assert( ( (DC->isFunctionOrMethod() && isa<TranslationUnitDecl>(CurContext))
+ assert( ( (isa<ObjCMethodDecl>(DC) && isa<TranslationUnitDecl>(CurContext))
|| DC->getParent() == CurContext ) &&
"The next DeclContext should be directly contained in the current one.");
CurContext = DC;
@@ -52,7 +52,7 @@ void Sema::PushDeclContext(DeclContext *DC) {
void Sema::PopDeclContext() {
assert(CurContext && "DeclContext imbalance!");
// If CurContext is a ObjC method, getParent() will return NULL.
- CurContext = CurContext->isFunctionOrMethod()
+ CurContext = isa<ObjCMethodDecl>(CurContext)
? Context.getTranslationUnitDecl()
: CurContext->getParent();
}
@@ -1332,42 +1332,53 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
// If this is a named struct, check to see if there was a previous forward
// declaration or definition.
- if (TagDecl *PrevDecl =
- dyn_cast_or_null<TagDecl>(LookupDecl(Name, Decl::IDNS_Tag, S))) {
+ // Use ScopedDecl instead of TagDecl, because a NamespaceDecl may come up.
+ if (ScopedDecl *PrevDecl =
+ dyn_cast_or_null<ScopedDecl>(LookupDecl(Name, Decl::IDNS_Tag, S))) {
- // 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 || 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_use_with_wrong_tag, Name->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_use);
- }
-
- // If this is a use or a forward declaration, we're good.
- if (TK != TK_Definition)
- return PrevDecl;
-
- // Diagnose attempts to redefine a tag.
- if (PrevDecl->isDefinition()) {
- Diag(NameLoc, diag::err_redefinition, Name->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- // If this is a redefinition, recover by making this struct be
- // anonymous, which will make any later references get the previous
- // definition.
- Name = 0;
- } else {
- // Okay, this is definition of a previously declared or referenced tag.
- // Move the location of the decl to be the definition site.
- PrevDecl->setLocation(NameLoc);
- return PrevDecl;
+ assert((isa<TagDecl>(PrevDecl) || isa<NamespaceDecl>(PrevDecl)) &&
+ "unexpected Decl type");
+ if (TagDecl *PrevTagDecl = dyn_cast<TagDecl>(PrevDecl)) {
+ // 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 || 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_use_with_wrong_tag, Name->getName());
+ Diag(PrevDecl->getLocation(), diag::err_previous_use);
+ }
+
+ // If this is a use or a forward declaration, we're good.
+ if (TK != TK_Definition)
+ return PrevDecl;
+
+ // Diagnose attempts to redefine a tag.
+ if (PrevTagDecl->isDefinition()) {
+ Diag(NameLoc, diag::err_redefinition, Name->getName());
+ Diag(PrevDecl->getLocation(), diag::err_previous_definition);
+ // If this is a redefinition, recover by making this struct be
+ // anonymous, which will make any later references get the previous
+ // definition.
+ Name = 0;
+ } else {
+ // Okay, this is definition of a previously declared or referenced tag.
+ // Move the location of the decl to be the definition site.
+ PrevDecl->setLocation(NameLoc);
+ return PrevDecl;
+ }
}
+ // If we get here, this is a definition of a new struct type in a nested
+ // scope, e.g. "struct foo; void bar() { struct foo; }", just create a new
+ // type.
+ } else {
+ // 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());
+ Diag(PrevDecl->getLocation(), diag::err_previous_definition);
+ Name = 0;
}
- // If we get here, this is a definition of a new struct type in a nested
- // scope, e.g. "struct foo; void bar() { struct foo; }", just create a new
- // type.
}
// If there is an identifier, use the location of the identifier as the
OpenPOWER on IntegriCloud