aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-01-24 17:15:04 +0000
committerAnders Carlsson <andersca@mac.com>2010-01-24 17:15:04 +0000
commit7a6e13aa2e3874fecf45043ed1a26900b8c13b98 (patch)
tree1a26f1d49af9aee4a9ee2c4c56f2117bfebe632b
parent0757c8ccb79210ce1f22142851cdcbf6e42a71d6 (diff)
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
-rw-r--r--include/clang/AST/DeclCXX.h39
-rw-r--r--test/SemaCXX/explicit.cpp39
2 files changed, 67 insertions, 11 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 73ebf52d38..6692394b2d 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -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.
diff --git a/test/SemaCXX/explicit.cpp b/test/SemaCXX/explicit.cpp
new file mode 100644
index 0000000000..717ed1e3ca
--- /dev/null
+++ b/test/SemaCXX/explicit.cpp
@@ -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);
+ }
+}