diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-09-20 01:15:31 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-09-20 01:15:31 +0000 |
commit | 541b38be7bf3afded3269a33586418254d82d7b3 (patch) | |
tree | 50251df12a54fbe196671445b8eee3d1a785b8cd /clang/lib/Sema/SemaCodeComplete.cpp | |
parent | 508939428d005dff37df7f2131aeb06ed674b719 (diff) | |
download | bcm5719-llvm-541b38be7bf3afded3269a33586418254d82d7b3.tar.gz bcm5719-llvm-541b38be7bf3afded3269a33586418254d82d7b3.zip |
Switch the semantic DeclContext for a block-scope declaration of a function or
variable from being the function to being the enclosing namespace scope (in
C++) or the TU (in C). This allows us to fix a selection of related issues
where we would build incorrect redeclaration chains for such declarations, and
fail to notice type mismatches.
Such declarations are put into a new IdentifierNamespace, IDNS_LocalExtern,
which is only found when searching scopes, and not found when searching
DeclContexts. Such a declaration is only made visible in its DeclContext if
there are no non-LocalExtern declarations.
llvm-svn: 191064
Diffstat (limited to 'clang/lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 5e084eb5d41..e3e17b96018 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -715,8 +715,8 @@ unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) { return CCP_Unlikely; // Context-based decisions. - const DeclContext *DC = ND->getDeclContext()->getRedeclContext(); - if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC)) { + const DeclContext *LexicalDC = ND->getLexicalDeclContext(); + if (LexicalDC->isFunctionOrMethod()) { // _cmd is relatively rare if (const ImplicitParamDecl *ImplicitParam = dyn_cast<ImplicitParamDecl>(ND)) @@ -726,6 +726,8 @@ unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) { return CCP_LocalDeclaration; } + + const DeclContext *DC = ND->getDeclContext()->getRedeclContext(); if (DC->isRecord() || isa<ObjCContainerDecl>(DC)) return CCP_MemberDeclaration; @@ -876,8 +878,8 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) { for (; I != IEnd; ++I) { // A tag declaration does not hide a non-tag declaration. if (I->first->hasTagIdentifierNamespace() && - (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary | - Decl::IDNS_ObjCProtocol))) + (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary | + Decl::IDNS_LocalExtern | Decl::IDNS_ObjCProtocol))) continue; // Protocols are in distinct namespaces from everything else. @@ -1038,7 +1040,9 @@ void ResultBuilder::ExitScope() { bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const { ND = cast<NamedDecl>(ND->getUnderlyingDecl()); - unsigned IDNS = Decl::IDNS_Ordinary; + // If name lookup finds a local extern declaration, then we are in a + // context where it behaves like an ordinary name. + unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; if (SemaRef.getLangOpts().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; else if (SemaRef.getLangOpts().ObjC1) { @@ -1056,7 +1060,7 @@ bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const { if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) return false; - unsigned IDNS = Decl::IDNS_Ordinary; + unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; if (SemaRef.getLangOpts().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; else if (SemaRef.getLangOpts().ObjC1) { @@ -1083,7 +1087,7 @@ bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const { bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const { ND = cast<NamedDecl>(ND->getUnderlyingDecl()); - unsigned IDNS = Decl::IDNS_Ordinary; + unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; if (SemaRef.getLangOpts().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace; |