diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/IdentifierResolver.cpp | 27 | ||||
-rw-r--r-- | lib/Sema/IdentifierResolver.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 5 |
4 files changed, 42 insertions, 12 deletions
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp index 79898e4380..037802c640 100644 --- a/lib/Sema/IdentifierResolver.cpp +++ b/lib/Sema/IdentifierResolver.cpp @@ -15,6 +15,7 @@ #include "IdentifierResolver.h" #include "clang/Basic/IdentifierTable.h" #include "clang/AST/Decl.h" +#include "clang/Parse/Scope.h" #include <list> #include <vector> @@ -113,6 +114,25 @@ void IdentifierResolver::AddDecl(NamedDecl *D, Scope *S) { } else IDI = toIdDeclInfo(Ptr); + // C++ [basic.scope]p4: + // -- exactly one declaration shall declare a class name or + // enumeration name that is not a typedef name and the other + // declarations shall all refer to the same object or + // enumerator, or all refer to functions and function templates; + // in this case the class name or enumeration name is hidden. + if (isa<TagDecl>(D)) { + // We are pushing the name of a tag (enum or class). + IdDeclInfo::ShadowedIter TopIter = IDI->shadowed_end() - 1; + if (S->isDeclScope(*TopIter)) { + // There is already a declaration with the same name in the same + // scope. It must be found before we find the new declaration, + // so swap the order on the shadowed declaration stack. + NamedDecl *Temp = *TopIter; + *TopIter = D; + D = Temp; + } + } + IDI->PushShadowed(D); } @@ -159,16 +179,15 @@ void IdentifierResolver::RemoveDecl(NamedDecl *D) { /// Lookup - Find the non-shadowed decl that belongs to a particular /// Decl::IdentifierNamespace. -NamedDecl *IdentifierResolver::Lookup(const IdentifierInfo *II, unsigned NSI) { +NamedDecl *IdentifierResolver::Lookup(const IdentifierInfo *II, unsigned NS) { assert(II && "null param passed"); - Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI; void *Ptr = II->getFETokenInfo<void>(); if (!Ptr) return NULL; if (isDeclPtr(Ptr)) { NamedDecl *D = static_cast<NamedDecl*>(Ptr); - return (D->getIdentifierNamespace() == NS) ? D : NULL; + return (D->getIdentifierNamespace() & NS) ? D : NULL; } IdDeclInfo *IDI = toIdDeclInfo(Ptr); @@ -178,7 +197,7 @@ NamedDecl *IdentifierResolver::Lookup(const IdentifierInfo *II, unsigned NSI) { for (IdDeclInfo::ShadowedIter SI = IDI->shadowed_end(); SI != IDI->shadowed_begin(); --SI) { NamedDecl *D = *(SI-1); - if (D->getIdentifierNamespace() == NS) + if (D->getIdentifierNamespace() & NS) return D; } diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h index bdaab694fe..abe568d602 100644 --- a/lib/Sema/IdentifierResolver.h +++ b/lib/Sema/IdentifierResolver.h @@ -38,8 +38,8 @@ public: /// The decl must already be part of the decl chain. void RemoveDecl(NamedDecl *D); - /// Lookup - Find the non-shadowed decl that belongs to a particular - /// Decl::IdentifierNamespace. + /// Lookup - Find the non-shadowed decl that belongs to one or more + /// of the specified Decl::IdentifierNamespaces. NamedDecl *Lookup(const IdentifierInfo *II, unsigned NSI); private: diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c47a027fec..328741ec0f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -35,7 +35,9 @@ using namespace clang; Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) { Decl *IIDecl = LookupDecl(&II, Decl::IDNS_Ordinary, S, false); - if (IIDecl && (isa<TypedefDecl>(IIDecl) || isa<ObjCInterfaceDecl>(IIDecl))) + if (IIDecl && (isa<TypedefDecl>(IIDecl) || + isa<ObjCInterfaceDecl>(IIDecl) || + isa<TagDecl>(IIDecl))) return IIDecl; return 0; } @@ -102,7 +104,9 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) { Decl *Sema::LookupDecl(const IdentifierInfo *II, unsigned NSI, Scope *S, bool enableLazyBuiltinCreation) { if (II == 0) return 0; - Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI; + unsigned NS = NSI; + if (getLangOptions().CPlusPlus && (NS & Decl::IDNS_Ordinary)) + NS |= Decl::IDNS_Tag; // Scan up the scope chain looking for a decl that matches this identifier // that is in the appropriate namespace. This search should not take long, as @@ -113,7 +117,7 @@ Decl *Sema::LookupDecl(const IdentifierInfo *II, unsigned NSI, // If we didn't find a use of this identifier, and if the identifier // corresponds to a compiler builtin, create the decl object for the builtin // now, injecting it into translation unit scope, and return it. - if (NS == Decl::IDNS_Ordinary) { + if (NS & Decl::IDNS_Ordinary) { if (enableLazyBuiltinCreation) { // If this is a builtin on this (or all) targets, create the decl. if (unsigned BuiltinID = II->getBuiltinID()) @@ -746,7 +750,13 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { Decl *PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S); ScopedDecl *New; bool InvalidDecl = false; - + + // In C++, the previous declaration we find might be a tag type + // (class or enum). In this case, the new declaration will hide the + // tag type. + if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag) + PrevDecl = 0; + QualType R = GetTypeForDeclarator(D, S); assert(!R.isNull() && "GetTypeForDeclarator() returned null type"); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 223cb56636..33797c4255 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -105,7 +105,7 @@ QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) { DS.getTypeSpecSign() == 0 && "Can't handle qualifiers on typedef names yet!"); // TypeQuals handled by caller. - Result = Context.getTagDeclType(cast<TagDecl>(D)); + Result = Context.getTypeDeclType(cast<TypeDecl>(D)); break; } case DeclSpec::TST_typedef: { @@ -114,6 +114,7 @@ QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) { assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 && DS.getTypeSpecSign() == 0 && "Can't handle qualifiers on typedef names yet!"); + // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so // we have this "hack" for now... if (ObjCInterfaceDecl *ObjCIntDecl = dyn_cast<ObjCInterfaceDecl>(D)) { @@ -140,7 +141,7 @@ QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) { } } // TypeQuals handled by caller. - Result = Context.getTypedefType(cast<TypedefDecl>(D)); + Result = Context.getTypeDeclType(dyn_cast<TypeDecl>(D)); break; } case DeclSpec::TST_typeofType: |