diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 32 | ||||
-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 |
5 files changed, 65 insertions, 21 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 5af59aadd3..e4b48e21e4 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -788,6 +788,28 @@ QualType ASTContext::getFunctionType(QualType ResultTy, QualType *ArgArray, return QualType(FTP, 0); } +/// getTypeDeclType - Return the unique reference to the type for the +/// specified type declaration. +QualType ASTContext::getTypeDeclType(TypeDecl *Decl) { + if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); + + if (TypedefDecl *Typedef = dyn_cast_or_null<TypedefDecl>(Decl)) + return getTypedefType(Typedef); + else if (ObjCInterfaceDecl *ObjCInterface + = dyn_cast_or_null<ObjCInterfaceDecl>(Decl)) + return getObjCInterfaceType(ObjCInterface); + else if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Decl)) { + Decl->TypeForDecl = new RecordType(Record); + Types.push_back(Decl->TypeForDecl); + return QualType(Decl->TypeForDecl, 0); + } else if (EnumDecl *Enum = dyn_cast_or_null<EnumDecl>(Decl)) { + Decl->TypeForDecl = new EnumType(Enum); + Types.push_back(Decl->TypeForDecl); + return QualType(Decl->TypeForDecl, 0); + } else + assert(false && "TypeDecl without a type?"); +} + /// getTypedefType - Return the unique reference to the type for the /// specified typename decl. QualType ASTContext::getTypedefType(TypedefDecl *Decl) { @@ -913,15 +935,7 @@ QualType ASTContext::getTypeOfType(QualType tofType) { /// specified TagDecl (struct/union/class/enum) decl. QualType ASTContext::getTagDeclType(TagDecl *Decl) { assert (Decl); - - // The decl stores the type cache. - if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); - - TagType* T = new TagType(Decl, QualType()); - Types.push_back(T); - Decl->TypeForDecl = T; - - return QualType(T, 0); + return getTypeDeclType(Decl); } /// getSizeType - Return the unique type for "size_t" (C99 7.17), the result 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: |