зеркало из https://github.com/microsoft/clang.git
Fix a pretty bad bug where if a constructor (or conversion function) was marked as 'explicit', but then defined out-of-line, we would not treat it as being explicit.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94366 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
0757c8ccb7
Коммит
7a6e13aa2e
|
@ -1084,8 +1084,9 @@ public:
|
|||
/// };
|
||||
/// @endcode
|
||||
class CXXConstructorDecl : public CXXMethodDecl {
|
||||
/// Explicit - Whether this constructor is explicit.
|
||||
bool Explicit : 1;
|
||||
/// Explicit - Whether this constructor declaration has the
|
||||
/// 'explicit' keyword specified.
|
||||
bool IsExplicitSpecified : 1;
|
||||
|
||||
/// ImplicitlyDefined - Whether this constructor was implicitly
|
||||
/// defined by the compiler. When false, the constructor was defined
|
||||
|
@ -1103,9 +1104,10 @@ class CXXConstructorDecl : public CXXMethodDecl {
|
|||
|
||||
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
|
||||
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
|
||||
bool isExplicit, bool isInline, bool isImplicitlyDeclared)
|
||||
bool isExplicitSpecified, bool isInline,
|
||||
bool isImplicitlyDeclared)
|
||||
: CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false, isInline),
|
||||
Explicit(isExplicit), ImplicitlyDefined(false),
|
||||
IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
|
||||
BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
|
||||
setImplicit(isImplicitlyDeclared);
|
||||
}
|
||||
|
@ -1118,8 +1120,15 @@ public:
|
|||
bool isExplicit,
|
||||
bool isInline, bool isImplicitlyDeclared);
|
||||
|
||||
/// isExplicitSpecified - Whether this constructor declaration has the
|
||||
/// 'explicit' keyword specified.
|
||||
bool isExplicitSpecified() const { return IsExplicitSpecified; }
|
||||
|
||||
/// isExplicit - Whether this constructor was marked "explicit" or not.
|
||||
bool isExplicit() const { return Explicit; }
|
||||
bool isExplicit() const {
|
||||
return cast<CXXConstructorDecl>(getFirstDeclaration())
|
||||
->isExplicitSpecified();
|
||||
}
|
||||
|
||||
/// isImplicitlyDefined - Whether this constructor was implicitly
|
||||
/// defined. If false, then this constructor was defined by the
|
||||
|
@ -1290,16 +1299,16 @@ public:
|
|||
/// };
|
||||
/// @endcode
|
||||
class CXXConversionDecl : public CXXMethodDecl {
|
||||
/// Explicit - Whether this conversion function is marked
|
||||
/// "explicit", meaning that it can only be applied when the user
|
||||
/// IsExplicitSpecified - Whether this conversion function declaration is
|
||||
/// marked "explicit", meaning that it can only be applied when the user
|
||||
/// explicitly wrote a cast. This is a C++0x feature.
|
||||
bool Explicit : 1;
|
||||
bool IsExplicitSpecified : 1;
|
||||
|
||||
CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
|
||||
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
|
||||
bool isInline, bool isExplicit)
|
||||
bool isInline, bool isExplicitSpecified)
|
||||
: CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false, isInline),
|
||||
Explicit(isExplicit) { }
|
||||
IsExplicitSpecified(isExplicitSpecified) { }
|
||||
|
||||
public:
|
||||
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
|
||||
|
@ -1307,10 +1316,18 @@ public:
|
|||
QualType T, TypeSourceInfo *TInfo,
|
||||
bool isInline, bool isExplicit);
|
||||
|
||||
/// IsExplicitSpecified - Whether this conversion function declaration is
|
||||
/// marked "explicit", meaning that it can only be applied when the user
|
||||
/// explicitly wrote a cast. This is a C++0x feature.
|
||||
bool isExplicitSpecified() const { return IsExplicitSpecified; }
|
||||
|
||||
/// isExplicit - Whether this is an explicit conversion operator
|
||||
/// (C++0x only). Explicit conversion operators are only considered
|
||||
/// when the user has explicitly written a cast.
|
||||
bool isExplicit() const { return Explicit; }
|
||||
bool isExplicit() const {
|
||||
return cast<CXXConversionDecl>(getFirstDeclaration())
|
||||
->isExplicitSpecified();
|
||||
}
|
||||
|
||||
/// getConversionType - Returns the type that this conversion
|
||||
/// function is converting to.
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
|
||||
namespace Constructor {
|
||||
struct A {
|
||||
A(int);
|
||||
};
|
||||
|
||||
struct B {
|
||||
explicit B(int);
|
||||
};
|
||||
|
||||
B::B(int) { }
|
||||
|
||||
struct C {
|
||||
void f(const A&);
|
||||
void f(const B&);
|
||||
};
|
||||
|
||||
void f(C c) {
|
||||
c.f(10);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Conversion {
|
||||
struct A {
|
||||
operator int();
|
||||
explicit operator bool();
|
||||
};
|
||||
|
||||
A::operator bool() { return false; }
|
||||
|
||||
struct B {
|
||||
void f(int);
|
||||
void f(bool);
|
||||
};
|
||||
|
||||
void f(A a, B b) {
|
||||
b.f(a);
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче