PR27513: When determining which declaration to put into an exported lookup

table for a module / PCH, never map from a normal declaration of a class to an
injected-class-name declaration (or vice versa). Those declarations live in
distinct lookup tables and should not be confused.

We really shouldn't be using a CXXRecordDecl to represent an
injected-class-name in the first place; I've filed PR27532 so we don't forget.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@267632 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Smith 2016-04-26 23:40:43 +00:00
parent 2e58709f44
commit ca0241ca1e
13 changed files with 51 additions and 2 deletions

View File

@ -3107,11 +3107,20 @@ static NamedDecl *getDeclForLocalLookup(const LangOptions &LangOpts,
if (Decl *Redecl = D->getPreviousDecl()) {
// For Redeclarable decls, a prior declaration might be local.
for (; Redecl; Redecl = Redecl->getPreviousDecl()) {
if (!Redecl->isFromASTFile())
// If we find a local decl, we're done.
if (!Redecl->isFromASTFile()) {
// Exception: in very rare cases (for injected-class-names), not all
// redeclarations are in the same semantic context. Skip ones in a
// different context. They don't go in this lookup table at all.
if (!Redecl->getDeclContext()->getRedeclContext()->Equals(
D->getDeclContext()->getRedeclContext()))
continue;
return cast<NamedDecl>(Redecl);
}
// If we find a decl from a (chained-)PCH stop since we won't find a
// local one.
if (D->getOwningModuleID() == 0)
if (Redecl->getOwningModuleID() == 0)
break;
}
} else if (Decl *First = D->getCanonicalDecl()) {

View File

@ -0,0 +1,5 @@
#include "b.h"
inline void f() { basic_string<char> s; }
#include "c.h"

View File

@ -0,0 +1,3 @@
#include "mystring.h"
#include "b1.h"
#include "b2.h"

View File

@ -0,0 +1 @@
#include "b11.h"

View File

@ -0,0 +1,2 @@
#include "mystring.h"
#include "b111.h"

View File

@ -0,0 +1,3 @@
#include "mystring.h"
#include "b1111.h"
#include "b1112.h"

View File

@ -0,0 +1 @@
#include "mystring.h"

View File

@ -0,0 +1 @@
#include "mystring.h"

View File

@ -0,0 +1 @@
#include "mystring.h"

View File

@ -0,0 +1 @@
#include "mystring.h"

View File

@ -0,0 +1,7 @@
module "c.h" {header "c.h" export *}
module "b2.h" { header "b2.h" export *}
module "b.h" {header "b.h" export *}
module "b111.h" { header "b111.h" export *}
module "b11.h" { header "b11.h" export *}
module "b1111.h" { header "b1111.h" export *}
module "b1112.h" { header "b1112.h" export *}

View File

@ -0,0 +1,8 @@
#ifndef _GLIBCXX_STRING
#define _GLIBCXX_STRING
template<typename> struct basic_string {
struct _Alloc_hider {} _M_dataplus;
~basic_string() { _Alloc_hider h; }
};
extern template class basic_string<char>;
#endif

7
test/Modules/pr27513.cpp Normal file
View File

@ -0,0 +1,7 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27513 -verify %s
// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27513/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR27513 -verify %s
#include "Inputs/PR27513/a.h"
//expected-no-diagnostics