]> granicus.if.org Git - clang/commitdiff
Fix a pretty bad bug where if a constructor (or conversion function) was marked as...
authorAnders Carlsson <andersca@mac.com>
Sun, 24 Jan 2010 17:15:04 +0000 (17:15 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 24 Jan 2010 17:15:04 +0000 (17:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94366 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclCXX.h
test/SemaCXX/explicit.cpp [new file with mode: 0644]

index 73ebf52d383b95b5530ef47636b6f41d3f9e99b6..6692394b2d12aca65d41225e373bd3a30c781a8b 100644 (file)
@@ -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 (file)
index 0000000..717ed1e
--- /dev/null
@@ -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);
+  }
+}