forked from OSchip/llvm-project
Take care another assert:
struct A { struct B; }; struct A::B { void m() {} // Assertion failed: getContainingDC(DC) == CurContext && "The next DeclContext should be lexically contained in the current one." }; Introduce DeclContext::getLexicalParent which may be different from DeclContext::getParent when nested-names are involved, e.g: namespace A { struct S; } struct A::S {}; // getParent() == namespace 'A' // getLexicalParent() == translation unit llvm-svn: 59650
This commit is contained in:
parent
ef5e6934cb
commit
0d09c4944e
|
@ -300,6 +300,21 @@ public:
|
|||
const_cast<const DeclContext*>(this)->getParent());
|
||||
}
|
||||
|
||||
/// getLexicalParent - Returns the containing lexical DeclContext. May be
|
||||
/// different from getParent, e.g.:
|
||||
///
|
||||
/// namespace A {
|
||||
/// struct S;
|
||||
/// }
|
||||
/// struct A::S {}; // getParent() == namespace 'A'
|
||||
/// // getLexicalParent() == translation unit
|
||||
///
|
||||
const DeclContext *getLexicalParent() const;
|
||||
DeclContext *getLexicalParent() {
|
||||
return const_cast<DeclContext*>(
|
||||
const_cast<const DeclContext*>(this)->getLexicalParent());
|
||||
}
|
||||
|
||||
bool isFunctionOrMethod() const {
|
||||
switch (DeclKind) {
|
||||
case Decl::Block:
|
||||
|
|
|
@ -361,3 +361,12 @@ const DeclContext *DeclContext::getParent() const {
|
|||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const DeclContext *DeclContext::getLexicalParent() const {
|
||||
if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
|
||||
return SD->getLexicalDeclContext();
|
||||
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(this))
|
||||
return BD->getParentContext();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -53,10 +53,10 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) {
|
|||
// A C++ inline method is parsed *after* the topmost class it was declared in
|
||||
// is fully parsed (it's "complete").
|
||||
// The parsing of a C++ inline method happens at the declaration context of
|
||||
// the topmost (non-nested) class it is declared in.
|
||||
// the topmost (non-nested) class it is lexically declared in.
|
||||
assert(isa<CXXRecordDecl>(MD->getParent()) && "C++ method not in Record.");
|
||||
DC = MD->getParent();
|
||||
while (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC->getParent()))
|
||||
while (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC->getLexicalParent()))
|
||||
DC = RD;
|
||||
|
||||
// Return the declaration context of the topmost class the inline method is
|
||||
|
@ -70,7 +70,7 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) {
|
|||
if (ScopedDecl *SD = dyn_cast<ScopedDecl>(DC))
|
||||
return SD->getLexicalDeclContext();
|
||||
|
||||
return DC->getParent();
|
||||
return DC->getLexicalParent();
|
||||
}
|
||||
|
||||
void Sema::PushDeclContext(DeclContext *DC) {
|
||||
|
|
|
@ -45,12 +45,19 @@ struct A::undef; // expected-error {{'undef' does not name a tag member in the s
|
|||
namespace A2 {
|
||||
typedef int INT;
|
||||
struct RC;
|
||||
struct CC {
|
||||
struct NC;
|
||||
};
|
||||
}
|
||||
|
||||
struct A2::RC {
|
||||
INT x;
|
||||
};
|
||||
|
||||
struct A2::CC::NC {
|
||||
void m() {}
|
||||
};
|
||||
|
||||
void f3() {
|
||||
N::x = 0; // expected-error {{use of undeclared identifier 'N'}}
|
||||
int N;
|
||||
|
|
Loading…
Reference in New Issue