mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
Make Decl::isOutOfLine() virtual, and use that to determine when definitions
are for out of line declarations more easily. This simplifies the logic and handles the case of out-of-line class definitions correctly. Fixes PR6107. llvm-svn: 96729
This commit is contained in:
@@ -561,7 +561,7 @@ public:
|
||||
|
||||
/// \brief Determine whether this is or was instantiated from an out-of-line
|
||||
/// definition of a static data member.
|
||||
bool isOutOfLine() const;
|
||||
virtual bool isOutOfLine() const;
|
||||
|
||||
/// \brief If this is a static data member, find its out-of-line definition.
|
||||
VarDecl *getOutOfLineDefinition();
|
||||
@@ -1306,7 +1306,7 @@ public:
|
||||
|
||||
/// \brief Determine whether this is or was instantiated from an out-of-line
|
||||
/// definition of a member function.
|
||||
bool isOutOfLine() const;
|
||||
virtual bool isOutOfLine() const;
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
|
||||
@@ -331,7 +331,7 @@ public:
|
||||
return const_cast<Decl*>(this)->getLexicalDeclContext();
|
||||
}
|
||||
|
||||
bool isOutOfLine() const {
|
||||
virtual bool isOutOfLine() const {
|
||||
return getLexicalDeclContext() != getDeclContext();
|
||||
}
|
||||
|
||||
|
||||
@@ -680,12 +680,12 @@ const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const {
|
||||
}
|
||||
|
||||
bool VarDecl::isOutOfLine() const {
|
||||
if (!isStaticDataMember())
|
||||
return false;
|
||||
|
||||
if (Decl::isOutOfLine())
|
||||
return true;
|
||||
|
||||
|
||||
if (!isStaticDataMember())
|
||||
return false;
|
||||
|
||||
// If this static data member was instantiated from a static data member of
|
||||
// a class template, check whether that static data member was defined
|
||||
// out-of-line.
|
||||
|
||||
@@ -436,14 +436,15 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
|
||||
if (AddToContext)
|
||||
CurContext->addDecl(D);
|
||||
|
||||
// Out-of-line function and variable definitions should not be pushed into
|
||||
// scope.
|
||||
if ((isa<FunctionTemplateDecl>(D) &&
|
||||
cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->isOutOfLine()) ||
|
||||
(isa<FunctionDecl>(D) &&
|
||||
(cast<FunctionDecl>(D)->isFunctionTemplateSpecialization() ||
|
||||
cast<FunctionDecl>(D)->isOutOfLine())) ||
|
||||
(isa<VarDecl>(D) && cast<VarDecl>(D)->isOutOfLine()))
|
||||
// Out-of-line definitions shouldn't be pushed into scope in C++.
|
||||
// Out-of-line variable and function definitions shouldn't even in C.
|
||||
if ((getLangOptions().CPlusPlus || isa<VarDecl>(D) || isa<FunctionDecl>(D)) &&
|
||||
D->isOutOfLine())
|
||||
return;
|
||||
|
||||
// Template instantiations should also not be pushed into scope.
|
||||
if (isa<FunctionDecl>(D) &&
|
||||
cast<FunctionDecl>(D)->isFunctionTemplateSpecialization())
|
||||
return;
|
||||
|
||||
// If this replaces anything in the current scope,
|
||||
|
||||
25
clang/test/CXX/class/class.nest/p3.cpp
Normal file
25
clang/test/CXX/class/class.nest/p3.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
// C++0x [class.nest] p3:
|
||||
// If class X is defined in a namespace scope, a nested class Y may be
|
||||
// declared in class X and later defined in the definition of class X or be
|
||||
// later defined in a namespace scope enclosing the definition of class X.
|
||||
|
||||
namespace example {
|
||||
class E {
|
||||
class I1;
|
||||
class I2;
|
||||
class I1 { };
|
||||
};
|
||||
class E::I2 { };
|
||||
}
|
||||
|
||||
// Don't insert out-of-line inner class definitions into the namespace scope.
|
||||
namespace PR6107 {
|
||||
struct S1 { };
|
||||
struct S2 {
|
||||
struct S1;
|
||||
};
|
||||
struct S2::S1 { };
|
||||
S1 s1;
|
||||
}
|
||||
Reference in New Issue
Block a user